diff --git a/BUILD.gn b/BUILD.gn
index 74a0094..e18b1a8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1003,6 +1003,7 @@
       ":layout_test_data_mojo_bindings_lite",
       "//content/shell:content_shell",
       "//content/test:mojo_web_test_bindings_js_data_deps",
+      "//content/shell:mojo_bindings_js_data_deps",
       "//device/bluetooth/public/mojom:fake_bluetooth_interfaces_js_data_deps",
       "//device/usb/public/mojom:mojom_js_data_deps",
       "//device/vr/public/mojom:mojom_js_data_deps",
diff --git a/DEPS b/DEPS
index f6fc11fc..ecaa419 100644
--- a/DEPS
+++ b/DEPS
@@ -133,11 +133,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': '62b501499a648a495c2c3a4a0d500639777b2bca',
+  'skia_revision': '2f9297dff115615218ddba3e1805103de35b9862',
   # 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': 'ea50a032a6e5e9c796e408bf2dafc14b767d9896',
+  'v8_revision': '30b5ab61e732f0606c5eeef973bd817a9ad38a51',
   # 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.
@@ -145,11 +145,11 @@
   # 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': '3089f92e8a772ec675ea8f70ec1abca91b6b79ae',
+  'angle_revision': '565441b1078b6eabf6f3d1785c5c5de9fd5271a9',
   # 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': 'ac3a4a49bde9fdf764d4c4db659ad6b6ebd81da2',
+  'swiftshader_revision': '58edd47c2c9de72ad580d5cecdb1416250f4a1ab',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -806,7 +806,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '61aa9d9fcdcc2022297f828c06402127dc309ed3',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e3fc3ca79abb0f0088a419f124a5e643c596d6fb',
       'condition': 'checkout_linux',
   },
 
@@ -831,7 +831,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '020b429fbf42915482a97b437a67b6e8398ca9fa',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fe1dbe120c9905324026fa503ac1690dc96e16e2',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -866,7 +866,7 @@
   },
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '1b9f48f542058549f984d981ef331951559f9cb0',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '4500d7f55f3d101a85a55a993bb8125c0825966f',
 
   'src/third_party/flac':
     Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596',
@@ -1130,7 +1130,7 @@
 
   'src/third_party/nasm': {
       'url': Var('chromium_git') + '/chromium/deps/nasm.git' + '@' +
-      '076332ea7c414313ab9d6d5b56396641051df5ea'
+      'c8b248039ec1f75a7c5733bbe76d7fa416ce097a'
   },
 
   'src/third_party/netty-tcnative/src': {
@@ -1396,7 +1396,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@37691666204f287346e6a6dc50e4182b29940c39',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@263da2a5734e4fdb0fa9704e02d7c496f349cb93',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
index ef33a63..5ad3272 100644
--- a/android_webview/browser/aw_permission_manager.cc
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -328,6 +328,7 @@
       case PermissionType::PAYMENT_HANDLER:
       case PermissionType::BACKGROUND_FETCH:
       case PermissionType::IDLE_DETECTION:
+      case PermissionType::PERIODIC_BACKGROUND_SYNC:
         NOTIMPLEMENTED() << "RequestPermissions is not implemented for "
                          << static_cast<int>(permissions[i]);
         pending_request_raw->SetPermissionStatus(permissions[i],
@@ -521,6 +522,7 @@
       case PermissionType::PAYMENT_HANDLER:
       case PermissionType::BACKGROUND_FETCH:
       case PermissionType::IDLE_DETECTION:
+      case PermissionType::PERIODIC_BACKGROUND_SYNC:
         NOTIMPLEMENTED() << "CancelPermission not implemented for "
                          << static_cast<int>(permission);
         break;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index f03ec4e..c348bab 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1271,8 +1271,6 @@
     "ws/ash_gpu_interface_provider.h",
     "ws/ash_window_manager.cc",
     "ws/ash_window_manager.h",
-    "ws/ax_ash_window_utils.cc",
-    "ws/ax_ash_window_utils.h",
     "ws/multi_user_window_manager_bridge.cc",
     "ws/multi_user_window_manager_bridge.h",
     "ws/window_lookup.cc",
@@ -1325,7 +1323,7 @@
     "//ash/autotest",
     "//ash/components/cursor",
     "//ash/components/fast_ink",
-    "//ash/components/shortcut_viewer/public/mojom",
+    "//ash/components/shortcut_viewer",
     "//ash/components/tap_visualizer/public/mojom",
     "//ash/keyboard/arc",
     "//ash/login/resources:resources_grit",
@@ -1537,9 +1535,7 @@
   deps = [
     ":ash_shell_lib",
     ":test_support",
-    "//ash/components/shortcut_viewer:lib",
-    "//ash/components/shortcut_viewer/public/cpp:manifest",
-    "//ash/components/shortcut_viewer/public/mojom",
+    "//ash/components/shortcut_viewer",
     "//ash/components/tap_visualizer:lib",
     "//ash/components/tap_visualizer/public/cpp:manifest",
     "//ash/components/tap_visualizer/public/mojom",
@@ -1918,7 +1914,6 @@
     "wm/workspace/workspace_window_resizer_unittest.cc",
     "wm/workspace_controller_unittest.cc",
     "ws/ash_window_manager_unittest.cc",
-    "ws/ax_ash_window_utils_unittest.cc",
     "ws/window_lookup_unittest.cc",
     "ws/window_service_delegate_impl_unittest.cc",
   ]
diff --git a/ash/assistant/assistant_alarm_timer_controller.cc b/ash/assistant/assistant_alarm_timer_controller.cc
index 4075143f..70ecf43 100644
--- a/ash/assistant/assistant_alarm_timer_controller.cc
+++ b/ash/assistant/assistant_alarm_timer_controller.cc
@@ -259,6 +259,14 @@
   assistant_ = assistant;
 }
 
+void AssistantAlarmTimerController::OnAssistantControllerConstructed() {
+  assistant_controller_->ui_controller()->AddModelObserver(this);
+}
+
+void AssistantAlarmTimerController::OnAssistantControllerDestroying() {
+  assistant_controller_->ui_controller()->RemoveModelObserver(this);
+}
+
 void AssistantAlarmTimerController::OnDeepLinkReceived(
     assistant::util::DeepLinkType type,
     const std::map<std::string, std::string>& params) {
@@ -285,6 +293,38 @@
   PerformAlarmTimerAction(action.value(), alarm_timer_id, duration);
 }
 
+void AssistantAlarmTimerController::OnUiVisibilityChanged(
+    AssistantVisibility new_visibility,
+    AssistantVisibility old_visibility,
+    base::Optional<AssistantEntryPoint> entry_point,
+    base::Optional<AssistantExitPoint> exit_point) {
+  // When the Assistant UI transitions from a visible state, we'll dismiss any
+  // ringing alarms or timers (assuming certain conditions have been met).
+  if (old_visibility != AssistantVisibility::kVisible)
+    return;
+
+  // We only do this if the AlarmTimerManager is enabled, as otherwise we would
+  // have to issue an Assistant query to stop ringing alarms/timers which would
+  // cause Assistant UI to once again show. This would be a bad user experience.
+  if (!chromeos::assistant::features::IsAlarmTimerManagerEnabled())
+    return;
+
+  // We only do this if timer notifications are enabled, as otherwise the
+  // ringing alarm/timer isn't bound to any particular UI affordance so it can
+  // maintain its own lifecycle.
+  if (!chromeos::assistant::features::IsTimerNotificationEnabled())
+    return;
+
+  // We only do this if in-Assistant notifications are enabled, as in-Assistant
+  // alarm/timer notifications only live as long the Assistant UI. Per UX
+  // requirement, when Assistant UI dismisses with an in-Assistant timer
+  // notification showing, any ringing alarms/timers should be stopped.
+  if (!chromeos::assistant::features::IsInAssistantNotificationsEnabled())
+    return;
+
+  assistant_->StopAlarmTimerRinging();
+}
+
 void AssistantAlarmTimerController::PerformAlarmTimerAction(
     const assistant::util::AlarmTimerAction& action,
     const base::Optional<std::string>& alarm_timer_id,
diff --git a/ash/assistant/assistant_alarm_timer_controller.h b/ash/assistant/assistant_alarm_timer_controller.h
index 38f1789..67f986f 100644
--- a/ash/assistant/assistant_alarm_timer_controller.h
+++ b/ash/assistant/assistant_alarm_timer_controller.h
@@ -8,6 +8,7 @@
 #include "ash/assistant/assistant_controller_observer.h"
 #include "ash/assistant/model/assistant_alarm_timer_model.h"
 #include "ash/assistant/model/assistant_alarm_timer_model_observer.h"
+#include "ash/assistant/model/assistant_ui_model_observer.h"
 #include "ash/public/interfaces/assistant_controller.mojom.h"
 #include "base/macros.h"
 #include "base/timer/timer.h"
@@ -28,7 +29,8 @@
 class AssistantAlarmTimerController
     : public mojom::AssistantAlarmTimerController,
       public AssistantControllerObserver,
-      public AssistantAlarmTimerModelObserver {
+      public AssistantAlarmTimerModelObserver,
+      public AssistantUiModelObserver {
  public:
   explicit AssistantAlarmTimerController(
       AssistantController* assistant_controller);
@@ -60,10 +62,19 @@
   void SetAssistant(chromeos::assistant::mojom::Assistant* assistant);
 
   // AssistantControllerObserver:
+  void OnAssistantControllerConstructed() override;
+  void OnAssistantControllerDestroying() override;
   void OnDeepLinkReceived(
       assistant::util::DeepLinkType type,
       const std::map<std::string, std::string>& params) override;
 
+  // AssistantUiModelObserver:
+  void OnUiVisibilityChanged(
+      AssistantVisibility new_visibility,
+      AssistantVisibility old_visibility,
+      base::Optional<AssistantEntryPoint> entry_point,
+      base::Optional<AssistantExitPoint> exit_point) override;
+
  private:
   void PerformAlarmTimerAction(
       const assistant::util::AlarmTimerAction& action,
diff --git a/ash/components/shortcut_viewer/BUILD.gn b/ash/components/shortcut_viewer/BUILD.gn
index bb72c0d..08e4450 100644
--- a/ash/components/shortcut_viewer/BUILD.gn
+++ b/ash/components/shortcut_viewer/BUILD.gn
@@ -3,17 +3,15 @@
 # found in the LICENSE file.
 
 # KSV: Keyboard Shortcut Viewer
-source_set("lib") {
+source_set("shortcut_viewer") {
   sources = [
     "keyboard_shortcut_item.cc",
     "keyboard_shortcut_item.h",
     "keyboard_shortcut_viewer_metadata.cc",
     "keyboard_shortcut_viewer_metadata.h",
     "ksv_export.h",
-    "last_window_closed_observer.cc",
-    "last_window_closed_observer.h",
-    "shortcut_viewer_application.cc",
-    "shortcut_viewer_application.h",
+    "shortcut_viewer.cc",
+    "shortcut_viewer.h",
     "views/bubble_view.cc",
     "views/bubble_view.h",
     "views/keyboard_shortcut_item_list_view.cc",
@@ -29,13 +27,11 @@
   defines = [ "KSV_IMPLEMENTATION" ]
 
   deps = [
-    "//ash/components/shortcut_viewer/public/mojom",
     "//ash/components/shortcut_viewer/vector_icons",
     "//ash/components/strings",
     "//ash/public/cpp",
     "//ash/public/cpp/resources:ash_public_unscaled_resources",
     "//cc/paint",
-    "//services/service_manager/public/cpp/",
     "//ui/accessibility",
     "//ui/aura",
     "//ui/chromeos/events",
@@ -44,8 +40,6 @@
     "//ui/events/devices",
     "//ui/events/ozone:events_ozone_layout",
     "//ui/views",
-    "//ui/views/mus",
-    "//ui/views/mus:resources",
   ]
 }
 
@@ -55,7 +49,7 @@
     "views/keyboard_shortcut_view_unittest.cc",
   ]
   deps = [
-    ":lib",
+    ":shortcut_viewer",
     "//ash:test_support",
     "//base/test:test_support",
     "//services/ws/public/cpp/input_devices:test_support",
diff --git a/ash/components/shortcut_viewer/DEPS b/ash/components/shortcut_viewer/DEPS
index f7657e5..9083c1ecd 100644
--- a/ash/components/shortcut_viewer/DEPS
+++ b/ash/components/shortcut_viewer/DEPS
@@ -1,6 +1,4 @@
 include_rules = [
-  # KSV is intended to be a small app with restrictive DEPS in order to make it
-  # easy to be migrated to a completely independent mojo app under mustash.
   "+ash/components/strings",
   "+services/ws/public",
   "+ui/accessibility",
diff --git a/ash/components/shortcut_viewer/README.md b/ash/components/shortcut_viewer/README.md
index 132127e6..f959726 100644
--- a/ash/components/shortcut_viewer/README.md
+++ b/ash/components/shortcut_viewer/README.md
@@ -1,4 +1,4 @@
 This directory contains Keyboard Shortcut Viewer (KSV), which is an easily
 discoverable and intuitively organized UI for users to be familiar with
-Chrome OS keyboard shortcuts. The KSV is designed as a self-contained app.
+Chrome OS keyboard shortcuts.
 Design doc: go/chrome-os-ksv
diff --git a/ash/components/shortcut_viewer/last_window_closed_observer.cc b/ash/components/shortcut_viewer/last_window_closed_observer.cc
deleted file mode 100644
index 28724a0..0000000
--- a/ash/components/shortcut_viewer/last_window_closed_observer.cc
+++ /dev/null
@@ -1,31 +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.
-
-#include "ash/components/shortcut_viewer/last_window_closed_observer.h"
-
-#include "ui/aura/env.h"
-#include "ui/aura/window.h"
-
-namespace keyboard_shortcut_viewer {
-
-LastWindowClosedObserver::LastWindowClosedObserver(
-    const base::RepeatingClosure& callback)
-    : callback_(callback) {
-  env_observer_.Add(aura::Env::GetInstance());
-}
-
-LastWindowClosedObserver::~LastWindowClosedObserver() = default;
-
-void LastWindowClosedObserver::OnWindowInitialized(aura::Window* window) {
-  window_observer_.Add(window);
-}
-
-void LastWindowClosedObserver::OnWindowDestroyed(aura::Window* window) {
-  window_observer_.Remove(window);
-
-  if (!window_observer_.IsObservingSources())
-    callback_.Run();
-}
-
-}  // namespace keyboard_shortcut_viewer
diff --git a/ash/components/shortcut_viewer/last_window_closed_observer.h b/ash/components/shortcut_viewer/last_window_closed_observer.h
deleted file mode 100644
index 07800ee..0000000
--- a/ash/components/shortcut_viewer/last_window_closed_observer.h
+++ /dev/null
@@ -1,45 +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 ASH_COMPONENTS_SHORTCUT_VIEWER_LAST_WINDOW_CLOSED_OBSERVER_H_
-#define ASH_COMPONENTS_SHORTCUT_VIEWER_LAST_WINDOW_CLOSED_OBSERVER_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "ui/aura/env_observer.h"
-#include "ui/aura/window_observer.h"
-
-namespace aura {
-class Env;
-}  // namespace aura
-
-namespace keyboard_shortcut_viewer {
-
-// Monitors aura::Env and invokes a callback when the last known window is
-// closed.
-class LastWindowClosedObserver : public aura::EnvObserver,
-                                 public aura::WindowObserver {
- public:
-  explicit LastWindowClosedObserver(const base::RepeatingClosure& callback);
-  ~LastWindowClosedObserver() override;
-
- private:
-  // aura::EnvObserver:
-  void OnWindowInitialized(aura::Window* window) override;
-
-  // aura::WindowObserver:
-  void OnWindowDestroyed(aura::Window* window) override;
-
-  base::RepeatingClosure callback_;
-
-  ScopedObserver<aura::Env, aura::EnvObserver> env_observer_{this};
-  ScopedObserver<aura::Window, aura::WindowObserver> window_observer_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(LastWindowClosedObserver);
-};
-
-}  // namespace keyboard_shortcut_viewer
-
-#endif  // ASH_COMPONENTS_SHORTCUT_VIEWER_LAST_WINDOW_CLOSED_OBSERVER_H_
diff --git a/ash/components/shortcut_viewer/public/cpp/BUILD.gn b/ash/components/shortcut_viewer/public/cpp/BUILD.gn
deleted file mode 100644
index 01e5b6f..0000000
--- a/ash/components/shortcut_viewer/public/cpp/BUILD.gn
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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.
-
-source_set("manifest") {
-  sources = [
-    "manifest.cc",
-    "manifest.h",
-  ]
-
-  deps = [
-    "//ash/components/shortcut_viewer/public/mojom",
-    "//base",
-    "//services/service_manager/public/cpp",
-    "//services/ws/public/mojom:constants",
-    "//ui/accessibility/mojom",
-  ]
-}
diff --git a/ash/components/shortcut_viewer/public/cpp/OWNERS b/ash/components/shortcut_viewer/public/cpp/OWNERS
deleted file mode 100644
index 6faeaa47..0000000
--- a/ash/components/shortcut_viewer/public/cpp/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-per-file manifest.cc=set noparent
-per-file manifest.cc=file://ipc/SECURITY_OWNERS
-per-file manifest.h=set noparent
-per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/ash/components/shortcut_viewer/public/cpp/manifest.cc b/ash/components/shortcut_viewer/public/cpp/manifest.cc
deleted file mode 100644
index e245b14..0000000
--- a/ash/components/shortcut_viewer/public/cpp/manifest.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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/components/shortcut_viewer/public/cpp/manifest.h"
-
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
-#include "base/no_destructor.h"
-#include "services/service_manager/public/cpp/manifest_builder.h"
-#include "services/ws/public/mojom/constants.mojom.h"
-#include "ui/accessibility/mojom/ax_host.mojom.h"
-
-namespace shortcut_viewer {
-
-const service_manager::Manifest& GetManifest() {
-  static base::NoDestructor<service_manager::Manifest> manifest{
-      service_manager::ManifestBuilder()
-          .WithServiceName(mojom::kServiceName)
-          .WithDisplayName("Keyboard Shortcut Viewer")
-          .WithOptions(service_manager::ManifestOptionsBuilder()
-                           .WithSandboxType("none")
-                           .Build())
-          .ExposeCapability(
-              mojom::kToggleUiCapability,
-              service_manager::Manifest::InterfaceList<mojom::ShortcutViewer>())
-          .RequireCapability(ax::mojom::kAXHostServiceName, "app")
-          .RequireCapability(ws::mojom::kServiceName, "app")
-          .Build()};
-  return *manifest;
-}
-
-}  // namespace shortcut_viewer
diff --git a/ash/components/shortcut_viewer/public/cpp/manifest.h b/ash/components/shortcut_viewer/public/cpp/manifest.h
deleted file mode 100644
index d44bf8a..0000000
--- a/ash/components/shortcut_viewer/public/cpp/manifest.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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_COMPONENTS_SHORTCUT_VIEWER_PUBLIC_CPP_MANIFEST_H_
-#define ASH_COMPONENTS_SHORTCUT_VIEWER_PUBLIC_CPP_MANIFEST_H_
-
-#include "services/service_manager/public/cpp/manifest.h"
-
-namespace shortcut_viewer {
-
-const service_manager::Manifest& GetManifest();
-
-}  // namespace shortcut_viewer
-
-#endif  // ASH_COMPONENTS_SHORTCUT_VIEWER_PUBLIC_CPP_MANIFEST_H_
diff --git a/ash/components/shortcut_viewer/public/mojom/BUILD.gn b/ash/components/shortcut_viewer/public/mojom/BUILD.gn
deleted file mode 100644
index 81a95890..0000000
--- a/ash/components/shortcut_viewer/public/mojom/BUILD.gn
+++ /dev/null
@@ -1,15 +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.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-
-mojom("mojom") {
-  sources = [
-    "shortcut_viewer.mojom",
-  ]
-
-  public_deps = [
-    "//mojo/public/mojom/base",
-  ]
-}
diff --git a/ash/components/shortcut_viewer/public/mojom/OWNERS b/ash/components/shortcut_viewer/public/mojom/OWNERS
deleted file mode 100644
index 08850f4..0000000
--- a/ash/components/shortcut_viewer/public/mojom/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom b/ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom
deleted file mode 100644
index d3020a1..0000000
--- a/ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom
+++ /dev/null
@@ -1,21 +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.
-
-module shortcut_viewer.mojom;
-
-import "mojo/public/mojom/base/time.mojom";
-
-const string kServiceName = "shortcut_viewer_app";
-
-// Grants a client the ability to toggle the Keyboard Shortcut Viewer window
-// through the ShortcutViewer interface defined below.
-const string kToggleUiCapability = "toggle_ui";
-
-// Used to toggle the Keyboard Shortcut Viewer window.
-interface ShortcutViewer {
-  // |user_gesture_time| is the time of the user gesture that caused the window
-  // to show. Used for metrics.
-  Toggle(mojo_base.mojom.TimeTicks user_gesture_time);
-};
-
diff --git a/ash/components/shortcut_viewer/shortcut_viewer.cc b/ash/components/shortcut_viewer/shortcut_viewer.cc
new file mode 100644
index 0000000..2884388
--- /dev/null
+++ b/ash/components/shortcut_viewer/shortcut_viewer.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 "ash/components/shortcut_viewer/shortcut_viewer.h"
+
+#include "ash/components/shortcut_viewer/views/keyboard_shortcut_view.h"
+
+namespace keyboard_shortcut_viewer {
+
+void Toggle(base::TimeTicks user_gesture_time) {
+  KeyboardShortcutView::Toggle(user_gesture_time, nullptr);
+}
+
+}  // namespace keyboard_shortcut_viewer
diff --git a/ash/components/shortcut_viewer/shortcut_viewer.h b/ash/components/shortcut_viewer/shortcut_viewer.h
new file mode 100644
index 0000000..75c6c8f
--- /dev/null
+++ b/ash/components/shortcut_viewer/shortcut_viewer.h
@@ -0,0 +1,18 @@
+// 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_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_H_
+#define ASH_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_H_
+
+#include "base/time/time.h"
+
+namespace keyboard_shortcut_viewer {
+
+// Toggle the Keyboard Shortcut Viewer window. |user_gesture_time| is the time
+// of the user gesture that caused the window to show. Used for metrics.
+void Toggle(base::TimeTicks user_gesture_time);
+
+}  // namespace keyboard_shortcut_viewer
+
+#endif  // ASH_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_H_
diff --git a/ash/components/shortcut_viewer/shortcut_viewer_application.cc b/ash/components/shortcut_viewer/shortcut_viewer_application.cc
deleted file mode 100644
index 01940f46..0000000
--- a/ash/components/shortcut_viewer/shortcut_viewer_application.cc
+++ /dev/null
@@ -1,89 +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.
-
-#include "ash/components/shortcut_viewer/shortcut_viewer_application.h"
-
-#include "ash/components/shortcut_viewer/last_window_closed_observer.h"
-#include "ash/components/shortcut_viewer/views/keyboard_shortcut_view.h"
-#include "ash/public/cpp/ash_client.h"
-#include "base/bind.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "ui/events/devices/input_device_manager.h"
-#include "ui/views/mus/aura_init.h"
-
-namespace keyboard_shortcut_viewer {
-
-ShortcutViewerApplication::ShortcutViewerApplication(
-    service_manager::mojom::ServiceRequest request)
-    : service_binding_(this, std::move(request)) {
-  registry_.AddInterface<shortcut_viewer::mojom::ShortcutViewer>(
-      base::BindRepeating(&ShortcutViewerApplication::AddBinding,
-                          base::Unretained(this)));
-}
-
-ShortcutViewerApplication::~ShortcutViewerApplication() = default;
-
-// static
-void ShortcutViewerApplication::RegisterForTraceEvents() {
-  TRACE_EVENT0("shortcut_viewer", "ignored");
-}
-
-void ShortcutViewerApplication::OnStart() {
-  views::AuraInit::InitParams params;
-  params.connector = service_binding_.GetConnector();
-  params.identity = service_binding_.identity();
-  params.register_path_provider = false;
-  params.use_accessibility_host = true;
-  aura_init_ = views::AuraInit::Create(params);
-  if (!aura_init_) {
-    Terminate();
-    return;
-  }
-
-  // Register as a client of the window manager.
-  ash::ash_client::Init();
-
-  // Quit the application when the window is closed.
-  last_window_closed_observer_ = std::make_unique<LastWindowClosedObserver>(
-      base::BindRepeating(&ShortcutViewerApplication::OnLastWindowClosed,
-                          base::Unretained(this)));
-}
-
-void ShortcutViewerApplication::OnBindInterface(
-    const service_manager::BindSourceInfo& remote_info,
-    const std::string& interface_name,
-    mojo::ScopedMessagePipeHandle interface_pipe) {
-  registry_.BindInterface(interface_name, std::move(interface_pipe));
-}
-
-void ShortcutViewerApplication::OnDeviceListsComplete() {
-  ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
-  KeyboardShortcutView::Toggle(user_gesture_time_, nullptr);
-}
-
-void ShortcutViewerApplication::Toggle(base::TimeTicks user_gesture_time) {
-  user_gesture_time_ = user_gesture_time;
-
-  // This app needs InputDeviceManager information that loads asynchronously via
-  // InputDeviceClient. If the device list is incomplete, wait for it to load.
-  DCHECK(ui::InputDeviceManager::HasInstance());
-  if (ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete())
-    KeyboardShortcutView::Toggle(user_gesture_time_, nullptr);
-  else
-    ui::InputDeviceManager::GetInstance()->AddObserver(this);
-}
-
-void ShortcutViewerApplication::AddBinding(
-    shortcut_viewer::mojom::ShortcutViewerRequest request) {
-  shortcut_viewer_binding_.Close();
-  shortcut_viewer_binding_.Bind(std::move(request));
-}
-
-void ShortcutViewerApplication::OnLastWindowClosed() {
-  service_binding_.RequestClose();
-}
-
-}  // namespace keyboard_shortcut_viewer
diff --git a/ash/components/shortcut_viewer/shortcut_viewer_application.h b/ash/components/shortcut_viewer/shortcut_viewer_application.h
deleted file mode 100644
index 979240d..0000000
--- a/ash/components/shortcut_viewer/shortcut_viewer_application.h
+++ /dev/null
@@ -1,79 +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 ASH_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_APPLICATION_H_
-#define ASH_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_APPLICATION_H_
-
-#include <memory>
-
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/public/cpp/service_binding.h"
-#include "services/service_manager/public/mojom/service.mojom.h"
-#include "ui/events/devices/input_device_event_observer.h"
-
-namespace views {
-class AuraInit;
-}  // namespace views
-
-namespace keyboard_shortcut_viewer {
-
-class LastWindowClosedObserver;
-
-// A mojo application that shows the keyboard shortcut viewer window.
-class ShortcutViewerApplication
-    : public service_manager::Service,
-      public ui::InputDeviceEventObserver,
-      public shortcut_viewer::mojom::ShortcutViewer {
- public:
-  explicit ShortcutViewerApplication(
-      service_manager::mojom::ServiceRequest request);
-  ~ShortcutViewerApplication() override;
-
-  // Records a single trace event for shortcut viewer. chrome://tracing doesn't
-  // allow selecting a trace event category for recording until the tracing
-  // system has seen at least one event.
-  static void RegisterForTraceEvents();
-
- private:
-  // service_manager::Service:
-  void OnStart() override;
-  void OnBindInterface(const service_manager::BindSourceInfo& remote_info,
-                       const std::string& interface_name,
-                       mojo::ScopedMessagePipeHandle interface_pipe) override;
-
-  // ui::InputDeviceEventObserver:
-  void OnDeviceListsComplete() override;
-
-  // shortcut_viewer::mojom:ShortcutViewer:
-  void Toggle(base::TimeTicks user_gesture_time) override;
-
-  void AddBinding(shortcut_viewer::mojom::ShortcutViewerRequest request);
-
-  void OnLastWindowClosed();
-
-  service_manager::ServiceBinding service_binding_;
-
-  std::unique_ptr<views::AuraInit> aura_init_;
-  std::unique_ptr<LastWindowClosedObserver> last_window_closed_observer_;
-
-  service_manager::BinderRegistry registry_;
-
-  mojo::Binding<shortcut_viewer::mojom::ShortcutViewer>
-      shortcut_viewer_binding_{this};
-
-  // Timestamp of the user gesture (e.g. Ctrl-Shift-/ keystroke) that triggered
-  // showing the window. Used for metrics.
-  base::TimeTicks user_gesture_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(ShortcutViewerApplication);
-};
-
-}  // namespace keyboard_shortcut_viewer
-
-#endif  // ASH_COMPONENTS_SHORTCUT_VIEWER_SHORTCUT_VIEWER_APPLICATION_H_
diff --git a/ash/display/screen_orientation_controller.h b/ash/display/screen_orientation_controller.h
index af4cb31..6fb1fc2 100644
--- a/ash/display/screen_orientation_controller.h
+++ b/ash/display/screen_orientation_controller.h
@@ -26,7 +26,17 @@
 
 namespace ash {
 
-using OrientationLockType = mojom::OrientationLockType;
+enum class OrientationLockType {
+  kAny,
+  kNatural,
+  kCurrent,
+  kPortrait,
+  kLandscape,
+  kPortraitPrimary,
+  kPortraitSecondary,
+  kLandscapePrimary,
+  kLandscapeSecondary,
+};
 
 // Test if the orientation lock type is primary/landscape/portrait.
 bool IsPrimaryOrientation(OrientationLockType type);
diff --git a/ash/display/screen_orientation_controller_test_api.h b/ash/display/screen_orientation_controller_test_api.h
index 5920bee..9e35d1a 100644
--- a/ash/display/screen_orientation_controller_test_api.h
+++ b/ash/display/screen_orientation_controller_test_api.h
@@ -12,9 +12,7 @@
 namespace ash {
 class ScreenOrientationController;
 
-namespace mojom {
 enum class OrientationLockType;
-}
 
 class ScreenOrientationControllerTestApi {
  public:
@@ -29,9 +27,9 @@
 
   void SetRotationLocked(bool rotation_locked);
 
-  mojom::OrientationLockType UserLockedOrientation() const;
+  OrientationLockType UserLockedOrientation() const;
 
-  mojom::OrientationLockType GetCurrentOrientation() const;
+  OrientationLockType GetCurrentOrientation() const;
 
   void UpdateNaturalOrientation();
 
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc
index d0a435d..e73d9f5 100644
--- a/ash/frame/non_client_frame_view_ash.cc
+++ b/ash/frame/non_client_frame_view_ash.cc
@@ -261,7 +261,6 @@
   Shell::Get()->split_view_controller()->AddObserver(this);
 
   frame_window->SetProperty(kNonClientFrameViewAshKey, this);
-  wm::MakeGestureDraggableInImmersiveMode(frame_window);
 }
 
 NonClientFrameViewAsh::~NonClientFrameViewAsh() {
diff --git a/ash/media/media_notification_view.cc b/ash/media/media_notification_view.cc
index 2fe9821..6a266d6 100644
--- a/ash/media/media_notification_view.cc
+++ b/ash/media/media_notification_view.cc
@@ -416,12 +416,12 @@
 void MediaNotificationView::CreateMediaButton(
     MediaSessionAction action,
     const base::string16& accessible_name) {
-  views::ImageButton* button = views::CreateVectorImageButton(this);
+  auto button = views::CreateVectorImageButton(this);
   button->set_tag(static_cast<int>(action));
   button->SetPreferredSize(kMediaButtonSize);
   button->SetAccessibleName(accessible_name);
   button->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
-  button_row_->AddChildView(button);
+  button_row_->AddChildView(std::move(button));
 }
 
 MediaNotificationBackground*
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index 1aa4102..2a1f69a0 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -30,8 +30,6 @@
     "app_list/tokenized_string_match.h",
     "app_menu_constants.h",
     "app_types.h",
-    "ash_client.cc",
-    "ash_client.h",
     "ash_constants.h",
     "ash_features.cc",
     "ash_features.h",
diff --git a/ash/public/cpp/ash_client.cc b/ash/public/cpp/ash_client.cc
deleted file mode 100644
index 159fa15..0000000
--- a/ash/public/cpp/ash_client.cc
+++ /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.
-
-#include "ash/public/cpp/ash_client.h"
-
-#include "ash/public/cpp/mus_property_mirror_ash.h"
-#include "ash/public/cpp/window_properties.h"
-#include "ui/views/mus/mus_client.h"
-
-namespace ash {
-namespace ash_client {
-
-void Init() {
-  // Register ash specific window properties to be transported.
-  views::MusClient* mus_client = views::MusClient::Get();
-  aura::WindowTreeClientDelegate* delegate = mus_client;
-  RegisterWindowProperties(delegate->GetPropertyConverter());
-
-  // Setup property mirror between window and host.
-  mus_client->SetMusPropertyMirror(std::make_unique<MusPropertyMirrorAsh>());
-}
-
-}  // namespace ash_client
-}  // namespace ash
diff --git a/ash/public/cpp/ash_client.h b/ash/public/cpp/ash_client.h
deleted file mode 100644
index 2caf174..0000000
--- a/ash/public/cpp/ash_client.h
+++ /dev/null
@@ -1,20 +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 ASH_PUBLIC_CPP_ASH_CLIENT_H_
-#define ASH_PUBLIC_CPP_ASH_CLIENT_H_
-
-#include "ash/public/cpp/ash_public_export.h"
-
-namespace ash {
-namespace ash_client {
-
-// Initializes a client application (e.g. keyboard shortcut viewer) such that
-// it can communicate with the ash window manager.
-ASH_PUBLIC_EXPORT void Init();
-
-}  // namespace ash_client
-}  // namespace ash
-
-#endif  // ASH_PUBLIC_CPP_ASH_CLIENT_H_
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc
index 2888c62..132f0bb6 100644
--- a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc
+++ b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc
@@ -686,16 +686,6 @@
     return false;
   }
 
-  // Don't perform an immersive reveal when gesture scrolls from the top ought
-  // to be dragging the window.
-  aura::Window* window = widget_->GetNativeWindow();
-  if (window->env()->mode() == aura::Env::Mode::MUS)
-    window = window->GetRootWindow();
-  if (window->GetProperty(
-          aura::client::kGestureDragFromClientAreaTopMovesWindow)) {
-    return false;
-  }
-
   // When the top-of-window views are not fully revealed, handle gestures which
   // start in the top few pixels of the screen.
   gfx::Rect hit_bounds_in_screen(GetDisplayBoundsInScreen());
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc
index 750874c0..cce62d7 100644
--- a/ash/public/cpp/window_properties.cc
+++ b/ash/public/cpp/window_properties.cc
@@ -73,10 +73,6 @@
       ws::mojom::WindowManager::kFrameInactiveColor_Property,
       aura::PropertyConverter::CreateAcceptAnyValueCallback());
   property_converter->RegisterPrimitiveProperty(
-      aura::client::kGestureDragFromClientAreaTopMovesWindow,
-      mojom::kGestureDragFromClientAreaTopMovesWindow_Property,
-      aura::PropertyConverter::CreateAcceptAnyValueCallback());
-  property_converter->RegisterPrimitiveProperty(
       kHideInOverviewKey, mojom::kHideInOverview_Property,
       aura::PropertyConverter::CreateAcceptAnyValueCallback());
   property_converter->RegisterPrimitiveProperty(
diff --git a/ash/public/interfaces/ash_window_manager.mojom b/ash/public/interfaces/ash_window_manager.mojom
index f43be191..e96a2646 100644
--- a/ash/public/interfaces/ash_window_manager.mojom
+++ b/ash/public/interfaces/ash_window_manager.mojom
@@ -15,18 +15,6 @@
   kRight,  // The phantom window controller is previewing a snap to the left.
 };
 
-enum OrientationLockType {
-  kAny,
-  kNatural,
-  kCurrent,
-  kPortrait,
-  kLandscape,
-  kPortraitPrimary,
-  kPortraitSecondary,
-  kLandscapePrimary,
-  kLandscapeSecondary,
-};
-
 // Interface exposed via WindowTree::BindWindowManagerInterface(). This
 // interface is used for functionality specific to Ash that is associated with
 // windows created by the window service.
@@ -37,12 +25,6 @@
 
   CommitSnap(uint64 window_id, SnapDirection snap);
 
-  // Locks or unlocks the screen orientation. The provided window is the source
-  // of the orientation request and need not be a top level window, but the
-  // client connection type must not be an embedding (i.e. renderer).
-  LockOrientation(uint64 window_id, OrientationLockType type);
-  UnlockOrientation(uint64 window_id);
-
   // Maximizes the window in response to a double click or tap on the HTCAPTION
   // area.
   MaximizeWindowByCaptionClick(uint64 window_id, ui.mojom.PointerKind pointer);
diff --git a/ash/public/interfaces/window_properties.mojom b/ash/public/interfaces/window_properties.mojom
index f1ed3686..8bc07b3 100644
--- a/ash/public/interfaces/window_properties.mojom
+++ b/ash/public/interfaces/window_properties.mojom
@@ -93,7 +93,3 @@
 
 // A boolean property to indicate a picture-in-picture window.
 const string kIsWindowPip_Property = "ash:is-window-pip";
-
-// A boolean that corresponds to kGestureDragFromClientAreaTopMovesWindow.
-const string kGestureDragFromClientAreaTopMovesWindow_Property =
-    "ash:gesture-drag-from-client-area-top-moves-window";
diff --git a/ash/shell.cc b/ash/shell.cc
index 6414b376..629fb2ab 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -164,7 +164,6 @@
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_shadow_controller_delegate.h"
 #include "ash/wm/workspace_controller.h"
-#include "ash/ws/ax_ash_window_utils.h"
 #include "ash/ws/window_service_owner.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -987,10 +986,6 @@
     frame_values.max_title_bar_button_width =
         NonClientFrameController::GetMaxTitleBarButtonWidth();
     views::WindowManagerFrameValues::SetInstance(frame_values);
-
-    // Accessibility node tree serialization needs to "jump the fence" and
-    // convert between ash proxy and mus client windows.
-    views::AXAuraWindowUtils::Set(std::make_unique<AXAshWindowUtils>());
   }
 
   if (!::features::IsMultiProcessMash()) {
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc
index c74d1f6..e1e43a6 100644
--- a/ash/shell/content/client/shell_browser_main_parts.cc
+++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
 #include "ash/keyboard/test_keyboard_ui.h"
 #include "ash/login_status.h"
@@ -158,11 +157,6 @@
       test_ime_driver::mojom::kServiceName));
   connector->WarmService(service_manager::ServiceFilter::ByName(
       tap_visualizer::mojom::kServiceName));
-  shortcut_viewer::mojom::ShortcutViewerPtr shortcut_viewer;
-  connector->BindInterface(service_manager::ServiceFilter::ByName(
-                               shortcut_viewer::mojom::kServiceName),
-                           mojo::MakeRequest(&shortcut_viewer));
-  shortcut_viewer->Toggle(base::TimeTicks::Now());
   ash::Shell::Get()->InitWaylandServer(nullptr);
 }
 
diff --git a/ash/shell/content/client/shell_content_browser_client.cc b/ash/shell/content/client/shell_content_browser_client.cc
index 8119c3ab..1513bc8 100644
--- a/ash/shell/content/client/shell_content_browser_client.cc
+++ b/ash/shell/content/client/shell_content_browser_client.cc
@@ -8,8 +8,6 @@
 #include <utility>
 
 #include "ash/ash_service.h"
-#include "ash/components/shortcut_viewer/public/cpp/manifest.h"
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
 #include "ash/components/tap_visualizer/public/cpp/manifest.h"
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
 #include "ash/public/cpp/manifest.h"
@@ -48,8 +46,6 @@
   static base::NoDestructor<service_manager::Manifest> manifest{
       service_manager::ManifestBuilder()
           .RequireCapability(device::mojom::kServiceName, "device:fingerprint")
-          .RequireCapability(shortcut_viewer::mojom::kServiceName,
-                             shortcut_viewer::mojom::kToggleUiCapability)
           .RequireCapability(tap_visualizer::mojom::kServiceName,
                              tap_visualizer::mojom::kShowUiCapability)
           .Build()};
@@ -61,7 +57,6 @@
       service_manager::ManifestBuilder()
           .PackageService(service_manager::Manifest(ash::GetManifest())
                               .Amend(ash::GetManifestOverlayForTesting()))
-          .PackageService(shortcut_viewer::GetManifest())
           .PackageService(tap_visualizer::GetManifest())
           .PackageService(test_ime_driver::GetManifest())
           .Build()};
@@ -92,8 +87,7 @@
 
 base::Optional<service_manager::Manifest>
 ShellContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
-  // This is necessary for outgoing interface requests (such as the keyboard
-  // shortcut viewer).
+  // This is necessary for outgoing interface requests.
   if (name == content::mojom::kBrowserServiceName)
     return GetAshShellBrowserOverlayManifest();
 
@@ -105,8 +99,6 @@
 
 void ShellContentBrowserClient::RegisterOutOfProcessServices(
     OutOfProcessServiceMap* services) {
-  (*services)[shortcut_viewer::mojom::kServiceName] = base::BindRepeating(
-      &base::ASCIIToUTF16, shortcut_viewer::mojom::kServiceName);
   (*services)[tap_visualizer::mojom::kServiceName] = base::BindRepeating(
       &base::ASCIIToUTF16, tap_visualizer::mojom::kServiceName);
   (*services)[test_ime_driver::mojom::kServiceName] = base::BindRepeating(
diff --git a/ash/shell/content/client/shell_main_delegate.cc b/ash/shell/content/client/shell_main_delegate.cc
index c48a55712..03558cc 100644
--- a/ash/shell/content/client/shell_main_delegate.cc
+++ b/ash/shell/content/client/shell_main_delegate.cc
@@ -4,8 +4,6 @@
 
 #include "ash/shell/content/client/shell_main_delegate.h"
 
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
-#include "ash/components/shortcut_viewer/shortcut_viewer_application.h"
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
 #include "ash/components/tap_visualizer/tap_visualizer_app.h"
 #include "ash/shell/content/client/shell_content_browser_client.h"
@@ -30,13 +28,6 @@
   content::UtilityThread::Get()->ReleaseProcess();
 }
 
-std::unique_ptr<service_manager::Service> CreateShortcutViewer(
-    service_manager::mojom::ServiceRequest request) {
-  logging::SetLogPrefix("shortcut");
-  return std::make_unique<keyboard_shortcut_viewer::ShortcutViewerApplication>(
-      std::move(request));
-}
-
 std::unique_ptr<service_manager::Service> CreateTapVisualizer(
     service_manager::mojom::ServiceRequest request) {
   logging::SetLogPrefix("tap");
@@ -60,8 +51,6 @@
     std::unique_ptr<service_manager::Service> service;
     if (service_name == test_ime_driver::mojom::kServiceName)
       service = CreateTestImeDriver(std::move(request));
-    else if (service_name == shortcut_viewer::mojom::kServiceName)
-      service = CreateShortcutViewer(std::move(request));
     else if (service_name == tap_visualizer::mojom::kServiceName)
       service = CreateTapVisualizer(std::move(request));
 
diff --git a/ash/system/flag_warning/flag_warning_tray.cc b/ash/system/flag_warning/flag_warning_tray.cc
index 16a7c2a3..d22fa62 100644
--- a/ash/system/flag_warning/flag_warning_tray.cc
+++ b/ash/system/flag_warning/flag_warning_tray.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
 #include "ash/public/cpp/ash_typography.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shelf/shelf.h"
@@ -57,12 +56,6 @@
 void FlagWarningTray::ButtonPressed(views::Button* sender,
                                     const ui::Event& event) {
   DCHECK_EQ(button_, sender);
-
-  // Open the shortcut viewer mini-app to demonstrate that mini-apps work.
-  shortcut_viewer::mojom::ShortcutViewerPtr shortcut_viewer_ptr;
-  Shell::Get()->connector()->BindInterface(shortcut_viewer::mojom::kServiceName,
-                                           &shortcut_viewer_ptr);
-  shortcut_viewer_ptr->Toggle(base::TimeTicks::Now());
 }
 
 void FlagWarningTray::GetAccessibleNodeData(ui::AXNodeData* node_data) {
diff --git a/ash/wm/non_client_frame_controller.cc b/ash/wm/non_client_frame_controller.cc
index 7ede688..9ac3311 100644
--- a/ash/wm/non_client_frame_controller.cc
+++ b/ash/wm/non_client_frame_controller.cc
@@ -268,8 +268,6 @@
   params.show_state = window_->GetProperty(aura::client::kShowStateKey);
   widget_->Init(params);
   did_init_native_widget_ = true;
-
-  wm::MakeGestureDraggableInImmersiveMode(window_);
 }
 
 // static
diff --git a/ash/wm/splitview/split_view_divider.h b/ash/wm/splitview/split_view_divider.h
index 04fce3e..e6f0e4d 100644
--- a/ash/wm/splitview/split_view_divider.h
+++ b/ash/wm/splitview/split_view_divider.h
@@ -29,9 +29,7 @@
 
 namespace ash {
 
-namespace mojom {
 enum class OrientationLockType;
-}
 
 class SplitViewController;
 
@@ -48,13 +46,13 @@
   // Gets the size of the divider widget. The divider widget is enlarged during
   // dragging. For now, it's a vertical rectangle.
   static gfx::Size GetDividerSize(const gfx::Rect& work_area_bounds,
-                                  mojom::OrientationLockType screen_orientation,
+                                  OrientationLockType screen_orientation,
                                   bool is_dragging);
 
   // static version of GetDividerBoundsInScreen(bool is_dragging) function.
   static gfx::Rect GetDividerBoundsInScreen(
       const gfx::Rect& work_area_bounds_in_screen,
-      mojom::OrientationLockType screen_orientation,
+      OrientationLockType screen_orientation,
       int divider_position,
       bool is_dragging);
 
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc
index 11e22b1..00e9bf8a 100644
--- a/ash/wm/toplevel_window_event_handler.cc
+++ b/ash/wm/toplevel_window_event_handler.cc
@@ -24,7 +24,6 @@
 #include "ui/aura/window_tracker.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/events/event.h"
 #include "ui/events/gestures/gesture_recognizer.h"
 #include "ui/views/widget/widget.h"
@@ -53,31 +52,22 @@
     return nullptr;
 
   aura::Window* toplevel = widget->GetNativeWindow();
-  if (features::IsUsingWindowService()) {
-    if (!toplevel->GetProperty(
-            aura::client::kGestureDragFromClientAreaTopMovesWindow)) {
-      return nullptr;
-    }
-  } else {
-    // Classic Ash: duplicate the logic from
-    // MakeGestureDraggableInImmersiveMode since there's no clear place during
-    // Widget init to hook that in.
-    if (!Shell::Get()
-             ->tablet_mode_controller()
-             ->IsTabletModeWindowManagerEnabled()) {
-      return nullptr;
-    }
-    wm::WindowState* window_state = wm::GetWindowState(toplevel);
-    if (!window_state ||
-        (!window_state->IsMaximized() && !window_state->IsFullscreen() &&
-         !window_state->IsSnapped())) {
-      return nullptr;
-    }
 
-    if (toplevel->GetProperty(aura::client::kAppType) ==
-        static_cast<int>(AppType::BROWSER)) {
-      return nullptr;
-    }
+  if (!Shell::Get()
+           ->tablet_mode_controller()
+           ->IsTabletModeWindowManagerEnabled()) {
+    return nullptr;
+  }
+  wm::WindowState* window_state = wm::GetWindowState(toplevel);
+  if (!window_state ||
+      (!window_state->IsMaximized() && !window_state->IsFullscreen() &&
+       !window_state->IsSnapped())) {
+    return nullptr;
+  }
+
+  if (toplevel->GetProperty(aura::client::kAppType) ==
+      static_cast<int>(AppType::BROWSER)) {
+    return nullptr;
   }
 
   if (event->details().scroll_y_hint() < 0)
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index 5a086f7..89d41e2d 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -117,65 +117,7 @@
   DISALLOW_COPY_AND_ASSIGN(InteriorResizeHandleTargeter);
 };
 
-// A class to track immersive and tablet mode state and update
-// kGestureDragFromClientAreaTopMovesWindow accordingly. It is owned by the
-// window it tracks by way of being an owned property.
-class GestureDraggableTracker : public aura::WindowObserver,
-                                public TabletModeObserver {
- public:
-  explicit GestureDraggableTracker(aura::Window* window)
-      : observed_window_(window) {
-    observed_window_->AddObserver(this);
-    Shell::Get()->tablet_mode_controller()->AddObserver(this);
-  }
-
-  ~GestureDraggableTracker() override {
-    observed_window_->RemoveObserver(this);
-    if (Shell::Get()->tablet_mode_controller())
-      Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
-  }
-
-  // aura::WindowObserver:
-  void OnWindowPropertyChanged(aura::Window* window,
-                               const void* key,
-                               intptr_t old) override {
-    if (key == kImmersiveIsActive)
-      UpdateFlag();
-  }
-
-  // TabletModeObserver:
-  void OnTabletModeStarted() override { UpdateFlag(); }
-  void OnTabletModeEnded() override { UpdateFlag(); }
-
- private:
-  void UpdateFlag() {
-    observed_window_->SetProperty(
-        aura::client::kGestureDragFromClientAreaTopMovesWindow,
-        observed_window_->GetProperty(kImmersiveIsActive) &&
-            Shell::Get()->tablet_mode_controller() &&
-            Shell::Get()
-                ->tablet_mode_controller()
-                ->IsTabletModeWindowManagerEnabled());
-  }
-
-  // |observed_window_| owns |this|.
-  aura::Window* observed_window_;
-
-  DISALLOW_COPY_AND_ASSIGN(GestureDraggableTracker);
-};
-
-DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(GestureDraggableTracker,
-                                   kGestureDraggableTracker,
-                                   nullptr)
-
 }  // namespace
-}  // namespace wm
-}  // namespace ash
-
-DEFINE_UI_CLASS_PROPERTY_TYPE(ash::wm::GestureDraggableTracker*)
-
-namespace ash {
-namespace wm {
 
 // TODO(beng): replace many of these functions with the corewm versions.
 void ActivateWindow(aura::Window* window) {
@@ -322,19 +264,6 @@
                       kResizeInsideBoundsSize);
 }
 
-void MakeGestureDraggableInImmersiveMode(aura::Window* frame_window) {
-  // For Browser windows, gesture drags from the top in immersive mode reveal
-  // the frame, so kGestureDragFromClientAreaTopMovesWindow should always be
-  // false.
-  if (static_cast<ash::AppType>(frame_window->GetProperty(
-          aura::client::kAppType)) == AppType::BROWSER) {
-    return;
-  }
-
-  frame_window->SetProperty(kGestureDraggableTracker,
-                            new GestureDraggableTracker(frame_window));
-}
-
 bool IsDraggingTabs(const aura::Window* window) {
   return window->GetProperty(ash::kIsDraggingTabsKey);
 }
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h
index 6c72d2df..b606f92 100644
--- a/ash/wm/window_util.h
+++ b/ash/wm/window_util.h
@@ -100,10 +100,6 @@
 ASH_EXPORT void InstallResizeHandleWindowTargeterForWindow(
     aura::Window* window);
 
-// Sets up the given window to be draggable via gesture sequences in certain
-// circumstances. See aura::client::kGestureDragFromClientAreaTopMovesWindow.
-ASH_EXPORT void MakeGestureDraggableInImmersiveMode(aura::Window* frame_window);
-
 // Returns true if |window| is currently in tab-dragging process.
 ASH_EXPORT bool IsDraggingTabs(const aura::Window* window);
 
diff --git a/ash/ws/ash_window_manager.cc b/ash/ws/ash_window_manager.cc
index 4cec6eb3b..f8511bf2 100644
--- a/ash/ws/ash_window_manager.cc
+++ b/ash/ws/ash_window_manager.cc
@@ -4,7 +4,6 @@
 
 #include "ash/ws/ash_window_manager.h"
 
-#include "ash/display/screen_orientation_controller.h"
 #include "ash/frame/non_client_frame_view_ash.h"
 #include "ash/shell.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
@@ -55,40 +54,6 @@
   }
 }
 
-void AshWindowManager::LockOrientation(
-    ws::Id window_id,
-    mojom::OrientationLockType lock_orientation) {
-  if (window_tree_->connection_type() ==
-      ws::WindowTree::ConnectionType::kEmbedding) {
-    DVLOG(1) << "LockOrientation not allowed from embed connection";
-    return;
-  }
-
-  aura::Window* window = window_tree_->GetWindowByTransportId(window_id);
-  if (window) {
-    Shell::Get()->screen_orientation_controller()->LockOrientationForWindow(
-        window, lock_orientation);
-  } else {
-    DVLOG(1) << "LockOrientation passed invalid window, id=" << window_id;
-  }
-}
-
-void AshWindowManager::UnlockOrientation(ws::Id window_id) {
-  if (window_tree_->connection_type() ==
-      ws::WindowTree::ConnectionType::kEmbedding) {
-    DVLOG(1) << "UnlockOrientation not allowed from embed connection";
-    return;
-  }
-
-  aura::Window* window = window_tree_->GetWindowByTransportId(window_id);
-  if (window) {
-    Shell::Get()->screen_orientation_controller()->UnlockOrientationForWindow(
-        window);
-  } else {
-    DVLOG(1) << "UnlockOrientation passed invalid window, id=" << window_id;
-  }
-}
-
 void AshWindowManager::MaximizeWindowByCaptionClick(
     ws::Id window_id,
     ui::mojom::PointerKind pointer) {
diff --git a/ash/ws/ash_window_manager.h b/ash/ws/ash_window_manager.h
index 042e1d4..681bbbf 100644
--- a/ash/ws/ash_window_manager.h
+++ b/ash/ws/ash_window_manager.h
@@ -34,9 +34,6 @@
   void AddWindowToTabletMode(ws::Id window_id) override;
   void ShowSnapPreview(ws::Id window_id, mojom::SnapDirection snap) override;
   void CommitSnap(ws::Id window_id, mojom::SnapDirection snap) override;
-  void LockOrientation(ws::Id window_id,
-                       mojom::OrientationLockType lock_orientation) override;
-  void UnlockOrientation(ws::Id window_id) override;
   void MaximizeWindowByCaptionClick(ws::Id window_id,
                                     ui::mojom::PointerKind pointer) override;
   void BounceWindow(ws::Id window_id) override;
diff --git a/ash/ws/ax_ash_window_utils.cc b/ash/ws/ax_ash_window_utils.cc
deleted file mode 100644
index 299ac4a2..0000000
--- a/ash/ws/ax_ash_window_utils.cc
+++ /dev/null
@@ -1,90 +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.
-
-#include "ash/ws/ax_ash_window_utils.h"
-
-#include <vector>
-
-#include "ash/shell.h"
-#include "ash/ws/window_lookup.h"
-#include "base/stl_util.h"
-#include "ui/views/widget/widget.h"
-
-namespace ash {
-
-AXAshWindowUtils::AXAshWindowUtils() = default;
-
-AXAshWindowUtils::~AXAshWindowUtils() = default;
-
-aura::Window* AXAshWindowUtils::GetParent(aura::Window* window) {
-  // Use --log-level=1 --vmodule=*ax_ash_window_utils*=1 to debug.
-  DVLOG(1) << "GetParent for " << window->GetName();
-  aura::Window* parent = window->parent();
-  if (parent)
-    return parent;
-
-  // If we don't have a parent, this might be the DesktopWindowTreeHostMus
-  // root window inside a client Widget. Check for a proxy window in ash.
-  aura::Window* proxy = window_lookup::GetProxyWindowForClientWindow(window);
-  if (!proxy)
-    return nullptr;
-
-  // "Jump the fence" to the parent of ash's proxy window. This will usually
-  // be a container window, like DefaultContainer.
-  return proxy->parent();
-}
-
-aura::Window::Windows AXAshWindowUtils::GetChildren(aura::Window* window) {
-  DVLOG(1) << "GetChildren for " << window->GetName();
-  std::vector<aura::Window*> windows;
-  windows.reserve(window->children().size());
-  for (aura::Window* child : window->children()) {
-    if (!window_lookup::IsProxyWindow(child)) {
-      // Window is owned by ash, behave as usual.
-      windows.push_back(child);
-      continue;
-    }
-    if (window_lookup::IsProxyWindowForOutOfProcess(child)) {
-      // Remote process clients like shortcut_viewer rely on the accessibility
-      // system serializing the Widget and Windows in ash.
-      windows.push_back(child);
-      continue;
-    }
-    // "Jump the fence" from ash proxy window to client window.
-    aura::Window* client = window_lookup::GetClientWindowForProxyWindow(child);
-    // Client window may not exist during DesktopWindowTreeHostMus teardown.
-    if (client)
-      windows.push_back(client);
-  }
-  return windows;
-}
-
-bool AXAshWindowUtils::IsRootWindow(aura::Window* window) const {
-  if (!window->IsRootWindow())
-    return false;
-  // SingleProcessMash behaves like classic ash. Only display roots are
-  // considered root windows for accessibility, not top-level Widgets or embeds.
-  std::vector<aura::Window*> roots = Shell::GetAllRootWindows();
-  return base::ContainsValue(roots, window);
-}
-
-views::Widget* AXAshWindowUtils::GetWidgetForNativeView(aura::Window* window) {
-  // If the window is owned by ash, behave as usual.
-  if (!window_lookup::IsProxyWindow(window))
-    return views::Widget::GetWidgetForNativeView(window);
-
-  // Remote process clients like shortcut_viewer rely on the accessibility
-  // system serializing the Widget and Windows in ash.
-  if (window_lookup::IsProxyWindowForOutOfProcess(window))
-    return views::Widget::GetWidgetForNativeView(window);
-
-  // For other proxy windows, jump the fence into the client window.
-  aura::Window* client = window_lookup::GetClientWindowForProxyWindow(window);
-  // Client window may not exist during DesktopWindowTreeHostMus teardown.
-  if (!client)
-    return nullptr;
-  return views::Widget::GetWidgetForNativeView(client);
-}
-
-}  // namespace ash
diff --git a/ash/ws/ax_ash_window_utils.h b/ash/ws/ax_ash_window_utils.h
deleted file mode 100644
index 301e8f5..0000000
--- a/ash/ws/ax_ash_window_utils.h
+++ /dev/null
@@ -1,36 +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 ASH_WS_AX_ASH_WINDOW_UTILS_H_
-#define ASH_WS_AX_ASH_WINDOW_UTILS_H_
-
-#include "ash/ash_export.h"
-#include "base/macros.h"
-#include "ui/views/accessibility/ax_aura_window_utils.h"
-
-namespace ash {
-
-// Provides functions for walking a tree of aura::Windows for accessibility. For
-// SingleProcessMash we want the accessibility tree to jump from a proxy aura
-// Window on the ash side directly to its corresponding client window. This is
-// just a temporary solution to that issue and should be removed once Mash is
-// fully launched. https://crbug.com/911945
-class ASH_EXPORT AXAshWindowUtils : public views::AXAuraWindowUtils {
- public:
-  AXAshWindowUtils();
-  ~AXAshWindowUtils() override;
-
-  // views::AXAuraWindowUtils:
-  aura::Window* GetParent(aura::Window* window) override;
-  aura::Window::Windows GetChildren(aura::Window* window) override;
-  bool IsRootWindow(aura::Window* window) const override;
-  views::Widget* GetWidgetForNativeView(aura::Window* window) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AXAshWindowUtils);
-};
-
-}  // namespace ash
-
-#endif  // ASH_WS_AX_ASH_WINDOW_UTILS_H_
diff --git a/ash/ws/ax_ash_window_utils_unittest.cc b/ash/ws/ax_ash_window_utils_unittest.cc
deleted file mode 100644
index 7185607..0000000
--- a/ash/ws/ax_ash_window_utils_unittest.cc
+++ /dev/null
@@ -1,224 +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.
-
-#include "ash/ws/ax_ash_window_utils.h"
-
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/test/ash_test_helper.h"
-#include "ash/wm/desks/desks_util.h"
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/accessibility/ax_node.h"
-#include "ui/accessibility/ax_tree.h"
-#include "ui/accessibility/ax_tree_id.h"
-#include "ui/accessibility/ax_tree_serializer.h"
-#include "ui/accessibility/ax_tree_source_checker.h"
-#include "ui/accessibility/ax_tree_update.h"
-#include "ui/aura/env.h"
-#include "ui/aura/mus/window_mus.h"
-#include "ui/aura/mus/window_tree_client.h"
-#include "ui/aura/mus/window_tree_host_mus.h"
-#include "ui/aura/mus/window_tree_host_mus_init_params.h"
-#include "ui/aura/test/mus/change_completion_waiter.h"
-#include "ui/aura/window.h"
-#include "ui/base/ui_base_features.h"
-#include "ui/views/accessibility/ax_aura_obj_cache.h"
-#include "ui/views/accessibility/ax_root_obj_wrapper.h"
-#include "ui/views/accessibility/ax_tree_source_views.h"
-#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/mus/mus_client.h"
-#include "ui/views/widget/widget.h"
-
-using views::AXAuraObjCache;
-using views::AXAuraObjWrapper;
-using views::AXTreeSourceViews;
-using views::MusClient;
-using views::Textfield;
-using views::View;
-using views::Widget;
-
-using AuraAXTreeSerializer = ui::
-    AXTreeSerializer<views::AXAuraObjWrapper*, ui::AXNodeData, ui::AXTreeData>;
-
-using AuraAXTreeSourceChecker =
-    ui::AXTreeSourceChecker<views::AXAuraObjWrapper*,
-                            ui::AXNodeData,
-                            ui::AXTreeData>;
-
-namespace ash {
-namespace {
-
-bool HasNodeWithName(ui::AXNode* node, const std::string& name) {
-  if (node->GetStringAttribute(ax::mojom::StringAttribute::kName) == name)
-    return true;
-  for (auto* child : node->children()) {
-    if (HasNodeWithName(child, name))
-      return true;
-  }
-  return false;
-}
-
-bool HasNodeWithValue(ui::AXNode* node, const std::string& value) {
-  if (node->GetStringAttribute(ax::mojom::StringAttribute::kValue) == value)
-    return true;
-  for (auto* child : node->children()) {
-    if (HasNodeWithValue(child, value))
-      return true;
-  }
-  return false;
-}
-
-class AXAshWindowUtilsTest : public SingleProcessMashTestBase {
- public:
-  AXAshWindowUtilsTest() = default;
-  ~AXAshWindowUtilsTest() override = default;
-
-  // AshTestBase:
-  void SetUp() override {
-    SingleProcessMashTestBase::SetUp();
-
-    // Create a widget with a child view.
-    widget_ = std::make_unique<Widget>();
-    Widget::InitParams params;
-    params.name = "Test Widget";
-    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-    params.bounds = gfx::Rect(0, 0, 200, 200);
-    params.native_widget =
-        MusClient::Get()->CreateNativeWidget(params, widget_.get());
-    widget_->Init(params);
-    widget_->Show();
-
-    textfield_ = new Textfield();
-    textfield_->SetText(base::ASCIIToUTF16("Test Textfield"));
-    widget_->GetContentsView()->AddChildView(textfield_);
-
-    // Flush all messages from the WindowTreeClient to ensure the window service
-    // has finished Widget creation.
-    aura::test::WaitForAllChangesToComplete();
-  }
-
-  void TearDown() override {
-    widget_.reset();
-    SingleProcessMashTestBase::TearDown();
-  }
-
- protected:
-  std::unique_ptr<Widget> widget_;
-  Textfield* textfield_ = nullptr;  // Owned by views hierarchy.
-
-  DISALLOW_COPY_AND_ASSIGN(AXAshWindowUtilsTest);
-};
-
-TEST_F(AXAshWindowUtilsTest, WalkUpToAshRoot) {
-  AXAshWindowUtils utils;
-
-  // Start with a window in the client.
-  aura::Window* window = widget_->GetNativeWindow();
-  EXPECT_EQ(aura::Env::Mode::MUS, window->env()->mode());
-
-  // Walk up to the root node.
-  while (true) {
-    aura::Window* parent = utils.GetParent(window);
-    if (!parent)
-      break;
-    window = parent;
-  }
-
-  // Walking up "jumped the fence" into ash windows.
-  EXPECT_EQ(aura::Env::Mode::LOCAL, window->env()->mode());
-  EXPECT_EQ(Shell::GetPrimaryRootWindow()->GetName(), window->GetName());
-}
-
-TEST_F(AXAshWindowUtilsTest, WalkDownToClientWindow) {
-  AXAshWindowUtils utils;
-
-  // Start with the widget's container.
-  aura::Window* container = Shell::GetContainer(
-      Shell::GetPrimaryRootWindow(), desks_util::GetActiveDeskContainerId());
-  EXPECT_EQ(aura::Env::Mode::LOCAL, container->env()->mode());
-
-  // Walking down "jumps the fence" into the client window.
-  std::vector<aura::Window*> children = utils.GetChildren(container);
-  ASSERT_EQ(1u, children.size());
-  aura::Window* child = children[0];
-  EXPECT_EQ(aura::Env::Mode::MUS, child->env()->mode());
-  EXPECT_EQ(widget_.get(), utils.GetWidgetForNativeView(child));
-}
-
-// Verify integration of AXAshWindowUtils with the accessibility subsystem
-// serialization code.
-TEST_F(AXAshWindowUtilsTest, SerializeNodeTree) {
-  // Build a desktop tree serializer similar to AutomationManagerAura.
-  AXAuraObjCache cache;
-  cache.OnRootWindowObjCreated(Shell::GetPrimaryRootWindow());
-  AXRootObjWrapper root_wrapper(nullptr /* delegate */, &cache);
-  AXTreeSourceViews ax_tree_source(&root_wrapper,
-                                   ui::AXTreeID::CreateNewAXTreeID(), &cache);
-  AuraAXTreeSerializer ax_serializer(&ax_tree_source);
-
-  // Initial tree is valid.
-  AuraAXTreeSourceChecker checker(&ax_tree_source);
-  ASSERT_TRUE(checker.Check());
-
-  // Simulate initial serialization.
-  ui::AXTreeUpdate initial_update;
-  ax_serializer.SerializeChanges(ax_tree_source.GetRoot(), &initial_update);
-
-  // Tree includes system UI.
-  ui::AXTree ax_tree(initial_update);
-  EXPECT_TRUE(HasNodeWithName(ax_tree.root(), "Shelf"));
-
-  // Remove the child view and re-add it, which should fire some events.
-  widget_->GetContentsView()->RemoveAllChildViews(false /* delete_children */);
-  widget_->GetContentsView()->AddChildView(textfield_);
-
-  // Serialize walking up from the textfield.
-  ui::AXTreeUpdate label_update;
-  AXAuraObjWrapper* wrapper = cache.GetOrCreate(textfield_);
-  ASSERT_TRUE(ax_serializer.SerializeChanges(wrapper, &label_update));
-  ASSERT_TRUE(ax_tree.Unserialize(label_update));
-
-  // Tree still includes system UI.
-  EXPECT_TRUE(HasNodeWithName(ax_tree.root(), "Shelf"));
-
-  // The serializer also "jumped the fence" from the ash tree to the mus-client
-  // tree, so the tree has nodes from inside the Widget.
-  EXPECT_TRUE(HasNodeWithValue(ax_tree.root(), "Test Textfield"));
-
-  // AXAuraObjCache can reach into a client Widget to find a focused view.
-  textfield_->RequestFocus();
-  EXPECT_TRUE(textfield_->HasFocus());
-  AXAuraObjWrapper* textfield_wrapper = cache.GetOrCreate(textfield_);
-  EXPECT_EQ(textfield_wrapper, cache.GetFocus());
-}
-
-TEST_F(AXAshWindowUtilsTest, IsRootWindow) {
-  AXAshWindowUtils utils;
-
-  // From the client's perspective a widget's root window is a root.
-  aura::Window* widget_root = widget_->GetNativeWindow()->GetRootWindow();
-  EXPECT_TRUE(widget_root->IsRootWindow());
-
-  // Simulate an embedded remote client window.
-  aura::WindowTreeHostMus window_tree_host(aura::CreateInitParamsForTopLevel(
-      views::MusClient::Get()->window_tree_client()));
-  window_tree_host.InitHost();
-  window_tree_host.SetBounds(gfx::Rect(0, 0, 100, 200),
-                             viz::LocalSurfaceIdAllocation());
-  aura::Window* embed_root = window_tree_host.window();
-
-  // From the client's perspective the embed is a root.
-  EXPECT_TRUE(embed_root->IsRootWindow());
-
-  // Accessibility serialization only considers display roots to be roots.
-  EXPECT_TRUE(utils.IsRootWindow(Shell::GetPrimaryRootWindow()));
-  EXPECT_FALSE(utils.IsRootWindow(embed_root));
-  EXPECT_FALSE(utils.IsRootWindow(widget_root));
-}
-
-}  // namespace
-}  // namespace ash
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index ea29e14b..50030ec 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -111,12 +111,7 @@
 //                    const char* name,
 //                    const char* scope,
 //                    unsigned long long id,
-//                    int num_args,
-//                    const char** arg_names,
-//                    const unsigned char* arg_types,
-//                    const unsigned long long* arg_values,
-//                    std::unique_ptr<ConvertableToTraceFormat>*
-//                    convertable_values,
+//                    base::trace_event::TraceArguments* args,
 //                    unsigned int flags)
 #define TRACE_EVENT_API_ADD_TRACE_EVENT trace_event_internal::AddTraceEvent
 
@@ -129,12 +124,7 @@
 //                    const char* scope,
 //                    unsigned long long id,
 //                    unsigned long long bind_id,
-//                    int num_args,
-//                    const char** arg_names,
-//                    const unsigned char* arg_types,
-//                    const unsigned long long* arg_values,
-//                    std::unique_ptr<ConvertableToTraceFormat>*
-//                    convertable_values,
+//                    base::trace_event::TraceArguments* args,
 //                    unsigned int flags)
 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID \
   trace_event_internal::AddTraceEventWithBindId
@@ -149,12 +139,7 @@
 //                    const char* scope,
 //                    unsigned long long id,
 //                    int process_id,
-//                    int num_args,
-//                    const char** arg_names,
-//                    const unsigned char* arg_types,
-//                    const unsigned long long* arg_values,
-//                    std::unique_ptr<ConvertableToTraceFormat>*
-//                    convertable_values,
+//                    base::trace_event::TraceArguments* args,
 //                    unsigned int flags)
 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID \
   trace_event_internal::AddTraceEventWithProcessId
@@ -169,12 +154,7 @@
 //                    unsigned long long id,
 //                    int thread_id,
 //                    const TimeTicks& timestamp,
-//                    int num_args,
-//                    const char** arg_names,
-//                    const unsigned char* arg_types,
-//                    const unsigned long long* arg_values,
-//                    std::unique_ptr<ConvertableToTraceFormat>*
-//                    convertable_values,
+//                    base::trace_event::TraceArguments* args,
 //                    unsigned int flags)
 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \
   trace_event_internal::AddTraceEventWithThreadIdAndTimestamp
@@ -732,98 +712,6 @@
                                  const base::TimeTicks& now,
                                  const base::ThreadTicks& thread_now);
 
-// TODO(898794): Remove these functions once all callers have been updated
-// to use base::trace_event::Arguments instead.
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEvent(char phase,
-              const unsigned char* category_group_enabled,
-              const char* name,
-              const char* scope,
-              unsigned long long id,
-              int num_args,
-              const char* const* arg_names,
-              const unsigned char* arg_types,
-              const unsigned long long* arg_values,
-              std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-                  convertable_values,
-              unsigned int flags);
-
-base::trace_event::TraceEventHandle BASE_EXPORT AddTraceEventWithBindId(
-    char phase,
-    const unsigned char* category_group_enabled,
-    const char* name,
-    const char* scope,
-    unsigned long long id,
-    unsigned long long bind_id,
-    int num_args,
-    const char* const* arg_names,
-    const unsigned char* arg_types,
-    const unsigned long long* arg_values,
-    std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-        convertable_values,
-    unsigned int flags);
-
-base::trace_event::TraceEventHandle BASE_EXPORT AddTraceEventWithProcessId(
-    char phase,
-    const unsigned char* category_group_enabled,
-    const char* name,
-    const char* scope,
-    unsigned long long id,
-    int process_id,
-    int num_args,
-    const char* const* arg_names,
-    const unsigned char* arg_types,
-    const unsigned long long* arg_values,
-    std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-        convertable_values,
-    unsigned int flags);
-
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithThreadIdAndTimestamp(
-    char phase,
-    const unsigned char* category_group_enabled,
-    const char* name,
-    const char* scope,
-    unsigned long long id,
-    int thread_id,
-    const base::TimeTicks& timestamp,
-    int num_args,
-    const char* const* arg_names,
-    const unsigned char* arg_types,
-    const unsigned long long* arg_values,
-    std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-        convertable_values,
-    unsigned int flags);
-
-base::trace_event::TraceEventHandle BASE_EXPORT
-AddTraceEventWithThreadIdAndTimestamp(
-    char phase,
-    const unsigned char* category_group_enabled,
-    const char* name,
-    const char* scope,
-    unsigned long long id,
-    unsigned long long bind_id,
-    int thread_id,
-    const base::TimeTicks& timestamp,
-    int num_args,
-    const char* const* arg_names,
-    const unsigned char* arg_types,
-    const unsigned long long* arg_values,
-    std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-        convertable_values,
-    unsigned int flags);
-
-void BASE_EXPORT
-AddMetadataEvent(const unsigned char* category_group_enabled,
-                 const char* name,
-                 int num_args,
-                 const char* const* arg_names,
-                 const unsigned char* arg_types,
-                 const unsigned long long* arg_values,
-                 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>*
-                     convertable_values,
-                 unsigned int flags);
-
 // These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
 // functions are defined here instead of in the macro, because the arg_values
 // could be temporary objects, such as std::string. In order to store
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 4406479..d24d1e3 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8914644572533835024
\ No newline at end of file
+8914618441507983984
\ No newline at end of file
diff --git a/chrome/VERSION b/chrome/VERSION
index 3d0ccd8a..fb6b144 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=76
 MINOR=0
-BUILD=3783
+BUILD=3784
 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index c2ad824..15d3efd 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -710,10 +710,11 @@
   "java/src/org/chromium/chrome/browser/gcore/GoogleApiClientHelper.java",
   "java/src/org/chromium/chrome/browser/gcore/LifecycleHook.java",
   "java/src/org/chromium/chrome/browser/gesturenav/ArrowChipView.java",
-  "java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegateImpl.java",
+  "java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegate.java",
   "java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java",
   "java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java",
   "java/src/org/chromium/chrome/browser/gesturenav/SideSlideLayout.java",
+  "java/src/org/chromium/chrome/browser/gesturenav/TabSwitcherActionDelegate.java",
   "java/src/org/chromium/chrome/browser/gesturenav/TabbedActionDelegate.java",
   "java/src/org/chromium/chrome/browser/gsa/ContextReporter.java",
   "java/src/org/chromium/chrome/browser/gsa/GSAAccountChangeListener.java",
@@ -904,6 +905,7 @@
   "java/src/org/chromium/chrome/browser/nfc/BeamController.java",
   "java/src/org/chromium/chrome/browser/nfc/BeamProvider.java",
   "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java",
+  "java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java",
   "java/src/org/chromium/chrome/browser/night_mode/NightModeStateProvider.java",
   "java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java",
   "java/src/org/chromium/chrome/browser/night_mode/SystemNightModeMonitor.java",
diff --git a/chrome/android/features/tab_ui/java/res/layout/grid_tab_switcher_layout.xml b/chrome/android/features/tab_ui/java/res/layout/grid_tab_switcher_layout.xml
new file mode 100644
index 0000000..9d21981
--- /dev/null
+++ b/chrome/android/features/tab_ui/java/res/layout/grid_tab_switcher_layout.xml
@@ -0,0 +1,19 @@
+<?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. -->
+<org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/history_navigation"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView
+        android:id="@+id/tab_list_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipToPadding="false"
+        android:paddingStart="8dp"
+        android:paddingEnd="8dp"
+        android:visibility="invisible"/>
+</org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout>
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml
index c188cad..a12c02aa 100644
--- a/chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml
+++ b/chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml
@@ -11,4 +11,3 @@
     android:paddingStart="8dp"
     android:paddingEnd="8dp"
     android:visibility="invisible"/>
-
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
index 474a57e4..db98904 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
@@ -11,6 +11,8 @@
 import org.chromium.chrome.browser.compositor.layouts.OverviewModeController;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
 import org.chromium.chrome.browser.tab.Tab;
@@ -80,8 +82,12 @@
         mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
                 tabModelSelector, mMultiThumbnailCardProvider, titleProvider, true,
                 mMediator::getCreateGroupButtonOnClickListener, gridCardOnClickListenerProvider,
-                compositorViewHolder, true, COMPONENT_NAME);
-
+                compositorViewHolder, true,
+                org.chromium.chrome.tab_ui.R.layout.grid_tab_switcher_layout, COMPONENT_NAME);
+        HistoryNavigationLayout navigation =
+                compositorViewHolder.findViewById(R.id.history_navigation);
+        navigation.setNavigationDelegate(
+                HistoryNavigationDelegate.createForTabSwitcher(tabModelSelector::getCurrentTab));
         mContainerViewChangeProcessor = PropertyModelChangeProcessor.create(containerViewModel,
                 mTabGridCoordinator.getContainerView(), TabGridContainerViewBinder::bind);
 
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
index 5b9ecf11..807020b 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -13,6 +13,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.tab_ui.R;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
@@ -42,7 +43,8 @@
 
         mTabListCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
                 tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, null,
-                null, compositorViewHolder, false, COMPONENT_NAME);
+                null, compositorViewHolder, false, R.layout.tab_list_recycler_view_layout,
+                COMPONENT_NAME);
 
         mMediator = new TabGridDialogMediator(context, this::resetWithListOfTabs,
                 mToolbarPropertyModel, tabModelSelector, tabCreatorManager, resetHandler);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java
index 504d183..e9ebf9e 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetCoordinator.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
+import org.chromium.chrome.tab_ui.R;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
@@ -44,7 +45,8 @@
 
         mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
                 tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, null,
-                null, bottomSheetController.getBottomSheet(), false, COMPONENT_NAME);
+                null, bottomSheetController.getBottomSheet(), false,
+                R.layout.tab_list_recycler_view_layout, COMPONENT_NAME);
 
         mMediator = new TabGridSheetMediator(mContext, bottomSheetController,
                 this::resetWithListOfTabs, mToolbarPropertyModel, tabModelSelector,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
index 32bf5b1..04371c49 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -23,6 +23,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter;
 import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator;
+import org.chromium.chrome.tab_ui.R;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
@@ -75,7 +76,8 @@
 
         mTabStripCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.STRIP,
                 mContext, tabModelSelector, null, null, false, null, null,
-                mTabStripToolbarCoordinator.getTabListContainerView(), true, COMPONENT_NAME);
+                mTabStripToolbarCoordinator.getTabListContainerView(), true,
+                R.layout.tab_list_recycler_view_layout, COMPONENT_NAME);
 
         mTabGridSheetCoordinator =
                 new TabGridSheetCoordinator(mContext, activity.getBottomSheetController(),
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
index 5824872..1cc4f4cf 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.support.annotation.IntDef;
+import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.GridLayoutManager;
@@ -63,6 +64,7 @@
      *         to provide "Create group" button.
      * @param parentView {@link ViewGroup} The root view of the UI.
      * @param attachToParent Whether the UI should attach to root view.
+     * @param layoutId ID of the layout resource.
      * @param componentName A unique string uses to identify different components for UMA recording.
      *                      Recommended to use the class name or make sure the string is unique
      *                      through actions.xml file.
@@ -73,7 +75,8 @@
             @Nullable TabListMediator.CreateGroupButtonProvider createGroupButtonProvider,
             @Nullable TabListMediator
                     .GridCardOnClickListenerProvider gridCardOnClickListenerProvider,
-            @NonNull ViewGroup parentView, boolean attachToParent, String componentName) {
+            @NonNull ViewGroup parentView, boolean attachToParent, @LayoutRes int layoutId,
+            String componentName) {
         TabListModel tabListModel = new TabListModel();
         mMode = mode;
 
@@ -94,13 +97,11 @@
             throw new IllegalArgumentException(
                     "Attempting to create a tab list UI with invalid mode");
         }
-
         if (!attachToParent) {
             mRecyclerView = (TabListRecyclerView) LayoutInflater.from(context).inflate(
-                    R.layout.tab_list_recycler_view_layout, parentView, false);
+                    layoutId, parentView, false);
         } else {
-            LayoutInflater.from(context).inflate(
-                    R.layout.tab_list_recycler_view_layout, parentView, true);
+            LayoutInflater.from(context).inflate(layoutId, parentView, true);
             mRecyclerView = parentView.findViewById(R.id.tab_list_view);
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
index aa10e15..14234e0d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -461,6 +461,19 @@
     }
 
     /**
+     * @param view {@link View} to define the area on.
+     * @param left Left The left coordinate of the area.
+     * @param top The top coordinate of the area.
+     * @param right The right coordinate of the area.
+     * @param bottom The bottom coordinate of the area.
+     * @return A {@link Runnable} that sets the input space in which swipe triggers navigation.
+     */
+    public Runnable createNavigationInputAreaSetter(
+            View view, int left, int top, int right, int bottom) {
+        return () -> {};
+    }
+
+    /**
      * Starts monitoring network quality. Must be called after native initialization is complete.
      */
     public void startMonitoringNetworkQuality() {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
index 92b3a83e..5f35548 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.native_page.BasicNativePage;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
 import org.chromium.chrome.browser.profiles.Profile;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java
index 01901cf0..c813ea9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java
@@ -19,7 +19,6 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.compositor.LayerTitleCache;
 import org.chromium.chrome.browser.compositor.animation.CompositorAnimator;
@@ -41,6 +40,7 @@
 import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
 import org.chromium.chrome.browser.gesturenav.NavigationHandler;
+import org.chromium.chrome.browser.gesturenav.TabSwitcherActionDelegate;
 import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabList;
@@ -530,23 +530,8 @@
             }
         };
         if (mNavigationEnabled && mNavigationHandler == null) {
-            final ChromeActivity activity = currentTab().getActivity();
-            mNavigationHandler =
-                    new NavigationHandler(mViewContainer, new NavigationHandler.ActionDelegate() {
-                        @Override
-                        public boolean canNavigate(boolean forward) {
-                            return !forward;
-                        }
-                        @Override
-                        public void navigate(boolean forward) {
-                            // Called only when !forward.
-                            activity.onBackPressed();
-                        }
-                        @Override
-                        public boolean willBackExitApp() {
-                            return currentTab() == null;
-                        }
-                    });
+            mNavigationHandler = new NavigationHandler(mViewContainer,
+                    new TabSwitcherActionDelegate(mTabModelSelector::getCurrentTab));
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java
index 95b64ff..c2b57d5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java
@@ -6,7 +6,7 @@
 
 import android.view.View;
 
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 
 /**
  * A coordinator that represents the main download manager UI page. This visually shows a list of
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
index 829cc3cf..8e71dbc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
@@ -20,8 +20,8 @@
 import org.chromium.chrome.browser.download.home.snackbars.DeleteUndoCoordinator;
 import org.chromium.chrome.browser.download.home.toolbar.ToolbarCoordinator;
 import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.preferences.download.DownloadPreferences;
 import org.chromium.chrome.browser.profiles.Profile;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
index 904bf03..abe4c17 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -37,7 +37,7 @@
 import org.chromium.chrome.browser.download.home.metrics.UmaUtils.MenuAction;
 import org.chromium.chrome.browser.download.home.toolbar.ToolbarUtils;
 import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.native_page.BasicNativePage;
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.preferences.download.DownloadPreferences;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegate.java
new file mode 100644
index 0000000..e2cb0f9
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegate.java
@@ -0,0 +1,91 @@
+// 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.gesturenav;
+
+import android.content.Context;
+
+import org.chromium.base.Supplier;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.tab.Tab;
+
+/**
+ * Provides navigation-related configuration for pages using {@link HistoryNavigationLayout}.
+ */
+public abstract class HistoryNavigationDelegate {
+    private final boolean mIsEnabled;
+    private final boolean mDelegateSwipes;
+
+    private HistoryNavigationDelegate(Context context) {
+        mIsEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION)
+                && (context instanceof ChromeActivity);
+        mDelegateSwipes = ChromeFeatureList.isEnabled(ChromeFeatureList.DELEGATE_OVERSCROLL_SWIPES);
+    }
+
+    /**
+     * @return {@code true} if history navigation is enabled.
+     */
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    /**
+     * @return {@code true} if swipe events are delegated to websites first.
+     */
+    public boolean delegateSwipes() {
+        return mDelegateSwipes;
+    }
+
+    /**
+     * @return {@link NavigationHandler#ActionDelegate} object.
+     */
+    public abstract NavigationHandler.ActionDelegate createActionDelegate();
+
+    // Implementation for native pages with TabbedActionDelegate that uses Tab.goForward/goBack
+    // to implement history navigation.
+    private static class NativePageDelegate extends HistoryNavigationDelegate {
+        private final Tab mTab;
+
+        private NativePageDelegate(Tab tab) {
+            super(tab.getActivity());
+            mTab = tab;
+        }
+
+        @Override
+        public NavigationHandler.ActionDelegate createActionDelegate() {
+            return new TabbedActionDelegate(mTab);
+        }
+    }
+
+    /**
+     * Creates {@link HistoryNavigationDelegate} for a native page.
+     */
+    public static HistoryNavigationDelegate createForNativePage(Tab tab) {
+        return new NativePageDelegate(tab);
+    }
+
+    // Implementation for tab switcher. Can't go forward, and going back exits
+    // the switcher. Can exit Chrome if there's no current tab to go back to.
+    private static class TabSwitcherNavigationDelegate extends HistoryNavigationDelegate {
+        private Supplier<Tab> mCurrentTab;
+
+        private TabSwitcherNavigationDelegate(Supplier<Tab> currentTab) {
+            super(currentTab.get().getActivity());
+            mCurrentTab = currentTab;
+        }
+
+        @Override
+        public NavigationHandler.ActionDelegate createActionDelegate() {
+            return new TabSwitcherActionDelegate(mCurrentTab);
+        }
+    }
+
+    /**
+     * Creates {@link HistoryNavigationDelegate} for tab switcher.
+     */
+    public static HistoryNavigationDelegate createForTabSwitcher(Supplier<Tab> currentTab) {
+        return new TabSwitcherNavigationDelegate(currentTab);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegateImpl.java
deleted file mode 100644
index 840e840..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationDelegateImpl.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.gesturenav;
-
-import android.content.Context;
-
-import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.ChromeFeatureList;
-import org.chromium.chrome.browser.tab.Tab;
-
-/**
- * {@link HistoryNavigationLayout#HistoryNavigationDelegate} implementation for
- * native pages in tabbed mode.
- */
-public class HistoryNavigationDelegateImpl
-        implements HistoryNavigationLayout.HistoryNavigationDelegate {
-    private final Tab mTab;
-    private final boolean mIsEnabled;
-    private final boolean mDelegateSwipes;
-
-    public HistoryNavigationDelegateImpl(Context context, Tab tab) {
-        mTab = tab;
-        mIsEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION)
-                && (context instanceof ChromeActivity);
-        mDelegateSwipes = ChromeFeatureList.isEnabled(ChromeFeatureList.DELEGATE_OVERSCROLL_SWIPES);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    @Override
-    public boolean delegateSwipes() {
-        return mDelegateSwipes;
-    }
-
-    @Override
-    public NavigationHandler.ActionDelegate createActionDelegate() {
-        return new TabbedActionDelegate(mTab);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java
index b3beb695..8b5b780 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java
@@ -24,26 +24,6 @@
     private GestureDetector mDetector;
     private NavigationHandler mNavigationHandler;
 
-    /**
-     * Interface providing navigation-related configuration for native pages using this class.
-     */
-    public interface HistoryNavigationDelegate {
-        /**
-         * @return {@code true} if history navigation is enabled.
-         */
-        boolean isEnabled();
-
-        /**
-         * @return {@code true} if swipe events are delegated to websites first.
-         */
-        boolean delegateSwipes();
-
-        /**
-         * @return {@link NavigationHandler#ActionDelegate} object.
-         */
-        NavigationHandler.ActionDelegate createActionDelegate();
-    }
-
     public HistoryNavigationLayout(Context context) {
         this(context, null);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
index 3beed66..779a9cee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
@@ -7,10 +7,12 @@
 import android.support.annotation.IntDef;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 
 import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.AppHooks;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -81,6 +83,13 @@
         mParentView = parentView;
         mDelegate = delegate;
         mEdgeWidthPx = EDGE_WIDTH_DP * parentView.getResources().getDisplayMetrics().density;
+        parentView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                AppHooks.get().createNavigationInputAreaSetter(v, left, top, right, bottom).run();
+            }
+        });
     }
 
     private void createLayout() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/TabSwitcherActionDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/TabSwitcherActionDelegate.java
new file mode 100644
index 0000000..afa83d2
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/TabSwitcherActionDelegate.java
@@ -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.
+
+package org.chromium.chrome.browser.gesturenav;
+
+import org.chromium.base.Supplier;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.tab.Tab;
+
+/**
+ * Implementation of {@link NavigationHandler#ActionDelegate} that works for Tab switcher.
+ * Swipe from left exits the tab switcher and goes back to the current tab. Can exit
+ * Chrome app itself if there's no current tab.
+ */
+public class TabSwitcherActionDelegate implements NavigationHandler.ActionDelegate {
+    private final Supplier<Tab> mCurrentTab;
+    private final ChromeActivity mActivity;
+
+    public TabSwitcherActionDelegate(Supplier<Tab> currentTab) {
+        mCurrentTab = currentTab;
+
+        // Cache the activity at the beginning since it may not be reachable
+        // later when current tab becomes null.
+        mActivity = currentTab.get().getActivity();
+    }
+
+    @Override
+    public boolean canNavigate(boolean forward) {
+        return !forward;
+    }
+
+    @Override
+    public void navigate(boolean forward) {
+        assert !forward : "Should be called only for back navigation";
+        mActivity.onBackPressed();
+    }
+
+    @Override
+    public boolean willBackExitApp() {
+        return mCurrentTab.get() == null;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index 0493699..80e94f96 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -31,7 +31,7 @@
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.PrefChangeRegistrar;
 import org.chromium.chrome.browser.preferences.PrefChangeRegistrar.PrefObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
index 4dd1384..38a9180 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -16,8 +16,7 @@
 import org.chromium.chrome.browser.download.DownloadPage;
 import org.chromium.chrome.browser.explore_sites.ExploreSitesPage;
 import org.chromium.chrome.browser.feed.FeedNewTabPage;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegateImpl;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.history.HistoryPage;
 import org.chromium.chrome.browser.ntp.IncognitoNewTabPage;
 import org.chromium.chrome.browser.ntp.NewTabPage;
@@ -244,7 +243,7 @@
 
         @Override
         public HistoryNavigationDelegate createHistoryNavigationDelegate() {
-            return new HistoryNavigationDelegateImpl(mTab.getActivity(), mTab);
+            return HistoryNavigationDelegate.createForNativePage(mTab);
         }
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageHost.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageHost.java
index 2cc67e80..9f9b54c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageHost.java
@@ -6,7 +6,7 @@
 
 import android.support.annotation.Nullable;
 
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content_public.browser.LoadUrlParams;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
index 47a7789..20b0d27 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
@@ -161,6 +161,12 @@
         AppCompatDelegate.setDefaultNightMode(
                 mNightModeOn ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
         for (Observer observer : mObservers) observer.onNightModeStateChanged();
+
+        NightModeMetrics.recordNightModeState(mNightModeOn);
+        NightModeMetrics.recordThemePreferencesState(themeSetting);
+        if (mNightModeOn) {
+            NightModeMetrics.recordNightModeEnabledReason(themeSetting, mPowerSaveModeOn);
+        }
     }
 
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java
new file mode 100644
index 0000000..ea5f375
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java
@@ -0,0 +1,105 @@
+// 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.night_mode;
+
+import android.support.annotation.IntDef;
+
+import org.chromium.base.metrics.CachedMetrics;
+import org.chromium.base.metrics.RecordUserAction;
+import org.chromium.chrome.browser.preferences.themes.ThemePreferences;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Records user actions and histograms related to the night mode state.
+ */
+public class NightModeMetrics {
+    private static final CachedMetrics.BooleanHistogramSample BOOLEAN_NIGHT_MODE_STATE =
+            new CachedMetrics.BooleanHistogramSample("Android.DarkTheme.EnabledState");
+
+    private static final CachedMetrics
+            .EnumeratedHistogramSample ENUMERATED_NIGHT_MODE_ENABLED_REASON =
+            new CachedMetrics.EnumeratedHistogramSample(
+                    "Android.DarkTheme.EnabledReason", NightModeEnabledReason.NUM_ENTRIES);
+
+    private static final CachedMetrics.EnumeratedHistogramSample ENUMERATED_THEME_PREFERENCE_STATE =
+            new CachedMetrics.EnumeratedHistogramSample("Android.DarkTheme.Preference.State",
+                    ThemePreferences.ThemeSetting.NUM_ENTRIES);
+
+    /**
+     * Different ways that night mode (aka dark theme) can be enabled. This is used for histograms
+     * and should therefore be treated as append-only. See DarkThemeEnabledReason in
+     * tools/metrics/histograms/enums.xml.
+     */
+    @IntDef({NightModeEnabledReason.USER_PREFERENCE, NightModeEnabledReason.POWER_SAVE_MODE,
+            NightModeEnabledReason.OTHER})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface NightModeEnabledReason {
+        int USER_PREFERENCE = 0;
+        int POWER_SAVE_MODE = 1;
+        // TODO(https://crbug.com/941819): Rename this.
+        int OTHER = 2;
+        int NUM_ENTRIES = 3;
+    }
+
+    /**
+     * Records the new night mode state in histogram.
+     * @param isInNightMode Whether the app is currently in night mode.
+     */
+    public static void recordNightModeState(boolean isInNightMode) {
+        BOOLEAN_NIGHT_MODE_STATE.record(isInNightMode);
+    }
+
+    /**
+     * Records the reason that night mode is turned on.
+     * @param setting The {@link ThemePreferences.ThemeSetting} that the user selects.
+     * @param powerSaveModeOn Whether or not power save mode is on.
+     */
+    public static void recordNightModeEnabledReason(
+            @ThemePreferences.ThemeSetting int setting, boolean powerSaveModeOn) {
+        ENUMERATED_NIGHT_MODE_ENABLED_REASON.record(
+                calculateNightModeEnabledReason(setting, powerSaveModeOn));
+    }
+
+    @NightModeEnabledReason
+    private static int calculateNightModeEnabledReason(
+            @ThemePreferences.ThemeSetting int setting, boolean powerSaveModeOn) {
+        if (setting == ThemePreferences.ThemeSetting.DARK) {
+            return NightModeEnabledReason.USER_PREFERENCE;
+        }
+        if (powerSaveModeOn) return NightModeEnabledReason.POWER_SAVE_MODE;
+        return NightModeEnabledReason.OTHER;
+    }
+
+    /**
+     * Records the theme preference state on start up and when theme preference changes.
+     * @param setting The new {@link ThemePreferences.ThemeSetting} that the user selects.
+     */
+    public static void recordThemePreferencesState(@ThemePreferences.ThemeSetting int setting) {
+        ENUMERATED_THEME_PREFERENCE_STATE.record(setting);
+    }
+
+    /**
+     * Records when user changes the theme preferences.
+     * @param setting The new {@link ThemePreferences.ThemeSetting} that the user selects.
+     */
+    public static void recordThemePreferencesChanged(@ThemePreferences.ThemeSetting int setting) {
+        switch (setting) {
+            case ThemePreferences.ThemeSetting.SYSTEM_DEFAULT:
+                RecordUserAction.record("Android.DarkTheme.Preference.SystemDefault");
+                break;
+            case ThemePreferences.ThemeSetting.LIGHT:
+                RecordUserAction.record("Android.DarkTheme.Preference.Light");
+                break;
+            case ThemePreferences.ThemeSetting.DARK:
+                RecordUserAction.record("Android.DarkTheme.Preference.Dark");
+                break;
+            default:
+                assert false : "Theme preferences change should be recorded.";
+        }
+        recordThemePreferencesState(setting);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
index 299ac51..f258c4b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -17,7 +17,7 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegateImpl;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout;
 import org.chromium.chrome.browser.native_page.ContextMenuManager;
 import org.chromium.chrome.browser.ntp.NewTabPage.FakeboxDelegate;
@@ -128,7 +128,7 @@
                 mRecyclerView::setTouchEnabled, closeContextMenuCallback,
                 NewTabPage.CONTEXT_MENU_USER_ACTION_PREFIX);
         mTab.getWindowAndroid().addContextMenuCloseListener(mContextMenuManager);
-        setNavigationDelegate(new HistoryNavigationDelegateImpl(getContext(), mTab));
+        setNavigationDelegate(HistoryNavigationDelegate.createForNativePage(mTab));
 
         mNewTabPageLayout.initialize(manager, tab, tileGroupDelegate, searchProviderHasLogo,
                 searchProviderIsGoogle, mRecyclerView, mContextMenuManager, mUiConfig);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java
index d45c306..4e3585d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/RadioButtonGroupThemePreference.java
@@ -11,6 +11,7 @@
 
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.night_mode.NightModeMetrics;
 import org.chromium.chrome.browser.preferences.themes.ThemePreferences.ThemeSetting;
 import org.chromium.chrome.browser.widget.RadioButtonWithDescription;
 
@@ -69,6 +70,7 @@
             }
         }
         callChangeListener(mSetting);
+        NightModeMetrics.recordThemePreferencesChanged(mSetting);
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
index 051d431..18b47ad 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
@@ -25,6 +25,10 @@
  * Fragment to manage the theme user settings.
  */
 public class ThemePreferences extends PreferenceFragment {
+    /**
+     * Theme preference variations. This is also used for histograms and should therefore be treated
+     * as append-only. See DarkThemePreferences in tools/metrics/histograms/enums.xml.
+     */
     @IntDef({ThemeSetting.SYSTEM_DEFAULT, ThemeSetting.LIGHT, ThemeSetting.DARK})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ThemeSetting {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index ca7b2fcf2..b1b1c1c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -32,7 +32,7 @@
 import org.chromium.chrome.browser.TabLoadStatus;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.native_page.NativePageHost;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabBrowserControlsState;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
index 211ee67..8c2ea9ca 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
@@ -26,8 +26,8 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout;
-import org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout.HistoryNavigationDelegate;
 import org.chromium.chrome.browser.widget.FadingShadow;
 import org.chromium.chrome.browser.widget.FadingShadowView;
 import org.chromium.chrome.browser.widget.LoadingView;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
index 0abd90c..5c76b20 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -650,6 +650,7 @@
     public void testBlockedAmbientBadgeDoesNotAppearAgainForMonths() throws Exception {
         // Visit a site that is a PWA. The ambient badge should show.
         String webBannerUrl = WebappTestPage.getServiceWorkerUrl(mTestServer);
+        resetEngagementForUrl(webBannerUrl, 10);
 
         Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab();
         new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl);
@@ -683,6 +684,31 @@
     }
 
     @Test
+    @MediumTest
+    @Feature({"AppBanners"})
+    @CommandLineFlags.Add("enable-features=" + ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_INFOBAR)
+    public void testAmbientBadgeDoesNotAppearWhenEventCanceled() throws Exception {
+        String webBannerUrl = WebappTestPage.getServiceWorkerUrlWithAction(
+                mTestServer, "stash_event_and_prevent_default");
+        resetEngagementForUrl(webBannerUrl, 10);
+        navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, webBannerUrl);
+
+        // As the page called preventDefault on the beforeinstallprompt event, we do not expect to
+        // see an ambient badge.
+        InfoBarUtil.waitUntilNoInfoBarsExist(mTabbedActivityTestRule.getInfoBars());
+
+        // Even after waiting for three months, there should not be no ambient badge.
+        AppBannerManager.setTimeDeltaForTesting(91);
+        navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, webBannerUrl);
+        InfoBarUtil.waitUntilNoInfoBarsExist(mTabbedActivityTestRule.getInfoBars());
+
+        // When the page is ready and calls prompt() on the beforeinstallprompt event, only then we
+        // expect to see the modal banner.
+        Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab();
+        tapAndWaitForModalBanner(tab);
+    }
+
+    @Test
     @SmallTest
     @Feature({"AppBanners"})
     @CommandLineFlags.Add("disable-features=" + ChromeFeatureList.EXPERIMENTAL_APP_BANNERS)
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index f4a6d896..75b228f 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-76.0.3782.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-76.0.3783.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
index 18409af..6a5f879 100644
--- a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
+++ b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
@@ -10,7 +10,7 @@
     android:paddingVertical="@dimen/most_likely_carousel_edge_spacer"
     android:gravity="center_horizontal">
 
-    <android.support.v7.widget.RecyclerView
+    <org.chromium.chrome.browser.touchless.SiteSuggestionsRecyclerView
         android:id="@+id/most_likely_launcher_recycler"
         android:background="@color/modern_primary_color"
         android:scrollbars="none"
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java
index d821cc0..a82340d 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java
@@ -215,7 +215,7 @@
             }
         } else if (propertyKey == SHOULD_FOCUS_VIEW && mModel.get(SHOULD_FOCUS_VIEW)
                 && mModel.get(ASYNC_FOCUS_DELEGATE) != null) {
-            mModel.get(ASYNC_FOCUS_DELEGATE).onResult(mRecyclerView);
+            mLayoutManager.focusCenterItem();
             mModel.set(SHOULD_FOCUS_VIEW, false);
         } else if (propertyKey == INITIAL_INDEX_KEY) {
             mLayoutManager.scrollToPosition(mModel.get(INITIAL_INDEX_KEY));
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
index fe7721ee..8995da7 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
@@ -5,7 +5,7 @@
 package org.chromium.chrome.browser.touchless;
 
 import android.content.Context;
-import android.support.v7.widget.LinearLayoutManager;
+import android.graphics.Rect;
 import android.support.v7.widget.RecyclerView;
 import android.util.SparseArray;
 import android.view.View;
@@ -18,7 +18,7 @@
  * layout such that items at the edges are smaller than the center item and keeping focus
  * to the middle of the view.
  */
-class SiteSuggestionsLayoutManager extends LinearLayoutManager {
+class SiteSuggestionsLayoutManager extends RecyclerView.LayoutManager {
     private static final float[] SCALE_FACTORS = {0.8f, 0.9f, 1f, 0.9f, 0.8f};
     private static final float SUM_FACTORS;
     // Initialize SUM_FACTORS to be sum of scale factors.
@@ -32,16 +32,19 @@
     private static final int MAX_TILES = 5;
 
     private int mFocusPosition;
+    private View mFocusView;
+    private boolean mShouldFocusAfterLayout;
     private boolean mNeedRebind;
     private Context mContext;
+    private RecyclerView mRecyclerView;
 
     SiteSuggestionsLayoutManager(Context context) {
-        super(context);
-        setReverseLayout(false);
-        setOrientation(LinearLayoutManager.HORIZONTAL);
+        setAutoMeasureEnabled(true);
         mContext = context;
         mFocusPosition = 0;
         mNeedRebind = false;
+        mFocusView = null;
+        mShouldFocusAfterLayout = false;
     }
 
     @Override
@@ -113,6 +116,9 @@
                 viewCache.remove(i);
                 attachView(child);
             }
+            if (i == mFocusPosition) {
+                mFocusView = child;
+            }
         }
 
         resizeViews();
@@ -125,6 +131,14 @@
     }
 
     @Override
+    public void onLayoutCompleted(RecyclerView.State state) {
+        super.onLayoutCompleted(state);
+        if (mShouldFocusAfterLayout) {
+            mFocusView.requestFocus();
+        }
+    }
+
+    @Override
     public boolean canScrollHorizontally() {
         return getItemCount() > 1;
     }
@@ -175,7 +189,6 @@
     /**
      * Returns what the first visible item position should be. Might not be accurate during layout.
      */
-    @Override
     public int findFirstVisibleItemPosition() {
         return Math.max(0, mFocusPosition - 2);
     }
@@ -183,7 +196,6 @@
     /**
      * Returns what the last visible item position should be. Might not be accurate during layout.
      */
-    @Override
     public int findLastVisibleItemPosition() {
         int lastVisiblePosition = mFocusPosition + 2;
         if (lastVisiblePosition < 0 || lastVisiblePosition == Integer.MAX_VALUE) {
@@ -220,6 +232,18 @@
         requestFullRebind();
     }
 
+    @Override
+    public void onAttachedToWindow(RecyclerView view) {
+        super.onAttachedToWindow(view);
+        mRecyclerView = view;
+    }
+
+    @Override
+    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
+        super.onDetachedFromWindow(view, recycler);
+        mRecyclerView = null;
+    }
+
     /**
      * Requests layout such that it forces rebind of all visible items with
      * updated data from the adapter.
@@ -229,6 +253,18 @@
         requestLayout();
     }
 
+    void focusCenterItem() {
+        focusCenterItem(View.FOCUS_DOWN, null);
+    }
+
+    boolean focusCenterItem(int direction, Rect previouslyFocusedRect) {
+        if (mRecyclerView.isComputingLayout() || mFocusView == null) {
+            mShouldFocusAfterLayout = true;
+            return true;
+        }
+        return mFocusView.requestFocus(direction, previouslyFocusedRect);
+    }
+
     /**
      * Resizes currently attached views based on their position (larger in the middle).
      *
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsMediator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsMediator.java
index 8b903c2..0bae4c15 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsMediator.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsMediator.java
@@ -51,21 +51,31 @@
     private Profile mProfile;
     private int mIconSize;
 
+    // Whether we should set focus to the data. Used to delay focus-setting until after loading
+    // pending suggestions.
+    private boolean mShouldSetFocus;
+    // Whether we have pending requests for suggestions.
+    private boolean mHasPendingRequests;
+
     SiteSuggestionsMediator(
             PropertyModel model, Profile profile, ImageFetcher imageFetcher, int minIconSize) {
         mModel = model;
         mImageFetcher = imageFetcher;
         mIconSize = minIconSize;
         mProfile = profile;
+
+        mHasPendingRequests = true;
         mMostVisitedSites =
                 SuggestionsDependencyFactory.getInstance().createMostVisitedSites(mProfile);
         mMostVisitedSites.setObserver(this, NUM_FETCHED_SITES);
+
         mModel.addObserver(this);
         ExploreSitesBridge.getEspCatalog(mProfile, this::onGetEspCatalog);
     }
 
     @Override
     public void onSiteSuggestionsAvailable(List<SiteSuggestion> siteSuggestions) {
+        mHasPendingRequests = false;
         HashSet<String> urls = new HashSet<>();
         for (PropertyModel model : mModel.get(SiteSuggestionsCoordinator.SUGGESTIONS_KEY)) {
             urls.add(model.get(SiteSuggestionModel.URL_KEY));
@@ -113,6 +123,10 @@
             mModel.set(SiteSuggestionsCoordinator.INITIAL_INDEX_KEY, INITIAL_SCROLLED_POSITION);
             mModel.set(SiteSuggestionsCoordinator.CURRENT_INDEX_KEY, INITIAL_SCROLLED_POSITION);
         }
+
+        if (mShouldSetFocus) {
+            mModel.set(SiteSuggestionsCoordinator.SHOULD_FOCUS_VIEW, true);
+        }
     }
 
     @Override
@@ -145,6 +159,7 @@
             // When removal of a site causes us to have fewer sites than we want to display, fetch
             // again.
             if (itemCount < MAX_DISPLAYED_TILES) {
+                mHasPendingRequests = true;
                 mMostVisitedSites.setObserver(this, NUM_FETCHED_SITES);
             }
         }
@@ -156,7 +171,11 @@
 
     @Override
     public void requestFocus() {
-        mModel.set(SiteSuggestionsCoordinator.SHOULD_FOCUS_VIEW, true);
+        if (mHasPendingRequests) {
+            mShouldSetFocus = true;
+        } else {
+            mModel.set(SiteSuggestionsCoordinator.SHOULD_FOCUS_VIEW, true);
+        }
     }
 
     @Override
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsRecyclerView.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsRecyclerView.java
new file mode 100644
index 0000000..2572952
--- /dev/null
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsRecyclerView.java
@@ -0,0 +1,40 @@
+// 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.touchless;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+
+/**
+ * Creates a custom recycler view that would initialize focus search on the middle child.
+ */
+public class SiteSuggestionsRecyclerView extends RecyclerView {
+    private SiteSuggestionsLayoutManager mLayoutManager;
+
+    public SiteSuggestionsRecyclerView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void setLayoutManager(LayoutManager layout) {
+        super.setLayoutManager(layout);
+
+        if (layout instanceof SiteSuggestionsLayoutManager) {
+            mLayoutManager = (SiteSuggestionsLayoutManager) layout;
+        }
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        // If we don't have layoutmanager or if we're searching based on a previous focus,
+        // default to parent focus search.
+        if (mLayoutManager == null || previouslyFocusedRect != null) {
+            return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
+        }
+        return mLayoutManager.focusCenterItem(direction, null);
+    }
+}
diff --git a/chrome/android/touchless/touchless_java_sources.gni b/chrome/android/touchless/touchless_java_sources.gni
index 69640629..6d92469 100644
--- a/chrome/android/touchless/touchless_java_sources.gni
+++ b/chrome/android/touchless/touchless_java_sources.gni
@@ -21,6 +21,7 @@
   "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java",
   "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java",
   "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsMediator.java",
+  "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsRecyclerView.java",
   "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsTileView.java",
   "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsViewHolderFactory.java",
   "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolder.java",
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index 384429e..ed2c1c2 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -456,8 +456,6 @@
 
   if (is_chromeos) {
     deps += [
-      "//ash/components/shortcut_viewer/public/cpp:manifest",
-      "//ash/components/shortcut_viewer/public/mojom",
       "//ash/components/tap_visualizer/public/cpp:manifest",
       "//ash/components/tap_visualizer/public/mojom",
       "//chrome/browser/chromeos/kiosk_next_home/mojom",
@@ -620,7 +618,6 @@
 
   if (is_chromeos) {
     deps += [
-      "//ash/components/shortcut_viewer/public/cpp:manifest",
       "//ash/components/tap_visualizer/public/cpp:manifest",
       "//ash/public/cpp:manifest",
       "//chrome/browser/chromeos:ash_pref_connector_manifest",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index 0d61110..97b37a5 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -48,8 +48,6 @@
 #include "third_party/blink/public/mojom/webshare/webshare.mojom.h"
 
 #if defined(OS_CHROMEOS)
-#include "ash/components/shortcut_viewer/public/cpp/manifest.h"  // nogncheck
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"  // nogncheck
 #include "ash/components/tap_visualizer/public/cpp/manifest.h"  // nogncheck
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"  // nogncheck
 #include "chrome/browser/chromeos/kiosk_next_home/mojom/kiosk_next_home_interface_broker.mojom.h"  // nogncheck
@@ -199,8 +197,6 @@
             .RequireCapability(
                 chromeos::network_config::mojom::kServiceName,
                 chromeos::network_config::mojom::kNetworkConfigCapability)
-            .RequireCapability(shortcut_viewer::mojom::kServiceName,
-                               shortcut_viewer::mojom::kToggleUiCapability)
             // This is required for remoting, which runs in the browser and
             // injects events.
             .RequireCapability(ws::mojom::kServiceName, "privileged")
diff --git a/chrome/app/chrome_packaged_service_manifests.cc b/chrome/app/chrome_packaged_service_manifests.cc
index b483065..02b3b793 100644
--- a/chrome/app/chrome_packaged_service_manifests.cc
+++ b/chrome/app/chrome_packaged_service_manifests.cc
@@ -22,7 +22,6 @@
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
 #if defined(OS_CHROMEOS)
-#include "ash/components/shortcut_viewer/public/cpp/manifest.h"
 #include "ash/components/tap_visualizer/public/cpp/manifest.h"
 #include "ash/public/cpp/manifest.h"
 #include "chrome/browser/chromeos/prefs/ash_pref_connector_manifest.h"
@@ -120,7 +119,6 @@
                                    InstanceSharingPolicy::kSingleton)
                            .Build())
           .RequireCapability("network", "network_service")
-          .RequireCapability("device", "device:wake_lock")
           .Build()};
   return *manifest;
 }
@@ -168,7 +166,6 @@
       GetProfileImportManifest(),
 #endif
 #if defined(OS_CHROMEOS)
-      shortcut_viewer::GetManifest(),
       tap_visualizer::GetManifest(),
       ash::GetManifest(),
       GetAshPrefConnectorManifest(),
diff --git a/chrome/app_shim/BUILD.gn b/chrome/app_shim/BUILD.gn
index 785b7796..1d09936e 100644
--- a/chrome/app_shim/BUILD.gn
+++ b/chrome/app_shim/BUILD.gn
@@ -21,7 +21,7 @@
 
   deps = [
     "//chrome:strings",
-    "//chrome/browser/ui:ui",
+    "//chrome/browser/ui",
     "//chrome/common",
     "//chrome/common:mojo_bindings",
     "//components/crash/content/app",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7a37d87..ba45101 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -156,6 +156,8 @@
     "background_sync/background_sync_metrics.h",
     "background_sync/background_sync_permission_context.cc",
     "background_sync/background_sync_permission_context.h",
+    "background_sync/periodic_background_sync_permission_context.cc",
+    "background_sync/periodic_background_sync_permission_context.h",
     "bad_message.cc",
     "bad_message.h",
     "banners/app_banner_manager.cc",
@@ -1909,7 +1911,7 @@
     "//components/metrics:net",
     "//components/metrics:ui",
     "//components/metrics_services_manager",
-    "//components/mirroring/browser:browser",
+    "//components/mirroring/browser",
     "//components/mirroring/mojom:constants",
     "//components/mirroring/mojom:host",
     "//components/mirroring/mojom:service",
@@ -1935,7 +1937,7 @@
     "//components/policy/content/",
     "//components/policy/core/browser",
     "//components/policy/proto",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//components/previews/content",
     "//components/previews/core",
     "//components/profile_metrics",
@@ -4788,7 +4790,7 @@
 
     deps += [
       "//components/spellcheck/browser",
-      "//components/spellcheck/common:common",
+      "//components/spellcheck/common",
     ]
 
     if (!is_android) {
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 8de8b92c..9d38b45 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -110,7 +110,7 @@
   # interfaces in //ash/public/interfaces. See //ash/README.md.
   "-ash",
   "+ash/public",
-  "+ash/components/shortcut_viewer/public/mojom",
+  "+ash/components/shortcut_viewer",
   "+ash/components/tap_visualizer/public/mojom",
 
   # The message center may not exist, or may run out of process (in mash).
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 78854ed..85878a4 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2387,6 +2387,9 @@
      ENABLE_DISABLE_VALUE_TYPE(
          chromeos::switches::kShowAndroidFilesInFilesApp,
          chromeos::switches::kHideAndroidFilesInFilesApp)},
+    {"crostini-gpu-support", flag_descriptions::kCrostiniGpuSupportName,
+     flag_descriptions::kCrostiniGpuSupportDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kCrostiniGpuSupport)},
     {"crostini-usb-allow-unsupported",
      flag_descriptions::kCrostiniUsbAllowUnsupportedName,
      flag_descriptions::kCrostiniUsbAllowUnsupportedDescription, kOsCrOS,
diff --git a/chrome/browser/android/download/download_manager_service.cc b/chrome/browser/android/download/download_manager_service.cc
index 4567806..7fab0bf4 100644
--- a/chrome/browser/android/download/download_manager_service.cc
+++ b/chrome/browser/android/download/download_manager_service.cc
@@ -33,7 +33,6 @@
 #include "components/download/public/common/download_item_impl.h"
 #include "components/download/public/common/download_url_loader_factory_getter_impl.h"
 #include "components/download/public/common/simple_download_manager_coordinator.h"
-#include "components/download/public/common/url_download_handler_factory.h"
 #include "components/download/public/task/task_manager_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/download_item_utils.h"
@@ -249,9 +248,6 @@
     content::BrowserContext* context) {
   if (in_progress_manager_) {
     DCHECK(!context->IsOffTheRecord());
-    // We are no longer interested in listening to |in_progress_manager_|,
-    // remove this object from being the delegate.
-    in_progress_manager_->SetDelegate(nullptr);
     // Set |is_pending_downloads_loaded_| to false so that we need to wait for
     // download history to initialize before performing new download actions.
     is_pending_downloads_loaded_ = false;
@@ -697,7 +693,7 @@
   base::FilePath data_dir;
   base::android::GetDataDirectory(&data_dir);
   in_progress_manager_ = std::make_unique<download::InProgressDownloadManager>(
-      this, data_dir.Append(chrome::kInitialProfile),
+      nullptr, data_dir.Append(chrome::kInitialProfile),
       base::BindRepeating(&IgnoreOriginSecurityCheck),
       base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe));
   content::GetNetworkServiceFromConnector(service_binding_.GetConnector());
@@ -708,6 +704,7 @@
           factory->Clone()));
   in_progress_manager_->set_download_start_observer(
       DownloadControllerBase::Get());
+  in_progress_manager_->SetDelegate(this);
 }
 
 void DownloadManagerService::OnPendingDownloadsLoaded() {
@@ -755,17 +752,12 @@
 }
 
 void DownloadManagerService::OnDownloadsInitialized() {
+  // We are no longer interested in listening to |in_progress_manager_|, remove
+  // this object from being the delegate.
+  in_progress_manager_->SetDelegate(nullptr);
   OnPendingDownloadsLoaded();
 }
 
-std::unique_ptr<service_manager::Connector>
-DownloadManagerService::GetServiceConnector() {
-  service_manager::Connector* connector = service_binding_.GetConnector();
-  if (connector)
-    return connector->Clone();  // Clone for use on a different thread.
-  return nullptr;
-}
-
 content::DownloadManager* DownloadManagerService::GetDownloadManager(
     bool is_off_the_record) {
   Profile* profile = ProfileManager::GetActiveUserProfile();
diff --git a/chrome/browser/android/download/download_manager_service.h b/chrome/browser/android/download/download_manager_service.h
index 547fd5b..9bb8fca 100644
--- a/chrome/browser/android/download/download_manager_service.h
+++ b/chrome/browser/android/download/download_manager_service.h
@@ -239,7 +239,6 @@
 
   // download::InProgressDownloadManager::Delegate implementations.
   void OnDownloadsInitialized() override;
-  std::unique_ptr<service_manager::Connector> GetServiceConnector() override;
 
   typedef base::Callback<void(bool)> ResumeCallback;
   void set_resume_callback_for_testing(const ResumeCallback& resume_cb) {
diff --git a/chrome/browser/android/metrics/BUILD.gn b/chrome/browser/android/metrics/BUILD.gn
index 2180062..7c005ea7 100644
--- a/chrome/browser/android/metrics/BUILD.gn
+++ b/chrome/browser/android/metrics/BUILD.gn
@@ -11,10 +11,10 @@
       "ukm_utils_for_test.cc",
     ]
     deps = [
-      "//chrome/browser:browser",
+      "//chrome/browser",
       "//chrome/browser/android/metrics:jni_headers",
       "//components/metrics_services_manager:metrics_services_manager",
-      "//components/ukm:ukm",
+      "//components/ukm",
     ]
   }
 
diff --git a/chrome/browser/android/vr/BUILD.gn b/chrome/browser/android/vr/BUILD.gn
index 8b87c02..e99cebf 100644
--- a/chrome/browser/android/vr/BUILD.gn
+++ b/chrome/browser/android/vr/BUILD.gn
@@ -92,9 +92,9 @@
     "//base",
     "//cc",
     "//chrome/android/features/vr:jni_headers",
-    "//chrome/browser/ui:ui",
+    "//chrome/browser/ui",
     "//chrome/browser/vr:vr_common",
-    "//chrome/common:common",
+    "//chrome/common",
     "//chrome/common:constants",
     "//components/language/core/browser",
     "//components/omnibox/browser",
@@ -256,7 +256,7 @@
     ":test_support",
     ":vr_android",
     "//base/test:test_support",
-    "//chrome/browser:browser",
+    "//chrome/browser",
     "//components/translate/core/language_detection:language_detection",
     "//device/vr:fakes",
     "//device/vr/public/mojom",
@@ -265,6 +265,6 @@
     "//services/network:test_support",
     "//testing/android/native_test:native_test_native_code",
     "//testing/gmock",
-    "//testing/gtest:gtest",
+    "//testing/gtest",
   ]
 }
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc
index 776a6214..7edf890 100644
--- a/chrome/browser/apps/app_service/arc_apps.cc
+++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -472,6 +472,23 @@
                        is_placeholder_icon, icon_effects, std::move(callback));
 }
 
+apps::mojom::InstallSource GetInstallSource(const ArcAppListPrefs* prefs,
+                                            const std::string& package_name) {
+  if (prefs->IsDefault(package_name)) {
+    return apps::mojom::InstallSource::kDefault;
+  }
+
+  if (prefs->IsOem(package_name)) {
+    return apps::mojom::InstallSource::kOem;
+  }
+
+  if (prefs->IsControlledByPolicy(package_name)) {
+    return apps::mojom::InstallSource::kPolicy;
+  }
+
+  return apps::mojom::InstallSource::kUser;
+}
+
 apps::mojom::AppPtr ArcApps::Convert(const std::string& app_id,
                                      const ArcAppListPrefs::AppInfo& app_info) {
   apps::mojom::AppPtr app = apps::mojom::App::New();
@@ -491,12 +508,7 @@
   app->last_launch_time = app_info.last_launch_time;
   app->install_time = app_info.install_time;
 
-  bool installed_internally =
-      prefs_->IsDefault(app_id) ||
-      prefs_->IsControlledByPolicy(app_info.package_name);
-  app->installed_internally = installed_internally
-                                  ? apps::mojom::OptionalBool::kTrue
-                                  : apps::mojom::OptionalBool::kFalse;
+  app->install_source = GetInstallSource(prefs_, app_info.package_name);
 
   app->is_platform_app = apps::mojom::OptionalBool::kFalse;
 
diff --git a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc
index fc08383..a1d8a2b 100644
--- a/chrome/browser/apps/app_service/built_in_chromeos_apps.cc
+++ b/chrome/browser/apps/app_service/built_in_chromeos_apps.cc
@@ -45,7 +45,8 @@
   app->last_launch_time = base::Time();
   app->install_time = base::Time();
 
-  app->installed_internally = apps::mojom::OptionalBool::kTrue;
+  app->install_source = apps::mojom::InstallSource::kSystem;
+
   app->is_platform_app = apps::mojom::OptionalBool::kFalse;
   app->show_in_launcher = internal_app.show_in_launcher
                               ? apps::mojom::OptionalBool::kTrue
diff --git a/chrome/browser/apps/app_service/crostini_apps.cc b/chrome/browser/apps/app_service/crostini_apps.cc
index c12baba3..7bc6fbb 100644
--- a/chrome/browser/apps/app_service/crostini_apps.cc
+++ b/chrome/browser/apps/app_service/crostini_apps.cc
@@ -201,7 +201,10 @@
   app->last_launch_time = registration.LastLaunchTime();
   app->install_time = registration.InstallTime();
 
-  app->installed_internally = apps::mojom::OptionalBool::kFalse;
+  // TODO(crbug.com/955937): Change after deciding how crostini apps will
+  // show in App Management.
+  app->install_source = apps::mojom::InstallSource::kUser;
+
   app->is_platform_app = apps::mojom::OptionalBool::kFalse;
 
   // TODO(crbug.com/826982): if Crostini isn't enabled, don't show the Terminal
diff --git a/chrome/browser/apps/app_service/extension_apps.cc b/chrome/browser/apps/app_service/extension_apps.cc
index 783f8fed..27eded7 100644
--- a/chrome/browser/apps/app_service/extension_apps.cc
+++ b/chrome/browser/apps/app_service/extension_apps.cc
@@ -22,6 +22,8 @@
 #include "chrome/browser/ui/app_list/extension_uninstaller.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/web_applications/components/web_app_constants.h"
+#include "chrome/browser/web_applications/extensions/web_app_extension_ids_map.h"
 #include "chrome/common/extensions/extension_metrics.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/services/app_service/public/mojom/types.mojom.h"
@@ -440,6 +442,37 @@
   }
 }
 
+apps::mojom::InstallSource GetInstallSource(
+    const Profile* profile,
+    const extensions::Extension* extension) {
+  if (extensions::Manifest::IsComponentLocation(extension->location()) ||
+      web_app::ExtensionIdsMap::HasExtensionIdWithInstallSource(
+          profile->GetPrefs(), extension->id(),
+          web_app::InstallSource::kSystemInstalled)) {
+    return apps::mojom::InstallSource::kSystem;
+  }
+
+  if (extensions::Manifest::IsPolicyLocation(extension->location()) ||
+      web_app::ExtensionIdsMap::HasExtensionIdWithInstallSource(
+          profile->GetPrefs(), extension->id(),
+          web_app::InstallSource::kExternalPolicy)) {
+    return apps::mojom::InstallSource::kPolicy;
+  }
+
+  if (extension->was_installed_by_oem()) {
+    return apps::mojom::InstallSource::kOem;
+  }
+
+  if (extension->was_installed_by_default() ||
+      web_app::ExtensionIdsMap::HasExtensionIdWithInstallSource(
+          profile->GetPrefs(), extension->id(),
+          web_app::InstallSource::kExternalDefault)) {
+    return apps::mojom::InstallSource::kDefault;
+  }
+
+  return apps::mojom::InstallSource::kUser;
+}
+
 apps::mojom::AppPtr ExtensionApps::Convert(
     const extensions::Extension* extension,
     apps::mojom::Readiness readiness) {
@@ -482,17 +515,7 @@
     PopulatePermissions(extension, &app->permissions);
   }
 
-  // TODO(crbug.com/826982): does this catch default installed web apps?
-  //
-  // https://crrev.com/c/1377955/3/chrome/browser/apps/app_service/extension_apps.cc#263
-  bool installed_internally =
-      extension->was_installed_by_default() ||
-      extension->was_installed_by_oem() ||
-      extensions::Manifest::IsComponentLocation(extension->location()) ||
-      extensions::Manifest::IsPolicyLocation(extension->location());
-  app->installed_internally = installed_internally
-                                  ? apps::mojom::OptionalBool::kTrue
-                                  : apps::mojom::OptionalBool::kFalse;
+  app->install_source = GetInstallSource(profile_, extension);
 
   app->is_platform_app = extension->is_platform_app()
                              ? apps::mojom::OptionalBool::kTrue
diff --git a/chrome/browser/ash_service_registry.cc b/chrome/browser/ash_service_registry.cc
index b48ae74..48be746 100644
--- a/chrome/browser/ash_service_registry.cc
+++ b/chrome/browser/ash_service_registry.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ash_service_registry.h"
 
 #include "ash/ash_service.h"
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/public/interfaces/constants.mojom.h"
@@ -35,7 +34,6 @@
 
 // Services shared between mash and non-mash configs.
 constexpr Service kCommonServices[] = {
-    {shortcut_viewer::mojom::kServiceName, IDS_ASH_SHORTCUT_VIEWER_APP_NAME},
     {tap_visualizer::mojom::kServiceName, IDS_ASH_TAP_VISUALIZER_APP_NAME},
 };
 
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
new file mode 100644
index 0000000..167bab4
--- /dev/null
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.cc
@@ -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.
+
+#include "chrome/browser/background_sync/periodic_background_sync_permission_context.h"
+
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_features.h"
+
+PeriodicBackgroundSyncPermissionContext::
+    PeriodicBackgroundSyncPermissionContext(Profile* profile)
+    : PermissionContextBase(profile,
+                            CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
+
+bool PeriodicBackgroundSyncPermissionContext::IsRestrictedToSecureOrigins()
+    const {
+  return true;
+}
+
+ContentSetting
+PeriodicBackgroundSyncPermissionContext::GetPermissionStatusInternal(
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin) const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (!base::FeatureList::IsEnabled(features::kPeriodicBackgroundSync))
+    return CONTENT_SETTING_BLOCK;
+
+  // TODO(crbug.com/925297): Add PWA detection logic, and restrict the feature
+  // to origins with a PWA installed.
+
+  auto* host_content_settings_map =
+      HostContentSettingsMapFactory::GetForProfile(profile());
+  DCHECK(host_content_settings_map);
+
+  return PermissionContextBase::GetPermissionStatusInternal(
+      render_frame_host, requesting_origin, embedding_origin);
+}
+
+void PeriodicBackgroundSyncPermissionContext::DecidePermission(
+    content::WebContents* web_contents,
+    const PermissionRequestID& id,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    bool user_gesture,
+    const BrowserPermissionCallback& callback) {
+  // The user should never be prompted to authorize Periodic Background Sync
+  // from PeriodicBackgroundSyncPermissionContext.
+  NOTREACHED();
+}
+
+void PeriodicBackgroundSyncPermissionContext::NotifyPermissionSet(
+    const PermissionRequestID& id,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    const BrowserPermissionCallback& callback,
+    bool persist,
+    ContentSetting content_setting) {
+  DCHECK(!persist);
+  PermissionContextBase::NotifyPermissionSet(
+      id, requesting_origin, embedding_origin, std::move(callback), persist,
+      content_setting);
+}
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context.h b/chrome/browser/background_sync/periodic_background_sync_permission_context.h
new file mode 100644
index 0000000..1bc677b8
--- /dev/null
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context.h
@@ -0,0 +1,51 @@
+// 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_BROWSER_BACKGROUND_SYNC_PERIODIC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_
+#define CHROME_BROWSER_BACKGROUND_SYNC_PERIODIC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_
+
+#include "base/macros.h"
+#include "chrome/browser/permissions/permission_context_base.h"
+#include "components/content_settings/core/common/content_settings.h"
+
+class Profile;
+
+// This permission context is responsible for getting, deciding on and updating
+// the Periodic Background Sync permission for a particular website. This
+// permission guards the use of the Periodic Background Sync API. It's not being
+// persisted because it's dynamic and relies on either the presence of a PWA for
+// the origin, and the Periodic and one-shot Background Sync content settings.
+// The user is never prompted for this permission. They can disable the feature
+// by disabling the (one-shot) Background Sync permission from content settings
+// UI. The periodic Background Sync content setting can be disabled via Finch,
+// and will prevent usage of the API.
+class PeriodicBackgroundSyncPermissionContext : public PermissionContextBase {
+ public:
+  explicit PeriodicBackgroundSyncPermissionContext(Profile* profile);
+  ~PeriodicBackgroundSyncPermissionContext() override = default;
+
+ private:
+  // PermissionContextBase implementation.
+  bool IsRestrictedToSecureOrigins() const override;
+  ContentSetting GetPermissionStatusInternal(
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin,
+      const GURL& embedding_origin) const override;
+  void DecidePermission(content::WebContents* web_contents,
+                        const PermissionRequestID& id,
+                        const GURL& requesting_origin,
+                        const GURL& embedding_origin,
+                        bool user_gesture,
+                        const BrowserPermissionCallback& callback) override;
+  void NotifyPermissionSet(const PermissionRequestID& id,
+                           const GURL& requesting_origin,
+                           const GURL& embedding_origin,
+                           const BrowserPermissionCallback& callback,
+                           bool persist,
+                           ContentSetting content_setting) override;
+
+  DISALLOW_COPY_AND_ASSIGN(PeriodicBackgroundSyncPermissionContext);
+};
+
+#endif  // CHROME_BROWSER_BACKGROUND_SYNC_PERIODIC_BACKGROUND_SYNC_PERMISSION_CONTEXT_H_
diff --git a/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
new file mode 100644
index 0000000..4bec21971
--- /dev/null
+++ b/chrome/browser/background_sync/periodic_background_sync_permission_context_unittest.cc
@@ -0,0 +1,111 @@
+// 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/browser/background_sync/periodic_background_sync_permission_context.h"
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_profile.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 "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class PeriodicBackgroundSyncPermissionContextTest
+    : public ChromeRenderViewHostTestHarness {
+ protected:
+  PeriodicBackgroundSyncPermissionContextTest() = default;
+  ~PeriodicBackgroundSyncPermissionContextTest() override = default;
+
+  ContentSetting GetPermissionStatus(
+      const GURL& url,
+      PeriodicBackgroundSyncPermissionContext* permission_context,
+      bool with_frame) {
+    content::RenderFrameHost* render_frame_host = nullptr;
+
+    if (with_frame) {
+      content::WebContentsTester::For(web_contents())->NavigateAndCommit(url);
+      render_frame_host = web_contents()->GetMainFrame();
+    }
+
+    auto permission_result = permission_context->GetPermissionStatus(
+        render_frame_host, /* requesting_origin= */ url,
+        /* embedding_origin= */ url);
+    return permission_result.content_setting;
+  }
+
+  void SetPeriodicSyncContentSetting(const GURL& url, ContentSetting setting) {
+    auto* host_content_settings_map =
+        HostContentSettingsMapFactory::GetForProfile(profile());
+    ASSERT_TRUE(host_content_settings_map);
+    host_content_settings_map->SetContentSettingDefaultScope(
+        /* primary_url= */ url, /* secondary_url= */ url,
+        CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
+        /* resource_identifier= */ std::string(), setting);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PeriodicBackgroundSyncPermissionContextTest);
+};
+
+TEST_F(PeriodicBackgroundSyncPermissionContextTest, DenyWhenFeatureDisabled) {
+  PeriodicBackgroundSyncPermissionContext permission_context(profile());
+
+  GURL url("https://example.com");
+  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
+                                /* with_frame= */ true),
+            CONTENT_SETTING_BLOCK);
+}
+
+TEST_F(PeriodicBackgroundSyncPermissionContextTest, DenyForInsecureOrigin) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
+
+  PeriodicBackgroundSyncPermissionContext permission_context(profile());
+
+  GURL url("http://example.com");
+  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
+                                /* with_frame= */ false),
+            CONTENT_SETTING_BLOCK);
+}
+
+TEST_F(PeriodicBackgroundSyncPermissionContextTest, AllowWithFrame) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
+
+  GURL url("https://example.com");
+  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+
+  PeriodicBackgroundSyncPermissionContext permission_context(profile());
+
+  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
+                                /* with_frame= */ true),
+            CONTENT_SETTING_ALLOW);
+}
+
+TEST_F(PeriodicBackgroundSyncPermissionContextTest, AllowWithoutFrame) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kPeriodicBackgroundSync);
+
+  GURL url("https://example.com");
+  SetPeriodicSyncContentSetting(url, CONTENT_SETTING_ALLOW);
+
+  PeriodicBackgroundSyncPermissionContext permission_context(profile());
+
+  EXPECT_EQ(GetPermissionStatus(url, &permission_context,
+                                /* with_frame= */ false),
+            CONTENT_SETTING_ALLOW);
+}
+
+}  // namespace
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index d337295..533ebfe8 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -730,10 +730,12 @@
     }
   }
 
-  bool need_prompt = IsExperimentalAppBannersEnabled() ||
-                     reply == blink::mojom::AppBannerPromptReply::CANCEL;
+  bool event_canceled = reply == blink::mojom::AppBannerPromptReply::CANCEL;
+  bool need_prompt = IsExperimentalAppBannersEnabled() || event_canceled;
 
   if (need_prompt && state_ == State::SENDING_EVENT) {
+    if (!event_canceled)
+      MaybeShowAmbientBadge();
     UpdateState(State::PENDING_PROMPT);
     return;
   }
@@ -743,6 +745,8 @@
   ShowBanner();
 }
 
+void AppBannerManager::MaybeShowAmbientBadge() {}
+
 void AppBannerManager::ShowBanner() {
   content::WebContents* contents = web_contents();
   WebappInstallSource install_source;
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 797b5cb..9acd3c3 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -168,7 +168,7 @@
   void SendBannerAccepted();
 
   // Sends a message to the renderer that the user dismissed the banner.
-  virtual void SendBannerDismissed();
+  void SendBannerDismissed();
 
   // Returns a WeakPtr to this object. Exposed so subclasses/infobars may
   // may bind callbacks without needing their own WeakPtrFactory.
@@ -210,10 +210,7 @@
   // Called when the current site is eligible to show a banner. Returns true if
   // the banner should not be shown because the site is already installed, and
   // false if the banner should be shown because the site is not yet installed.
-  // Overridden in platform-specific code to perform actions when it is
-  // guaranteed that a site is banner-eligible, depending on whether the site is
-  // installed (i.e. the ambient badge).
-  virtual bool CheckIfInstalled();
+  bool CheckIfInstalled();
 
   // Return a string identifying this app for metrics.
   virtual std::string GetAppIdentifier();
@@ -285,6 +282,11 @@
   // display it later), or otherwise allow it to be shown.
   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
+  // override this to show UI (e.g. on Android).
+  virtual void MaybeShowAmbientBadge();
+
   // Updates the current state to |state|. Virtual to allow overriding in tests.
   virtual void UpdateState(State state);
 
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc
index 4d3b7053..de396aa 100644
--- a/chrome/browser/banners/app_banner_manager_android.cc
+++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -126,14 +126,6 @@
   AppBannerManager::RequestAppBanner(validated_url);
 }
 
-void AppBannerManagerAndroid::SendBannerDismissed() {
-  AppBannerManager::SendBannerDismissed();
-
-  // If we are dismissing the banner, the site can't be installed.
-  if (IsExperimentalAppBannersEnabled())
-    MaybeShowAmbientBadge();
-}
-
 void AppBannerManagerAndroid::AddToHomescreenFromBadge() {
   ShowBannerUi(InstallableMetrics::GetInstallSource(
       web_contents(), InstallTrigger::AMBIENT_BADGE));
@@ -162,14 +154,6 @@
                                     : "play";
 }
 
-bool AppBannerManagerAndroid::CheckIfInstalled() {
-  bool is_installed = AppBannerManager::CheckIfInstalled();
-  if (IsExperimentalAppBannersEnabled() && !is_installed)
-    MaybeShowAmbientBadge();
-
-  return is_installed;
-}
-
 bool AppBannerManagerAndroid::IsWebAppConsideredInstalled(
     content::WebContents* web_contents,
     const GURL& validated_url,
@@ -248,11 +232,6 @@
 
   primary_icon_ = bitmap;
 
-  // We will not reach this point if the app is already installed since querying
-  // for native app details will return nothing.
-  if (IsExperimentalAppBannersEnabled())
-    MaybeShowAmbientBadge();
-
   // 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
diff --git a/chrome/browser/banners/app_banner_manager_android.h b/chrome/browser/banners/app_banner_manager_android.h
index 4724834..d7f0edb 100644
--- a/chrome/browser/banners/app_banner_manager_android.h
+++ b/chrome/browser/banners/app_banner_manager_android.h
@@ -84,7 +84,6 @@
 
   // AppBannerManager overrides.
   void RequestAppBanner(const GURL& validated_url) override;
-  void SendBannerDismissed() override;
 
   // InstallableAmbientBadgeInfoBarAndroid::Client overrides.
   void AddToHomescreenFromBadge() override;
@@ -94,7 +93,6 @@
   // AppBannerManager overrides.
   std::string GetAppIdentifier() override;
   std::string GetBannerType() override;
-  bool CheckIfInstalled() override;
   bool IsWebAppConsideredInstalled(content::WebContents* web_contents,
                                    const GURL& validated_url,
                                    const GURL& start_url,
@@ -105,6 +103,7 @@
   void OnAppIconFetched(const SkBitmap& bitmap) override;
   void ResetCurrentPageData() override;
   void ShowBannerUi(WebappInstallSource install_source) override;
+  void MaybeShowAmbientBadge() override;
 
  private:
   friend class content::WebContentsUserData<AppBannerManagerAndroid>;
@@ -129,10 +128,6 @@
   // Returns the appropriate app name based on whether we have a native/web app.
   base::string16 GetAppName() const override;
 
-  // Shows the ambient badge if the current page advertises a native app or is
-  // a PWA.
-  void MaybeShowAmbientBadge();
-
   // Hides the ambient badge if it is showing.
   void HideAmbientBadge();
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 8b487cf..85b2d5e 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -118,6 +118,7 @@
     "//chromeos/geolocation",
     "//chromeos/login/auth",
     "//chromeos/login/login_state",
+    "//chromeos/login/session",
     "//chromeos/network",
     "//chromeos/services/device_sync/public/cpp",
     "//chromeos/services/machine_learning/public/cpp",
@@ -152,7 +153,7 @@
     "//components/feedback",
     "//components/flags_ui",
     "//components/gcm_driver",
-    "//components/google/core/common:common",
+    "//components/google/core/common",
     "//components/guest_view/browser",
     "//components/image_fetcher/core",
     "//components/invalidation/impl",
@@ -170,7 +171,7 @@
     "//components/password_manager/core/browser:hash_password_manager",
     "//components/policy:generated",
     "//components/policy/core/browser",
-    "//components/policy/core/common:common",
+    "//components/policy/core/common",
     "//components/policy/core/common:common_constants",
     "//components/pref_registry",
     "//components/proxy_config",
@@ -187,7 +188,7 @@
     "//components/sync",
     "//components/sync_preferences",
     "//components/tracing:startup_tracing",
-    "//components/translate/core/browser:browser",
+    "//components/translate/core/browser",
     "//components/ukm/content",
     "//components/user_manager",
     "//components/vector_icons",
@@ -199,7 +200,7 @@
     "//components/viz/host",
     "//components/web_modal",
     "//components/web_resource",
-    "//components/webdata/common:common",
+    "//components/webdata/common",
     "//components/zoom",
     "//content/public/browser",
     "//content/public/common",
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
index 9010ba6..f38c24f 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/supervised_user/supervised_user_constants.h"
-#include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -518,35 +517,6 @@
   EXPECT_FALSE(ShouldShowAccessibilityMenu());
 }
 
-// Tests text caret highlighting for remote mojo applications (e.g. shortcut
-// viewer). This test integration of AccessibilityManager with the IME driver.
-IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, CaretHighlightInRemoteApp) {
-  AccessibilityManager::Get()->SetCaretHighlightEnabled(true);
-
-  // App launch is asynchronous so we will wait for a non-empty caret bounds
-  // update.
-  auto wait_for_bounds = [](base::RunLoop* run_loop, const gfx::Rect& bounds) {
-    // Under mash the first bounds update we see might be from the ash process
-    // clearing its caret highlight. Wait for the app's highlight to show up.
-    if (!bounds.IsEmpty())
-      run_loop->Quit();
-  };
-  base::RunLoop run_loop;
-  AccessibilityManager::Get()->SetCaretBoundsObserverForTest(
-      base::BindRepeating(wait_for_bounds, &run_loop));
-
-  // Focus will move to the search field and show a text caret highlight.
-  keyboard_shortcut_viewer_util::ToggleKeyboardShortcutViewer();
-
-  // Wait for the app to launch, the IME session to start and the caret bounds
-  // to be set.
-  run_loop.Run();
-
-  // Browser tests spin the message loop during shutdown which can lead to
-  // additional bounds updates.
-  AccessibilityManager::Get()->SetCaretBoundsObserverForTest(base::DoNothing());
-}
-
 // For signin screen to user session accessibility manager tests.
 class AccessibilityManagerLoginTest : public OobeBaseTest {
  protected:
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
index 50feda9a..a6e9523 100644
--- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
 #include "chrome/browser/ui/browser.h"
@@ -237,44 +236,6 @@
   EXPECT_EQ("Not pressed", speech_monitor_.GetNextUtterance());
 }
 
-// Tests the keyboard shortcut viewer, which is an out-of-process mojo app.
-IN_PROC_BROWSER_TEST_F(LoggedInSpokenFeedbackTest, KeyboardShortcutViewer) {
-  EnableChromeVox();
-  keyboard_shortcut_viewer_util::ToggleKeyboardShortcutViewer();
-
-  // Focus should move to the search field and ChromeVox should speak it.
-  while ("Search for keyboard shortcuts" !=
-         speech_monitor_.GetNextUtterance()) {
-  }
-
-  // Capture the destroyed AX tree id when the remote host disconnects.
-  base::RunLoop run_loop;
-  ui::AXTreeID destroyed_tree_id = ui::AXTreeIDUnknown();
-  extensions::AutomationEventRouter::GetInstance()
-      ->SetTreeDestroyedCallbackForTest(base::BindRepeating(
-          [](base::RunLoop* run_loop, ui::AXTreeID* destroyed_tree_id,
-             ui::AXTreeID tree_id) {
-            *destroyed_tree_id = tree_id;
-            run_loop->Quit();
-          },
-          &run_loop, &destroyed_tree_id));
-
-  // Close the remote shortcut viewer app.
-  keyboard_shortcut_viewer_util::ToggleKeyboardShortcutViewer();
-
-  // Wait for the AX tree to be destroyed.
-  run_loop.Run();
-
-  // Verify an AX tree was destroyed. It's awkward to get the remote app's
-  // actual tree ID, so just ensure it's a valid ID and not the desktop.
-  EXPECT_NE(ui::AXTreeIDUnknown(), destroyed_tree_id);
-  EXPECT_NE(AutomationManagerAura::GetInstance()->ax_tree_id(),
-            destroyed_tree_id);
-
-  extensions::AutomationEventRouter::GetInstance()
-      ->SetTreeDestroyedCallbackForTest(base::DoNothing());
-}
-
 //
 // Spoken feedback tests in both a logged in browser window and guest mode.
 //
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
index f9edc2f0..099ddca 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
@@ -97,12 +97,13 @@
 }
 
 views::View* PlatformVerificationDialog::CreateExtraView() {
-  learn_more_button_ = views::CreateVectorImageButton(this);
-  views::SetImageFromVectorIcon(learn_more_button_,
+  auto learn_more_button = views::CreateVectorImageButton(this);
+  views::SetImageFromVectorIcon(learn_more_button.get(),
                                 vector_icons::kHelpOutlineIcon);
-  learn_more_button_->SetAccessibleName(
+  learn_more_button->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_CHROMEOS_ACC_LEARN_MORE));
-  learn_more_button_->SetFocusForPlatform();
+  learn_more_button->SetFocusForPlatform();
+  learn_more_button_ = learn_more_button.release();
   return learn_more_button_;
 }
 
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 9b64a40b..c40bb2af 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -144,6 +144,7 @@
 #include "chromeos/disks/disk_mount_manager.h"
 #include "chromeos/login/auth/login_event_recorder.h"
 #include "chromeos/login/login_state/login_state.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "chromeos/network/fast_transition_observer.h"
 #include "chromeos/network/network_cert_loader.h"
 #include "chromeos/network/network_handler.h"
@@ -679,6 +680,8 @@
           DBusThreadManager::Get()->GetDebugDaemonClient(),
           g_browser_process->local_state());
 
+  session_termination_manager_ =
+      std::make_unique<chromeos::SessionTerminationManager>();
   lock_to_single_user_manager_ =
       std::make_unique<policy::LockToSingleUserManager>();
 
@@ -1216,6 +1219,7 @@
   crosvm_metrics_.reset();
 
   network_change_manager_client_.reset();
+  session_termination_manager_.reset();
 
   // Destroy DBus services immediately after threads are stopped.
   dbus_services_.reset();
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index c68e257..b10e4ee1 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -52,6 +52,7 @@
 class PowerMetricsReporter;
 class RendererFreezer;
 class SchedulerConfigurationManager;
+class SessionTerminationManager;
 class ShutdownPolicyForwarder;
 class WakeOnWifiManager;
 
@@ -169,6 +170,7 @@
   std::unique_ptr<chromeos::system::DarkResumeController>
       dark_resume_controller_;
 
+  std::unique_ptr<SessionTerminationManager> session_termination_manager_;
   std::unique_ptr<policy::LockToSingleUserManager> lock_to_single_user_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsChromeos);
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index abd1ad56..ea74f46b 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -910,6 +910,8 @@
   request.set_name(std::move(name));
   request.set_start_termina(true);
   request.set_owner_id(owner_id_);
+  if (base::FeatureList::IsEnabled(chromeos::features::kCrostiniGpuSupport))
+    request.set_enable_gpu(true);
 
   vm_tools::concierge::DiskImage* disk_image = request.add_disks();
   disk_image->set_path(std::move(disk_path_string));
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index 00f52a75..8dd50a11 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -218,7 +218,8 @@
   storage::FileSystemOperationRunner::OperationID* operation_id =
       new storage::FileSystemOperationRunner::OperationID;
   *operation_id = file_system_context->operation_runner()->Copy(
-      source_url, destination_url, storage::FileSystemOperation::OPTION_NONE,
+      source_url, destination_url,
+      storage::FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
       storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
       base::BindRepeating(&OnCopyProgress, profile_id,
                           base::Unretained(operation_id)),
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 6ecc4567..3392907 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -78,6 +78,7 @@
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/login/auth/key.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/account_id/account_id.h"
 #include "components/arc/arc_util.h"
@@ -120,6 +121,8 @@
 #include "ui/views/widget/widget.h"
 
 using PolicyFetchResult = policy::PreSigninPolicyFetcher::PolicyFetchResult;
+using RebootOnSignOutPolicy =
+    enterprise_management::DeviceRebootOnUserSignoutProto;
 
 namespace apu = arc::policy_util;
 
@@ -406,6 +409,15 @@
 
 void ExistingUserController::UpdateLoginDisplay(
     const user_manager::UserList& users) {
+  int reboot_on_signout_policy = -1;
+  cros_settings_->GetInteger(kDeviceRebootOnUserSignout,
+                             &reboot_on_signout_policy);
+  if (reboot_on_signout_policy != -1 &&
+      reboot_on_signout_policy !=
+          RebootOnSignOutPolicy::REBOOT_ON_SIGNOUT_MODE_UNSPECIFIED &&
+      reboot_on_signout_policy != RebootOnSignOutPolicy::NEVER) {
+    SessionTerminationManager::Get()->RebootIfNecessary();
+  }
   bool show_users_on_signin;
   user_manager::UserList filtered_users;
 
@@ -856,12 +868,13 @@
       last_login_attempt_account_id_);
   if (failure.reason() == AuthFailure::OWNER_REQUIRED) {
     ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error);
-    // Using Untretained here is safe because SessionManagerClient is destroyed
-    // after the task runner, in ChromeBrowserMainParts::PostDestroyThreads().
+    // Using Untretained here is safe because SessionTerminationManager is
+    // destroyed after the task runner, in
+    // ChromeBrowserMainParts::PostDestroyThreads().
     base::PostDelayedTaskWithTraits(
         FROM_HERE, {content::BrowserThread::UI},
-        base::BindOnce(&SessionManagerClient::StopSession,
-                       base::Unretained(SessionManagerClient::Get())),
+        base::BindOnce(&SessionTerminationManager::StopSession,
+                       base::Unretained(SessionTerminationManager::Get())),
         base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
   } else if (failure.reason() == AuthFailure::TPM_ERROR) {
     ShowTPMError();
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc
index c84d480..edd80234 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -54,6 +54,7 @@
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/login/auth/authenticator.h"
 #include "chromeos/login/auth/extended_authenticator.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "components/password_manager/core/browser/hash_password_manager.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/session_manager/core/session_manager_observer.h"
@@ -524,8 +525,8 @@
     // avoid complications with displaying the lock screen over the login
     // screen while remaining secure in the case the user walks away during
     // the sign-in steps. See crbug.com/112225 and crbug.com/110933.
-    VLOG(1) << "Calling session manager's StopSession D-Bus method";
-    SessionManagerClient::Get()->StopSession();
+    VLOG(1) << "The user session cannot be locked, logging out";
+    SessionTerminationManager::Get()->StopSession();
   }
 }
 
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 97d89e418..471c30b 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -118,6 +118,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/login/auth/stub_authenticator_builder.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "chromeos/network/network_cert_loader.h"
 #include "chromeos/network/portal_detector/network_portal_detector.h"
 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
@@ -1865,7 +1866,7 @@
     LOG(ERROR) << "Could not get list of active user sessions after crash.";
     // If we could not get list of active user sessions it is safer to just
     // sign out so that we don't get in the inconsistent state.
-    SessionManagerClient::Get()->StopSession();
+    SessionTerminationManager::Get()->StopSession();
     return;
   }
 
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
index 3cb31258..8494ccf 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_util.cc
@@ -70,10 +70,11 @@
   return IsPluginVmAllowedForProfile(profile) && IsPluginVmConfigured(profile);
 }
 
-// TODO(timloh): Implement detection for Plugin VM windows, e.g. by setting an
-// exo application id (crbug.com/940319).
 bool IsPluginVmWindow(const aura::Window* window) {
-  return false;
+  const std::string* app_id = exo::GetShellApplicationId(window);
+  if (!app_id)
+    return false;
+  return *app_id == "org.chromium.plugin_vm_ui";
 }
 
 void OnPluginVmDispatcherStarted(Profile* profile,
diff --git a/chrome/browser/chromeos/policy/lock_to_single_user_manager.cc b/chrome/browser/chromeos/policy/lock_to_single_user_manager.cc
index 270fabd..e97da6c 100644
--- a/chrome/browser/chromeos/policy/lock_to_single_user_manager.cc
+++ b/chrome/browser/chromeos/policy/lock_to_single_user_manager.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/user_manager/user_manager.h"
@@ -83,8 +84,12 @@
   // Force user logout if failed to lock the device to single user mount.
   const RebootOnSignOutReply extension =
       reply->GetExtension(RebootOnSignOutReply::reply);
-  if (extension.result() != RebootOnSignOutResult::SUCCESS &&
-      extension.result() != RebootOnSignOutResult::PCR_ALREADY_EXTENDED) {
+  if (extension.result() == RebootOnSignOutResult::SUCCESS ||
+      extension.result() == RebootOnSignOutResult::PCR_ALREADY_EXTENDED) {
+    // The device is locked to single user on TPM level. Update the cache in
+    // SessionTerminationManager, so that it triggers reboot on sign out.
+    chromeos::SessionTerminationManager::Get()->SetDeviceLockedToSingleUser();
+  } else {
     LOG(ERROR) << "Signing out user: failed to lock device to single user: "
                << extension.result();
     chrome::AttemptUserExit();
diff --git a/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc b/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
index 509c0b01..4e8d23b8 100644
--- a/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/lock_to_single_user_manager_unittest.cc
@@ -16,6 +16,7 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
 #include "chromeos/login/login_state/login_state.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/account_id/account_id.h"
 #include "components/arc/arc_service_manager.h"
@@ -96,6 +97,8 @@
       base::WrapUnique(fake_user_manager_)};
   std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
   std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
+  // Required for initialization.
+  chromeos::SessionTerminationManager termination_manager_;
   std::unique_ptr<LockToSingleUserManager> lock_to_single_user_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(LockToSingleUserManagerTest);
diff --git a/chrome/browser/chromeos/power/ml/smart_dim/BUILD.gn b/chrome/browser/chromeos/power/ml/smart_dim/BUILD.gn
index dba4838..ee0161b 100644
--- a/chrome/browser/chromeos/power/ml/smart_dim/BUILD.gn
+++ b/chrome/browser/chromeos/power/ml/smart_dim/BUILD.gn
@@ -24,8 +24,8 @@
     "//chrome/browser/chromeos/power/ml:user_activity_ukm_logger_helpers",
     "//chrome/common:constants",
     "//chromeos:chromeos",
-    "//chromeos/services/machine_learning/public/cpp:cpp",
-    "//chromeos/services/machine_learning/public/mojom:mojom",
+    "//chromeos/services/machine_learning/public/cpp",
+    "//chromeos/services/machine_learning/public/mojom",
     "//components/assist_ranker",
     "//components/assist_ranker/proto",
     "//components/sessions",
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.cc b/chrome/browser/chromeos/ui/echo_dialog_view.cc
index 1ada390..35b55bdd 100644
--- a/chrome/browser/chromeos/ui/echo_dialog_view.cc
+++ b/chrome/browser/chromeos/ui/echo_dialog_view.cc
@@ -76,12 +76,13 @@
 }
 
 views::View* EchoDialogView::CreateExtraView() {
-  learn_more_button_ = views::CreateVectorImageButton(this);
-  views::SetImageFromVectorIcon(learn_more_button_,
+  auto learn_more_button = views::CreateVectorImageButton(this);
+  views::SetImageFromVectorIcon(learn_more_button.get(),
                                 vector_icons::kHelpOutlineIcon);
-  learn_more_button_->SetAccessibleName(
+  learn_more_button->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_CHROMEOS_ACC_LEARN_MORE));
-  learn_more_button_->SetFocusForPlatform();
+  learn_more_button->SetFocusForPlatform();
+  learn_more_button_ = learn_more_button.release();
   return learn_more_button_;
 }
 
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index 030fd73..0457cdf 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -228,7 +228,7 @@
             host_content_settings_map->GetContentSetting(
                 host, host, CONTENT_SETTINGS_TYPE_COOKIES, std::string()));
 #if BUILDFLAG(ENABLE_PLUGINS)
-  EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
+  EXPECT_EQ(CONTENT_SETTING_BLOCK,
             host_content_settings_map->GetContentSetting(
                 host, host, CONTENT_SETTINGS_TYPE_PLUGINS, std::string()));
 #endif
@@ -633,24 +633,13 @@
                 std::string()));
 
 #if BUILDFLAG(ENABLE_PLUGINS)
-  EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
+  EXPECT_EQ(CONTENT_SETTING_BLOCK,
             host_content_settings_map->GetContentSetting(
-                host_ending_with_dot,
-                host_ending_with_dot,
-                CONTENT_SETTINGS_TYPE_PLUGINS,
-                std::string()));
+                host_ending_with_dot, host_ending_with_dot,
+                CONTENT_SETTINGS_TYPE_PLUGINS, std::string()));
   host_content_settings_map->SetContentSettingDefaultScope(
       host_ending_with_dot, GURL(), CONTENT_SETTINGS_TYPE_PLUGINS,
       std::string(), CONTENT_SETTING_DEFAULT);
-  EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
-            host_content_settings_map->GetContentSetting(
-                host_ending_with_dot,
-                host_ending_with_dot,
-                CONTENT_SETTINGS_TYPE_PLUGINS,
-                std::string()));
-  host_content_settings_map->SetContentSettingDefaultScope(
-      host_ending_with_dot, GURL(), CONTENT_SETTINGS_TYPE_PLUGINS,
-      std::string(), CONTENT_SETTING_BLOCK);
   EXPECT_EQ(CONTENT_SETTING_BLOCK,
             host_content_settings_map->GetContentSetting(
                 host_ending_with_dot,
@@ -1205,7 +1194,7 @@
 
   // Remove the preference to manage the default-content-setting for Plugins.
   prefs->RemoveManagedPref(prefs::kManagedDefaultPluginsSetting);
-  EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
+  EXPECT_EQ(CONTENT_SETTING_BLOCK,
             host_content_settings_map->GetDefaultContentSetting(
                 CONTENT_SETTINGS_TYPE_PLUGINS, NULL));
 #endif
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index e10c172..382c1c5 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -105,7 +105,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
-#include "content/public/common/service_manager_connection.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/download_test_observer.h"
 #include "content/public/test/slow_download_http_response.h"
@@ -122,10 +121,6 @@
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/device/public/mojom/wake_lock.mojom.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
-#include "services/service_manager/public/cpp/connector.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/page_transition_types.h"
@@ -1200,40 +1195,6 @@
   std::unique_ptr<TestSafeBrowsingServiceFactory> test_safe_browsing_factory_;
 };
 
-class DownloadWakeLockTest : public DownloadTest {
- public:
-  DownloadWakeLockTest() = default;
-
-  void Initialize() {
-    auto* connection = content::ServiceManagerConnection::GetForProcess();
-    auto* connector = connection->GetConnector();
-    connector_ = connector->Clone();
-    connector_->BindInterface(device::mojom::kServiceName,
-                              &wake_lock_provider_);
-  }
-
-  // Returns the number of active wake locks of type |type|.
-  int GetActiveWakeLocks(device::mojom::WakeLockType type) {
-    base::RunLoop run_loop;
-    int result_count = 0;
-    wake_lock_provider_->GetActiveWakeLocksForTests(
-        type,
-        base::BindOnce(
-            [](base::RunLoop* run_loop, int* result_count, int32_t count) {
-              *result_count = count;
-              run_loop->Quit();
-            },
-            &run_loop, &result_count));
-    run_loop.Run();
-    return result_count;
-  }
-
- protected:
-  device::mojom::WakeLockProviderPtr wake_lock_provider_;
-  std::unique_ptr<service_manager::Connector> connector_;
-  DISALLOW_COPY_AND_ASSIGN(DownloadWakeLockTest);
-};
-
 }  // namespace
 
 // NOTES:
@@ -3746,20 +3707,6 @@
   ASSERT_TRUE(origin_three.ShutdownAndWaitUntilComplete());
 }
 
-IN_PROC_BROWSER_TEST_F(DownloadWakeLockTest, WakeLockAcquireAndCancel) {
-  Initialize();
-  EXPECT_EQ(0, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  DownloadItem* download_item = CreateSlowTestDownload();
-  ASSERT_TRUE(download_item);
-  EXPECT_EQ(1, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  download_item->Cancel(true);
-  EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
-  EXPECT_EQ(0, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-}
-
 #if defined(FULL_SAFE_BROWSING)
 
 namespace {
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
index 0240666..ede8794 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
+++ b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
@@ -191,9 +191,9 @@
     EXPECT_EQ(CONTENT_SETTING_ALLOW,
               map->GetContentSetting(
                   url, url, CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string()));
-    EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
-              map->GetContentSetting(
-                  url, url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string()));
+    EXPECT_EQ(CONTENT_SETTING_BLOCK,
+              map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS,
+                                     std::string()));
     EXPECT_EQ(CONTENT_SETTING_BLOCK,
               map->GetContentSetting(
                   url, url, CONTENT_SETTINGS_TYPE_POPUPS, std::string()));
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 7d82df0..23ffb4d 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -42,6 +42,7 @@
 #include "extensions/common/manifest_constants.h"
 #include "pdf/buildflags.h"
 #include "printing/buildflags/buildflags.h"
+#include "storage/browser/fileapi/file_system_features.h"
 #include "ui/accessibility/accessibility_switches.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -682,7 +683,12 @@
         content::BrowserContext::GetStoragePartitionForSite(
             off_the_record_context, site)
             ->GetFileSystemContext();
-    file_system_context->EnableTemporaryFileSystemInIncognito();
+    // Incognito file system is enabled by default. This function can be removed
+    // when the feature flag is removed.
+    if (!base::FeatureList::IsEnabled(
+            storage::features::kEnableFilesystemInIncognito)) {
+      file_system_context->EnableTemporaryFileSystemInIncognito();
+    }
   }
 }
 
diff --git a/chrome/browser/extensions/convert_web_app.cc b/chrome/browser/extensions/convert_web_app.cc
index c47b89d..42ab440 100644
--- a/chrome/browser/extensions/convert_web_app.cc
+++ b/chrome/browser/extensions/convert_web_app.cc
@@ -20,6 +20,7 @@
 #include "base/json/json_file_value_serializer.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -37,6 +38,7 @@
 #include "extensions/common/image_util.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_handlers/file_handler_info.h"
+#include "net/base/url_util.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/color_utils.h"
@@ -52,10 +54,10 @@
 const char kScopeUrlHandlerId[] = "scope";
 
 std::unique_ptr<base::DictionaryValue> CreateFileHandlersForBookmarkApp(
-    blink::Manifest::FileHandler file_handler) {
+    const blink::Manifest::FileHandler& manifest_file_handler) {
   base::Value file_handlers(base::Value::Type::DICTIONARY);
 
-  for (const auto& handler : file_handler) {
+  for (const auto& handler : manifest_file_handler.files) {
     base::Value file_handler(base::Value::Type::DICTIONARY);
     file_handler.SetKey(keys::kFileHandlerIncludeDirectories,
                         base::Value(false));
@@ -81,8 +83,13 @@
     file_handler.SetKey(keys::kFileHandlerExtensions,
                         std::move(file_extensions));
 
-    file_handlers.SetKey(base::UTF16ToUTF8(handler.name),
-                         std::move(file_handler));
+    // Use '{action}/?name={name}' as the id for the file handler, so we don't
+    // have to introduce a new field to the extension manifest.
+    file_handlers.SetKey(
+        net::AppendQueryParameter(manifest_file_handler.action, "name",
+                                  base::UTF16ToUTF8(handler.name))
+            .spec(),
+        std::move(file_handler));
   }
 
   return base::DictionaryValue::From(
diff --git a/chrome/browser/extensions/convert_web_app_unittest.cc b/chrome/browser/extensions/convert_web_app_unittest.cc
index b5d1526..1b90973 100644
--- a/chrome/browser/extensions/convert_web_app_unittest.cc
+++ b/chrome/browser/extensions/convert_web_app_unittest.cc
@@ -419,24 +419,25 @@
   WebApplicationInfo web_app;
   web_app.title = base::ASCIIToUTF16("Graphr");
   web_app.description = base::ASCIIToUTF16("A magical graphy thing");
-  web_app.app_url = GURL("https://not-a-real-site.not-a-tld/");
-  web_app.scope = GURL("https://not-a-real-site.not-a-tld/");
+  web_app.app_url = GURL("https://graphr.n/");
+  web_app.scope = GURL("https://graphr.n/");
 
   {
     blink::Manifest::FileHandler file_handler;
+    file_handler.action = GURL("https://graphr.n/open-file/");
 
     blink::Manifest::FileFilter graph;
     graph.name = base::ASCIIToUTF16("Graph");
     graph.accept.push_back(base::ASCIIToUTF16("text/svg+xml"));
     graph.accept.push_back(base::ASCIIToUTF16(""));
     graph.accept.push_back(base::ASCIIToUTF16(".svg"));
-    file_handler.push_back(graph);
+    file_handler.files.push_back(graph);
 
     blink::Manifest::FileFilter raw;
     raw.name = base::ASCIIToUTF16("Raw");
     raw.accept.push_back(base::ASCIIToUTF16(".csv"));
     raw.accept.push_back(base::ASCIIToUTF16("text/csv"));
-    file_handler.push_back(raw);
+    file_handler.files.push_back(raw);
 
     web_app.file_handler =
         base::Optional<blink::Manifest::FileHandler>(std::move(file_handler));
@@ -453,7 +454,7 @@
 
   EXPECT_EQ(2u, file_handler_info.size());
 
-  EXPECT_EQ("Graph", file_handler_info[0].id);
+  EXPECT_EQ("https://graphr.n/open-file/?name=Graph", file_handler_info[0].id);
   EXPECT_FALSE(file_handler_info[0].include_directories);
   EXPECT_EQ(extensions::file_handler_verbs::kOpenWith,
             file_handler_info[0].verb);
@@ -464,7 +465,7 @@
   EXPECT_THAT(file_handler_info[0].types,
               testing::UnorderedElementsAre("text/svg+xml"));
 
-  EXPECT_EQ("Raw", file_handler_info[1].id);
+  EXPECT_EQ("https://graphr.n/open-file/?name=Raw", file_handler_info[1].id);
   EXPECT_FALSE(file_handler_info[1].include_directories);
   EXPECT_EQ(extensions::file_handler_verbs::kOpenWith,
             file_handler_info[1].verb);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 7a2739ae..b83ab02 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -459,6 +459,11 @@
     "expiry_milestone": 77
   },
   {
+    "name": "crostini-gpu-support",
+    "owners": [ "nverne", "benwells" ],
+    "expiry_milestone": 78
+  },
+  {
     "name": "crostini-usb-allow-unsupported",
     "owners": [ "nverne", "benwells" ],
     "expiry_milestone": 77
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index badad4b..13ff4fd 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2988,6 +2988,9 @@
 const char kCrostiniBackupName[] = "Crostini Backup";
 const char kCrostiniBackupDescription[] = "Enable Crostini export and import.";
 
+const char kCrostiniGpuSupportName[] = "Crostini GPU Support";
+const char kCrostiniGpuSupportDescription[] = "Enable Crostini GPU support.";
+
 const char kCrostiniUsbAllowUnsupportedName[] =
     "Crostini Usb Allow Unsupported";
 const char kCrostiniUsbAllowUnsupportedDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 6d9a075..58ac754 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1800,6 +1800,9 @@
 extern const char kCrostiniBackupName[];
 extern const char kCrostiniBackupDescription[];
 
+extern const char kCrostiniGpuSupportName[];
+extern const char kCrostiniGpuSupportDescription[];
+
 extern const char kCrostiniUsbAllowUnsupportedName[];
 extern const char kCrostiniUsbAllowUnsupportedDescription[];
 
diff --git a/chrome/browser/lifetime/termination_notification.cc b/chrome/browser/lifetime/termination_notification.cc
index 06d4c1bb..c7b2ce1 100644
--- a/chrome/browser/lifetime/termination_notification.cc
+++ b/chrome/browser/lifetime/termination_notification.cc
@@ -17,6 +17,7 @@
 #include "chromeos/dbus/power/power_policy_controller.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/dbus/update_engine_client.h"
+#include "chromeos/login/session/session_termination_manager.h"
 #endif
 
 namespace browser_shutdown {
@@ -65,7 +66,7 @@
     } else if (chrome::IsAttemptingShutdown()) {
       // Don't ask SessionManager to stop session if the shutdown request comes
       // from session manager.
-      chromeos::SessionManagerClient::Get()->StopSession();
+      chromeos::SessionTerminationManager::Get()->StopSession();
     }
   } else {
     if (chrome::IsAttemptingShutdown()) {
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 7c41959..7efbe09 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/accessibility/accessibility_permission_context.h"
 #include "chrome/browser/background_fetch/background_fetch_permission_context.h"
 #include "chrome/browser/background_sync/background_sync_permission_context.h"
+#include "chrome/browser/background_sync/periodic_background_sync_permission_context.h"
 #include "chrome/browser/clipboard/clipboard_read_permission_context.h"
 #include "chrome/browser/clipboard/clipboard_write_permission_context.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -128,6 +129,8 @@
       return CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH;
     case PermissionType::IDLE_DETECTION:
       return CONTENT_SETTINGS_TYPE_IDLE_DETECTION;
+    case PermissionType::PERIODIC_BACKGROUND_SYNC:
+      return CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC;
     case PermissionType::NUM:
       // This will hit the NOTREACHED below.
       break;
@@ -316,6 +319,8 @@
       std::make_unique<BackgroundFetchPermissionContext>(profile);
   permission_contexts_[CONTENT_SETTINGS_TYPE_IDLE_DETECTION] =
       std::make_unique<IdleDetectionPermissionContext>(profile);
+  permission_contexts_[CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC] =
+      std::make_unique<PeriodicBackgroundSyncPermissionContext>(profile);
 }
 
 PermissionManager::~PermissionManager() {
diff --git a/chrome/browser/permissions/permission_util.cc b/chrome/browser/permissions/permission_util.cc
index f8fe4f2..b0d2cd1 100644
--- a/chrome/browser/permissions/permission_util.cc
+++ b/chrome/browser/permissions/permission_util.cc
@@ -54,6 +54,8 @@
       return "BackgroundFetch";
     case CONTENT_SETTINGS_TYPE_IDLE_DETECTION:
       return "IdleDetection";
+    case CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC:
+      return "PeriodicBackgroundSync";
     default:
       break;
   }
@@ -128,6 +130,8 @@
     *out = PermissionType::PAYMENT_HANDLER;
   } else if (type == CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH) {
     *out = PermissionType::BACKGROUND_FETCH;
+  } else if (type == CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC) {
+    *out = PermissionType::PERIODIC_BACKGROUND_SYNC;
   } else {
     return false;
   }
@@ -152,6 +156,7 @@
     case CONTENT_SETTINGS_TYPE_CLIPBOARD_READ:
     case CONTENT_SETTINGS_TYPE_PAYMENT_HANDLER:
     case CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH:
+    case CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC:
       return true;
     default:
       return false;
diff --git a/chrome/browser/plugins/flash_permission_browsertest.cc b/chrome/browser/plugins/flash_permission_browsertest.cc
index 021baa5..db2c646 100644
--- a/chrome/browser/plugins/flash_permission_browsertest.cc
+++ b/chrome/browser/plugins/flash_permission_browsertest.cc
@@ -7,11 +7,14 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/permissions/permissions_browsertest.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
@@ -61,6 +64,24 @@
         switches::kOverridePluginPowerSaverForTesting, "never");
   }
 
+  void SetUpOnMainThread() override {
+    PermissionsBrowserTest::SetUpOnMainThread();
+
+    // This browser test verifies the Flash permission prompt behavior. The
+    // permission prompt only appears when Flash permission is set to DETECT.
+    HostContentSettingsMapFactory::GetForProfile(browser()->profile())
+        ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS,
+                                   CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
+  }
+
+  void TearDownOnMainThread() override {
+    HostContentSettingsMapFactory::GetForProfile(browser()->profile())
+        ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS,
+                                   CONTENT_SETTING_DEFAULT);
+
+    PermissionsBrowserTest::TearDownOnMainThread();
+  }
+
   void TriggerPrompt() override {
     if (prompt_factory()->response_type() ==
         PermissionRequestManager::ACCEPT_ALL) {
diff --git a/chrome/browser/plugins/plugin_info_host_impl_unittest.cc b/chrome/browser/plugins/plugin_info_host_impl_unittest.cc
index f5eabe4..c75e508 100644
--- a/chrome/browser/plugins/plugin_info_host_impl_unittest.cc
+++ b/chrome/browser/plugins/plugin_info_host_impl_unittest.cc
@@ -254,19 +254,20 @@
 
   PluginMetadata::SecurityStatus security_status =
       PluginMetadata::SECURITY_STATUS_UP_TO_DATE;
-  context()->DecidePluginStatus(GURL(), main_frame_origin, plugin,
-                                security_status, content::kFlashPluginName,
-                                &status);
-  EXPECT_EQ(chrome::mojom::PluginStatus::kFlashHiddenPreferHtml, status);
-
-  // Now block plugins.
-  host_content_settings_map()->SetDefaultContentSetting(
-      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
 
   context()->DecidePluginStatus(GURL(), main_frame_origin, plugin,
                                 security_status, content::kFlashPluginName,
                                 &status);
   EXPECT_EQ(chrome::mojom::PluginStatus::kBlockedNoLoading, status);
+
+  // Now enable plugins.
+  host_content_settings_map()->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
+
+  context()->DecidePluginStatus(GURL(), main_frame_origin, plugin,
+                                security_status, content::kFlashPluginName,
+                                &status);
+  EXPECT_EQ(chrome::mojom::PluginStatus::kPlayImportantContent, status);
 }
 
 TEST_F(PluginInfoHostImplTest, RunAllFlashInAllowMode) {
@@ -310,7 +311,10 @@
   EXPECT_THAT(status, Eq(chrome::mojom::PluginStatus::kAllowed));
 }
 
-TEST_F(PluginInfoHostImplTest, PluginsAllowedInWhitelistedSchemes) {
+TEST_F(PluginInfoHostImplTest, PluginsOnlyAllowedInWhitelistedSchemes) {
+  host_content_settings_map()->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
+
   VerifyPluginContentSetting(GURL("http://example.com"), "foo",
                              CONTENT_SETTING_DETECT_IMPORTANT_CONTENT, true,
                              false);
@@ -332,17 +336,6 @@
   {
     bool is_managed = false;
     EXPECT_EQ(
-        CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
-        PluginUtils::UnsafeGetRawDefaultFlashContentSetting(map, &is_managed));
-    EXPECT_FALSE(is_managed);
-  }
-
-  // Block plugins by default.
-  map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS,
-                                CONTENT_SETTING_BLOCK);
-  {
-    bool is_managed = false;
-    EXPECT_EQ(
         CONTENT_SETTING_BLOCK,
         PluginUtils::UnsafeGetRawDefaultFlashContentSetting(map, &is_managed));
     EXPECT_FALSE(is_managed);
diff --git a/chrome/browser/resources/app_management/browser_proxy.html b/chrome/browser/resources/app_management/browser_proxy.html
index 018e777..e66afd2 100644
--- a/chrome/browser/resources/app_management/browser_proxy.html
+++ b/chrome/browser/resources/app_management/browser_proxy.html
@@ -1,7 +1,8 @@
 <link rel="import" href="chrome://resources/html/cr.html">
-<script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-<script src="chrome://resources/js/big_buffer.mojom-lite.js"></script>
-<script src="chrome://resources/js/time.mojom-lite.js"></script>
+<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
+<link rel="import" href="chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom.html">
+<link rel="import" href="chrome://resources/mojo/mojo/public/mojom/base/time.mojom.html">
+
 <script src="image_info.mojom-lite.js"></script>
 <script src="bitmap.mojom-lite.js"></script>
 <script src="image.mojom-lite.js"></script>
diff --git a/chrome/browser/resources/app_management/browser_proxy.js b/chrome/browser/resources/app_management/browser_proxy.js
index f534dba..8d1b78b 100644
--- a/chrome/browser/resources/app_management/browser_proxy.js
+++ b/chrome/browser/resources/app_management/browser_proxy.js
@@ -20,7 +20,10 @@
 
         const /** @type {!Array<App>}*/ appList = [
           app_management.FakePageHandler.createApp(
-              'ahfgeienlihckogmohjhadlkjgocpleb', {title: 'Web Store'}),
+              'ahfgeienlihckogmohjhadlkjgocpleb', {
+                title: 'Web Store (system app)',
+                installSource: InstallSource.kSystem
+              }),
           app_management.FakePageHandler.createApp(
               'aohghmighlieiainnegkcijnfilokake',
               {title: 'Docs', type: AppType.kArc}),
@@ -30,7 +33,10 @@
           app_management.FakePageHandler.createApp(
               'pjkljhegncpnkpknbcohdijeoejaedia', {title: 'Gmail'}),
           app_management.FakePageHandler.createApp(
-              'aapocclcgogkmnckokdopfmhonfmgoek', {title: 'Slide'}),
+              'aapocclcgogkmnckokdopfmhonfmgoek', {
+                title: 'Slides (policy installed)',
+                installSource: InstallSource.kPolicy
+              }),
         ];
 
         this.handler.setApps(appList);
diff --git a/chrome/browser/resources/app_management/constants.js b/chrome/browser/resources/app_management/constants.js
index 89f99d8..a3ca577 100644
--- a/chrome/browser/resources/app_management/constants.js
+++ b/chrome/browser/resources/app_management/constants.js
@@ -47,3 +47,5 @@
 const TriState = apps.mojom.TriState;
 
 const OptionalBool = apps.mojom.OptionalBool;
+
+const InstallSource = apps.mojom.InstallSource;
diff --git a/chrome/browser/resources/app_management/fake_page_handler.js b/chrome/browser/resources/app_management/fake_page_handler.js
index 7a6303848..9a06d5f 100644
--- a/chrome/browser/resources/app_management/fake_page_handler.js
+++ b/chrome/browser/resources/app_management/fake_page_handler.js
@@ -79,6 +79,7 @@
         version: '5.1',
         size: '9.0MB',
         isPinned: apps.mojom.OptionalBool.kFalse,
+        installSource: apps.mojom.InstallSource.kUser,
         permissions: {},
       };
 
diff --git a/chrome/browser/resources/app_management/permission_view_header.html b/chrome/browser/resources/app_management/permission_view_header.html
index 1f7e2c9..b3d63d7 100644
--- a/chrome/browser/resources/app_management/permission_view_header.html
+++ b/chrome/browser/resources/app_management/permission_view_header.html
@@ -4,6 +4,7 @@
 <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 
 <dom-module id="app-management-permission-view-header">
   <template>
@@ -36,15 +37,26 @@
       #uninstall-button {
         background: white;
       }
+
+      #policy-indicator {
+        fill: var(--google-grey-refresh-500);
+        padding-inline-end: 10px;
+      }
     </style>
     <cr-icon-button class="icon-arrow-back" id="closeButton"
         on-click="onClickBackButton_" aria-label="$i18n{back}"></cr-icon-button>
     <img id="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]">
     <div class="page-title">[[app_.title]]</div>
     <slot name="extra-right-buttons"></slot>
-    <paper-button id="uninstall-button" on-click="onClickUninstallButton_">
-      $i18n{uninstall}
-    </paper-button>
+    <div id="uninstall-wrapper" title$="[[getUninstallButtonHoverText_(app_)]]">
+      <template is="dom-if" if="[[isPolicyApp_(app_)]]">
+        <iron-icon id="policy-indicator" icon="cr:domain"></iron-icon>
+      </template>
+      <paper-button id="uninstall-button" on-click="onClickUninstallButton_"
+        disabled$="[[getUninstallButtonDisableState_(app_)]]">
+        $i18n{uninstall}
+      </paper-button>
+    </div>
   </template>
   <script src="permission_view_header.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/app_management/permission_view_header.js b/chrome/browser/resources/app_management/permission_view_header.js
index 248478a..a6caf89 100644
--- a/chrome/browser/resources/app_management/permission_view_header.js
+++ b/chrome/browser/resources/app_management/permission_view_header.js
@@ -21,6 +21,68 @@
   },
 
   /**
+   *
+   * Returns True if the uninstall button should be disabled due to app install
+   * type.
+   *
+   * @param {App} app
+   * @return {boolean}
+   * @private
+   */
+  getUninstallButtonDisableState_: function(app) {
+    switch (app.installSource) {
+      case InstallSource.kSystem:
+      case InstallSource.kPolicy:
+        return true;
+      case InstallSource.kOem:
+      case InstallSource.kDefault:
+      case InstallSource.kSync:
+      case InstallSource.kUser:
+      case InstallSource.kUnknown:
+        return false;
+      default:
+        assertNotReached();
+    }
+  },
+
+  /**
+   * Returns string to be shown as a tool tip over the uninstall button.
+   *
+   * @param {App} app
+   * @return {string}
+   * @private
+   */
+  getUninstallButtonHoverText_: function(app) {
+    // TODO(crbug.com/957795) Replace strings and add them into i18n.
+    switch (app.installSource) {
+      case InstallSource.kSystem:
+        return app.title + ' cannot be uninstalled as it is part of Chrome OS.';
+      case InstallSource.kPolicy:
+        return app.title + ' cannot be uninstalled as it has been' +
+            ' installed by your administrator.';
+      case InstallSource.kOem:
+      case InstallSource.kDefault:
+      case InstallSource.kSync:
+      case InstallSource.kUser:
+      case InstallSource.kUnknown:
+        return `Click to uninstall ${app.title}.`;
+      default:
+        assertNotReached();
+    }
+  },
+
+  /**
+   * Returns true if the app was installed by a policy
+   *
+   * @param {App} app
+   * @returns {boolean}
+   * @private
+   */
+  isPolicyApp_: function(app) {
+    return app.installSource === InstallSource.kPolicy;
+  },
+
+  /**
    * @param {App} app
    * @return {string}
    * @private
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
index fc845f79f..fdd34a71 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
@@ -23,8 +23,8 @@
   <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page_manager.html">
   <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page.html">
   <link rel="import" href="chrome://resources/html/util.html">
+  <link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
 
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
   <script src="uuid.mojom-lite.js"></script>
   <script src="device.mojom-lite.js"></script>
   <script src="adapter.mojom-lite.js"></script>
diff --git a/chrome/browser/resources/chromeos/camera/src/manifest.json b/chrome/browser/resources/chromeos/camera/src/manifest.json
index 8b02855..412686f9 100644
--- a/chrome/browser/resources/chromeos/camera/src/manifest.json
+++ b/chrome/browser/resources/chromeos/camera/src/manifest.json
@@ -3,7 +3,7 @@
   "manifest_version": 2,
   "name": "__MSG_name__",
   "description": "__MSG_description__",
-  "version": "6.0.0",
+  "version": "6.1.0",
   "default_locale": "en",
   "minimum_chrome_version": "60.0.0.0",
   "icons": {
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn
index 5569a15f..0b0ed03 100644
--- a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn
+++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn
@@ -30,7 +30,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/browser/resources/chromeos/zip_archiver:char_coding",
     "//ppapi/cpp",
     "//third_party/minizip:minizip",
diff --git a/chrome/browser/resources/discards/mojo_api.html b/chrome/browser/resources/discards/mojo_api.html
index 57b999df..3b7bbda 100644
--- a/chrome/browser/resources/discards/mojo_api.html
+++ b/chrome/browser/resources/discards/mojo_api.html
@@ -3,8 +3,8 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file.
 -->
-<script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-<script src="chrome://resources/js/time.mojom-lite.js"></script>
+<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
+<link rel="import" href="chrome://resources/mojo/mojo/public/mojom/base/time.mojom.html">
 <script src="mojo/public/mojom/base/process_id.mojom-lite.js"></script>
 <script
     src="chrome/browser/resource_coordinator/lifecycle_unit_state.mojom-lite.js">
diff --git a/chrome/browser/resources/downloads/browser_proxy.html b/chrome/browser/resources/downloads/browser_proxy.html
index c71963cd..505910d7 100644
--- a/chrome/browser/resources/downloads/browser_proxy.html
+++ b/chrome/browser/resources/downloads/browser_proxy.html
@@ -1,4 +1,4 @@
 <link rel="import" href="chrome://resources/html/cr.html">
-<script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
 <script src="downloads.mojom-lite.js"></script>
 <script src="browser_proxy.js"></script>
diff --git a/chrome/browser/resources/engagement/site_engagement.html b/chrome/browser/resources/engagement/site_engagement.html
index 1b890ccb..48c2a8a 100644
--- a/chrome/browser/resources/engagement/site_engagement.html
+++ b/chrome/browser/resources/engagement/site_engagement.html
@@ -3,8 +3,8 @@
   <title>Site Engagement</title>
   <meta charset="utf-8">
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-  <script src="chrome://resources/js/url.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome/browser/engagement/site_engagement_details.mojom-lite.js">
   </script>
diff --git a/chrome/browser/resources/eoc_internals/eoc_internals.html b/chrome/browser/resources/eoc_internals/eoc_internals.html
index 6b5bb2f1..66eb4d6 100644
--- a/chrome/browser/resources/eoc_internals/eoc_internals.html
+++ b/chrome/browser/resources/eoc_internals/eoc_internals.html
@@ -13,7 +13,7 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
   <link rel="stylesheet" href="eoc_internals.css">
 
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="eoc_internals.mojom-lite.js"></script>
 
diff --git a/chrome/browser/resources/explore_sites_internals/explore_sites_internals.html b/chrome/browser/resources/explore_sites_internals/explore_sites_internals.html
index c44201d..ac94797 100644
--- a/chrome/browser/resources/explore_sites_internals/explore_sites_internals.html
+++ b/chrome/browser/resources/explore_sites_internals/explore_sites_internals.html
@@ -14,7 +14,7 @@
   <link rel="stylesheet" href="chrome://resources/css/throbber.css">
   <link rel="stylesheet" href="explore_sites_internals.css">
 
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="explore_sites_internals.mojom-lite.js"></script>
 
diff --git a/chrome/browser/resources/feed_internals/feed_internals.html b/chrome/browser/resources/feed_internals/feed_internals.html
index 0c385da..a6a380e 100644
--- a/chrome/browser/resources/feed_internals/feed_internals.html
+++ b/chrome/browser/resources/feed_internals/feed_internals.html
@@ -15,8 +15,8 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
   <link rel="stylesheet" href="feed_internals.css">
 
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-  <script src="chrome://resources/js/url.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="feed_internals.mojom-lite.js"></script>
 
diff --git a/chrome/browser/resources/interventions_internals/index.html b/chrome/browser/resources/interventions_internals/index.html
index 21885f2..4f17156 100644
--- a/chrome/browser/resources/interventions_internals/index.html
+++ b/chrome/browser/resources/interventions_internals/index.html
@@ -5,8 +5,8 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Interventions-Internals</title>
     <script src="chrome://resources/js/cr.js"></script>
-    <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-    <script src="chrome://resources/js/url.mojom-lite.js"></script>
+    <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
+    <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
     <script src="chrome://resources/js/util.js"></script>
     <script src="chrome/browser/ui/webui/interventions_internals/interventions_internals.mojom-lite.js">
     </script>
diff --git a/chrome/browser/resources/media/media_engagement.html b/chrome/browser/resources/media/media_engagement.html
index f9062ed..8922e663 100644
--- a/chrome/browser/resources/media/media_engagement.html
+++ b/chrome/browser/resources/media/media_engagement.html
@@ -4,10 +4,11 @@
   <title>Media Engagement</title>
   <meta charset="utf-8">
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/promise_resolver.js"></script>
-  <script src="chrome://resources/js/unguessable_token.mojom-lite.js"></script>
-  <script src="chrome://resources/js/origin.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/url/mojom/origin.mojom-lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
 
   <script src="chrome/browser/media/media_engagement_score_details.mojom-lite.js">
diff --git a/chrome/browser/resources/omnibox/omnibox.html b/chrome/browser/resources/omnibox/omnibox.html
index d052e79..8b8549e 100644
--- a/chrome/browser/resources/omnibox/omnibox.html
+++ b/chrome/browser/resources/omnibox/omnibox.html
@@ -7,7 +7,7 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
   <link rel="stylesheet" href="omnibox.css">
   <script src="chrome://resources/js/cr.js"></script>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome/browser/ui/webui/omnibox/omnibox.mojom-lite.js"></script>
   <script src="omnibox_element.js"></script>
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn
index 6b8baae..9f756a1a 100644
--- a/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -18,6 +18,7 @@
     insert_in_head = "<base href=\"chrome://print\">"
     input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir)
     js_out_files = [ "crisper.js" ]
+    replace_for_html_imports_polyfill = "crisper.js"
 
     excludes = [ "pdf/pdf_scripting_api.js" ]
 
diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html
index 4bbfa95..4940d59 100644
--- a/chrome/browser/resources/print_preview/print_preview.html
+++ b/chrome/browser/resources/print_preview/print_preview.html
@@ -64,6 +64,8 @@
   </style>
 </head>
 <body>
+  <script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js">
+  </script>
   <print-preview-app></print-preview-app>
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
diff --git a/chrome/browser/resources/reset_password/reset_password.html b/chrome/browser/resources/reset_password/reset_password.html
index 60838025..fa9d646c 100644
--- a/chrome/browser/resources/reset_password/reset_password.html
+++ b/chrome/browser/resources/reset_password/reset_password.html
@@ -7,9 +7,9 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <link rel="import" href="chrome://resources/html/polymer.html">
   <link rel="import" href="chrome://resources/cr_elements/icons.html">
+  <link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
   <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
   <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="reset_password.mojom-lite.js"></script>
   <script src="reset_password.js"></script>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn
index 1850d5a..03e1949 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_settings_main/BUILD.gn
@@ -15,7 +15,7 @@
     "../..:page_visibility",
     "../..:route",
     "../..:search_settings",
-    "../../about_page:about_page",
+    "../../about_page",
     "../../settings_page:main_page_behavior",
     "../os_settings_page:os_settings_page",
     "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
index 68bf8d37..b098e77 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
@@ -14,7 +14,7 @@
   deps = [
     "../..:global_scroll_target_behavior",
     "../..:page_visibility",
-    "../../prefs:prefs",
+    "../../prefs",
     "../os_settings_main:os_settings_main",
     "//ui/webui/resources/cr_elements:cr_container_shadow_behavior",
     "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
diff --git a/chrome/browser/resources/settings/languages_page/BUILD.gn b/chrome/browser/resources/settings/languages_page/BUILD.gn
index e59eba2..c461ede4 100644
--- a/chrome/browser/resources/settings/languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/languages_page/BUILD.gn
@@ -34,7 +34,7 @@
   deps = [
     ":languages_browser_proxy",
     ":languages_types",
-    "../prefs:prefs",
+    "../prefs",
     "../prefs:prefs_types",
     "//ui/webui/resources/js:assert",
     "//ui/webui/resources/js:cr",
@@ -76,7 +76,7 @@
   deps = [
     ":languages",
     ":languages_types",
-    "../prefs:prefs",
+    "../prefs",
   ]
   externs_list = [ "$externs_path/language_settings_private.js" ]
 }
diff --git a/chrome/browser/resources/settings/search_page/BUILD.gn b/chrome/browser/resources/settings/search_page/BUILD.gn
index 458a5b7c..48ae8f73 100644
--- a/chrome/browser/resources/settings/search_page/BUILD.gn
+++ b/chrome/browser/resources/settings/search_page/BUILD.gn
@@ -13,7 +13,7 @@
 js_library("search_page") {
   deps = [
     "..:route",
-    "../prefs:prefs",
+    "../prefs",
     "../search_engines_page:search_engines_browser_proxy",
     "../settings_page:settings_animated_pages",
     "//ui/webui/resources/js:cr",
diff --git a/chrome/browser/resources/settings/settings_main/BUILD.gn b/chrome/browser/resources/settings/settings_main/BUILD.gn
index cce4e824d..c4eddc9 100644
--- a/chrome/browser/resources/settings/settings_main/BUILD.gn
+++ b/chrome/browser/resources/settings/settings_main/BUILD.gn
@@ -15,7 +15,7 @@
     "..:page_visibility",
     "..:route",
     "..:search_settings",
-    "../about_page:about_page",
+    "../about_page",
     "../basic_page:basic_page",
     "../settings_page:main_page_behavior",
     "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
diff --git a/chrome/browser/resources/settings/settings_ui/BUILD.gn b/chrome/browser/resources/settings/settings_ui/BUILD.gn
index 87fc3a3..ae564be 100644
--- a/chrome/browser/resources/settings/settings_ui/BUILD.gn
+++ b/chrome/browser/resources/settings/settings_ui/BUILD.gn
@@ -14,7 +14,7 @@
   deps = [
     "..:global_scroll_target_behavior",
     "..:page_visibility",
-    "../prefs:prefs",
+    "../prefs",
     "../settings_main:settings_main",
     "//ui/webui/resources/cr_elements:cr_container_shadow_behavior",
     "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
diff --git a/chrome/browser/resources/snippets_internals/snippets_internals.html b/chrome/browser/resources/snippets_internals/snippets_internals.html
index 4c240d4..e004b60 100644
--- a/chrome/browser/resources/snippets_internals/snippets_internals.html
+++ b/chrome/browser/resources/snippets_internals/snippets_internals.html
@@ -13,7 +13,7 @@
   <link rel="stylesheet" href="snippets_internals.css">
 
   <script src="chrome://resources/js/cr.js"></script>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/jstemplate_compiled.js"></script>
   <script src="chrome://resources/js/util.js"></script>
 
diff --git a/chrome/browser/resources/usb_internals/usb_internals.html b/chrome/browser/resources/usb_internals/usb_internals.html
index 66cf6a6..21010b8 100644
--- a/chrome/browser/resources/usb_internals/usb_internals.html
+++ b/chrome/browser/resources/usb_internals/usb_internals.html
@@ -16,12 +16,12 @@
   <script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
   <script src="chrome://resources/js/cr/ui/tabs.js"></script>
   <script src="chrome://resources/js/cr/ui/tree.js"></script>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/util.js"></script>
-  <script src="chrome://resources/js/big_buffer.mojom-lite.js"></script>
-  <script src="chrome://resources/js/file.mojom-lite.js"></script>
-  <script src="chrome://resources/js/string16.mojom-lite.js"></script>
-  <script src="chrome://resources/js/url.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/mojom/base/file.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
 
   <script src="device.mojom-lite.js"></script>
   <script src="device_manager_client.mojom-lite.js"></script>
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index b7a963c..4565e2b3 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -135,16 +135,16 @@
       "//chrome/common/safe_browsing:proto",
       "//components/safe_browsing:csd_proto",
       "//components/safe_browsing:safe_browsing",
-      "//components/safe_browsing/browser:browser",
-      "//components/safe_browsing/common:common",
+      "//components/safe_browsing/browser",
+      "//components/safe_browsing/common",
       "//components/safe_browsing/common:safe_browsing_prefs",
       "//components/safe_browsing/db:metadata_proto",
       "//components/safe_browsing/db:whitelist_checker_client",
       "//components/safe_browsing/password_protection",
+      "//components/safe_browsing/triggers",
       "//components/safe_browsing/triggers:ad_sampler_trigger",
       "//components/safe_browsing/triggers:suspicious_site_trigger",
       "//components/safe_browsing/triggers:trigger_throttler",
-      "//components/safe_browsing/triggers:triggers",
     ]
     if (safe_browsing_mode == 1) {
       # "Safe Browsing Full" files in addition to the "basic" ones to use for
@@ -245,14 +245,14 @@
         "//chrome/common/safe_browsing:disk_image_type_sniffer_mac",
         "//chrome/common/safe_browsing:download_type_util",
         "//chrome/services/file_util/public/cpp",
-        "//components/content_settings/core/browser:browser",
-        "//components/language/core/common:common",
-        "//components/prefs:prefs",
-        "//components/safe_browsing/db:db",
+        "//components/content_settings/core/browser",
+        "//components/language/core/common",
+        "//components/prefs",
+        "//components/safe_browsing/db",
         "//components/security_interstitials/content:security_interstitial_page",
-        "//components/signin/core/browser:browser",
-        "//content/public/browser:browser",
-        "//net:net",
+        "//components/signin/core/browser",
+        "//content/public/browser",
+        "//net",
       ]
       if (is_win) {
         deps += [ "//chrome/browser/safe_browsing/incident_reporting:state_store_data_proto" ]
@@ -291,11 +291,11 @@
 
   deps = [
     "//components/keyed_service/content",
-    "//components/prefs:prefs",
-    "//components/safe_browsing/common:common",
+    "//components/prefs",
+    "//components/safe_browsing/common",
     "//components/safe_browsing/common:safe_browsing_prefs",
-    "//components/signin/core/browser:browser",
-    "//content/public/browser:browser",
+    "//components/signin/core/browser",
+    "//content/public/browser",
     "//services/identity/public/cpp",
   ]
 }
@@ -313,7 +313,7 @@
       "//components/safe_browsing/db:database_manager",
       "//components/safe_browsing/db:test_database_manager",
       "//components/safe_browsing/db:v4_protocol_manager_util",
-      "//content/public/browser:browser",
+      "//content/public/browser",
     ]
   }
 }
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
index fbb19f3..d74b7d0 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
@@ -14,7 +14,6 @@
 #include "components/sync/device_info/device_info.h"
 #include "components/sync/device_info/device_info_sync_service.h"
 #include "components/sync/device_info/device_info_tracker.h"
-#include "components/sync/driver/profile_sync_service.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_user_settings.h"
@@ -34,13 +33,6 @@
          base::FeatureList::IsEnabled(kSendTabToSelfShowSendingUI);
 }
 
-bool IsSyncPaused(Profile* profile) {
-  syncer::ProfileSyncService* service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile);
-  return service->GetDisableReasons() ==
-         syncer::SyncService::DISABLE_REASON_PAUSED;
-}
-
 bool IsUserSyncTypeActive(Profile* profile) {
   SendTabToSelfSyncService* service =
       SendTabToSelfSyncServiceFactory::GetForProfile(profile);
@@ -58,12 +50,6 @@
          device_sync_service->GetDeviceInfoTracker()->CountActiveDevices() > 1;
 }
 
-bool IsSettingRequirementsMet(Profile* profile) {
-  // If sending is enabled, then so is receiving.
-  return IsSendingEnabled() && !IsSyncPaused(profile) &&
-         IsUserSyncTypeActive(profile) && IsSyncingOnMultipleDevices(profile);
-}
-
 bool IsContentRequirementsMet(const GURL& url, Profile* profile) {
   bool is_http_or_https = url.SchemeIsHTTPOrHTTPS();
   bool is_native_page = url.SchemeIs(content::kChromeUIScheme);
@@ -79,7 +65,9 @@
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
 
-  return IsSettingRequirementsMet(profile) &&
+  // If sending is enabled, then so is receiving.
+  return IsSendingEnabled() && IsUserSyncTypeActive(profile) &&
+         IsSyncingOnMultipleDevices(profile) &&
          IsContentRequirementsMet(web_contents->GetURL(), profile);
 }
 
@@ -89,7 +77,8 @@
     return false;
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  return IsSettingRequirementsMet(profile) &&
+  return IsSendingEnabled() && IsUserSyncTypeActive(profile) &&
+         IsSyncingOnMultipleDevices(profile) &&
          (IsContentRequirementsMet(web_contents->GetURL(), profile) ||
           IsContentRequirementsMet(link_url, profile));
 }
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util.h b/chrome/browser/send_tab_to_self/send_tab_to_self_util.h
index fa537de..80f5c769 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util.h
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util.h
@@ -21,18 +21,12 @@
 // flags are enabled.
 bool IsSendingEnabled();
 
-// Return true if the the sync mode is paused.
-bool IsSyncPaused(Profile* profile);
-
 // Returns true if the SendTabToSelf sync datatype is active.
 bool IsUserSyncTypeActive(Profile* profile);
 
 // Returns true if the user syncing on two or more devices.
 bool IsSyncingOnMultipleDevices(Profile* profile);
 
-// Returns true if the flag and sync setting requirements are met.
-bool IsSettingRequirementsMet(Profile* profile);
-
 // Returns true if the tab and web content requirements are met:
 //  User is viewing an HTTP or HTTPS page.
 //  User is not on a native page.
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
index ced4fa7d..1ad5fa8 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
@@ -185,14 +185,6 @@
   EXPECT_FALSE(IsReceivingEnabled());
 }
 
-TEST_F(SendTabToSelfUtilTest, IsSyncPaused) {
-  EXPECT_FALSE(IsSyncPaused(profile()));
-
-  test_sync_service_->SetDisableReasons(
-      syncer::SyncService::DISABLE_REASON_PAUSED);
-  EXPECT_TRUE(IsSyncPaused(profile()));
-}
-
 TEST_F(SendTabToSelfUtilTest, IsSyncingOnMultipleDevices_True) {
   mock_device_sync_service_->SetTrackerActiveDevices(2);
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index a635b49c..d97713c 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -404,7 +404,7 @@
     "//components/browser_sync",
     "//components/browsing_data/content",
     "//components/browsing_data/core",
-    "//components/bubble:bubble",
+    "//components/bubble",
     "//components/consent_auditor/",
     "//components/content_settings/core/browser",
     "//components/crx_file",
@@ -462,7 +462,7 @@
     "//components/renderer_context_menu",
     "//components/resources",
     "//components/safe_browsing:features",
-    "//components/safe_browsing/common:common",
+    "//components/safe_browsing/common",
     "//components/safe_browsing/common:safe_browsing_prefs",
     "//components/safe_browsing/db:database_manager",
     "//components/safe_browsing/db:util",
@@ -482,7 +482,7 @@
     "//components/startup_metric_utils/browser:lib",
     "//components/strings",
     "//components/subresource_filter/content/browser",
-    "//components/subresource_filter/core/browser:browser",
+    "//components/subresource_filter/core/browser",
     "//components/supervised_user_error_page",
     "//components/sync",
     "//components/sync_preferences",
@@ -490,7 +490,7 @@
     "//components/tracing:startup_tracing",
     "//components/translate/translate_internals",
     "//components/ui_devtools",
-    "//components/ukm:ukm",
+    "//components/ukm",
     "//components/ukm/content",
     "//components/ukm/debug:util",
     "//components/undo",
@@ -516,7 +516,7 @@
     "//extensions/buildflags",
     "//gpu/config",
     "//media",
-    "//net:net",
+    "//net",
     "//ppapi/buildflags",
     "//printing/buildflags",
     "//rlz/buildflags",
@@ -762,7 +762,7 @@
       "//chrome/android:jni_headers",
       "//components/embedder_support/android:web_contents_delegate",
       "//components/navigation_interception",
-      "//components/subresource_filter/core/browser:browser",
+      "//components/subresource_filter/core/browser",
       "//crypto:platform",
       "//device/usb/mojo",
       "//device/usb/public/cpp",
@@ -1793,8 +1793,7 @@
     ]
     deps += [
       "//ash",
-      "//ash/components/shortcut_viewer:lib",
-      "//ash/components/shortcut_viewer/public/mojom",
+      "//ash/components/shortcut_viewer",
       "//ash/public/cpp",
       "//ash/public/cpp/resources:ash_public_unscaled_resources",
       "//ash/public/cpp/vector_icons",
diff --git a/chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.cc b/chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.cc
index abcace9..10a4c29 100644
--- a/chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.cc
+++ b/chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.cc
@@ -4,20 +4,13 @@
 
 #include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
 
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
+#include "ash/components/shortcut_viewer/shortcut_viewer.h"
 #include "base/time/time.h"
-#include "content/public/common/service_manager_connection.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace keyboard_shortcut_viewer_util {
 
 void ToggleKeyboardShortcutViewer() {
-  shortcut_viewer::mojom::ShortcutViewerPtr shortcut_viewer_ptr;
-  service_manager::Connector* connector =
-      content::ServiceManagerConnection::GetForProcess()->GetConnector();
-  connector->BindInterface(shortcut_viewer::mojom::kServiceName,
-                           &shortcut_viewer_ptr);
-  shortcut_viewer_ptr->Toggle(base::TimeTicks::Now());
+  keyboard_shortcut_viewer::Toggle(base::TimeTicks::Now());
 }
 
 }  // namespace keyboard_shortcut_viewer_util
diff --git a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
index 24ffdd3..48d404ef 100644
--- a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
@@ -5,54 +5,39 @@
 #include "chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h"
 
 #include "ash/display/screen_orientation_controller.h"
-#include "ash/public/interfaces/constants.mojom.h"
 #include "ash/shell.h"
 #include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/service_manager_connection.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "ui/aura/mus/window_mus.h"
-#include "ui/aura/mus/window_tree_client.h"
-#include "ui/base/ui_base_features.h"
-#include "ui/views/mus/desktop_window_tree_host_mus.h"
-#include "ui/views/mus/mus_client.h"
 
 namespace {
 
-ash::mojom::OrientationLockType ToAshOrientationLockType(
+ash::OrientationLockType ToAshOrientationLockType(
     blink::WebScreenOrientationLockType blink_orientation_lock) {
   switch (blink_orientation_lock) {
     case blink::kWebScreenOrientationLockDefault:
     case blink::kWebScreenOrientationLockAny:
-      return ash::mojom::OrientationLockType::kAny;
+      return ash::OrientationLockType::kAny;
     case blink::kWebScreenOrientationLockPortrait:
-      return ash::mojom::OrientationLockType::kPortrait;
+      return ash::OrientationLockType::kPortrait;
     case blink::kWebScreenOrientationLockPortraitPrimary:
-      return ash::mojom::OrientationLockType::kPortraitPrimary;
+      return ash::OrientationLockType::kPortraitPrimary;
     case blink::kWebScreenOrientationLockPortraitSecondary:
-      return ash::mojom::OrientationLockType::kPortraitSecondary;
+      return ash::OrientationLockType::kPortraitSecondary;
     case blink::kWebScreenOrientationLockLandscape:
-      return ash::mojom::OrientationLockType::kLandscape;
+      return ash::OrientationLockType::kLandscape;
     case blink::kWebScreenOrientationLockLandscapePrimary:
-      return ash::mojom::OrientationLockType::kLandscapePrimary;
+      return ash::OrientationLockType::kLandscapePrimary;
     case blink::kWebScreenOrientationLockLandscapeSecondary:
-      return ash::mojom::OrientationLockType::kLandscapeSecondary;
+      return ash::OrientationLockType::kLandscapeSecondary;
     case blink::kWebScreenOrientationLockNatural:
-      return ash::mojom::OrientationLockType::kNatural;
+      return ash::OrientationLockType::kNatural;
   }
-  return ash::mojom::OrientationLockType::kAny;
+  return ash::OrientationLockType::kAny;
 }
 
 }  // namespace
 
 ScreenOrientationDelegateChromeos::ScreenOrientationDelegateChromeos() {
-  if (features::IsUsingWindowService()) {
-    ash_window_manager_ =
-        views::MusClient::Get()
-            ->window_tree_client()
-            ->BindWindowManagerInterface<ash::mojom::AshWindowManager>();
-  }
-
   content::WebContents::SetScreenOrientationDelegate(this);
 }
 
@@ -68,16 +53,9 @@
 void ScreenOrientationDelegateChromeos::Lock(
     content::WebContents* web_contents,
     blink::WebScreenOrientationLockType orientation_lock) {
-  if (features::IsUsingWindowService()) {
-    ash_window_manager_->LockOrientation(
-        aura::WindowMus::Get(web_contents->GetNativeView())->server_id(),
-        ToAshOrientationLockType(orientation_lock));
-  } else {
-    ash::Shell::Get()
-        ->screen_orientation_controller()
-        ->LockOrientationForWindow(web_contents->GetNativeView(),
-                                   ToAshOrientationLockType(orientation_lock));
-  }
+  ash::Shell::Get()->screen_orientation_controller()->LockOrientationForWindow(
+      web_contents->GetNativeView(),
+      ToAshOrientationLockType(orientation_lock));
 }
 
 bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported() {
@@ -87,12 +65,7 @@
 
 void ScreenOrientationDelegateChromeos::Unlock(
     content::WebContents* web_contents) {
-  if (features::IsUsingWindowService()) {
-    ash_window_manager_->UnlockOrientation(
-        aura::WindowMus::Get(web_contents->GetNativeView())->server_id());
-  } else {
-    ash::Shell::Get()
-        ->screen_orientation_controller()
-        ->UnlockOrientationForWindow(web_contents->GetNativeView());
-  }
+  ash::Shell::Get()
+      ->screen_orientation_controller()
+      ->UnlockOrientationForWindow(web_contents->GetNativeView());
 }
diff --git a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h
index 61ee5ac1..e8b79b40 100644
--- a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_UI_ASH_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_
 #define CHROME_BROWSER_UI_ASH_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_
 
-#include "ash/public/interfaces/ash_window_manager.mojom.h"
 #include "content/public/browser/screen_orientation_delegate.h"
 
 // Chrome OS implementation for screen orientation JS api.
@@ -23,8 +22,6 @@
   bool ScreenOrientationProviderSupported() override;
   void Unlock(content::WebContents* web_contents) override;
 
-  ash::mojom::AshWindowManagerAssociatedPtr ash_window_manager_;
-
   DISALLOW_COPY_AND_ASSIGN(ScreenOrientationDelegateChromeos);
 };
 
diff --git a/chrome/browser/ui/ash/shortcut_viewer_browsertest.cc b/chrome/browser/ui/ash/shortcut_viewer_browsertest.cc
deleted file mode 100644
index 027a835..0000000
--- a/chrome/browser/ui/ash/shortcut_viewer_browsertest.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
-#include "base/command_line.h"
-#include "base/time/time.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/common/service_manager_connection.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/ws/common/switches.h"
-#include "services/ws/public/mojom/constants.mojom.h"
-#include "services/ws/public/mojom/window_server_test.mojom-test-utils.h"
-#include "services/ws/public/mojom/window_server_test.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/compositor/compositor_switches.h"
-
-class ShortcutViewerBrowserTest : public InProcessBrowserTest {
- public:
-  ShortcutViewerBrowserTest() = default;
-  ~ShortcutViewerBrowserTest() override = default;
-
-  // InProcessBrowserTest:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitch(ws::switches::kUseTestConfig);
-    // This test ensures a paint happens, which requires pixel output.
-    command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ShortcutViewerBrowserTest);
-};
-
-IN_PROC_BROWSER_TEST_F(ShortcutViewerBrowserTest, Paints) {
-  // Start up shortcut_viewer.
-  service_manager::Connector* connector =
-      content::ServiceManagerConnection::GetForProcess()->GetConnector();
-  shortcut_viewer::mojom::ShortcutViewerPtr shortcut_viewer;
-  connector->BindInterface(service_manager::ServiceFilter::ByName(
-                               shortcut_viewer::mojom::kServiceName),
-                           mojo::MakeRequest(&shortcut_viewer));
-  shortcut_viewer->Toggle(base::TimeTicks::Now());
-
-  // Connect to WindowService and verify shortcut_viewer painted.
-  ws::mojom::WindowServerTestPtr test_interface;
-  connector->BindInterface(
-      service_manager::ServiceFilter::ByName(ws::mojom::kServiceName),
-      mojo::MakeRequest(&test_interface));
-
-  bool success = false;
-  ws::mojom::WindowServerTestAsyncWaiter wait_for(test_interface.get());
-  wait_for.EnsureClientHasDrawnWindow(shortcut_viewer::mojom::kServiceName,
-                                      &success);
-  EXPECT_TRUE(success);
-}
diff --git a/chrome/browser/ui/cocoa/notifications/BUILD.gn b/chrome/browser/ui/cocoa/notifications/BUILD.gn
index f55cf0c..0f07a25 100644
--- a/chrome/browser/ui/cocoa/notifications/BUILD.gn
+++ b/chrome/browser/ui/cocoa/notifications/BUILD.gn
@@ -2,8 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/util/branding.gni")
 import("//build/config/mac/rules.gni")
+import("//build/util/branding.gni")
 
 mac_app_bundle("alert_notification_xpc_service") {
   output_name = "AlertNotificationService"
@@ -24,7 +24,7 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//third_party/crashpad/crashpad/client",
   ]
 
@@ -60,6 +60,6 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index e2c57b0..bba98f2 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -743,8 +743,8 @@
   EXPECT_FALSE(bubble_content.title.empty());
   ASSERT_EQ(0U, bubble_content.list_items.size());
   EXPECT_EQ(0U, bubble_content.radio_group.radio_items.size());
-  EXPECT_FALSE(bubble_content.custom_link.empty());
-  EXPECT_TRUE(bubble_content.custom_link_enabled);
+  EXPECT_FALSE(bubble_content.custom_link_enabled);
+  EXPECT_TRUE(bubble_content.custom_link.empty());
   EXPECT_FALSE(bubble_content.manage_text.empty());
   EXPECT_TRUE(bubble_content.show_learn_more);
 }
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 74266986..0cc5dd7 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -328,7 +328,7 @@
 #if BUILDFLAG(ENABLE_PLUGINS)
   setting = content_settings->GetContentSetting(
       url(), url(), CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
-  EXPECT_EQ(setting, CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
+  EXPECT_EQ(setting, CONTENT_SETTING_BLOCK);
 #endif
   setting = content_settings->GetContentSetting(
       url(), url(), CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string());
diff --git a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
index 6dd7cd9..bca008eb 100644
--- a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
+++ b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
@@ -94,11 +94,12 @@
 }
 
 views::View* InvertBubbleView::CreateExtraView() {
-  views::ImageButton* learn_more = views::CreateVectorImageButton(this);
-  views::SetImageFromVectorIcon(learn_more, vector_icons::kHelpOutlineIcon);
+  auto learn_more = views::CreateVectorImageButton(this);
+  views::SetImageFromVectorIcon(learn_more.get(),
+                                vector_icons::kHelpOutlineIcon);
   learn_more->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
   learn_more->set_tag(kLearnMoreButton);
-  return learn_more;
+  return learn_more.release();
 }
 
 int InvertBubbleView::GetDialogButtons() const {
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
index 96f6bee..2f45d85 100644
--- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
+++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -176,13 +176,15 @@
             IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS),
         views::style::CONTEXT_LABEL, ChromeTextStyle::STYLE_RED));
 
-    delete_card_from_local_button_ = views::CreateVectorImageButton(listener);
-    views::SetImageFromVectorIcon(delete_card_from_local_button_,
+    auto delete_card_from_local_button =
+        views::CreateVectorImageButton(listener);
+    views::SetImageFromVectorIcon(delete_card_from_local_button.get(),
                                   kTrashCanIcon);
-    delete_card_from_local_button_->SetTooltipText(l10n_util::GetStringUTF16(
+    delete_card_from_local_button->SetTooltipText(l10n_util::GetStringUTF16(
         IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP));
-    migratable_card_description_view->AddChildView(
-        delete_card_from_local_button_);
+    delete_card_from_local_button_ =
+        migratable_card_description_view->AddChildView(
+            std::move(delete_card_from_local_button));
   }
 
   return migratable_card_description_view;
diff --git a/chrome/browser/ui/views/confirm_bubble_views.cc b/chrome/browser/ui/views/confirm_bubble_views.cc
index e1187daa2..8a28dfa 100644
--- a/chrome/browser/ui/views/confirm_bubble_views.cc
+++ b/chrome/browser/ui/views/confirm_bubble_views.cc
@@ -45,12 +45,6 @@
   layout->StartRow(views::GridLayout::kFixedSize, 0);
   layout->AddView(label);
 
-  // Initialize the help button.
-  help_button_ = CreateVectorImageButton(this);
-  help_button_->SetFocusForPlatform();
-  help_button_->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-  SetImageFromVectorIcon(help_button_, vector_icons::kHelpOutlineIcon);
-
   chrome::RecordDialogCreation(chrome::DialogIdentifier::CONFIRM_BUBBLE);
 }
 
@@ -83,6 +77,11 @@
 }
 
 views::View* ConfirmBubbleViews::CreateExtraView() {
+  auto help_button = CreateVectorImageButton(this);
+  help_button->SetFocusForPlatform();
+  help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+  help_button_ = help_button.release();
+  SetImageFromVectorIcon(help_button_, vector_icons::kHelpOutlineIcon);
   return help_button_;
 }
 
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
index e8f817d..34931765 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -545,15 +545,16 @@
   DCHECK(content_setting_bubble_model_);
   const auto& bubble_content = content_setting_bubble_model_->bubble_content();
   const auto* layout = ChromeLayoutProvider::Get();
-  std::vector<View*> extra_views;
+  std::vector<std::unique_ptr<views::View>> extra_views;
   // Optionally add a help icon if the view wants to link to a help page.
   if (bubble_content.show_learn_more) {
-    learn_more_button_ = views::CreateVectorImageButton(this);
-    learn_more_button_->SetFocusForPlatform();
-    learn_more_button_->SetTooltipText(
+    auto learn_more_button = views::CreateVectorImageButton(this);
+    learn_more_button->SetFocusForPlatform();
+    learn_more_button->SetTooltipText(
         l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+    learn_more_button_ = learn_more_button.get();
     StyleLearnMoreButton(GetNativeTheme());
-    extra_views.push_back(learn_more_button_);
+    extra_views.push_back(std::move(learn_more_button));
   }
   // Optionally add a "Manage" button if the view wants to use a button to
   // invoke a separate management UI related to the dialog content.
@@ -566,18 +567,18 @@
     manage_button_->SetMinSize(gfx::Size(
         layout->GetDistanceMetric(views::DISTANCE_DIALOG_BUTTON_MINIMUM_WIDTH),
         0));
-    extra_views.push_back(manage_button_);
+    extra_views.push_back(base::WrapUnique(manage_button_));
   }
   if (extra_views.empty())
     return nullptr;
   if (extra_views.size() == 1)
-    return extra_views.front();
+    return extra_views.front().release();
   views::View* container = new views::View();
   container->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal, gfx::Insets(),
       layout->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL)));
-  for (auto* extra_view : extra_views)
-    container->AddChildView(extra_view);
+  for (auto& extra_view : extra_views)
+    container->AddChildView(std::move(extra_view));
   return container;
 }
 
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc
index f2bd4f6..8f681ec5 100644
--- a/chrome/browser/ui/views/device_chooser_content_view.cc
+++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -314,25 +314,28 @@
 }
 
 std::unique_ptr<views::View> DeviceChooserContentView::CreateExtraView() {
-  std::vector<views::View*> extra_views;
+  std::vector<std::unique_ptr<views::View>> extra_views;
   if (chooser_controller_->ShouldShowHelpButton()) {
-    views::ImageButton* help_button = views::CreateVectorImageButton(this);
-    views::SetImageFromVectorIcon(help_button, vector_icons::kHelpOutlineIcon);
+    auto help_button = views::CreateVectorImageButton(this);
+    views::SetImageFromVectorIcon(help_button.get(),
+                                  vector_icons::kHelpOutlineIcon);
     help_button->SetFocusForPlatform();
     help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
     help_button->set_tag(kHelpButtonTag);
-    extra_views.push_back(help_button);
+    extra_views.push_back(std::move(help_button));
   }
 
   if (chooser_controller_->ShouldShowReScanButton()) {
-    bluetooth_status_container_ = new BluetoothStatusContainer(this);
-    extra_views.push_back(bluetooth_status_container_);
+    auto bluetooth_status_container =
+        std::make_unique<BluetoothStatusContainer>(this);
+    bluetooth_status_container_ = bluetooth_status_container.get();
+    extra_views.push_back(std::move(bluetooth_status_container));
   }
 
   if (extra_views.empty())
     return nullptr;
   if (extra_views.size() == 1)
-    return std::unique_ptr<views::View>(extra_views.at(0));
+    return std::move(extra_views.at(0));
 
   auto container = std::make_unique<views::View>();
   auto layout = std::make_unique<views::BoxLayout>(
@@ -342,8 +345,9 @@
   layout->set_cross_axis_alignment(
       views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
   container->SetLayoutManager(std::move(layout));
-  for (auto* view : extra_views)
-    container->AddChildView(view);
+
+  for (auto& view : extra_views)
+    container->AddChildView(std::move(view));
   return container;
 }
 
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 5751f73..7b76380 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -135,7 +135,6 @@
       model_(std::move(download)),
       save_button_(nullptr),
       discard_button_(nullptr),
-      dropdown_button_(views::CreateVectorImageButton(this)),
       dangerous_download_label_(nullptr),
       dangerous_download_label_sized_(false),
       creation_time_(base::Time::Now()),
@@ -163,13 +162,14 @@
   status_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   status_label_ = AddChildView(std::move(status_label));
 
-  dropdown_button_->SetAccessibleName(l10n_util::GetStringUTF16(
+  auto dropdown_button = views::CreateVectorImageButton(this);
+  dropdown_button->SetAccessibleName(l10n_util::GetStringUTF16(
       IDS_DOWNLOAD_ITEM_DROPDOWN_BUTTON_ACCESSIBLE_TEXT));
 
-  dropdown_button_->SetBorder(
+  dropdown_button->SetBorder(
       views::CreateEmptyBorder(gfx::Insets(kDropdownBorderWidth)));
-  dropdown_button_->set_has_ink_drop_action_on_click(false);
-  AddChildView(dropdown_button_);
+  dropdown_button->set_has_ink_drop_action_on_click(false);
+  dropdown_button_ = AddChildView(std::move(dropdown_button));
 
   LoadIcon();
 
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h
index 4a5dd68..c5711ad 100644
--- a/chrome/browser/ui/views/download/download_item_view.h
+++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -367,7 +367,7 @@
   views::Label* status_label_;
 
   // The drop down button.
-  views::ImageButton* dropdown_button_;
+  views::ImageButton* dropdown_button_ = nullptr;
 
   // Dangerous mode label.
   views::Label* dangerous_download_label_;
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc
index 71eba48..9865cc2 100644
--- a/chrome/browser/ui/views/download/download_shelf_view.cc
+++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -64,8 +64,6 @@
     : browser_(browser),
       new_item_animation_(this),
       shelf_animation_(this),
-      show_all_view_(nullptr),
-      close_button_(views::CreateVectorImageButton(this)),
       parent_(parent),
       mouse_watcher_(
           std::make_unique<views::MouseWatcherViewHost>(this, gfx::Insets()),
@@ -78,9 +76,9 @@
       this, l10n_util::GetStringUTF16(IDS_SHOW_ALL_DOWNLOADS));
   AddChildView(show_all_view_);
 
-  close_button_->SetAccessibleName(
-      l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
-  AddChildView(close_button_);
+  auto close_button = views::CreateVectorImageButton(this);
+  close_button->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
+  close_button_ = AddChildView(std::move(close_button));
 
   accessible_alert_ = new views::View();
   AddChildView(accessible_alert_);
diff --git a/chrome/browser/ui/views/download/download_shelf_view.h b/chrome/browser/ui/views/download/download_shelf_view.h
index 7c62497..af3e3a4 100644
--- a/chrome/browser/ui/views/download/download_shelf_view.h
+++ b/chrome/browser/ui/views/download/download_shelf_view.h
@@ -168,7 +168,7 @@
   std::vector<DownloadItemView*> download_views_;
 
   // Button for showing all downloads (chrome://downloads).
-  views::MdTextButton* show_all_view_;
+  views::MdTextButton* show_all_view_ = nullptr;
 
   // Button for closing the downloads. This is contained as a child, and
   // deleted by View.
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc
index 053370f..b5f349c 100644
--- a/chrome/browser/ui/views/find_bar_view.cc
+++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -149,53 +149,51 @@
 ////////////////////////////////////////////////////////////////////////////////
 // FindBarView, public:
 
-FindBarView::FindBarView(FindBarHost* host)
-    : find_bar_host_(host),
-      find_text_(new views::Textfield),
-      match_count_text_(new MatchCountLabel()),
-      focus_forwarder_view_(new FocusForwarderView(find_text_)),
-      separator_(new views::Separator()),
-      find_previous_button_(views::CreateVectorImageButton(this)),
-      find_next_button_(views::CreateVectorImageButton(this)),
-      close_button_(views::CreateVectorImageButton(this)) {
-  find_text_->set_id(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
-  find_text_->SetDefaultWidthInChars(kDefaultCharWidth);
-  find_text_->SetMinimumWidthInChars(kMinimumCharWidth);
-  find_text_->set_controller(this);
-  find_text_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FIND));
-  find_text_->SetTextInputFlags(ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF);
-  AddChildView(find_text_);
+FindBarView::FindBarView(FindBarHost* host) : find_bar_host_(host) {
+  auto find_text = std::make_unique<views::Textfield>();
+  find_text->set_id(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
+  find_text->SetDefaultWidthInChars(kDefaultCharWidth);
+  find_text->SetMinimumWidthInChars(kMinimumCharWidth);
+  find_text->set_controller(this);
+  find_text->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FIND));
+  find_text->SetTextInputFlags(ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF);
+  find_text_ = AddChildView(std::move(find_text));
 
-  match_count_text_->SetEventTargeter(
+  auto match_count_text = std::make_unique<MatchCountLabel>();
+  match_count_text->SetEventTargeter(
       std::make_unique<views::ViewTargeter>(this));
-  AddChildView(match_count_text_);
+  match_count_text_ = AddChildView(std::move(match_count_text));
 
-  AddChildView(separator_);
+  separator_ = AddChildView(std::make_unique<views::Separator>());
 
-  find_previous_button_->set_id(VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON);
-  find_previous_button_->SetFocusForPlatform();
-  find_previous_button_->SetTooltipText(
+  auto find_previous_button = views::CreateVectorImageButton(this);
+  find_previous_button->set_id(VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON);
+  find_previous_button->SetFocusForPlatform();
+  find_previous_button->SetTooltipText(
       l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP));
-  find_previous_button_->SetAccessibleName(
+  find_previous_button->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_ACCNAME_PREVIOUS));
-  AddChildView(find_previous_button_);
+  find_previous_button_ = AddChildView(std::move(find_previous_button));
 
-  find_next_button_->set_id(VIEW_ID_FIND_IN_PAGE_NEXT_BUTTON);
-  find_next_button_->SetFocusForPlatform();
-  find_next_button_->SetTooltipText(
+  auto find_next_button = views::CreateVectorImageButton(this);
+  find_next_button->set_id(VIEW_ID_FIND_IN_PAGE_NEXT_BUTTON);
+  find_next_button->SetFocusForPlatform();
+  find_next_button->SetTooltipText(
       l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_NEXT_TOOLTIP));
-  find_next_button_->SetAccessibleName(
+  find_next_button->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_ACCNAME_NEXT));
-  AddChildView(find_next_button_);
+  find_next_button_ = AddChildView(std::move(find_next_button));
 
-  close_button_->set_id(VIEW_ID_FIND_IN_PAGE_CLOSE_BUTTON);
-  close_button_->SetFocusForPlatform();
-  close_button_->SetTooltipText(
+  auto close_button = views::CreateVectorImageButton(this);
+  close_button->set_id(VIEW_ID_FIND_IN_PAGE_CLOSE_BUTTON);
+  close_button->SetFocusForPlatform();
+  close_button->SetTooltipText(
       l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP));
-  close_button_->SetAnimationDuration(0);
-  AddChildView(close_button_);
+  close_button->SetAnimationDuration(0);
+  close_button_ = AddChildView(std::move(close_button));
 
-  AddChildView(focus_forwarder_view_);
+  auto focus_forwarder_view = std::make_unique<FocusForwarderView>(find_text_);
+  focus_forwarder_view_ = AddChildView(std::move(focus_forwarder_view));
 
   EnableCanvasFlippingForRTLUI(true);
 
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index d9ab3ba..0d8d6660 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -109,19 +109,19 @@
     AddChildView(icon_);
   }
 
-  close_button_ = views::CreateVectorImageButton(this);
+  auto close_button = views::CreateVectorImageButton(this);
   // This is the wrong color, but allows the button's size to be computed
   // correctly.  We'll reset this with the correct color in OnThemeChanged().
-  views::SetImageFromVectorIcon(close_button_, vector_icons::kCloseRoundedIcon,
+  views::SetImageFromVectorIcon(close_button.get(),
+                                vector_icons::kCloseRoundedIcon,
                                 gfx::kPlaceholderColor);
-  close_button_->SetAccessibleName(
-      l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
-  close_button_->SetFocusForPlatform();
+  close_button->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
+  close_button->SetFocusForPlatform();
   gfx::Insets close_button_spacing = GetCloseButtonSpacing();
-  close_button_->SetProperty(views::kMarginsKey,
-                             new gfx::Insets(close_button_spacing.top(), 0,
-                                             close_button_spacing.bottom(), 0));
-  AddChildView(close_button_);
+  close_button->SetProperty(views::kMarginsKey,
+                            new gfx::Insets(close_button_spacing.top(), 0,
+                                            close_button_spacing.bottom(), 0));
+  close_button_ = AddChildView(std::move(close_button));
 }
 
 InfoBarView::~InfoBarView() {
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
index 4e9902e..18e5e70 100644
--- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -59,12 +59,13 @@
 #endif
 }
 
-views::ImageButton* CreateCloseButton(views::ButtonListener* listener,
-                                      SkColor color) {
-  views::ImageButton* close_button = CreateVectorImageButton(listener);
-  SetImageFromVectorIconWithColor(close_button, vector_icons::kCloseRoundedIcon,
-                                  GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
-                                  color);
+std::unique_ptr<views::ImageButton> CreateCloseButton(
+    views::ButtonListener* listener,
+    SkColor color) {
+  auto close_button = CreateVectorImageButton(listener);
+  SetImageFromVectorIconWithColor(
+      close_button.get(), vector_icons::kCloseRoundedIcon,
+      GetLayoutConstant(LOCATION_BAR_ICON_SIZE), color);
   close_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_CLOSE));
   close_button->SetBorder(views::CreateEmptyBorder(
       gfx::Insets(GetLayoutConstant(LOCATION_BAR_CHILD_INTERIOR_PADDING))));
@@ -190,8 +191,7 @@
   const gfx::FontList& font_list = views::style::GetFont(
       CONTEXT_OMNIBOX_PRIMARY, views::style::STYLE_PRIMARY);
 
-  close_button_ = CreateCloseButton(this, foreground_color);
-  AddChildView(close_button_);
+  close_button_ = AddChildView(CreateCloseButton(this, foreground_color));
 
   location_icon_view_ = new LocationIconView(font_list, this);
   AddChildView(location_icon_view_);
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 153fb78..75fc69f6 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -269,11 +269,11 @@
     AddChildView(icon_view);
   }
 
-  clear_all_button_ = views::CreateVectorImageButton(this);
-  clear_all_button_->SetTooltipText(
+  auto clear_all_button = views::CreateVectorImageButton(this);
+  clear_all_button->SetTooltipText(
       l10n_util::GetStringUTF16(IDS_OMNIBOX_CLEAR_ALL));
+  clear_all_button_ = AddChildView(std::move(clear_all_button));
   RefreshClearAllButtonIcon();
-  AddChildView(clear_all_button_);
 
   // Initialize the location entry. We do this to avoid a black flash which is
   // visible when the location entry has just been initialized.
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.cc b/chrome/browser/ui/views/page_info/chosen_object_view.cc
index b455d3b..72c88c9 100644
--- a/chrome/browser/ui/views/page_info/chosen_object_view.cc
+++ b/chrome/browser/ui/views/page_info/chosen_object_view.cc
@@ -76,7 +76,7 @@
   layout->AddView(label);
 
   // Create the delete button.
-  delete_button_ = views::CreateVectorImageButton(this);
+  delete_button_ = views::CreateVectorImageButton(this).release();
   views::SetImageFromVectorIcon(
       delete_button_, vector_icons::kCloseRoundedIcon,
       views::style::GetColor(*this, CONTEXT_BODY_TEXT_LARGE,
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.cc b/chrome/browser/ui/views/payments/payment_request_item_list.cc
index c0db5bf2c..99738405 100644
--- a/chrome/browser/ui/views/payments/payment_request_item_list.cc
+++ b/chrome/browser/ui/views/payments/payment_request_item_list.cc
@@ -104,7 +104,7 @@
     layout->AddView(extra_view.release());
 
   if (show_edit_button_) {
-    views::ImageButton* edit_button = views::CreateVectorImageButton(this);
+    auto edit_button = views::CreateVectorImageButton(this);
     const SkColor icon_color =
         color_utils::DeriveDefaultIconColor(SK_ColorBLACK);
     edit_button->SetImage(views::Button::STATE_NORMAL,
@@ -115,7 +115,7 @@
     edit_button->set_id(static_cast<int>(DialogViewID::EDIT_ITEM_BUTTON));
     edit_button->SetAccessibleName(
         l10n_util::GetStringUTF16(IDS_PAYMENTS_EDIT));
-    layout->AddView(edit_button);
+    layout->AddView(edit_button.release());
   }
 
   UpdateAccessibleName();
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc
index 1ce4ad3..5a13605 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.cc
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -218,9 +218,9 @@
   if (!show_back_arrow) {
     layout->SkipColumns(1);
   } else {
-    views::ImageButton* back_arrow = views::CreateVectorImageButton(listener);
+    auto back_arrow = views::CreateVectorImageButton(listener);
     views::SetImageFromVectorIcon(
-        back_arrow, vector_icons::kBackArrowIcon,
+        back_arrow.get(), vector_icons::kBackArrowIcon,
         color_utils::GetColorWithMaxContrast(background_color));
     constexpr int kBackArrowSize = 16;
     back_arrow->SetSize(gfx::Size(kBackArrowSize, kBackArrowSize));
@@ -229,7 +229,7 @@
         static_cast<int>(PaymentRequestCommonTags::BACK_BUTTON_TAG));
     back_arrow->set_id(static_cast<int>(DialogViewID::BACK_BUTTON));
     back_arrow->SetAccessibleName(l10n_util::GetStringUTF16(IDS_PAYMENTS_BACK));
-    layout->AddView(back_arrow);
+    layout->AddView(back_arrow.release());
   }
 
   layout->AddView(header_content_view.release());
diff --git a/chrome/browser/ui/views/profiles/badged_profile_photo.cc b/chrome/browser/ui/views/profiles/badged_profile_photo.cc
index 9cf94b9..77c1a655 100644
--- a/chrome/browser/ui/views/profiles/badged_profile_photo.cc
+++ b/chrome/browser/ui/views/profiles/badged_profile_photo.cc
@@ -17,15 +17,14 @@
 
 constexpr int kBadgeIconSize = 16;
 constexpr int kBadgeBorderWidth = 2;
-// Width/Height of the current profile photo.
-constexpr int kImageSize = 40;
 // The space between the right/bottom edge of the profile badge and the
 // right/bottom edge of the profile icon.
 constexpr int kBadgeSpacing = 4;
 // Width and Height of the badged profile photo. Doesn't include the badge
 // border to the right and to the bottom.
-constexpr int kBadgedProfilePhotoWidth = kImageSize + kBadgeSpacing;
-constexpr int kBadgedProfilePhotoHeight = kImageSize;
+constexpr int kBadgedProfilePhotoWidth =
+    BadgedProfilePhoto::kImageSize + kBadgeSpacing;
+constexpr int kBadgedProfilePhotoHeight = BadgedProfilePhoto::kImageSize;
 
 // A custom ImageView that removes the part where the badge will be placed
 // including the (transparent) border.
diff --git a/chrome/browser/ui/views/profiles/badged_profile_photo.h b/chrome/browser/ui/views/profiles/badged_profile_photo.h
index bdff3a48..5588c20e 100644
--- a/chrome/browser/ui/views/profiles/badged_profile_photo.h
+++ b/chrome/browser/ui/views/profiles/badged_profile_photo.h
@@ -28,6 +28,9 @@
 
   static const char kViewClassName[];
 
+  // Width/Height of the profile photo.
+  static constexpr int kImageSize = 40;
+
   // Constructs a View hierarchy with the gfx::ImageSkia corresponding to
   // |badge_type| positioned in the bottom-right corner of |profile_photo|. In
   // RTL mode the badge is positioned in the bottom-left corner. The profile
diff --git a/chrome/browser/ui/views/profiles/incognito_menu_view.h b/chrome/browser/ui/views/profiles/incognito_menu_view.h
index cd1aff8..9270b38 100644
--- a/chrome/browser/ui/views/profiles/incognito_menu_view.h
+++ b/chrome/browser/ui/views/profiles/incognito_menu_view.h
@@ -18,10 +18,6 @@
 
 class Browser;
 
-// TODO(https://crbug.com/934689): Separation of providing content for different
-// menus and the UI effort to view it between this class and
-// |ProfileMenuViewBase| is in progress.
-
 // This bubble view is displayed when the user clicks on the avatar button in
 // incognito mode and displays the incognito menu.
 class IncognitoMenuView : public ProfileMenuViewBase {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 4133653..d6e579e 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -53,11 +53,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/canvas_image_source.h"
 #include "ui/gfx/image/image_skia_operations.h"
-#include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/accessibility/view_accessibility.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/button/md_text_button.h"
-#include "ui/views/layout/fill_layout.h"
 
 namespace {
 
@@ -450,76 +446,31 @@
   if (error == sync_ui_util::NO_SYNC_ERROR)
     return false;
 
-  ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
-
   if (dice_enabled_) {
     AddDiceSyncErrorView(avatar_item, error, button_string_id);
     return true;
   }
 
-  // TODO(https://crbug.com/934689): Move layout management to
-  // ProfileMenuViewBase.
-  // Sets an overall horizontal layout.
-  std::unique_ptr<views::View> view = std::make_unique<views::View>();
-  auto layout = std::make_unique<views::BoxLayout>(
-      views::BoxLayout::kHorizontal, gfx::Insets(GetMenuEdgeMargin()),
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL));
-  layout->set_cross_axis_alignment(
-      views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
-  view->SetLayoutManager(std::move(layout));
-
-  // Adds the sync problem icon.
-  views::ImageView* sync_problem_icon = new views::ImageView();
+  // Create pre-dice sync error view.
+  AddMenuGroup();
+  auto sync_problem_icon = std::make_unique<views::ImageView>();
   sync_problem_icon->SetImage(gfx::CreateVectorIcon(
-      kSyncProblemIcon, GetDefaultIconSize(), gfx::kGoogleRed700));
-  view->AddChildView(sync_problem_icon);
-
-  // Adds a vertical view to organize the error title, message, and button.
-  views::View* vertical_view = new views::View();
-  const int small_vertical_spacing =
-      provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_VERTICAL_SMALL);
-  auto vertical_layout = std::make_unique<views::BoxLayout>(
-      views::BoxLayout::kVertical, gfx::Insets(), small_vertical_spacing);
-  vertical_layout->set_cross_axis_alignment(
-      views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
-  vertical_view->SetLayoutManager(std::move(vertical_layout));
-
-  // Adds the title.
-  views::Label* title_label = new views::Label(
-      l10n_util::GetStringUTF16(IDS_SYNC_ERROR_USER_MENU_TITLE));
-  title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  title_label->SetEnabledColor(gfx::kGoogleRed700);
-  vertical_view->AddChildView(title_label);
-
-  // Adds body content.
-  views::Label* content_label =
-      new views::Label(l10n_util::GetStringUTF16(content_string_id));
-  content_label->SetMultiLine(true);
-  content_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  vertical_view->AddChildView(content_label);
+      kSyncProblemIcon, BadgedProfilePhoto::kImageSize, gfx::kGoogleRed700));
+  views::Button* button = CreateAndAddTitleCard(
+      std::move(sync_problem_icon),
+      l10n_util::GetStringUTF16(IDS_SYNC_ERROR_USER_MENU_TITLE),
+      l10n_util::GetStringUTF16(content_string_id), false);
+  static_cast<HoverButton*>(button)->SetStyle(HoverButton::STYLE_ERROR);
 
   // Adds an action button if an action exists.
   if (button_string_id) {
-    // Adds a padding row between error title/content and the button.
-    auto* padding = new views::View;
-    padding->SetPreferredSize(gfx::Size(
-        0,
-        provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
-    vertical_view->AddChildView(padding);
-
-    sync_error_button_ = views::MdTextButton::CreateSecondaryUiBlueButton(
-        this, l10n_util::GetStringUTF16(button_string_id));
+    sync_error_button_ = CreateAndAddBlueButton(
+        l10n_util::GetStringUTF16(button_string_id), true /* md_style */);
     // Track the error type so that the correct action can be taken in
     // ButtonPressed().
     sync_error_button_->set_id(error);
-    vertical_view->AddChildView(sync_error_button_);
-    view->SetBorder(views::CreateEmptyBorder(0, 0, small_vertical_spacing, 0));
   }
 
-  view->AddChildView(vertical_view);
-  AddMenuGroup();
-  AddViewItem(std::move(view));
-
   return true;
 }
 
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.h b/chrome/browser/ui/views/profiles/profile_chooser_view.h
index 73be6c16..6421116c 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.h
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.h
@@ -30,9 +30,6 @@
 class DiceSigninButtonView;
 class HoverButton;
 
-// TODO(https://crbug.com/934689): Separation of providing content for different
-// menus and the UI effort to view it between this class and
-// |ProfileMenuViewBase| is in progress.
 
 // This bubble view is displayed when the user clicks on the avatar button.
 // It displays a list of profiles and allows users to switch between profiles.
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index eb46e75..a83dc56 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -228,10 +228,6 @@
   }
 }
 
-int ProfileMenuViewBase::GetMenuEdgeMargin() const {
-  return kMenuEdgeMargin;
-}
-
 void ProfileMenuViewBase::AddMenuGroup(bool add_separator) {
   if (add_separator && !menu_item_groups_.empty()) {
     DCHECK(!menu_item_groups_.back().items.empty());
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.h b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
index f8e4e4db..49b97ec 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
@@ -92,11 +92,6 @@
 
   static ProfileMenuViewBase* GetBubbleForTesting();
 
-  // Spacing between the edge of the user menu and the top/bottom or left/right
-  // of the menu items.
-  // TODO(https://crbug.com/934689): Remove after refactoring.
-  int GetMenuEdgeMargin() const;
-
  protected:
   ProfileMenuViewBase(views::Button* anchor_button,
                       const gfx::Rect& anchor_rect,
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc
index 93d6bc1..d20354f2 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -42,10 +42,9 @@
                              views::MinimumFlexSizeRule::kScaleToZero,
                              views::MaximumFlexSizeRule::kUnbounded));
 
-  auto* group_menu_button =
-      views::CreateVectorImageButton(/*listener*/ nullptr);
-  views::SetImageFromVectorIcon(group_menu_button, kBrowserToolsIcon);
-  AddChildView(group_menu_button);
+  auto group_menu_button = views::CreateVectorImageButton(/*listener*/ nullptr);
+  views::SetImageFromVectorIcon(group_menu_button.get(), kBrowserToolsIcon);
+  AddChildView(std::move(group_menu_button));
 }
 
 void TabGroupHeader::OnPaint(gfx::Canvas* canvas) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
index b8930f3..ec149b36 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -73,11 +73,12 @@
   const base::string16& text = extra_view_info->text;
   if (!text.empty()) {
     if (extra_view_info->is_learn_more) {
-      image_button_ = views::CreateVectorImageButton(this);
-      image_button_->SetFocusForPlatform();
-      image_button_->SetTooltipText(text);
-      views::SetImageFromVectorIcon(image_button_,
+      auto image_button = views::CreateVectorImageButton(this);
+      image_button->SetFocusForPlatform();
+      image_button->SetTooltipText(text);
+      views::SetImageFromVectorIcon(image_button.get(),
                                     vector_icons::kHelpOutlineIcon);
+      image_button_ = image_button.release();
       extra_view.reset(image_button_);
     } else {
       extra_view = std::make_unique<views::Label>(text);
@@ -90,8 +91,8 @@
         views::BoxLayout::kHorizontal, gfx::Insets(),
         ChromeLayoutProvider::Get()->GetDistanceMetric(
             views::DISTANCE_RELATED_CONTROL_VERTICAL)));
-    parent->AddChildView(icon.release());
-    parent->AddChildView(extra_view.release());
+    parent->AddChildView(std::move(icon));
+    parent->AddChildView(std::move(extra_view));
     return parent;
   }
 
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc
index 75dd036..ea5d2ba 100644
--- a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc
+++ b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc
@@ -109,8 +109,7 @@
   }
 
   if (model()->IsBackButtonVisible()) {
-    std::unique_ptr<views::ImageButton> back_arrow(
-        views::CreateVectorImageButton(this));
+    auto back_arrow = views::CreateVectorImageButton(this);
     back_arrow->SetFocusForPlatform();
     back_arrow->SetAccessibleName(l10n_util::GetStringUTF16(IDS_BACK_BUTTON));
 
@@ -128,8 +127,8 @@
     back_arrow->SizeToPreferredSize();
     back_arrow->SetX(dialog_insets.left());
     back_arrow->SetY(dialog_insets.top());
-    back_arrow_button_ = back_arrow.get();
-    image_with_overlays->AddChildView(back_arrow.release());
+    back_arrow_button_ =
+        image_with_overlays->AddChildView(std::move(back_arrow));
   }
 
   return image_with_overlays;
diff --git a/chrome/browser/ui/webui/app_management/app_management.mojom b/chrome/browser/ui/webui/app_management/app_management.mojom
index cfad5cba..9779a9e 100644
--- a/chrome/browser/ui/webui/app_management/app_management.mojom
+++ b/chrome/browser/ui/webui/app_management/app_management.mojom
@@ -20,6 +20,7 @@
   string? version;
   string? size;
   map<uint32, apps.mojom.Permission> permissions;
+  apps.mojom.InstallSource install_source;
 };
 
 // Extension-based apps primarily use install-time permissions that cannot be
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
index 1cbf7df..e5f72e98 100644
--- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
+++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -187,6 +187,7 @@
   app->type = update.AppType();
   app->title = update.Name();
   app->permissions = std::move(permissions);
+  app->install_source = update.InstallSource();
 
   // On other OS's, is_pinned defaults to OptionalBool::kUnknown, which is
   // used to represent the fact that there is no concept of being pinned.
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index e1f1d900..79bf88d 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -57,6 +57,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/resources/grit/webui_resources.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
 
@@ -457,6 +458,9 @@
     source->AddResourcePath(kPrintPreviewResources[i].name,
                             kPrintPreviewResources[i].value);
   }
+  // Add the subpage loader, to load subpages in non-optimized builds.
+  source->AddResourcePath("subpage_loader.html", IDR_WEBUI_HTML_SUBPAGE_LOADER);
+  source->AddResourcePath("subpage_loader.js", IDR_WEBUI_JS_SUBPAGE_LOADER);
   source->SetDefaultResource(IDR_PRINT_PREVIEW_HTML);
   SetupPrintPreviewPlugin(source);
 #endif
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
index 1e723ef8..5879756 100644
--- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -215,8 +215,8 @@
     const base::ListValue* args) {
   AllowJavascript();
 
-  std::string account_email;
-  args->GetList()[0].GetAsString(&account_email);
+  CHECK(!args->GetList().empty());
+  const std::string& account_email = args->GetList()[0].GetString();
 
   InlineLoginHandlerDialogChromeOS::Show(account_email);
 }
@@ -225,8 +225,9 @@
   AllowJavascript();
 
   const base::DictionaryValue* dictionary = nullptr;
+  CHECK(!args->GetList().empty());
   args->GetList()[0].GetAsDictionary(&dictionary);
-  DCHECK(dictionary);
+  CHECK(dictionary);
 
   const AccountId device_account_id =
       ProfileHelper::Get()
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc
index 24707cd4..a184026 100644
--- a/chrome/browser/ui/webui/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -109,6 +109,7 @@
     {CONTENT_SETTINGS_TYPE_PLUGINS_DATA, nullptr},
     {CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH, nullptr},
     {CONTENT_SETTINGS_TYPE_INTENT_PICKER_DISPLAY, nullptr},
+    {CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC, nullptr},
 };
 static_assert(base::size(kContentSettingsTypeGroupNames) ==
                   // ContentSettingsType starts at -1, so add 1 here.
diff --git a/chrome/browser/ui/webui/usb_internals/BUILD.gn b/chrome/browser/ui/webui/usb_internals/BUILD.gn
index 958fa821..ed33e76 100644
--- a/chrome/browser/ui/webui/usb_internals/BUILD.gn
+++ b/chrome/browser/ui/webui/usb_internals/BUILD.gn
@@ -10,7 +10,7 @@
   ]
 
   deps = [
-    "//device/usb/public/mojom:mojom",
+    "//device/usb/public/mojom",
     "//device/usb/public/mojom:test",
   ]
 }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn
index c382d50..2533437 100644
--- a/chrome/browser/vr/BUILD.gn
+++ b/chrome/browser/vr/BUILD.gn
@@ -413,7 +413,7 @@
     "//components/ukm/content",
     "//components/url_formatter",
     "//components/vector_icons",
-    "//content/public/browser:browser",
+    "//content/public/browser",
     "//media",
     "//net",
     "//services/metrics/public/cpp:ukm_builders",
@@ -571,7 +571,7 @@
     ":vr_ui",
     "//base/test:test_support",
     "//cc:test_support",
-    "//components/omnibox/browser:browser",
+    "//components/omnibox/browser",
     "//components/omnibox/browser:vector_icons",
     "//components/security_state/core",
     "//content/test:test_support",
@@ -700,7 +700,7 @@
       "//device/base",
       "//device/vr:vr",
       "//device/vr/buildflags:buildflags",
-      "//device/vr/public/mojom:mojom",
+      "//device/vr/public/mojom",
       "//device/vr/public/mojom:test_mojom",
       "//services/service_manager/sandbox",
     ]
@@ -738,8 +738,8 @@
       ]
 
       deps += [
-        "//components/content_settings/core/browser:browser",
-        "//third_party/openvr:openvr",
+        "//components/content_settings/core/browser",
+        "//third_party/openvr",
       ]
 
       data_deps += [ "//device/vr:openvr_mock" ]
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn
index 6842544..38d573d 100644
--- a/chrome/browser/web_applications/components/BUILD.gn
+++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -4,7 +4,9 @@
 
 source_set("components") {
   sources = [
+    "app_registrar.cc",
     "app_registrar.h",
+    "app_registrar_observer.h",
     "install_finalizer.h",
     "install_manager.cc",
     "install_manager.h",
diff --git a/chrome/browser/web_applications/components/app_registrar.cc b/chrome/browser/web_applications/components/app_registrar.cc
new file mode 100644
index 0000000..42b352d9
--- /dev/null
+++ b/chrome/browser/web_applications/components/app_registrar.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/browser/web_applications/components/app_registrar.h"
+
+#include "chrome/browser/web_applications/components/app_registrar_observer.h"
+
+namespace web_app {
+
+AppRegistrar::AppRegistrar() = default;
+
+AppRegistrar::~AppRegistrar() = default;
+
+void AppRegistrar::AddObserver(AppRegistrarObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void AppRegistrar::RemoveObserver(const AppRegistrarObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h
index 4ae6254a..610f211 100644
--- a/chrome/browser/web_applications/components/app_registrar.h
+++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -6,15 +6,22 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_H_
 
 #include "base/callback_forward.h"
+#include "base/observer_list.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 
 class GURL;
 
 namespace web_app {
 
+class AppRegistrarObserver;
+
 class AppRegistrar {
  public:
-  virtual ~AppRegistrar() = default;
+  void AddObserver(AppRegistrarObserver* observer);
+  void RemoveObserver(const AppRegistrarObserver* observer);
+
+  AppRegistrar();
+  virtual ~AppRegistrar();
 
   virtual void Init(base::OnceClosure callback) = 0;
 
@@ -45,6 +52,9 @@
   // use HasScopeUrl() to know if the app has a scope before calling this
   // method.
   virtual GURL GetScopeUrlForApp(const AppId& app_id) const = 0;
+
+ protected:
+  base::ObserverList<AppRegistrarObserver> observers_;
 };
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/components/app_registrar_observer.h b/chrome/browser/web_applications/components/app_registrar_observer.h
new file mode 100644
index 0000000..7c49fb88
--- /dev/null
+++ b/chrome/browser/web_applications/components/app_registrar_observer.h
@@ -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.
+
+#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_OBSERVER_H_
+#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_OBSERVER_H_
+
+#include "base/observer_list_types.h"
+
+class AppId;
+
+namespace web_app {
+
+class AppRegistrarObserver : public base::CheckedObserver {
+ public:
+  virtual void OnWebAppInstalled(const AppId& app_id) {}
+  virtual void OnWebAppUninstalled(const AppId& app_id) {}
+  virtual void OnAppRegistrarShutdown() {}
+};
+
+}  // namespace web_app
+
+#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_OBSERVER_H_
diff --git a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
index 596fcfa..7278055 100644
--- a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
+++ b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
@@ -8,6 +8,7 @@
 #include "chrome/common/web_application_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "url/gurl.h"
 
 namespace web_app {
 
@@ -37,10 +38,11 @@
 
   {
     blink::Manifest::FileHandler file_handler;
+    file_handler.action = GURL("http://example.com/open-files");
     blink::Manifest::FileFilter file;
     file.accept.push_back(base::UTF8ToUTF16(".png"));
     file.name = base::UTF8ToUTF16("Images");
-    file_handler.push_back(file);
+    file_handler.files.push_back(file);
     manifest.file_handler =
         base::Optional<blink::Manifest::FileHandler>(std::move(file_handler));
   }
@@ -81,10 +83,11 @@
   // Check file handlers were updated
   EXPECT_TRUE(web_app_info.file_handler.has_value());
   auto file_handler = web_app_info.file_handler.value();
-  EXPECT_EQ(1u, file_handler.size());
-  EXPECT_EQ(base::UTF8ToUTF16("Images"), file_handler[0].name);
-  EXPECT_EQ(1u, file_handler[0].accept.size());
-  EXPECT_EQ(base::UTF8ToUTF16(".png"), file_handler[0].accept[0]);
+  EXPECT_EQ(manifest.file_handler->action, file_handler.action);
+  EXPECT_EQ(1u, file_handler.files.size());
+  EXPECT_EQ(base::UTF8ToUTF16("Images"), file_handler.files[0].name);
+  EXPECT_EQ(1u, file_handler.files[0].accept.size());
+  EXPECT_EQ(base::UTF8ToUTF16(".png"), file_handler.files[0].accept[0]);
 }
 
 // Tests "scope" is only set for installable sites.
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
index 6b471583..4a6cfaa 100644
--- a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
+++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
@@ -18,7 +18,12 @@
 WEB_CONTENTS_USER_DATA_KEY_IMPL(WebAppTabHelperBase)
 
 WebAppTabHelperBase::WebAppTabHelperBase(content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents) {}
+    : content::WebContentsObserver(web_contents) {
+  auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+      Profile::FromBrowserContext(web_contents->GetBrowserContext()));
+  DCHECK(provider);
+  observer_.Add(&provider->registrar());
+}
 
 WebAppTabHelperBase::~WebAppTabHelperBase() = default;
 
@@ -77,12 +82,13 @@
     ResetAppId();
 }
 
-void WebAppTabHelperBase::OnWebAppRegistryShutdown() {
+void WebAppTabHelperBase::OnAppRegistrarShutdown() {
   ResetAppId();
 }
 
 void WebAppTabHelperBase::ResetAppId() {
   app_id_.clear();
+
   OnAssociatedAppChanged();
 }
 
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.h b/chrome/browser/web_applications/components/web_app_tab_helper_base.h
index 124b4c76..2298845 100644
--- a/chrome/browser/web_applications/components/web_app_tab_helper_base.h
+++ b/chrome/browser/web_applications/components/web_app_tab_helper_base.h
@@ -6,7 +6,10 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_
 
 #include "base/macros.h"
+#include "base/scoped_observer.h"
 #include "base/unguessable_token.h"
+#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -23,7 +26,8 @@
 // (or legacy bookmark app).
 class WebAppTabHelperBase
     : public content::WebContentsObserver,
-      public content::WebContentsUserData<WebAppTabHelperBase> {
+      public content::WebContentsUserData<WebAppTabHelperBase>,
+      AppRegistrarObserver {
  public:
   ~WebAppTabHelperBase() override;
 
@@ -62,11 +66,6 @@
   friend class content::WebContentsUserData<WebAppTabHelperBase>;
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
-  // TODO(loyso): Call these methods for new extension-independent system.
-  void OnWebAppInstalled(const AppId& installed_app_id);
-  void OnWebAppUninstalled(const AppId& uninstalled_app_id);
-  void OnWebAppRegistryShutdown();
-
   // Clone |this| tab helper (preserving a derived type).
   virtual WebAppTabHelperBase* CloneForWebContents(
       content::WebContents* web_contents) const = 0;
@@ -79,6 +78,11 @@
  private:
   friend class WebAppAudioFocusBrowserTest;
 
+  // AppRegistrarObserver:
+  void OnWebAppInstalled(const AppId& installed_app_id) override;
+  void OnWebAppUninstalled(const AppId& uninstalled_app_id) override;
+  void OnAppRegistrarShutdown() override;
+
   void ResetAppId();
 
   // Runs any logic when the associated app either changes or is removed.
@@ -100,6 +104,8 @@
   // Weak reference to audio focus group id storage.
   WebAppAudioFocusIdMap* audio_focus_id_map_ = nullptr;
 
+  ScopedObserver<AppRegistrar, AppRegistrarObserver> observer_{this};
+
   DISALLOW_COPY_AND_ASSIGN(WebAppTabHelperBase);
 };
 
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
index 90f2588..086260b7 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
+++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
@@ -9,6 +9,7 @@
 #include "base/one_shot_event.h"
 #include "chrome/browser/extensions/convert_web_app.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
 #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
@@ -21,7 +22,9 @@
 namespace extensions {
 
 BookmarkAppRegistrar::BookmarkAppRegistrar(Profile* profile)
-    : profile_(profile) {}
+    : profile_(profile) {
+  extension_observer_.Add(ExtensionRegistry::Get(profile));
+}
 
 BookmarkAppRegistrar::~BookmarkAppRegistrar() = default;
 
@@ -82,6 +85,28 @@
   return scope_url;
 }
 
+void BookmarkAppRegistrar::OnExtensionInstalled(
+    content::BrowserContext* browser_context,
+    const extensions::Extension* extension,
+    bool is_update) {
+  for (web_app::AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppInstalled(extension->id());
+}
+
+void BookmarkAppRegistrar::OnExtensionUninstalled(
+    content::BrowserContext* browser_context,
+    const extensions::Extension* extension,
+    extensions::UninstallReason reason) {
+  for (web_app::AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppUninstalled(extension->id());
+}
+
+void BookmarkAppRegistrar::OnShutdown(ExtensionRegistry* registry) {
+  for (web_app::AppRegistrarObserver& observer : observers_)
+    observer.OnAppRegistrarShutdown();
+  extension_observer_.RemoveAll();
+}
+
 const Extension* BookmarkAppRegistrar::GetExtension(
     const web_app::AppId& app_id) const {
   return ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(app_id);
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
index 5ab43a4..fd4ef15 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
+++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
@@ -6,7 +6,10 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_REGISTRAR_H_
 
 #include "base/callback_forward.h"
+#include "base/scoped_observer.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
 
 class Profile;
 
@@ -14,7 +17,8 @@
 
 class Extension;
 
-class BookmarkAppRegistrar : public web_app::AppRegistrar {
+class BookmarkAppRegistrar : public web_app::AppRegistrar,
+                             public ExtensionRegistryObserver {
  public:
   explicit BookmarkAppRegistrar(Profile* profile);
   ~BookmarkAppRegistrar() override;
@@ -28,10 +32,22 @@
   bool HasScopeUrl(const web_app::AppId& app_id) const override;
   GURL GetScopeUrlForApp(const web_app::AppId& app_id) const override;
 
+  // ExtensionRegistryObserver:
+  void OnExtensionInstalled(content::BrowserContext* browser_context,
+                            const Extension* extension,
+                            bool is_update) override;
+  void OnExtensionUninstalled(content::BrowserContext* browser_context,
+                              const Extension* extension,
+                              UninstallReason reason) override;
+  void OnShutdown(ExtensionRegistry* registry) override;
+
  private:
   const Extension* GetExtension(const web_app::AppId& app_id) const;
 
   Profile* profile_;
+
+  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+      extension_observer_{this};
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc
index 430b2c0..0f877ffa 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc
+++ b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.cc
@@ -10,6 +10,7 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
 #include "url/gurl.h"
 
@@ -17,8 +18,6 @@
 
 BookmarkAppTabHelper::BookmarkAppTabHelper(content::WebContents* web_contents)
     : WebAppTabHelperBase(web_contents) {
-  scoped_observer_.Add(
-      ExtensionRegistry::Get(web_contents->GetBrowserContext()));
 }
 
 BookmarkAppTabHelper::~BookmarkAppTabHelper() = default;
@@ -77,25 +76,6 @@
          UrlHandlers::GetUrlHandlers(app);
 }
 
-void BookmarkAppTabHelper::OnExtensionInstalled(
-    content::BrowserContext* browser_context,
-    const extensions::Extension* extension,
-    bool is_update) {
-  OnWebAppInstalled(extension->id());
-}
-
-void BookmarkAppTabHelper::OnExtensionUninstalled(
-    content::BrowserContext* browser_context,
-    const extensions::Extension* extension,
-    extensions::UninstallReason reason) {
-  OnWebAppUninstalled(extension->id());
-}
-
-void BookmarkAppTabHelper::OnShutdown(ExtensionRegistry* registry) {
-  OnWebAppRegistryShutdown();
-  scoped_observer_.RemoveAll();
-}
-
 const Extension* BookmarkAppTabHelper::GetExtension() const {
   DCHECK(!app_id().empty());
   content::BrowserContext* browser_context =
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h
index 4f5870f80..d0565df 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h
+++ b/chrome/browser/web_applications/extensions/bookmark_app_tab_helper.h
@@ -6,10 +6,7 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_TAB_HELPER_H_
 
 #include "base/macros.h"
-#include "base/scoped_observer.h"
 #include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_registry_observer.h"
 
 namespace content {
 class WebContents;
@@ -20,8 +17,7 @@
 class Extension;
 
 // Allows to associate a tab with bookmark app.
-class BookmarkAppTabHelper : public web_app::WebAppTabHelperBase,
-                             public ExtensionRegistryObserver {
+class BookmarkAppTabHelper : public web_app::WebAppTabHelperBase {
  public:
   explicit BookmarkAppTabHelper(content::WebContents* web_contents);
   ~BookmarkAppTabHelper() override;
@@ -40,24 +36,12 @@
   bool IsUserInstalled() const override;
   bool IsFromInstallButton() const override;
 
-  // ExtensionRegistryObserver:
-  void OnExtensionInstalled(content::BrowserContext* browser_context,
-                            const Extension* extension,
-                            bool is_update) override;
-  void OnExtensionUninstalled(content::BrowserContext* browser_context,
-                              const Extension* extension,
-                              UninstallReason reason) override;
-  void OnShutdown(ExtensionRegistry* registry) override;
-
  private:
   // Get a pointer from app_id_. Semantically, we use app_id_ as a weak
   // reference. It might become nullptr in unforeseen circumstances (Uninstall).
   // TODO(loyso): Provide guarantees for app_id_. crbug.com/915034
   const Extension* GetExtension() const;
 
-  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> scoped_observer_{
-      this};
-
   DISALLOW_COPY_AND_ASSIGN(BookmarkAppTabHelper);
 };
 
diff --git a/chrome/chrome_cleaner/chrome_utils/BUILD.gn b/chrome/chrome_cleaner/chrome_utils/BUILD.gn
index 35e9253..8cf961c4 100644
--- a/chrome/chrome_cleaner/chrome_utils/BUILD.gn
+++ b/chrome/chrome_cleaner/chrome_utils/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
     "//components/chrome_cleaner/public/constants:constants",
   ]
@@ -24,7 +24,7 @@
   deps = [
     ":chrome_util_lib",
     ":force_installed_extension",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/logging/proto:shared_data_proto",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/parsers/json_parser",
@@ -56,7 +56,7 @@
     "extension_file_logger.h",
   ]
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
   ]
 }
@@ -72,7 +72,7 @@
   deps = [
     ":extension_file_logger_lib",
     ":extensions_util_lib",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/parsers/json_parser",
@@ -89,6 +89,6 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
diff --git a/chrome/chrome_cleaner/components/BUILD.gn b/chrome/chrome_cleaner/components/BUILD.gn
index c3acdda..cf1765d 100644
--- a/chrome/chrome_cleaner/components/BUILD.gn
+++ b/chrome/chrome_cleaner/components/BUILD.gn
@@ -18,13 +18,13 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/chrome_utils:extension_file_logger_lib",
     "//chrome/chrome_cleaner/chrome_utils:extensions_util_lib",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:uws_id",
-    "//chrome/chrome_cleaner/http:http",
+    "//chrome/chrome_cleaner/http",
     "//chrome/chrome_cleaner/http:http_status_codes",
     "//chrome/chrome_cleaner/logging:common",
     "//chrome/chrome_cleaner/logging:scoped_timed_task_logger",
@@ -37,9 +37,9 @@
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//components/chrome_cleaner/public/constants:constants",
     "//components/crx_file",
-    "//crypto:crypto",
+    "//crypto",
     "//third_party/zlib/google:zip",
-    "//url:url",
+    "//url",
   ]
 }
 
diff --git a/chrome/chrome_cleaner/crash/BUILD.gn b/chrome/chrome_cleaner/crash/BUILD.gn
index 5fb3ebb..aa29eb6f 100644
--- a/chrome/chrome_cleaner/crash/BUILD.gn
+++ b/chrome/chrome_cleaner/crash/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//third_party/crashpad/crashpad/client:client",
   ]
 }
@@ -25,13 +25,13 @@
 
   deps = [
     ":crash_keys",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/logging:common",
     "//chrome/chrome_cleaner/os:common_os",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/settings:engine_settings_header",
-    "//chrome/chrome_cleaner/settings:settings",
     "//chrome/chrome_cleaner/settings:settings_types",
     "//third_party/crashpad/crashpad/client",
     "//third_party/crashpad/crashpad/handler",
diff --git a/chrome/chrome_cleaner/engines/broker/BUILD.gn b/chrome/chrome_cleaner/engines/broker/BUILD.gn
index 80d803c..f1cbd56 100644
--- a/chrome/chrome_cleaner/engines/broker/BUILD.gn
+++ b/chrome/chrome_cleaner/engines/broker/BUILD.gn
@@ -28,7 +28,7 @@
 
   deps = [
     ":interface_metadata_observer",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:quarantine_constants",
     "//chrome/chrome_cleaner/constants:uws_id",
@@ -82,7 +82,7 @@
     "//base",
     "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/constants:common_strings",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/common:resources_header",
     "//chrome/chrome_cleaner/os:cleaner_os",
     "//chrome/chrome_cleaner/os:common_os",
@@ -121,7 +121,7 @@
 
   deps = [
     ":interface_metadata_observer",
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -133,7 +133,7 @@
 
   deps = [
     ":interface_metadata_observer",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
   ]
 
@@ -161,7 +161,7 @@
     ":common",
     ":interface_log_service",
     ":interface_metadata_observer",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/target:common",
@@ -174,7 +174,7 @@
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/pup_data:test_uws",
     "//chrome/chrome_cleaner/settings",
-    "//chrome/chrome_cleaner/strings:strings",
+    "//chrome/chrome_cleaner/strings",
     "//chrome/chrome_cleaner/test:test_executables",
     "//chrome/chrome_cleaner/test:test_pup_data",
     "//chrome/chrome_cleaner/test:test_scoped_service_handle",
diff --git a/chrome/chrome_cleaner/engines/common/BUILD.gn b/chrome/chrome_cleaner/engines/common/BUILD.gn
index 4fed247..464dc98 100644
--- a/chrome/chrome_cleaner/engines/common/BUILD.gn
+++ b/chrome/chrome_cleaner/engines/common/BUILD.gn
@@ -56,7 +56,7 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:engine_sandbox_interface",
     "//chrome/chrome_cleaner/ipc:ipc_test_util",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
diff --git a/chrome/chrome_cleaner/engines/controllers/BUILD.gn b/chrome/chrome_cleaner/engines/controllers/BUILD.gn
index 3c129a0..84aa370 100644
--- a/chrome/chrome_cleaner/engines/controllers/BUILD.gn
+++ b/chrome/chrome_cleaner/engines/controllers/BUILD.gn
@@ -11,7 +11,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/chrome_utils:force_installed_extension",
     "//chrome/chrome_cleaner/constants:uws_id",
     "//chrome/chrome_cleaner/engines/broker:common",
@@ -27,7 +27,7 @@
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:scanner_api",
     "//chrome/chrome_cleaner/scanner:scanner_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//components/chrome_cleaner/public/constants:constants",
     "//mojo/public/cpp/system",
   ]
@@ -47,12 +47,12 @@
   deps = [
     ":engine_cleaner_lib",
     ":facade_interface_header",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/cleaner:cleaner_headers",
     "//chrome/chrome_cleaner/components:components",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:uws_id",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/ipc:chrome_prompt_ipc",
     "//chrome/chrome_cleaner/ipc:sandbox",
     "//chrome/chrome_cleaner/logging:common",
@@ -61,7 +61,7 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/scanner:scanner_api",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/settings:settings_types",
     "//chrome/chrome_cleaner/ui:cleaner_ui",
     "//components/chrome_cleaner/public/constants:constants",
@@ -86,7 +86,7 @@
     "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:shortcut_parser_api",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:reporter_scanner",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
   ]
 }
 
@@ -124,7 +124,7 @@
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/engines/broker:cleaner_sandbox_interface",
     "//chrome/chrome_cleaner/engines/broker:common",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/common:resources_header",
     "//chrome/chrome_cleaner/ipc:chrome_prompt_ipc",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -133,14 +133,14 @@
     "//chrome/chrome_cleaner/logging/proto:removal_status_proto",
     "//chrome/chrome_cleaner/os:cleaner_os",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/proto:uwe_matcher_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:force_installed_extension_scanner",
     "//chrome/chrome_cleaner/scanner:force_installed_extension_scanner",
     "//chrome/chrome_cleaner/scanner:force_installed_extension_scanner_api",
     "//chrome/chrome_cleaner/scanner:scanner_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/ui:cleaner_ui",
     "//components/chrome_cleaner/public/constants:constants",
     "//mojo/public/cpp/platform",
@@ -165,7 +165,7 @@
     ":engine_cleaner_lib",
     ":main_controller",
     ":scanner_controller",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/chrome_utils:extension_id",
     "//chrome/chrome_cleaner/components:components",
@@ -187,7 +187,7 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/os:file_remover_api",
     "//chrome/chrome_cleaner/parsers/broker:parser_sandbox_broker",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:fake_shortcut_parser",
     "//chrome/chrome_cleaner/parsers/target:parser_sandbox_target",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
@@ -196,7 +196,7 @@
     "//chrome/chrome_cleaner/scanner:force_installed_extension_scanner_api",
     "//chrome/chrome_cleaner/scanner:mock_force_installed_extension_scanner",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/test:scoped_file",
     "//chrome/chrome_cleaner/test:test_component",
     "//chrome/chrome_cleaner/test:test_extensions",
diff --git a/chrome/chrome_cleaner/engines/target/BUILD.gn b/chrome/chrome_cleaner/engines/target/BUILD.gn
index 65d26b3..beb6799 100644
--- a/chrome/chrome_cleaner/engines/target/BUILD.gn
+++ b/chrome/chrome_cleaner/engines/target/BUILD.gn
@@ -30,7 +30,7 @@
     "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/crash:crash_keys",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/common:resources_header",
     "//chrome/chrome_cleaner/interfaces:engine_sandbox_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -82,7 +82,7 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:uws_id",
     "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
@@ -100,10 +100,10 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/engines/broker:common",
     "//chrome/chrome_cleaner/engines/broker:interface_metadata_observer",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/common:resources_header",
     "//chrome/chrome_cleaner/ipc:ipc_test_util",
     "//chrome/chrome_cleaner/os:cleaner_os",
@@ -125,10 +125,10 @@
   deps = [
     ":common",
     ":test_support",
-    "//base:base",
+    "//base",
     "//base/test:test_config",
     "//base/test:test_support",
-    "//chrome/chrome_cleaner/engines/common:common",
+    "//chrome/chrome_cleaner/engines/common",
     "//chrome/chrome_cleaner/engines/common:resources_header",
     "//chrome/chrome_cleaner/ipc:ipc_test_util",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
diff --git a/chrome/chrome_cleaner/executables/BUILD.gn b/chrome/chrome_cleaner/executables/BUILD.gn
index 9400ae2..b9a7c77 100644
--- a/chrome/chrome_cleaner/executables/BUILD.gn
+++ b/chrome/chrome_cleaner/executables/BUILD.gn
@@ -36,7 +36,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/engines/broker:common",
     "//chrome/chrome_cleaner/engines/controllers:facade_interface_header",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -73,7 +73,7 @@
       ":engine_definitions",
       ":engine_target_factory",
       ":shutdown_sequence",
-      "//base:base",
+      "//base",
       "//build/win:default_exe_manifest",
       "//chrome/chrome_cleaner/constants:common_strings",
       "//chrome/chrome_cleaner/constants:version_header",
@@ -91,10 +91,10 @@
       "//chrome/chrome_cleaner/parsers/broker:parser_sandbox_broker",
       "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:sandboxed_shortcut_parser",
       "//chrome/chrome_cleaner/parsers/target:parser_sandbox_target",
+      "//chrome/chrome_cleaner/settings",
       "//chrome/chrome_cleaner/settings:default_matching_options",
       "//chrome/chrome_cleaner/settings:engine_settings_header",
       "//chrome/chrome_cleaner/settings:matching_options",
-      "//chrome/chrome_cleaner/settings:settings",
       "//chrome/chrome_cleaner/settings:settings_types",
       "//sandbox/win:sandbox",
     ]
diff --git a/chrome/chrome_cleaner/http/BUILD.gn b/chrome/chrome_cleaner/http/BUILD.gn
index 0c88093..75ea1f9 100644
--- a/chrome/chrome_cleaner/http/BUILD.gn
+++ b/chrome/chrome_cleaner/http/BUILD.gn
@@ -27,7 +27,7 @@
   libs = [ "Winhttp.lib" ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//net/traffic_annotation",
   ]
 }
@@ -45,7 +45,7 @@
 
   deps = [
     ":http",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/chrome/chrome_cleaner/ipc/BUILD.gn b/chrome/chrome_cleaner/ipc/BUILD.gn
index c4de367..5c8f0bd 100644
--- a/chrome/chrome_cleaner/ipc/BUILD.gn
+++ b/chrome/chrome_cleaner/ipc/BUILD.gn
@@ -43,12 +43,12 @@
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/crash:crashpad_lib",
     "//chrome/chrome_cleaner/os:common_os",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/settings:engine_settings_header",
-    "//chrome/chrome_cleaner/settings:settings",
     "//chrome/chrome_cleaner/settings:settings_types",
     "//components/chrome_cleaner/public/constants:constants",
     "//mojo/public/cpp/system",
-    "//sandbox:sandbox",
+    "//sandbox",
   ]
 }
 
diff --git a/chrome/chrome_cleaner/logging/BUILD.gn b/chrome/chrome_cleaner/logging/BUILD.gn
index d9048ba..e2839ce744 100644
--- a/chrome/chrome_cleaner/logging/BUILD.gn
+++ b/chrome/chrome_cleaner/logging/BUILD.gn
@@ -11,7 +11,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -36,8 +36,8 @@
   deps = [
     ":logging_definitions",
     ":scoped_timed_task_logger",
-    "//base:base",
-    "//chrome/chrome_cleaner//http:http",  # For safe_browsing_reporter
+    "//base",
+    "//chrome/chrome_cleaner//http",  # For safe_browsing_reporter
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:version_header",
     "//chrome/chrome_cleaner/http:http_status_codes",
@@ -45,11 +45,11 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/settings:engine_settings_header",
-    "//chrome/chrome_cleaner/settings:settings",
     "//chrome/chrome_cleaner/settings:settings_types",
     "//components/chrome_cleaner/public/constants:constants",
-    "//url:url",
+    "//url",
   ]
 
   public_deps = [
@@ -93,7 +93,7 @@
     ":logging_definitions",
     ":noop_logging",
     ":reporter_logging",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
   ]
 }
 
@@ -162,7 +162,7 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/strings",
     "//components/chrome_cleaner/public/constants:constants",
   ]
@@ -187,7 +187,7 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//components/chrome_cleaner/public/constants:constants",
   ]
 }
@@ -262,11 +262,11 @@
     ":mock_logging_service",
     ":reporter_logging",
     ":test_utils",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:version_header",
-    "//chrome/chrome_cleaner/http:http",
+    "//chrome/chrome_cleaner/http",
     "//chrome/chrome_cleaner/http:mock_http_agent_factory",
     "//chrome/chrome_cleaner/logging:common",
     "//chrome/chrome_cleaner/logging:scoped_timed_task_logger",
@@ -278,7 +278,7 @@
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/pup_data:test_uws",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/test:test_branding_header",
     "//chrome/chrome_cleaner/test:test_pup_data",
     "//chrome/chrome_cleaner/test:test_util",
diff --git a/chrome/chrome_cleaner/os/BUILD.gn b/chrome/chrome_cleaner/os/BUILD.gn
index c3d68acc..b9cc064 100644
--- a/chrome/chrome_cleaner/os/BUILD.gn
+++ b/chrome/chrome_cleaner/os/BUILD.gn
@@ -53,7 +53,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:version_header",
     "//chrome/chrome_cleaner/proto:file_digest_proto",
@@ -62,7 +62,7 @@
 
     # For file_path_sanitization
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
-    "//crypto:crypto",
+    "//crypto",
   ]
 
   libs = [
@@ -102,7 +102,7 @@
   deps = [
     ":common_os",
     ":file_remover_api",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:quarantine_constants",
     "//chrome/chrome_cleaner/constants:version_header",
@@ -147,7 +147,7 @@
     ":cleaner_os",
     ":common_os",
     ":file_remover_api",
-    "//base:base",
+    "//base",
     "//base/test:test_config",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/constants:common_strings",
diff --git a/chrome/chrome_cleaner/parsers/broker/BUILD.gn b/chrome/chrome_cleaner/parsers/broker/BUILD.gn
index 0f7dd752a..d2a2b79ff 100644
--- a/chrome/chrome_cleaner/parsers/broker/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/broker/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -29,12 +29,12 @@
   ]
   deps = [
     ":parser_sandbox_broker",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/parsers/json_parser:json_splicer",
     "//chrome/chrome_cleaner/parsers/shortcut_parser:sandboxed_lnk_parser_test_util",
     "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:sandboxed_shortcut_parser",
diff --git a/chrome/chrome_cleaner/parsers/json_parser/BUILD.gn b/chrome/chrome_cleaner/parsers/json_parser/BUILD.gn
index 0d9420db..56f989fd 100644
--- a/chrome/chrome_cleaner/parsers/json_parser/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/json_parser/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -23,7 +23,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -47,7 +47,7 @@
   deps = [
     ":json_parser",
     ":json_splicer",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
diff --git a/chrome/chrome_cleaner/parsers/parser_utils/BUILD.gn b/chrome/chrome_cleaner/parsers/parser_utils/BUILD.gn
index 788ed45..a352e7e 100644
--- a/chrome/chrome_cleaner/parsers/parser_utils/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/parser_utils/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -20,9 +20,9 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
-    "//url:url",
+    "//url",
   ]
 }
 
@@ -33,7 +33,7 @@
   ]
   deps = [
     ":command_line_arguments_sanitizer",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/BUILD.gn b/chrome/chrome_cleaner/parsers/shortcut_parser/BUILD.gn
index 62eae8d..6248cc5 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/parsers/shortcut_parser/target:lnk_parser",
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/broker/BUILD.gn b/chrome/chrome_cleaner/parsers/shortcut_parser/broker/BUILD.gn
index 8e0d4b1..cb1077dc 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/broker/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/broker/BUILD.gn
@@ -8,7 +8,7 @@
     "shortcut_parser_api.h",
   ]
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/os:common_os",
   ]
@@ -22,7 +22,7 @@
 
   deps = [
     ":shortcut_parser_api",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
     "//chrome/chrome_cleaner/os:common_os",
@@ -39,7 +39,7 @@
   ]
   deps = [
     ":shortcut_parser_api",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//testing/gmock",
   ]
@@ -53,13 +53,13 @@
   ]
   deps = [
     ":sandboxed_shortcut_parser",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/parsers/broker:parser_sandbox_broker",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/parsers/json_parser:json_splicer",
     "//chrome/chrome_cleaner/parsers/shortcut_parser:sandboxed_lnk_parser_test_util",
     "//chrome/chrome_cleaner/parsers/shortcut_parser/target:lnk_parser",
diff --git a/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn b/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
index f2bc35d..cd2c923 100644
--- a/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/shortcut_parser/target/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
   ]
 }
@@ -23,7 +23,7 @@
 
   deps = [
     ":lnk_parser",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/test:test_util",
     "//testing/gtest",
diff --git a/chrome/chrome_cleaner/parsers/target/BUILD.gn b/chrome/chrome_cleaner/parsers/target/BUILD.gn
index d2ff2e2b..f96292b 100644
--- a/chrome/chrome_cleaner/parsers/target/BUILD.gn
+++ b/chrome/chrome_cleaner/parsers/target/BUILD.gn
@@ -11,7 +11,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -33,12 +33,12 @@
   ]
   deps = [
     ":parser_sandbox_target",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/interfaces:parser_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/parsers/json_parser:json_splicer",
     "//chrome/chrome_cleaner/parsers/shortcut_parser:sandboxed_lnk_parser_test_util",
     "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:sandboxed_shortcut_parser",
diff --git a/chrome/chrome_cleaner/pup_data/BUILD.gn b/chrome/chrome_cleaner/pup_data/BUILD.gn
index 9b0a9bbe..6c03437 100644
--- a/chrome/chrome_cleaner/pup_data/BUILD.gn
+++ b/chrome/chrome_cleaner/pup_data/BUILD.gn
@@ -15,7 +15,7 @@
 
   deps = [
     ":test_uws",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/chrome_utils:force_installed_extension",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
@@ -36,7 +36,7 @@
 
   deps = [
     ":pup_data_base",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:uws_id",
     "//chrome/chrome_cleaner/os:cleaner_os",
     "//chrome/chrome_cleaner/os:common_os",
@@ -85,7 +85,7 @@
     ":cleaner_pup_util",
     ":dynamic_pup",
     ":pup_data_base",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
diff --git a/chrome/chrome_cleaner/scanner/BUILD.gn b/chrome/chrome_cleaner/scanner/BUILD.gn
index 5337205..560cf575 100644
--- a/chrome/chrome_cleaner/scanner/BUILD.gn
+++ b/chrome/chrome_cleaner/scanner/BUILD.gn
@@ -8,7 +8,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -19,12 +19,12 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/strings",
   ]
 }
@@ -73,7 +73,7 @@
     "//chrome/chrome_cleaner/parsers/shortcut_parser/broker:shortcut_parser_api",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//components/chrome_cleaner/public/constants:constants",
     "//third_party/crashpad/crashpad/client",
     "//third_party/crashpad/crashpad/util",
@@ -94,7 +94,7 @@
     ":force_installed_extension_scanner_api",
     ":matcher_util",
     ":signature_matcher",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib",
     "//chrome/chrome_cleaner/chrome_utils:extension_id",
@@ -103,7 +103,7 @@
     "//chrome/chrome_cleaner/logging:mock_logging_service",
     "//chrome/chrome_cleaner/logging/proto:shared_data_proto",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:test_uws",
     "//chrome/chrome_cleaner/strings",
@@ -126,7 +126,7 @@
 
   deps = [
     "//chrome/chrome_cleaner/chrome_utils:force_installed_extension",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/proto:uwe_matcher_proto",
   ]
 }
@@ -143,7 +143,7 @@
     "//chrome/chrome_cleaner/chrome_utils:extensions_util_lib",
     "//chrome/chrome_cleaner/chrome_utils:force_installed_extension",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/proto:uwe_matcher_proto",
   ]
 }
@@ -162,7 +162,7 @@
     "//chrome/chrome_cleaner/chrome_utils:extensions_util_lib",
     "//chrome/chrome_cleaner/chrome_utils:force_installed_extension",
     "//chrome/chrome_cleaner/os:common_os",
-    "//chrome/chrome_cleaner/parsers/json_parser:json_parser",
+    "//chrome/chrome_cleaner/parsers/json_parser",
     "//chrome/chrome_cleaner/proto:uwe_matcher_proto",
     "//testing/gmock",
   ]
diff --git a/chrome/chrome_cleaner/settings/BUILD.gn b/chrome/chrome_cleaner/settings/BUILD.gn
index eb21429..572bb7a 100644
--- a/chrome/chrome_cleaner/settings/BUILD.gn
+++ b/chrome/chrome_cleaner/settings/BUILD.gn
@@ -37,7 +37,7 @@
 
   deps = [
     ":settings_types",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//components/chrome_cleaner/public/constants:constants",
   ]
@@ -124,7 +124,7 @@
     ":engine_settings_header",
     ":settings",
     ":settings_definitions",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/test:test_util",
diff --git a/chrome/chrome_cleaner/strings/BUILD.gn b/chrome/chrome_cleaner/strings/BUILD.gn
index ae9f3e6..ba3e12dd 100644
--- a/chrome/chrome_cleaner/strings/BUILD.gn
+++ b/chrome/chrome_cleaner/strings/BUILD.gn
@@ -10,7 +10,7 @@
     "string_util.h",
   ]
   deps = [
-    "//base:base",
+    "//base",
     "//base:i18n",
   ]
 }
@@ -25,7 +25,7 @@
 
   deps = [
     ":strings",
-    "//base:base",
+    "//base",
   ]
 }
 
diff --git a/chrome/chrome_cleaner/test/BUILD.gn b/chrome/chrome_cleaner/test/BUILD.gn
index 487c124..53f88a2 100644
--- a/chrome/chrome_cleaner/test/BUILD.gn
+++ b/chrome/chrome_cleaner/test/BUILD.gn
@@ -23,7 +23,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
   ]
 }
 
@@ -67,7 +67,7 @@
   deps = [
     ":test_strings",
     ":test_util",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/os:common_os",
   ]
@@ -80,7 +80,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/os:common_os",
   ]
 }
@@ -94,7 +94,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
   ]
@@ -172,7 +172,7 @@
     ":test_pup_data",
     ":test_strings",
     ":test_uws_catalog",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/os:cleaner_os",
@@ -181,7 +181,7 @@
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
     "//chrome/chrome_cleaner/scanner:matcher_util",
     "//chrome/chrome_cleaner/scanner:signature_matcher_api",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//chrome/chrome_cleaner/strings",
     "//components/chrome_cleaner/public/constants:constants",
     "//sandbox/win:sandbox",
@@ -232,7 +232,7 @@
   deps = [
     ":test_strings",
     ":test_util",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//build/win:default_exe_manifest",
     "//chrome/chrome_cleaner:other_executable_definitions",
@@ -250,7 +250,7 @@
 
   deps = [
     ":test_strings",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//build/win:default_exe_manifest",
   ]
diff --git a/chrome/chrome_cleaner/ui/BUILD.gn b/chrome/chrome_cleaner/ui/BUILD.gn
index 39629ae..bceece3 100644
--- a/chrome/chrome_cleaner/ui/BUILD.gn
+++ b/chrome/chrome_cleaner/ui/BUILD.gn
@@ -19,7 +19,7 @@
     "//chrome/chrome_cleaner/os:common_os",
     "//chrome/chrome_cleaner/pup_data:cleaner_pup_util",
     "//chrome/chrome_cleaner/pup_data:pup_data_base",
-    "//chrome/chrome_cleaner/settings:settings",
+    "//chrome/chrome_cleaner/settings",
     "//components/chrome_cleaner/public/constants:constants",
     "//components/chrome_cleaner/public/interfaces:interfaces",
   ]
@@ -37,7 +37,7 @@
 
   deps = [
     ":cleaner_ui",
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:uws_id",
     "//chrome/chrome_cleaner/ipc:mock_chrome_prompt_ipc",
     "//chrome/chrome_cleaner/test:test_pup_data",
diff --git a/chrome/chrome_cleaner/zip_archiver/BUILD.gn b/chrome/chrome_cleaner/zip_archiver/BUILD.gn
index f1ca219..a93570958 100644
--- a/chrome/chrome_cleaner/zip_archiver/BUILD.gn
+++ b/chrome/chrome_cleaner/zip_archiver/BUILD.gn
@@ -29,7 +29,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//testing/gtest",
     "//third_party/zlib:minizip",
   ]
diff --git a/chrome/chrome_cleaner/zip_archiver/broker/BUILD.gn b/chrome/chrome_cleaner/zip_archiver/broker/BUILD.gn
index bf41a66..b7db892 100644
--- a/chrome/chrome_cleaner/zip_archiver/broker/BUILD.gn
+++ b/chrome/chrome_cleaner/zip_archiver/broker/BUILD.gn
@@ -9,7 +9,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/interfaces:zip_archiver_interface",
     "//chrome/chrome_cleaner/ipc:mojo_task_runner",
@@ -29,7 +29,7 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/interfaces:zip_archiver_interface",
     "//chrome/chrome_cleaner/zip_archiver:test_support",
diff --git a/chrome/chrome_cleaner/zip_archiver/target/BUILD.gn b/chrome/chrome_cleaner/zip_archiver/target/BUILD.gn
index 55ac892..89ce2ec1 100644
--- a/chrome/chrome_cleaner/zip_archiver/target/BUILD.gn
+++ b/chrome/chrome_cleaner/zip_archiver/target/BUILD.gn
@@ -11,7 +11,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/chrome_cleaner/constants:common_strings",
     "//chrome/chrome_cleaner/constants:quarantine_constants",
     "//chrome/chrome_cleaner/interfaces:zip_archiver_interface",
@@ -35,7 +35,7 @@
 
   deps = [
     ":common",
-    "//base:base",
+    "//base",
     "//base/test:test_config",
     "//base/test:test_support",
     "//chrome/chrome_cleaner/constants:quarantine_constants",
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 1b2959c4..b85bfb5 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -222,7 +222,7 @@
     ":offline_page_auto_fetcher_mojom",
     ":page_load_metrics_mojom",
     ":supervised_user_commands_mojom",
-    "//base:base",
+    "//base",
     "//base:base_static",
     "//base:i18n",
     "//chrome:resources",
@@ -264,7 +264,7 @@
     "//components/translate/core/common",
     "//components/url_formatter",
     "//components/variations",
-    "//components/variations/net:net",
+    "//components/variations/net",
     "//components/visitedlink/common",
     "//content/public/common",
     "//extensions/buildflags",
@@ -395,7 +395,7 @@
       ]
 
       # This dependency is for a header used only by extensions code.
-      public_deps += [ "//ui/keyboard:keyboard" ]
+      public_deps += [ "//ui/keyboard" ]
     }
   }
 
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 9c248a1..038cd77 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -510,7 +510,7 @@
 // Show Flash deprecation warning to users who have manually enabled Flash.
 // https://crbug.com/918428
 const base::Feature kFlashDeprecationWarning{"FlashDeprecationWarning",
-                                             base::FEATURE_DISABLED_BY_DEFAULT};
+                                             base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
diff --git a/chrome/common/media_router/BUILD.gn b/chrome/common/media_router/BUILD.gn
index 1e7ac9c4..e12d028b5 100644
--- a/chrome/common/media_router/BUILD.gn
+++ b/chrome/common/media_router/BUILD.gn
@@ -4,11 +4,11 @@
 
 static_library("router") {
   public_deps = [
-    "//base:base",
+    "//base",
     "//base:i18n",
-    "//net:net",
+    "//net",
     "//third_party/icu",
-    "//url:url",
+    "//url",
   ]
 
   sources = [
@@ -54,7 +54,7 @@
 static_library("test_support") {
   testonly = true
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/test:test_support",
   ]
   public_deps = [
diff --git a/chrome/common/safe_browsing/BUILD.gn b/chrome/common/safe_browsing/BUILD.gn
index d96e5f17c..8caeff8 100644
--- a/chrome/common/safe_browsing/BUILD.gn
+++ b/chrome/common/safe_browsing/BUILD.gn
@@ -106,7 +106,7 @@
     ]
 
     deps = [
-      "//base:base",
+      "//base",
     ]
   }
 
diff --git a/chrome/common/win/BUILD.gn b/chrome/common/win/BUILD.gn
index 290ca61..434c1d74 100644
--- a/chrome/common/win/BUILD.gn
+++ b/chrome/common/win/BUILD.gn
@@ -9,7 +9,7 @@
 message_compiler("eventlog_messages") {
   visibility = [
     "//chrome/chrome_watcher:chrome_watcher",
-    "//chrome/common:common",
+    "//chrome/common",
     ":eventlog_provider",
   ]
 
diff --git a/chrome/credential_provider/gaiacp/BUILD.gn b/chrome/credential_provider/gaiacp/BUILD.gn
index b23664e..77dd53d 100644
--- a/chrome/credential_provider/gaiacp/BUILD.gn
+++ b/chrome/credential_provider/gaiacp/BUILD.gn
@@ -37,7 +37,7 @@
   ]
   deps = [
     ":string_resources",
-    "//base:base",
+    "//base",
     "//chrome/common:version_header",
     "//components/crash/core/common",
     "//components/version_info",
diff --git a/chrome/credential_provider/setup/BUILD.gn b/chrome/credential_provider/setup/BUILD.gn
index 4c7aed8..12cb384fb 100644
--- a/chrome/credential_provider/setup/BUILD.gn
+++ b/chrome/credential_provider/setup/BUILD.gn
@@ -24,7 +24,7 @@
     "setup_lib.h",
   ]
   public_deps = [
-    "//base:base",
+    "//base",
   ]
   deps = [
     ":version",
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index 04f84d2..67c0f84 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -176,7 +176,7 @@
     "//third_party/re2",
     "//third_party/widevine/cdm:buildflags",
     "//ui/surface",
-    "//v8:v8",
+    "//v8",
   ]
 
   data_deps = [
@@ -240,7 +240,7 @@
 
   if (safe_browsing_mode != 0) {
     deps += [
-      "//components/safe_browsing/common:common",
+      "//components/safe_browsing/common",
       "//components/safe_browsing/renderer",
     ]
     if (safe_browsing_mode == 1) {
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 3baed4f..7494d45 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -1717,6 +1717,22 @@
   }
 }
 
+// Tests that HasFillData() works correctly for fiiable and non-fillable fields.
+TEST_F(PasswordAutofillAgentTest, HasFillData) {
+  // Initially no fill data is available.
+  WebInputElement random_element = GetInputElementByID("random_field");
+  EXPECT_FALSE(password_autofill_agent_->HasFillData(username_element_));
+  EXPECT_FALSE(password_autofill_agent_->HasFillData(password_element_));
+  EXPECT_FALSE(password_autofill_agent_->HasFillData(random_element));
+
+  // This changes once fill data is simulated. |random_element| continue  to
+  // have no fill data, though.
+  SimulateOnFillPasswordForm(fill_data_);
+  EXPECT_TRUE(password_autofill_agent_->HasFillData(username_element_));
+  EXPECT_TRUE(password_autofill_agent_->HasFillData(password_element_));
+  EXPECT_FALSE(password_autofill_agent_->HasFillData(random_element));
+}
+
 // Tests that |FillIntoFocusedField| doesn't fill read-only text fields.
 TEST_F(PasswordAutofillAgentTest, FillIntoFocusedReadonlyTextField) {
   // Neither field should be autocompleted.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 522d236..e280b728 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -40,6 +40,7 @@
 #include "chrome/common/secure_origin_whitelist.h"
 #include "chrome/common/thread_profiler.h"
 #include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/renderer_resources.h"
@@ -1595,3 +1596,15 @@
   printing::SetAgent(user_agent);
 #endif
 }
+
+bool ChromeContentRendererClient::RequiresHtmlImports(const GURL& url) {
+  // Chrome Web UI pages are in the process of being migrated to use the HTML
+  // Imports Polyfill so that they will not require native imports. Return true
+  // for only pages that have not been updated yet. See
+  // https://crbug.com/937747.
+  bool canUsePolyfill = false;
+#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
+  canUsePolyfill = url.host() == chrome::kChromeUIPrintHost;
+#endif
+  return url.SchemeIs(content::kChromeUIScheme) && !canUsePolyfill;
+}
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 770d49a..d1d4e6f 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -211,6 +211,7 @@
                              const std::string& name) override;
   bool IsSafeRedirectTarget(const GURL& url) override;
   void DidSetUserAgent(const std::string& user_agent) override;
+  bool RequiresHtmlImports(const GURL& url) override;
 
 #if BUILDFLAG(ENABLE_PLUGINS)
   static chrome::mojom::PluginInfoHostAssociatedPtr& GetPluginInfoHost();
diff --git a/chrome/services/app_service/public/cpp/app_update.cc b/chrome/services/app_service/public/cpp/app_update.cc
index 6d07ee1..13d53cf 100644
--- a/chrome/services/app_service/public/cpp/app_update.cc
+++ b/chrome/services/app_service/public/cpp/app_update.cc
@@ -74,8 +74,8 @@
     state->permissions.clear();
     ClonePermissions(delta->permissions, &state->permissions);
   }
-  if (delta->installed_internally != apps::mojom::OptionalBool::kUnknown) {
-    state->installed_internally = delta->installed_internally;
+  if (delta->install_source != apps::mojom::InstallSource::kUnknown) {
+    state->install_source = delta->install_source;
   }
   if (delta->is_platform_app != apps::mojom::OptionalBool::kUnknown) {
     state->is_platform_app = delta->is_platform_app;
@@ -241,23 +241,35 @@
          (!state_ || (delta_->permissions != state_->permissions));
 }
 
-apps::mojom::OptionalBool AppUpdate::InstalledInternally() const {
+apps::mojom::InstallSource AppUpdate::InstallSource() const {
   if (delta_ &&
-      (delta_->installed_internally != apps::mojom::OptionalBool::kUnknown)) {
-    return delta_->installed_internally;
+      (delta_->install_source != apps::mojom::InstallSource::kUnknown)) {
+    return delta_->install_source;
   }
   if (state_) {
-    return state_->installed_internally;
+    return state_->install_source;
   }
-  return apps::mojom::OptionalBool::kUnknown;
+  return apps::mojom::InstallSource::kUnknown;
 }
 
-bool AppUpdate::InstalledInternallyChanged() const {
+bool AppUpdate::InstallSourceChanged() const {
   return delta_ &&
-         (delta_->installed_internally !=
-          apps::mojom::OptionalBool::kUnknown) &&
-         (!state_ ||
-          (delta_->installed_internally != state_->installed_internally));
+         (delta_->install_source != apps::mojom::InstallSource::kUnknown) &&
+         (!state_ || (delta_->install_source != state_->install_source));
+}
+
+apps::mojom::OptionalBool AppUpdate::InstalledInternally() const {
+  switch (InstallSource()) {
+    case apps::mojom::InstallSource::kUnknown:
+      return apps::mojom::OptionalBool::kUnknown;
+    case apps::mojom::InstallSource::kSystem:
+    case apps::mojom::InstallSource::kPolicy:
+    case apps::mojom::InstallSource::kOem:
+    case apps::mojom::InstallSource::kDefault:
+      return apps::mojom::OptionalBool::kTrue;
+    default:
+      return apps::mojom::OptionalBool::kFalse;
+  }
 }
 
 apps::mojom::OptionalBool AppUpdate::IsPlatformApp() const {
diff --git a/chrome/services/app_service/public/cpp/app_update.h b/chrome/services/app_service/public/cpp/app_update.h
index b9c422e..2428b48 100644
--- a/chrome/services/app_service/public/cpp/app_update.h
+++ b/chrome/services/app_service/public/cpp/app_update.h
@@ -82,8 +82,10 @@
   std::vector<apps::mojom::PermissionPtr> Permissions() const;
   bool PermissionsChanged() const;
 
+  apps::mojom::InstallSource InstallSource() const;
+  bool InstallSourceChanged() const;
+
   apps::mojom::OptionalBool InstalledInternally() const;
-  bool InstalledInternallyChanged() const;
 
   apps::mojom::OptionalBool IsPlatformApp() const;
   bool IsPlatformAppChanged() const;
diff --git a/chrome/services/app_service/public/cpp/app_update_unittest.cc b/chrome/services/app_service/public/cpp/app_update_unittest.cc
index 574c959a..1c42bcc 100644
--- a/chrome/services/app_service/public/cpp/app_update_unittest.cc
+++ b/chrome/services/app_service/public/cpp/app_update_unittest.cc
@@ -38,8 +38,8 @@
   std::vector<apps::mojom::PermissionPtr> expect_permissions_;
   bool expect_permissions_changed_;
 
-  apps::mojom::OptionalBool expect_installed_internally_;
-  bool expect_installed_internally_changed_;
+  apps::mojom::InstallSource expect_install_source_;
+  bool expect_install_source_changed_;
 
   apps::mojom::OptionalBool expect_is_platform_app_;
   bool expect_is_platform_app_changed_;
@@ -74,7 +74,7 @@
     expect_last_launch_time_changed_ = false;
     expect_install_time_changed_ = false;
     expect_permissions_changed_ = false;
-    expect_installed_internally_changed_ = false;
+    expect_install_source_changed_ = false;
     expect_is_platform_app_changed_ = false;
     expect_show_in_launcher_changed_ = false;
     expect_show_in_search_changed_ = false;
@@ -107,9 +107,8 @@
     EXPECT_EQ(expect_permissions_, u.Permissions());
     EXPECT_EQ(expect_permissions_changed_, u.PermissionsChanged());
 
-    EXPECT_EQ(expect_installed_internally_, u.InstalledInternally());
-    EXPECT_EQ(expect_installed_internally_changed_,
-              u.InstalledInternallyChanged());
+    EXPECT_EQ(expect_install_source_, u.InstallSource());
+    EXPECT_EQ(expect_install_source_changed_, u.InstallSourceChanged());
 
     EXPECT_EQ(expect_is_platform_app_, u.IsPlatformApp());
     EXPECT_EQ(expect_is_platform_app_changed_, u.IsPlatformAppChanged());
@@ -139,7 +138,7 @@
     expect_last_launch_time_ = base::Time();
     expect_install_time_ = base::Time();
     expect_permissions_.clear();
-    expect_installed_internally_ = apps::mojom::OptionalBool::kUnknown;
+    expect_install_source_ = apps::mojom::InstallSource::kUnknown;
     expect_is_platform_app_ = apps::mojom::OptionalBool::kUnknown;
     expect_show_in_launcher_ = apps::mojom::OptionalBool::kUnknown;
     expect_show_in_search_ = apps::mojom::OptionalBool::kUnknown;
@@ -306,19 +305,18 @@
       CheckExpects(u);
     }
 
-    // InstalledInternally tests.
-
+    // InstallSource tests.
     if (state) {
-      state->installed_internally = apps::mojom::OptionalBool::kFalse;
-      expect_installed_internally_ = apps::mojom::OptionalBool::kFalse;
-      expect_installed_internally_changed_ = false;
+      state->install_source = apps::mojom::InstallSource::kUser;
+      expect_install_source_ = apps::mojom::InstallSource::kUser;
+      expect_install_source_changed_ = false;
       CheckExpects(u);
     }
 
     if (delta) {
-      delta->installed_internally = apps::mojom::OptionalBool::kTrue;
-      expect_installed_internally_ = apps::mojom::OptionalBool::kTrue;
-      expect_installed_internally_changed_ = true;
+      delta->install_source = apps::mojom::InstallSource::kPolicy;
+      expect_install_source_ = apps::mojom::InstallSource::kPolicy;
+      expect_install_source_changed_ = true;
       CheckExpects(u);
     }
 
diff --git a/chrome/services/app_service/public/mojom/types.mojom b/chrome/services/app_service/public/mojom/types.mojom
index 19289f8..4a43e3c 100644
--- a/chrome/services/app_service/public/mojom/types.mojom
+++ b/chrome/services/app_service/public/mojom/types.mojom
@@ -30,7 +30,7 @@
   array<Permission> permissions;
 
   // Whether the app was installed by sync, policy or as a default app.
-  OptionalBool installed_internally;
+  InstallSource install_source;
 
   // Whether the app is an extensions::Extensions where is_platform_app()
   // returns true.
@@ -77,6 +77,17 @@
   kUninstalledByUser,
 };
 
+// How the app was installed.
+enum InstallSource {
+  kUnknown = 0,
+  kSystem,     // Installed with the system and is considered a part of the OS.
+  kPolicy,     // Installed by policy.
+  kOem,        // Installed by an OEM.
+  kDefault,    // Preinstalled by default, but is not considered a system app.
+  kSync,       // Installed by sync.
+  kUser,       // Installed by user action.
+};
+
 // Augments a bool to include an 'unknown' value.
 enum OptionalBool {
   kUnknown = 0,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ee684c6..8127926 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -150,7 +150,7 @@
     "//components/gcm_driver:test_support",
     "//components/gcm_driver/crypto:test_support",
     "//components/gcm_driver/instance_id:test_support",
-    "//components/history/core/test:test",
+    "//components/history/core/test",
     "//components/infobars/core",
     "//components/metrics:test_support",
     "//components/network_session_configurator/common",
@@ -1999,7 +1999,6 @@
         "../browser/ui/ash/network/networking_config_chromeos_browsertest.cc",
         "../browser/ui/ash/screen_orientation_delegate_chromeos_browsertest.cc",
         "../browser/ui/ash/shelf_browsertest.cc",
-        "../browser/ui/ash/shortcut_viewer_browsertest.cc",
         "../browser/ui/ash/system_tray_client_browsertest.cc",
         "../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc",
         "../browser/ui/ash/tab_scrubber_browsertest.cc",
@@ -2588,6 +2587,7 @@
     "../browser/background_fetch/background_fetch_permission_context_unittest.cc",
     "../browser/background_sync/background_sync_controller_impl_unittest.cc",
     "../browser/background_sync/background_sync_permission_context_unittest.cc",
+    "../browser/background_sync/periodic_background_sync_permission_context_unittest.cc",
     "../browser/banners/app_banner_settings_helper_unittest.cc",
     "../browser/bitmap_fetcher/bitmap_fetcher_service_unittest.cc",
     "../browser/bookmarks/managed_bookmark_service_unittest.cc",
@@ -4873,7 +4873,7 @@
       "//components/metrics:test_support",
       "//components/nacl/common:buildflags",
       "//components/os_crypt:test_support",
-      "//content/public/browser:browser",
+      "//content/public/browser",
       "//extensions/buildflags",
       "//skia",
       "//testing/gtest",
diff --git a/chrome/test/base/OWNERS b/chrome/test/base/OWNERS
index 0eaea86..cd977fd2 100644
--- a/chrome/test/base/OWNERS
+++ b/chrome/test/base/OWNERS
@@ -4,8 +4,9 @@
 per-file testing_browser_process.*=*
 per-file testing_profile.*=*
 
-per-file js2gtest.*=dtseng@chromium.org
 per-file javascript_browser_test.*=dtseng@chromium.org
+per-file js2gtest.*=dtseng@chromium.org
+per-file js2gtest.*=file://ui/webui/PLATFORM_OWNERS
 
 per-file *javascript*=file://ui/webui/PLATFORM_OWNERS
 per-file *web_ui*=file://ui/webui/PLATFORM_OWNERS
diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js
index 922de5c..92e729f0 100644
--- a/chrome/test/base/js2gtest.js
+++ b/chrome/test/base/js2gtest.js
@@ -407,6 +407,7 @@
       this[testFixture].prototype.isAsync + ',\n          ';
   var testShouldFail = this[testFixture].prototype.testShouldFail;
   var testPredicate = testShouldFail ? 'ASSERT_FALSE' : 'ASSERT_TRUE';
+  var loaderFile = this[testFixture].prototype.loaderFile;
   var extraLibraries = genIncludes.concat(
       this[testFixture].prototype.extraLibraries.map(includeFileToPath),
       resolveClosureModuleDeps(this[testFixture].prototype.closureModuleDeps),
@@ -522,6 +523,10 @@
     output(`
   set_use_mojo_lite_bindings();`);
   }
+  if (loaderFile) {
+    output(`
+  set_loader_file("${loaderFile}");`);
+  }
   if (testGenPreamble)
     testGenPreamble(testFixture, testFunction);
   if (browsePreload)
diff --git a/chrome/test/base/web_ui_browser_test.cc b/chrome/test/base/web_ui_browser_test.cc
index 19bbbd1..a25741b8 100644
--- a/chrome/test/base/web_ui_browser_test.cc
+++ b/chrome/test/base/web_ui_browser_test.cc
@@ -268,7 +268,19 @@
   WebUIJsInjectionReadyObserver injection_observer(
       web_contents, this, preload_test_fixture_, preload_test_name_);
   content::TestNavigationObserver navigation_observer(web_contents);
-  NavigateParams params(browser(), GURL(browse_to), ui::PAGE_TRANSITION_TYPED);
+
+  GURL browse_to_final(browse_to);
+  std::string path = browse_to.path();
+  if (!loader_file_.empty() && path.length() > 1) {
+    GURL::Replacements replace_url;
+    replace_url.SetPathStr(loader_file_);
+    // Remove the leading '/', and use file=<rest of the path> as the query.
+    std::string query = "file=" + path.substr(1);
+    replace_url.SetQueryStr(query);
+    browse_to_final = browse_to_final.ReplaceComponents(replace_url);
+  }
+
+  NavigateParams params(browser(), browse_to_final, ui::PAGE_TRANSITION_TYPED);
   params.disposition = WindowOpenDisposition::CURRENT_TAB;
 
   Navigate(&params);
@@ -358,6 +370,10 @@
   preload_test_name_ = preload_test_name;
 }
 
+void BaseWebUIBrowserTest::set_loader_file(const std::string& loader_file) {
+  loader_file_ = loader_file;
+}
+
 namespace {
 
 // DataSource for the dummy URL.  If no data source is provided then an error
diff --git a/chrome/test/base/web_ui_browser_test.h b/chrome/test/base/web_ui_browser_test.h
index d41314d..b44b7aee 100644
--- a/chrome/test/base/web_ui_browser_test.h
+++ b/chrome/test/base/web_ui_browser_test.h
@@ -107,6 +107,8 @@
   void set_preload_test_fixture(const std::string& preload_test_fixture);
   void set_preload_test_name(const std::string& preload_test_name);
 
+  void set_loader_file(const std::string& loader_file);
+
   // Enable command line flags for test.
   void SetUpCommandLine(base::CommandLine* command_line) override;
 
@@ -162,6 +164,11 @@
   std::string preload_test_fixture_;
   std::string preload_test_name_;
 
+  // When this is non-empty, this is the file to be substituted for the file in
+  // browsePreload, to load the HTML Imports polyfill and then load the real
+  // file after the polyfill is ready.
+  std::string loader_file_;
+
   // When this is non-NULL, this is The WebUI instance used for testing.
   // Otherwise the selected tab's web_ui is used.
   content::WebUI* override_selected_web_ui_;
diff --git a/chrome/test/data/banners/main.js b/chrome/test/data/banners/main.js
index da7603f..8714908b 100644
--- a/chrome/test/data/banners/main.js
+++ b/chrome/test/data/banners/main.js
@@ -16,6 +16,7 @@
   CANCEL_PROMPT_AND_NAVIGATE: 'cancel_prompt_and_navigate',
   CANCEL_PROMPT: 'cancel_prompt',
   STASH_EVENT: 'stash_event',
+  STASH_EVENT_AND_PREVENT_DEFAULT: 'stash_event_and_prevent_default',
 };
 
 const LISTENER = "listener";
@@ -74,29 +75,34 @@
 
 function addPromptListener(action) {
   window.addEventListener('beforeinstallprompt', function(e) {
-    e.preventDefault();
-
     switch (action) {
       case Action.VERIFY_APPINSTALLED_STASH_EVENT:
         stashedEvent = e;
         verifyEvents('appinstalled');
         break;
       case Action.CALL_PROMPT_DELAYED:
+        e.preventDefault();
         setTimeout(callPrompt, 0, e);
         break;
       case Action.CALL_PROMPT_IN_HANDLER:
         callPrompt(e);
         break;
       case Action.CALL_PROMPT_NO_USERCHOICE:
+        e.preventDefault();
         setTimeout(() => e.prompt(), 0);
         break;
       case Action.CANCEL_PROMPT_AND_NAVIGATE:
+        e.preventDefault();
         // Navigate the window to trigger cancellation in the renderer.
         setTimeout(function() { window.location.href = "/" }, 0);
         break;
       case Action.STASH_EVENT:
         stashedEvent = e;
         break;
+      case Action.STASH_EVENT_AND_PREVENT_DEFAULT:
+        stashedEvent = e;
+        e.preventDefault();
+        break;
     }
   });
 }
@@ -138,6 +144,10 @@
       addPromptListener(Action.STASH_EVENT);
       addClickListener(action);
       break;
+    case Action.STASH_EVENT_AND_PREVENT_DEFAULT:
+      addPromptListener(action);
+      addClickListener(Action.CALL_STASHED_PROMPT_ON_CLICK);
+      break;
     case Action.VERIFY_APPINSTALLED_STASH_EVENT:
     case Action.CALL_PROMPT_DELAYED:
     case Action.CALL_PROMPT_IN_HANDLER:
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
index 7c95c767..7ba4dee2 100644
--- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
+++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -20,15 +20,44 @@
     ];
   }
 
+  /** @override */
+  get loaderFile() {
+    return 'subpage_loader.html';
+  }
+
   // The name of the mocha suite. Should be overridden by subclasses.
   get suiteName() {
     return null;
   }
 
+  // The name of the custom element under test. Should be overridden by
+  // subclasses that are not directly loading the URL of a custom element.
+  get customElementName() {
+    const r = /chrome\:\/\/print\/([a-zA-Z-_]+)\/([a-zA-Z-_]+)\.html/;
+    const result = r.exec(this.browsePreload);
+    return 'print-preview-' + result[2].replace(/_/gi, '-');
+  }
+
   /** @param {string} testName The name of the test to run. */
   runMochaTest(testName) {
     runMochaTest(this.suiteName, testName);
   }
+
+  /** @override */
+  setUp() {
+    super.setUp();
+    suiteSetup(() => {
+      return new Promise(resolve => {
+               HTMLImports.whenReady(resolve);
+             })
+          .then(() => {
+            const customElementName = this.customElementName;
+            if (customElementName) {
+              return customElements.whenDefined(customElementName);
+            }
+          });
+    });
+  }
 };
 
 PrintPreviewAppTest = class extends PrintPreviewTest {
@@ -209,6 +238,12 @@
   get suiteName() {
     return select_behavior_test.suiteName;
   }
+
+  /** @override */
+  get customElementName() {
+    // This test is loading a behavior, not an element.
+    return null;
+  }
 };
 
 TEST_F('PrintPreviewSelectBehaviorTest', 'CallProcessSelectChange', function() {
diff --git a/chrome/test/data/webui/print_preview/select_behavior_test.js b/chrome/test/data/webui/print_preview/select_behavior_test.js
index 97d35e24..8eebf38 100644
--- a/chrome/test/data/webui/print_preview/select_behavior_test.js
+++ b/chrome/test/data/webui/print_preview/select_behavior_test.js
@@ -17,36 +17,43 @@
     let settingValue = '0';
 
     /** @override */
-    suiteSetup(function() {
-      document.body.innerHTML = `
-        <dom-module id="test-select">
-          <template>
-            <select value="{{selectedValue::change}}">
-              <option value="0" selected>0</option>
-              <option value="1">1</option>
-              <option value="2">2</option>
-            </select>
-          </template>
-        </dom-module>
-      `;
-
-      Polymer({
-        is: 'test-select',
-        behaviors: [print_preview.SelectBehavior],
-
-        onProcessSelectChange: function(value) {
-          settingValue = value;
-          this.fire('process-select-change-called', value);
-        },
-      });
-    });
-
-    /** @override */
     setup(function() {
-      PolymerTest.clearBody();
-      testSelect = document.createElement('test-select');
-      document.body.appendChild(testSelect);
-      testSelect.selectedValue = '0';
+      // In release mode tests, we need to wait for the page to actually import
+      // the select_behavior.html file, since the tests do not navigate there
+      // directly. Wait for an element that implements the behavior to be
+      // defined.
+      const whenReady = ((typeof print_preview !== 'undefined') &&
+                         !!print_preview.SelectBehavior) ?
+          Promise.resolve() :
+          customElements.whenDefined('print-preview-layout-settings');
+      return whenReady.then(() => {
+        document.body.innerHTML = `
+              <dom-module id="test-select">
+                <template>
+                  <select value="{{selectedValue::change}}">
+                    <option value="0" selected>0</option>
+                    <option value="1">1</option>
+                    <option value="2">2</option>
+                  </select>
+                </template>
+              </dom-module>
+            `;
+
+        Polymer({
+          is: 'test-select',
+          behaviors: [print_preview.SelectBehavior],
+
+          onProcessSelectChange: function(value) {
+            settingValue = value;
+            this.fire('process-select-change-called', value);
+          },
+        });
+
+        PolymerTest.clearBody();
+        testSelect = document.createElement('test-select');
+        document.body.appendChild(testSelect);
+        testSelect.selectedValue = '0';
+      });
     });
 
     // Tests that onProcessSelectChange() is called when the select value is
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index 5f6e9d9..a1a381d 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -151,8 +151,6 @@
     ]
     deps += [
       "//ash",
-      "//ash/components/shortcut_viewer:lib",
-      "//ash/components/shortcut_viewer/public/mojom",
       "//ash/components/tap_visualizer:lib",
       "//ash/components/tap_visualizer/public/mojom",
       "//chrome/services/file_util:lib",
@@ -190,7 +188,7 @@
     if (is_chromeos) {
       deps += [
         "//chrome/services/cups_ipp_parser:lib",
-        "//chrome/services/cups_ipp_parser/public/mojom:mojom",
+        "//chrome/services/cups_ipp_parser/public/mojom",
       ]
     }
   }
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS
index dfbae0f2..2f6bbda 100644
--- a/chrome/utility/DEPS
+++ b/chrome/utility/DEPS
@@ -56,8 +56,6 @@
 specific_include_rules = {
   "mash_service_factory.cc": [
     "+ash/ash_service.h",
-    "+ash/components/shortcut_viewer/public",
-    "+ash/components/shortcut_viewer/shortcut_viewer_application.h",
     "+ash/components/tap_visualizer/public",
     "+ash/components/tap_visualizer/tap_visualizer_app.h",
     "+ash/public/interfaces",
diff --git a/chrome/utility/mash_service_factory.cc b/chrome/utility/mash_service_factory.cc
index 0fabe9e7..5088cb5 100644
--- a/chrome/utility/mash_service_factory.cc
+++ b/chrome/utility/mash_service_factory.cc
@@ -7,8 +7,6 @@
 #include <memory>
 
 #include "ash/ash_service.h"
-#include "ash/components/shortcut_viewer/public/mojom/shortcut_viewer.mojom.h"
-#include "ash/components/shortcut_viewer/shortcut_viewer_application.h"
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
 #include "ash/components/tap_visualizer/tap_visualizer_app.h"
 #include "ash/public/interfaces/constants.mojom.h"
@@ -25,7 +23,7 @@
   kAsh = 0,
   kAutoclickDeprecated = 1,    // Deleted Aug 2018, https://crbug.com/876115
   kQuickLaunchDeprecated = 2,  // Deleted Feb 2019.
-  kShortcutViewer = 3,
+  kShortcutViewer = 3,         // Deleted May 2019, https://crbug.com/958073
   kTapVisualizer = 4,
   kFontDeprecated = 5,  // Font Service is not in use for mash, but run
                         // in-process in the browser
@@ -45,14 +43,6 @@
   return std::make_unique<ash::AshService>(std::move(request));
 }
 
-std::unique_ptr<service_manager::Service> CreateShortcutViewerApp(
-    service_manager::mojom::ServiceRequest request) {
-  RecordMashServiceLaunch(MashService::kShortcutViewer);
-  logging::SetLogPrefix("shortcut");
-  return std::make_unique<keyboard_shortcut_viewer::ShortcutViewerApplication>(
-      std::move(request));
-}
-
 std::unique_ptr<service_manager::Service> CreateTapVisualizerApp(
     service_manager::mojom::ServiceRequest request) {
   RecordMashServiceLaunch(MashService::kTapVisualizer);
@@ -72,11 +62,6 @@
     service_manager::mojom::ServiceRequest request) {
   if (service_name == ash::mojom::kServiceName)
     return CreateAshService(std::move(request));
-  if (service_name == shortcut_viewer::mojom::kServiceName) {
-    keyboard_shortcut_viewer::ShortcutViewerApplication ::
-        RegisterForTraceEvents();
-    return CreateShortcutViewerApp(std::move(request));
-  }
   if (service_name == tap_visualizer::mojom::kServiceName)
     return CreateTapVisualizerApp(std::move(request));
 
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 80b6c0c..c655efce 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -147,6 +147,7 @@
     "//chromeos/geolocation:unit_tests",
     "//chromeos/login/auth:unit_tests",
     "//chromeos/login/login_state:unit_tests",
+    "//chromeos/login/session:unit_tests",
     "//chromeos/network:test_support",
     "//chromeos/network:unit_tests",
     "//chromeos/services:unit_tests",
diff --git a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.html b/chromeos/components/multidevice/debug_webui/resources/proximity_auth.html
index a70c02e..6f6fa244 100644
--- a/chromeos/components/multidevice/debug_webui/resources/proximity_auth.html
+++ b/chromeos/components/multidevice/debug_webui/resources/proximity_auth.html
@@ -11,14 +11,15 @@
   <script src="webui.js"></script>
   <script src="logs.js"></script>
   <script src="proximity_auth.js"></script>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-  <script src="chrome://resources/js/time.mojom-lite.js"></script>
-  <script src="chrome://resources/js/chromeos/multidevice_types.mojom-lite.js">
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js">
   </script>
-  <script src="chrome://resources/js/chromeos/device_sync.mojom-lite.js"></script>
-  <script src="chrome://resources/js/chromeos/multidevice_setup.mojom-lite.js">
+  <script src="chrome://resources/mojo/mojo/public/mojom/base/time.mojom-lite.js">
   </script>
-  <script src="chrome://resources/js/chromeos/multidevice_setup_constants.mojom-lite.js">
+  <script src="chrome://resources/mojo/chromeos/components/multidevice/mojom/multidevice_types.mojom-lite.js">
+  </script>
+  <script src="chrome://resources/mojo/chromeos/services/device_sync/public/mojom/device_sync.mojom-lite.js">
+  </script>
+  <script src="chrome://resources/mojo/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-lite.js">
   </script>
 </head>
 
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 3a29482..8c98d08 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -20,7 +20,11 @@
 
 // Enables or disables Crostini Backup.
 const base::Feature kCrostiniBackup{"CrostiniBackup",
-                                    base::FEATURE_DISABLED_BY_DEFAULT};
+                                    base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Enables or disables Crostini GPU support.
+const base::Feature kCrostiniGpuSupport{"CrostiniGpuSupport",
+                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enables or disables Crostini support for usb mounting.
 const base::Feature kCrostiniUsbSupport{"CrostiniUsbSupport",
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index 8e5d112..18463f0 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -23,6 +23,8 @@
 extern const char kBlueZLongTermKeyBlocklistParamName[];
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCrostiniBackup;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+extern const base::Feature kCrostiniGpuSupport;
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCrostiniUsbSupport;
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 extern const base::Feature kCrostiniUsbAllowUnsupported;
diff --git a/chromeos/dbus/session_manager/session_manager_client.h b/chromeos/dbus/session_manager/session_manager_client.h
index d4e543d..381d195 100644
--- a/chromeos/dbus/session_manager/session_manager_client.h
+++ b/chromeos/dbus/session_manager/session_manager_client.h
@@ -151,7 +151,8 @@
   virtual void StartSession(
       const cryptohome::AccountIdentifier& cryptohome_id) = 0;
 
-  // Stops the current session.
+  // Stops the current session. Don't call directly unless there's no user on
+  // the device. Use SessionTerminationManager::StopSession instead.
   virtual void StopSession() = 0;
 
   // Starts the factory reset.
diff --git a/chromeos/login/session/BUILD.gn b/chromeos/login/session/BUILD.gn
new file mode 100644
index 0000000..9648cb3
--- /dev/null
+++ b/chromeos/login/session/BUILD.gn
@@ -0,0 +1,39 @@
+# 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("//testing/test.gni")
+
+assert(is_chromeos, "Non-Chrome-OS builds must not depend on //chromeos")
+
+component("session") {
+  defines = [ "IS_CHROMEOS_LOGIN_SESSION_IMPL" ]
+  deps = [
+    "//base",
+    "//chromeos/constants",
+    "//chromeos/dbus/cryptohome:cryptohome",
+    "//chromeos/dbus/cryptohome:cryptohome_proto",
+    "//chromeos/dbus/power:power",
+    "//chromeos/dbus/session_manager:session_manager",
+    "//third_party/protobuf:protobuf_lite",
+  ]
+  sources = [
+    "session_termination_manager.cc",
+    "session_termination_manager.h",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  deps = [
+    "//base",
+    "//chromeos/dbus/cryptohome:cryptohome",
+    "//chromeos/dbus/power:power",
+    "//chromeos/dbus/session_manager:session_manager",
+    "//chromeos/login/session:session",
+    "//testing/gtest",
+  ]
+  sources = [
+    "session_termination_manager_unittest.cc",
+  ]
+}
diff --git a/chromeos/login/session/session_termination_manager.cc b/chromeos/login/session/session_termination_manager.cc
new file mode 100644
index 0000000..1767d144
--- /dev/null
+++ b/chromeos/login/session/session_termination_manager.cc
@@ -0,0 +1,96 @@
+// 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/login/session/session_termination_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "chromeos/dbus/power/power_manager_client.h"
+#include "chromeos/dbus/session_manager/session_manager_client.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+namespace {
+
+SessionTerminationManager* g_instance = nullptr;
+
+}  // namespace
+
+SessionTerminationManager::SessionTerminationManager() : weak_factory_(this) {
+  DCHECK(!g_instance);
+  g_instance = this;
+}
+
+SessionTerminationManager::~SessionTerminationManager() {
+  g_instance = nullptr;
+}
+
+// static
+SessionTerminationManager* SessionTerminationManager::Get() {
+  DCHECK(g_instance);
+  return g_instance;
+}
+
+void SessionTerminationManager::StopSession() {
+  // If the device is locked to single user, it must reboot on sign out.
+  if (is_locked_to_single_user_) {
+    Reboot();
+  } else {
+    SessionManagerClient::Get()->StopSession();
+  }
+}
+
+void SessionTerminationManager::RebootIfNecessary() {
+  CryptohomeClient::Get()->WaitForServiceToBeAvailable(
+      base::BindOnce(&SessionTerminationManager::DidWaitForServiceToBeAvailable,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void SessionTerminationManager::SetDeviceLockedToSingleUser() {
+  is_locked_to_single_user_ = true;
+}
+
+void SessionTerminationManager::DidWaitForServiceToBeAvailable(
+    bool service_is_available) {
+  if (!service_is_available) {
+    LOG(ERROR) << "WaitForServiceToBeAvailable failed.";
+    return;
+  }
+  CryptohomeClient::Get()->GetTpmStatus(
+      cryptohome::GetTpmStatusRequest(),
+      base::BindOnce(&SessionTerminationManager::RebootIfNecessaryProcessReply,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void SessionTerminationManager::ProcessTpmStatusReply(
+    const base::Optional<cryptohome::BaseReply>& reply) {
+  if (!reply.has_value() || reply->has_error() ||
+      !reply->HasExtension(cryptohome::GetTpmStatusReply::reply)) {
+    LOG(ERROR) << "TPM status request failed, error: "
+               << (reply.has_value() && reply->has_error() ? reply->error()
+                                                           : 0);
+    return;
+  }
+  auto reply_proto = reply->GetExtension(cryptohome::GetTpmStatusReply::reply);
+  if (reply_proto.has_is_locked_to_single_user() &&
+      reply_proto.is_locked_to_single_user()) {
+    is_locked_to_single_user_ = true;
+  }
+}
+
+void SessionTerminationManager::Reboot() {
+  PowerManagerClient::Get()->RequestRestart(
+      power_manager::REQUEST_RESTART_OTHER, "Reboot forced by policy");
+}
+
+void SessionTerminationManager::RebootIfNecessaryProcessReply(
+    base::Optional<cryptohome::BaseReply> reply) {
+  ProcessTpmStatusReply(reply);
+  if (is_locked_to_single_user_)
+    Reboot();
+}
+
+}  // namespace chromeos
diff --git a/chromeos/login/session/session_termination_manager.h b/chromeos/login/session/session_termination_manager.h
new file mode 100644
index 0000000..3f58fc5
--- /dev/null
+++ b/chromeos/login/session/session_termination_manager.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 CHROMEOS_LOGIN_SESSION_SESSION_TERMINATION_MANAGER_H_
+#define CHROMEOS_LOGIN_SESSION_SESSION_TERMINATION_MANAGER_H_
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "chromeos/dbus/cryptohome/rpc.pb.h"
+
+namespace chromeos {
+
+// SessionTerminationManager is used to handle the session termination.
+class COMPONENT_EXPORT(CHROMEOS_LOGIN_SESSION) SessionTerminationManager {
+ public:
+  SessionTerminationManager();
+  ~SessionTerminationManager();
+
+  static SessionTerminationManager* Get();
+
+  // To be called instead of SessionManagerClient::StopSession.
+  void StopSession();
+
+  // To be called on login screen if the policy is set.
+  void RebootIfNecessary();
+
+  // To be called when the device gets locked to single user.
+  void SetDeviceLockedToSingleUser();
+
+ private:
+  void DidWaitForServiceToBeAvailable(bool service_is_available);
+  void ProcessTpmStatusReply(
+      const base::Optional<cryptohome::BaseReply>& reply);
+  void Reboot();
+  void RebootIfNecessaryProcessReply(
+      base::Optional<cryptohome::BaseReply> reply);
+
+  bool is_locked_to_single_user_ = false;
+  base::WeakPtrFactory<SessionTerminationManager> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SessionTerminationManager);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_LOGIN_SESSION_SESSION_TERMINATION_MANAGER_H_
diff --git a/chromeos/login/session/session_termination_manager_unittest.cc b/chromeos/login/session/session_termination_manager_unittest.cc
new file mode 100644
index 0000000..d065d41
--- /dev/null
+++ b/chromeos/login/session/session_termination_manager_unittest.cc
@@ -0,0 +1,51 @@
+// 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/login/session/session_termination_manager.h"
+
+#include "base/macros.h"
+#include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "chromeos/dbus/power/fake_power_manager_client.h"
+#include "chromeos/dbus/session_manager/session_manager_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+class SessionTerminationManagerTest : public testing::Test {
+ public:
+  SessionTerminationManagerTest() {
+    PowerManagerClient::InitializeFake();
+    power_client_ = FakePowerManagerClient::Get();
+    CryptohomeClient::InitializeFake();
+    SessionManagerClient::InitializeFake();
+  }
+  ~SessionTerminationManagerTest() override {
+    CryptohomeClient::Shutdown();
+    PowerManagerClient::Shutdown();
+    SessionManagerClient::Shutdown();
+  }
+
+ protected:
+  FakePowerManagerClient* power_client_;
+  SessionTerminationManager session_termination_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(SessionTerminationManagerTest);
+};
+
+// The device is not locked to single user. Check that no reboot is triggered
+// on sign out.
+TEST_F(SessionTerminationManagerTest, NoRebootTest) {
+  session_termination_manager_.StopSession();
+  EXPECT_EQ(0, power_client_->num_request_restart_calls());
+}
+
+// The device is locked to single user. Check that reboot is triggered on user
+// sign out.
+TEST_F(SessionTerminationManagerTest, RebootTest) {
+  session_termination_manager_.SetDeviceLockedToSingleUser();
+  session_termination_manager_.StopSession();
+  EXPECT_EQ(1, power_client_->num_request_restart_calls());
+}
+
+}  // namespace chromeos
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index f08d9b4..3cf86411 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -106,10 +106,7 @@
     "//components/user_prefs:user_prefs",
     "//content/public/browser:browser",
     "//content/public/common",
-    "//device/base",
     "//device/bluetooth",
-    "//device/usb",
-    "//device/usb/mojo",
     "//device/usb/public/mojom",
     "//google_apis",
     "//services/device/public/mojom",
diff --git a/components/arc/usb/DEPS b/components/arc/usb/DEPS
index 1c02ffb..272c37f0 100644
--- a/components/arc/usb/DEPS
+++ b/components/arc/usb/DEPS
@@ -1,4 +1,6 @@
 include_rules = [
-  "+device/base",
-  "+device/usb",
+  "+content/public/common/service_manager_connection.h",
+  "+device/usb/public",
+  "+services/device/public",
+  "+services/service_manager/public",
 ]
diff --git a/components/arc/usb/usb_host_bridge.cc b/components/arc/usb/usb_host_bridge.cc
index 1dcb4e3..822f4d6a 100644
--- a/components/arc/usb/usb_host_bridge.cc
+++ b/components/arc/usb/usb_host_bridge.cc
@@ -10,16 +10,16 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
+#include "base/strings/stringprintf.h"
 #include "chromeos/dbus/permission_broker/permission_broker_client.h"
 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/arc_features.h"
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/arc/usb/usb_host_ui_delegate.h"
-#include "device/base/device_client.h"
-#include "device/usb/mojo/type_converters.h"
-#include "device/usb/usb_device_handle.h"
-#include "device/usb/usb_device_linux.h"
+#include "content/public/common/service_manager_connection.h"
 #include "mojo/public/cpp/system/platform_handle.h"
+#include "services/device/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace arc {
 namespace {
@@ -68,14 +68,9 @@
   std::move(callback).Run(mojo::ScopedHandle());
 }
 
-using CheckedCallback =
-    base::RepeatingCallback<void(const std::string& guid, bool success)>;
-
-void OnGetDevicesComplete(
-    const CheckedCallback& callback,
-    const std::vector<scoped_refptr<device::UsbDevice>>& devices) {
-  for (const scoped_refptr<device::UsbDevice>& device : devices)
-    device->CheckUsbAccess(base::BindOnce(callback, device.get()->guid()));
+std::string GetDevicePath(const device::mojom::UsbDeviceInfo& device_info) {
+  return base::StringPrintf("/dev/bus/usb/%03d/%03d", device_info.bus_number,
+                            device_info.port_number);
 }
 
 }  // namespace
@@ -87,20 +82,12 @@
 
 ArcUsbHostBridge::ArcUsbHostBridge(content::BrowserContext* context,
                                    ArcBridgeService* bridge_service)
-    : arc_bridge_service_(bridge_service),
-      usb_observer_(this),
-      weak_factory_(this) {
+    : arc_bridge_service_(bridge_service) {
   arc_bridge_service_->usb_host()->SetHost(this);
   arc_bridge_service_->usb_host()->AddObserver(this);
-
-  usb_service_ = device::DeviceClient::Get()->GetUsbService();
-  if (usb_service_)
-    usb_observer_.Add(usb_service_);
 }
 
 ArcUsbHostBridge::~ArcUsbHostBridge() {
-  if (usb_service_)
-    usb_service_->RemoveObserver(this);
   arc_bridge_service_->usb_host()->RemoveObserver(this);
   arc_bridge_service_->usb_host()->SetHost(nullptr);
 }
@@ -113,45 +100,65 @@
                                          const std::string& package,
                                          bool interactive,
                                          RequestPermissionCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+
   if (guid.empty()) {
     HandleScanDeviceListRequest(package, std::move(callback));
     return;
   }
 
   VLOG(2) << "USB RequestPermission " << guid << " package " << package;
+
+  // GUIDs are unguessable so device list should be initialized when this
+  // method is being called with a valid GUID.
+  auto iter = devices_.find(guid);
+  if (iter == devices_.end()) {
+    LOG(WARNING) << "Unknown USB device " << guid;
+    std::move(callback).Run(false);
+    return;
+  }
+
   // Permission already requested.
-  if (HasPermissionForDevice(guid, package)) {
+  if (HasPermissionForDevice(*iter->second, package)) {
     std::move(callback).Run(true);
     return;
   }
 
   // The other side was just checking, fail without asking the user.
   if (!interactive) {
-    std::move(callback).Run(HasPermissionForDevice(guid, package));
+    std::move(callback).Run(false);
     return;
   }
 
+  DCHECK(ui_delegate_);
   // Ask the authorization from the user.
-  DoRequestUserAuthorization(guid, package, std::move(callback));
+  ui_delegate_->RequestUsbAccessPermission(
+      package, guid, iter->second->serial_number.value_or(base::string16()),
+      iter->second->manufacturer_name.value_or(base::string16()),
+      iter->second->product_name.value_or(base::string16()),
+      iter->second->vendor_id, iter->second->product_id, std::move(callback));
 }
 
 void ArcUsbHostBridge::OpenDevice(const std::string& guid,
                                   const base::Optional<std::string>& package,
                                   OpenDeviceCallback callback) {
-  if (!usb_service_ || !package) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+
+  if (!package) {
     std::move(callback).Run(mojo::ScopedHandle());
     return;
   }
 
-  device::UsbDeviceLinux* device =
-      static_cast<device::UsbDeviceLinux*>(usb_service_->GetDevice(guid).get());
-  if (!device) {
+  // GUIDs are unguessable so device list should be initialized when this
+  // method is being called with a valid GUID.
+  auto iter = devices_.find(guid);
+  if (iter == devices_.end()) {
     std::move(callback).Run(mojo::ScopedHandle());
     return;
   }
 
   // The RequestPermission was never done, abort.
-  if (!HasPermissionForDevice(guid, package.value())) {
+  if (!HasPermissionForDevice(*iter->second, package.value())) {
     std::move(callback).Run(mojo::ScopedHandle());
     return;
   }
@@ -159,7 +166,7 @@
   auto repeating_callback =
       base::AdaptCallbackForRepeating(std::move(callback));
   chromeos::PermissionBrokerClient::Get()->OpenPath(
-      device->device_path(),
+      GetDevicePath(*iter->second),
       base::BindOnce(&OnDeviceOpened, repeating_callback),
       base::BindOnce(&OnDeviceOpenError, repeating_callback));
 }
@@ -174,19 +181,18 @@
 
 void ArcUsbHostBridge::GetDeviceInfo(const std::string& guid,
                                      GetDeviceInfoCallback callback) {
-  if (!usb_service_) {
-    std::move(callback).Run(std::string(), nullptr);
-    return;
-  }
-  scoped_refptr<device::UsbDevice> device = usb_service_->GetDevice(guid);
-  if (!device.get()) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+
+  // GUIDs are unguessable so device list should be initialized when this
+  // method is being called with a valid GUID.
+  auto iter = devices_.find(guid);
+  if (iter == devices_.end()) {
     LOG(WARNING) << "Unknown USB device " << guid;
     std::move(callback).Run(std::string(), nullptr);
     return;
   }
 
-  device::mojom::UsbDeviceInfoPtr info =
-      device::mojom::UsbDeviceInfo::From(*device);
+  device::mojom::UsbDeviceInfoPtr info = iter->second->Clone();
   // b/69295049 the other side doesn't like optional strings.
   for (const device::mojom::UsbConfigurationInfoPtr& cfg :
        info->configurations) {
@@ -200,56 +206,33 @@
     }
   }
 
-  std::string path =
-      static_cast<device::UsbDeviceLinux*>(device.get())->device_path();
-
+  std::string path = GetDevicePath(*info);
   std::move(callback).Run(path, std::move(info));
 }
 
-// device::UsbService::Observer callbacks.
-
-void ArcUsbHostBridge::OnDeviceAdded(scoped_refptr<device::UsbDevice> device) {
-  device->CheckUsbAccess(base::BindOnce(&ArcUsbHostBridge::OnDeviceChecked,
-                                        weak_factory_.GetWeakPtr(),
-                                        device.get()->guid()));
-}
-
-void ArcUsbHostBridge::OnDeviceRemoved(
-    scoped_refptr<device::UsbDevice> device) {
-  mojom::UsbHostInstance* usb_host_instance = ARC_GET_INSTANCE_FOR_METHOD(
-      arc_bridge_service_->usb_host(), OnDeviceRemoved);
-
-  if (!usb_host_instance) {
-    VLOG(2) << "UsbInstance not ready yet";
-    return;
-  }
-
-  usb_host_instance->OnDeviceRemoved(device.get()->guid(),
-                                     GetEventReceiverPackages(device));
-
-  if (ui_delegate_)
-    ui_delegate_->DeviceRemoved(device.get()->guid());
-}
-
-// Notifies the observer that the UsbService it depends on is shutting down.
-void ArcUsbHostBridge::WillDestroyUsbService() {
-  // Disconnect.
-  arc_bridge_service_->usb_host()->SetHost(nullptr);
-}
-
 void ArcUsbHostBridge::OnConnectionReady() {
-  if (!usb_service_)
-    return;
-  // Send the (filtered) list of already existing USB devices to the other side.
-  usb_service_->GetDevices(
-      base::Bind(&OnGetDevicesComplete,
-                 base::BindRepeating(&ArcUsbHostBridge::OnDeviceChecked,
-                                     weak_factory_.GetWeakPtr())));
+  // Request UsbDeviceManagerPtr from DeviceService.
+  content::ServiceManagerConnection::GetForProcess()
+      ->GetConnector()
+      ->BindInterface(device::mojom::kServiceName,
+                      mojo::MakeRequest(&usb_manager_));
+  usb_manager_.set_connection_error_handler(
+      base::BindOnce(&ArcUsbHostBridge::Disconnect, base::Unretained(this)));
+
+  // Listen for added/removed device events.
+  DCHECK(!client_binding_);
+  device::mojom::UsbDeviceManagerClientAssociatedPtrInfo client;
+  client_binding_.Bind(mojo::MakeRequest(&client));
+  usb_manager_->EnumerateDevicesAndSetClient(
+      std::move(client), base::BindOnce(&ArcUsbHostBridge::InitDeviceList,
+                                        weak_factory_.GetWeakPtr()));
 }
 
 void ArcUsbHostBridge::OnConnectionClosed() {
   if (ui_delegate_)
     ui_delegate_->ClearPermissionRequests();
+
+  Disconnect();
 }
 
 void ArcUsbHostBridge::Shutdown() {
@@ -260,19 +243,29 @@
   ui_delegate_ = ui_delegate;
 }
 
-std::vector<std::string> ArcUsbHostBridge::GetEventReceiverPackages(
-    scoped_refptr<device::UsbDevice> device) {
-  if (!device) {
-    LOG(WARNING) << "Unknown USB device.";
-    return std::vector<std::string>();
-  }
+void ArcUsbHostBridge::InitDeviceList(
+    std::vector<device::mojom::UsbDeviceInfoPtr> devices) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+  for (auto& device_info : devices) {
+    DCHECK(device_info);
+    std::string guid = device_info->guid;
+    devices_.insert(std::make_pair(guid, std::move(device_info)));
 
-  if (!ui_delegate_)
-    return std::vector<std::string>();
+    // Send the (filtered) list of already existing USB devices to the other
+    // side.
+    usb_manager_->CheckAccess(guid,
+                              base::BindOnce(&ArcUsbHostBridge::OnDeviceChecked,
+                                             weak_factory_.GetWeakPtr(), guid));
+  }
+}
+
+std::vector<std::string> ArcUsbHostBridge::GetEventReceiverPackages(
+    const device::mojom::UsbDeviceInfo& device_info) {
+  DCHECK(ui_delegate_);
 
   std::unordered_set<std::string> receivers = ui_delegate_->GetEventPackageList(
-      device->guid(), device->serial_number(), device->vendor_id(),
-      device->product_id());
+      device_info.guid, device_info.serial_number.value_or(base::string16()),
+      device_info.vendor_id, device_info.product_id);
 
   return std::vector<std::string>(receivers.begin(), receivers.end());
 }
@@ -286,69 +279,37 @@
   if (!allowed)
     return;
 
+  // Device can be removed between being added and returning back from
+  // CheckAccess().
+  auto iter = devices_.find(guid);
+  if (iter == devices_.end())
+    return;
+
   mojom::UsbHostInstance* usb_host_instance = ARC_GET_INSTANCE_FOR_METHOD(
       arc_bridge_service_->usb_host(), OnDeviceAdded);
 
-  if (!usb_host_instance || !usb_service_)
+  if (!usb_host_instance)
     return;
 
-  usb_host_instance->OnDeviceAdded(
-      guid, GetEventReceiverPackages(usb_service_->GetDevice(guid)));
+  usb_host_instance->OnDeviceAdded(guid,
+                                   GetEventReceiverPackages(*iter->second));
 }
 
-void ArcUsbHostBridge::DoRequestUserAuthorization(
-    const std::string& guid,
-    const std::string& package,
-    RequestPermissionCallback callback) {
-  if (!ui_delegate_) {
-    std::move(callback).Run(false);
-    return;
-  }
-
-  if (!usb_service_) {
-    std::move(callback).Run(false);
-    return;
-  }
-
-  scoped_refptr<device::UsbDevice> device = usb_service_->GetDevice(guid);
-  if (!device.get()) {
-    LOG(WARNING) << "Unknown USB device " << guid;
-    std::move(callback).Run(false);
-    return;
-  }
-
-  ui_delegate_->RequestUsbAccessPermission(
-      package, guid, device->serial_number(), device->manufacturer_string(),
-      device->product_string(), device->vendor_id(), device->product_id(),
-      std::move(callback));
-}
-
-bool ArcUsbHostBridge::HasPermissionForDevice(const std::string& guid,
-                                              const std::string& package) {
-  if (!ui_delegate_)
-    return false;
-
-  if (!usb_service_)
-    return false;
-
-  scoped_refptr<device::UsbDevice> device = usb_service_->GetDevice(guid);
-  if (!device.get()) {
-    LOG(WARNING) << "Unknown USB device " << guid;
-    return false;
-  }
+bool ArcUsbHostBridge::HasPermissionForDevice(
+    const device::mojom::UsbDeviceInfo& device_info,
+    const std::string& package) {
+  DCHECK(ui_delegate_);
 
   return ui_delegate_->HasUsbAccessPermission(
-      package, guid, device->serial_number(), device->vendor_id(),
-      device->product_id());
+      package, device_info.guid,
+      device_info.serial_number.value_or(base::string16()),
+      device_info.vendor_id, device_info.product_id);
 }
 
 void ArcUsbHostBridge::HandleScanDeviceListRequest(
     const std::string& package,
     RequestPermissionCallback callback) {
-  if (!ui_delegate_) {
-    std::move(callback).Run(false);
-    return;
-  }
+  DCHECK(ui_delegate_);
 
   VLOG(2) << "USB Request USB scan devicelist permission "
           << "package: " << package;
@@ -356,4 +317,52 @@
                                                    std::move(callback));
 }
 
+// Disconnect the connection with the DeviceService.
+void ArcUsbHostBridge::Disconnect() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+
+  usb_manager_.reset();
+  client_binding_.Close();
+  devices_.clear();
+}
+
+void ArcUsbHostBridge::OnDeviceAdded(
+    device::mojom::UsbDeviceInfoPtr device_info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+  DCHECK(device_info);
+
+  // Update the device list.
+  DCHECK(!base::ContainsKey(devices_, device_info->guid));
+  std::string guid = device_info->guid;
+  devices_.insert(std::make_pair(guid, std::move(device_info)));
+
+  usb_manager_->CheckAccess(guid,
+                            base::BindOnce(&ArcUsbHostBridge::OnDeviceChecked,
+                                           weak_factory_.GetWeakPtr(), guid));
+}
+
+void ArcUsbHostBridge::OnDeviceRemoved(
+    device::mojom::UsbDeviceInfoPtr device_info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_);
+  DCHECK(device_info);
+
+  // Update the device list.
+  auto num_removed = devices_.erase(device_info->guid);
+  DCHECK_EQ(num_removed, 1u);
+
+  mojom::UsbHostInstance* usb_host_instance = ARC_GET_INSTANCE_FOR_METHOD(
+      arc_bridge_service_->usb_host(), OnDeviceRemoved);
+
+  if (!usb_host_instance) {
+    VLOG(2) << "UsbInstance not ready yet";
+    return;
+  }
+
+  usb_host_instance->OnDeviceRemoved(device_info->guid,
+                                     GetEventReceiverPackages(*device_info));
+
+  DCHECK(ui_delegate_);
+  ui_delegate_->DeviceRemoved(device_info->guid);
+}
+
 }  // namespace arc
diff --git a/components/arc/usb/usb_host_bridge.h b/components/arc/usb/usb_host_bridge.h
index 2586bb0..5d770e6e 100644
--- a/components/arc/usb/usb_host_bridge.h
+++ b/components/arc/usb/usb_host_bridge.h
@@ -5,18 +5,20 @@
 #ifndef COMPONENTS_ARC_USB_USB_HOST_BRIDGE_H_
 #define COMPONENTS_ARC_USB_USB_HOST_BRIDGE_H_
 
+#include <map>
 #include <string>
 #include <vector>
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/scoped_observer.h"
+#include "base/sequence_checker.h"
 #include "components/arc/common/usb_host.mojom.h"
 #include "components/arc/session/connection_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "device/usb/public/mojom/device.mojom.h"
 #include "device/usb/public/mojom/device_manager.mojom.h"
-#include "device/usb/usb_device.h"
-#include "device/usb/usb_service.h"
+#include "device/usb/public/mojom/device_manager_client.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
 
 namespace content {
 class BrowserContext;
@@ -32,7 +34,7 @@
 // Private implementation of UsbHostHost.
 class ArcUsbHostBridge : public KeyedService,
                          public ConnectionObserver<mojom::UsbHostInstance>,
-                         public device::UsbService::Observer,
+                         public device::mojom::UsbDeviceManagerClient,
                          public mojom::UsbHostHost {
  public:
   // Returns singleton instance for the given BrowserContext,
@@ -41,8 +43,8 @@
       content::BrowserContext* context);
 
   // The constructor will register an Observer with ArcBridgeService.
-  explicit ArcUsbHostBridge(content::BrowserContext* context,
-                            ArcBridgeService* bridge_service);
+  ArcUsbHostBridge(content::BrowserContext* context,
+                   ArcBridgeService* bridge_service);
   ~ArcUsbHostBridge() override;
 
   // Returns the factory instance for this class.
@@ -62,11 +64,6 @@
   void GetDeviceInfo(const std::string& guid,
                      GetDeviceInfoCallback callback) override;
 
-  // device::UsbService::Observer overrides:
-  void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override;
-  void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override;
-  void WillDestroyUsbService() override;
-
   // ConnectionObserver<mojom::UsbHostInstance> overrides:
   void OnConnectionReady() override;
   void OnConnectionClosed() override;
@@ -77,26 +74,39 @@
   void SetUiDelegate(ArcUsbHostUiDelegate* ui_delegate);
 
  private:
+  // Init |devices_| once the device list has been returned, so that we
+  // can get UsbDeviceInfo from |guid| for other methods.
+  void InitDeviceList(std::vector<device::mojom::UsbDeviceInfoPtr> devices);
   std::vector<std::string> GetEventReceiverPackages(
-      scoped_refptr<device::UsbDevice> device);
+      const device::mojom::UsbDeviceInfo& device_info);
   void OnDeviceChecked(const std::string& guid, bool allowed);
-  void DoRequestUserAuthorization(const std::string& guid,
-                                  const std::string& package,
-                                  RequestPermissionCallback callback);
-  bool HasPermissionForDevice(const std::string& guid,
+  bool HasPermissionForDevice(const device::mojom::UsbDeviceInfo& device_info,
                               const std::string& package);
   void HandleScanDeviceListRequest(const std::string& package,
                                    RequestPermissionCallback callback);
+  void Disconnect();
+
+  // device::mojom::UsbDeviceManagerClient implementation.
+  void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override;
+  void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_info) override;
+
+  SEQUENCE_CHECKER(sequence_);
 
   ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   mojom::UsbHostHostPtr usb_host_ptr_;
-  ScopedObserver<device::UsbService, device::UsbService::Observer>
-      usb_observer_;
-  device::UsbService* usb_service_;
+
+  // Connection to the DeviceService for usb manager.
+  device::mojom::UsbDeviceManagerPtr usb_manager_;
+  mojo::AssociatedBinding<device::mojom::UsbDeviceManagerClient>
+      client_binding_{this};
+
+  // A mapping from GUID -> UsbDeviceInfoPtr for each attached USB device.
+  std::map<std::string, device::mojom::UsbDeviceInfoPtr> devices_;
+
   ArcUsbHostUiDelegate* ui_delegate_ = nullptr;
 
   // WeakPtrFactory to use for callbacks.
-  base::WeakPtrFactory<ArcUsbHostBridge> weak_factory_;
+  base::WeakPtrFactory<ArcUsbHostBridge> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(ArcUsbHostBridge);
 };
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 484550ac..49d07a6b 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -17,6 +17,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -956,6 +957,13 @@
   return (password_form->username_element == element.NameForAutofill().Utf16());
 }
 
+bool PasswordAutofillAgent::HasFillData(
+    const WebFormControlElement& control_element) const {
+  const WebInputElement* element = ToWebInputElement(&control_element);
+  return element && (base::ContainsKey(web_input_to_password_info_, *element) ||
+                     base::ContainsKey(password_to_username_, *element));
+}
+
 bool PasswordAutofillAgent::ShowSuggestions(const WebInputElement& element,
                                             bool show_all,
                                             bool generation_popup_showing) {
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h
index ae04ed37..d2202c8 100644
--- a/components/autofill/content/renderer/password_autofill_agent.h
+++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -174,6 +174,9 @@
   // Returns whether the element is a username or password textfield.
   bool IsUsernameOrPasswordField(const blink::WebInputElement& element);
 
+  // Returns whether the agent has fill data stored for |control_element|.
+  bool HasFillData(const blink::WebFormControlElement& control_element) const;
+
   // Shows an Autofill popup with username suggestions for |element|. If
   // |show_all| is |true|, will show all possible suggestions for that element,
   // otherwise shows suggestions based on current value of |element|.
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
index 03d0c89f..610206d 100644
--- a/components/content_settings/core/browser/content_settings_registry.cc
+++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -168,8 +168,7 @@
            ContentSettingsInfo::PERSISTENT,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS);
 
-  Register(CONTENT_SETTINGS_TYPE_PLUGINS, "plugins",
-           CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
+  Register(CONTENT_SETTINGS_TYPE_PLUGINS, "plugins", CONTENT_SETTING_BLOCK,
            WebsiteSettingsInfo::SYNCABLE,
            WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
            ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
@@ -450,6 +449,17 @@
            ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
            ContentSettingsInfo::PERSISTENT,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
+
+  Register(CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
+           "periodic-background-sync", CONTENT_SETTING_ALLOW,
+           WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(),
+           ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
+           WebsiteSettingsInfo::SINGLE_ORIGIN_ONLY_SCOPE,
+           WebsiteSettingsRegistry::DESKTOP |
+               WebsiteSettingsRegistry::PLATFORM_ANDROID,
+           ContentSettingsInfo::INHERIT_IN_INCOGNITO,
+           ContentSettingsInfo::EPHEMERAL,
+           ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
 }
 
 void ContentSettingsRegistry::Register(
diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc
index cac5b0c..84a9a61d 100644
--- a/components/content_settings/core/common/content_settings.cc
+++ b/components/content_settings/core/common/content_settings.cc
@@ -27,10 +27,7 @@
 //
 // TODO(raymes): We should use a sparse histogram here on the hash of the
 // content settings type name instead.
-//
-// The array size must be explicit for the static_asserts below.
-constexpr size_t kNumHistogramValues = 43;
-constexpr HistogramValue kHistogramValue[kNumHistogramValues] = {
+constexpr HistogramValue kHistogramValue[] = {
     {CONTENT_SETTINGS_TYPE_COOKIES, 0},
     {CONTENT_SETTINGS_TYPE_IMAGES, 1},
     {CONTENT_SETTINGS_TYPE_JAVASCRIPT, 2},
@@ -74,6 +71,7 @@
     {CONTENT_SETTINGS_TYPE_IDLE_DETECTION, 47},
     {CONTENT_SETTINGS_TYPE_SERIAL_GUARD, 48},
     {CONTENT_SETTINGS_TYPE_SERIAL_CHOOSER_DATA, 49},
+    {CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC, 50},
 };
 
 }  // namespace
@@ -94,7 +92,7 @@
                         [](const HistogramValue& a, const HistogramValue& b) {
                           return a.type < b.type;
                         }));
-  static_assert(kHistogramValue[kNumHistogramValues - 1].type ==
+  static_assert(kHistogramValue[base::size(kHistogramValue) - 1].type ==
                     CONTENT_SETTINGS_NUM_TYPES - 1,
                 "Update content settings histogram lookup");
 
diff --git a/components/content_settings/core/common/content_settings_types.h b/components/content_settings/core/common/content_settings_types.h
index 338fdd7e..2867b6d 100644
--- a/components/content_settings/core/common/content_settings_types.h
+++ b/components/content_settings/core/common/content_settings_types.h
@@ -29,6 +29,7 @@
   // TODO(csharrison): Consider renaming it to POPUPS_AND_REDIRECTS, but it
   // might not be worth the trouble.
   CONTENT_SETTINGS_TYPE_POPUPS,
+
   CONTENT_SETTINGS_TYPE_GEOLOCATION,
   CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
   CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
@@ -136,6 +137,11 @@
   CONTENT_SETTINGS_TYPE_SERIAL_GUARD,
   CONTENT_SETTINGS_TYPE_SERIAL_CHOOSER_DATA,
 
+  // Nothing is stored in this setting at present. Please refer to
+  // PeriodicBackgroundSyncPermissionContext for details on how this permission
+  // is ascertained.
+  CONTENT_SETTINGS_TYPE_PERIODIC_BACKGROUND_SYNC,
+
   CONTENT_SETTINGS_NUM_TYPES,
 };
 
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn
index 419ee87c..2c3ee13 100644
--- a/components/download/internal/common/BUILD.gn
+++ b/components/download/internal/common/BUILD.gn
@@ -74,10 +74,8 @@
     "//components/leveldb_proto",
     "//mojo/public/c/system",
     "//net",
-    "//services/device/public/mojom:mojom",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/cpp",
-    "//services/service_manager/public/cpp:cpp",
   ]
 
   if (is_android) {
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS
index 015703b0..713aa40 100644
--- a/components/download/internal/common/DEPS
+++ b/components/download/internal/common/DEPS
@@ -22,9 +22,7 @@
   "+net/http/http_util.h",
   "+net/traffic_annotation/network_traffic_annotation.h",
   "+net/url_request/url_request_context_getter.h",
-  "+services/device/public/mojom",
   "+services/metrics/public/cpp",
   "+services/network/public/cpp",
   "+services/network/public/mojom",
-  "+services/service_manager/public/cpp",
 ]
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc
index 09a3173f..b1bc7b7d 100644
--- a/components/download/internal/common/download_item_impl.cc
+++ b/components/download/internal/common/download_item_impl.cc
@@ -421,7 +421,7 @@
       weak_ptr_factory_(this) {
   job_ = DownloadJobFactory::CreateJob(this, std::move(request_handle),
                                        DownloadCreateInfo(), true, nullptr,
-                                       nullptr, nullptr);
+                                       nullptr);
   delegate_->Attach();
   Init(true /* actively downloading */, TYPE_SAVE_PAGE_AS);
 }
@@ -1398,8 +1398,7 @@
   download_file_ = std::move(file);
   job_ = DownloadJobFactory::CreateJob(
       this, std::move(req_handle), new_create_info, false,
-      std::move(url_loader_factory_getter), url_request_context_getter,
-      delegate_ ? delegate_->GetServiceManagerConnector() : nullptr);
+      std::move(url_loader_factory_getter), url_request_context_getter);
   if (job_->IsParallelizable()) {
     RecordParallelizableDownloadCount(START_COUNT, IsParallelDownloadEnabled());
   }
diff --git a/components/download/internal/common/download_item_impl_delegate.cc b/components/download/internal/common/download_item_impl_delegate.cc
index f5dff20a..cc3fb6af5d 100644
--- a/components/download/internal/common/download_item_impl_delegate.cc
+++ b/components/download/internal/common/download_item_impl_delegate.cc
@@ -103,9 +103,4 @@
 
 void DownloadItemImplDelegate::ReportBytesWasted(DownloadItemImpl* download) {}
 
-service_manager::Connector*
-DownloadItemImplDelegate::GetServiceManagerConnector() {
-  return nullptr;
-}
-
 }  // namespace download
diff --git a/components/download/internal/common/download_job_factory.cc b/components/download/internal/common/download_job_factory.cc
index 0c35188..f3cea3ae 100644
--- a/components/download/internal/common/download_job_factory.cc
+++ b/components/download/internal/common/download_job_factory.cc
@@ -98,8 +98,7 @@
     bool is_save_package_download,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    net::URLRequestContextGetter* url_request_context_getter,
-    service_manager::Connector* connector) {
+    net::URLRequestContextGetter* url_request_context_getter) {
   if (is_save_package_download) {
     return std::make_unique<SavePackageDownloadJob>(download_item,
                                                     std::move(req_handle));
@@ -110,8 +109,7 @@
   if (IsParallelDownloadEnabled() && is_parallelizable) {
     return std::make_unique<ParallelDownloadJob>(
         download_item, std::move(req_handle), create_info,
-        std::move(url_loader_factory_getter), url_request_context_getter,
-        connector);
+        std::move(url_loader_factory_getter), url_request_context_getter);
   }
 
   // An ordinary download job.
diff --git a/components/download/internal/common/download_worker.cc b/components/download/internal/common/download_worker.cc
index ad5bec8..05f8261 100644
--- a/components/download/internal/common/download_worker.cc
+++ b/components/download/internal/common/download_worker.cc
@@ -16,7 +16,6 @@
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace download {
 namespace {
@@ -56,12 +55,10 @@
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = UrlDownloadHandlerFactory::Create(
       std::move(params), delegate, std::move(url_loader_factory_getter),
-      url_security_policy, std::move(url_request_context_getter),
-      std::move(connector), task_runner);
+      url_security_policy, std::move(url_request_context_getter), task_runner);
   task_runner->PostTask(
       FROM_HERE,
       base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadHandlerCreated,
@@ -90,15 +87,13 @@
     std::unique_ptr<DownloadUrlParameters> params,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-    service_manager::Connector* connector) {
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
   GetIOTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&CreateUrlDownloadHandler, std::move(params),
                                 weak_factory_.GetWeakPtr(),
                                 std::move(url_loader_factory_getter),
                                 base::BindRepeating(&IsURLSafe),
                                 std::move(url_request_context_getter),
-                                connector ? connector->Clone() : nullptr,
                                 base::ThreadTaskRunnerHandle::Get()));
 }
 
diff --git a/components/download/internal/common/download_worker.h b/components/download/internal/common/download_worker.h
index 6021c06..ec81471 100644
--- a/components/download/internal/common/download_worker.h
+++ b/components/download/internal/common/download_worker.h
@@ -17,11 +17,7 @@
 
 namespace net {
 class URLRequestContextGetter;
-}  // namespace net
-
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
+}
 
 namespace download {
 class DownloadURLLoaderFactoryGetter;
@@ -57,8 +53,7 @@
       std::unique_ptr<DownloadUrlParameters> params,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-      service_manager::Connector* connector);
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
 
   // Download operations.
   void Pause();
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc
index 0219413c..3298338e 100644
--- a/components/download/internal/common/in_progress_download_manager.cc
+++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -27,7 +27,6 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_response.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 #if defined(OS_ANDROID)
 #include "components/download/internal/common/android/download_collection_bridge.h"
@@ -87,15 +86,13 @@
     const GURL& site_url,
     const GURL& tab_url,
     const GURL& tab_referrer_url,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) {
   DCHECK(GetIOTaskRunner()->BelongsToCurrentThread());
   UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader(
       ResourceDownloader::BeginDownload(
           download_manager, std::move(params), std::move(request),
           std::move(url_loader_factory_getter), url_security_policy, site_url,
-          tab_url, tab_referrer_url, is_new_download, false,
-          std::move(connector), main_task_runner)
+          tab_url, tab_referrer_url, is_new_download, false, main_task_runner)
           .release(),
       base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
 
@@ -117,7 +114,6 @@
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) {
   DCHECK(GetIOTaskRunner()->BelongsToCurrentThread());
   UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader(
@@ -127,7 +123,7 @@
           std::move(url_chain), std::move(response), std::move(cert_status),
           std::move(url_loader_client_endpoints),
           std::move(url_loader_factory_getter), url_security_policy,
-          std::move(connector), main_task_runner)
+          main_task_runner)
           .release(),
       base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
 
@@ -208,6 +204,7 @@
 
 bool InProgressDownloadManager::DownloadUrl(
     std::unique_ptr<DownloadUrlParameters> params) {
+  DCHECK(!delegate_);
   DCHECK(params->is_transient());
 
   if (!url_loader_factory_getter_)
@@ -251,15 +248,13 @@
     const GURL& tab_referrer_url) {
   std::unique_ptr<network::ResourceRequest> request =
       CreateResourceRequest(params.get());
-  auto connector = delegate_ ? delegate_->GetServiceConnector() : nullptr;
   GetIOTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(&BeginResourceDownload, std::move(params),
                      std::move(request), std::move(url_loader_factory_getter),
                      url_security_policy_, is_new_download,
                      weak_factory_.GetWeakPtr(), site_url, tab_url,
-                     tab_referrer_url, std::move(connector),
-                     base::ThreadTaskRunnerHandle::Get()));
+                     tab_referrer_url, base::ThreadTaskRunnerHandle::Get()));
 }
 
 void InProgressDownloadManager::InterceptDownloadFromNavigation(
@@ -274,17 +269,16 @@
     net::CertStatus cert_status,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter) {
-  auto connector = delegate_ ? delegate_->GetServiceConnector() : nullptr;
   GetIOTaskRunner()->PostTask(
       FROM_HERE,
-      base::BindOnce(
-          &CreateDownloadHandlerForNavigation, weak_factory_.GetWeakPtr(),
-          std::move(resource_request), render_process_id, render_frame_id,
-          site_url, tab_url, tab_referrer_url, std::move(url_chain),
-          std::move(response), std::move(cert_status),
-          std::move(url_loader_client_endpoints),
-          std::move(url_loader_factory_getter), url_security_policy_,
-          std::move(connector), base::ThreadTaskRunnerHandle::Get()));
+      base::BindOnce(&CreateDownloadHandlerForNavigation,
+                     weak_factory_.GetWeakPtr(), std::move(resource_request),
+                     render_process_id, render_frame_id, site_url, tab_url,
+                     tab_referrer_url, std::move(url_chain),
+                     std::move(response), std::move(cert_status),
+                     std::move(url_loader_client_endpoints),
+                     std::move(url_loader_factory_getter), url_security_policy_,
+                     base::ThreadTaskRunnerHandle::Get()));
 }
 
 void InProgressDownloadManager::Initialize(
diff --git a/components/download/internal/common/parallel_download_job.cc b/components/download/internal/common/parallel_download_job.cc
index 1ac7dbbb..376700af3 100644
--- a/components/download/internal/common/parallel_download_job.cc
+++ b/components/download/internal/common/parallel_download_job.cc
@@ -27,8 +27,7 @@
     const DownloadCreateInfo& create_info,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    net::URLRequestContextGetter* url_request_context_getter,
-    service_manager::Connector* connector)
+    net::URLRequestContextGetter* url_request_context_getter)
     : DownloadJobImpl(download_item, std::move(request_handle), true),
       initial_request_offset_(create_info.offset),
       initial_received_slices_(download_item->GetReceivedSlices()),
@@ -36,8 +35,7 @@
       requests_sent_(false),
       is_canceled_(false),
       url_loader_factory_getter_(std::move(url_loader_factory_getter)),
-      url_request_context_getter_(url_request_context_getter),
-      connector_(connector) {}
+      url_request_context_getter_(url_request_context_getter) {}
 
 ParallelDownloadJob::~ParallelDownloadJob() = default;
 
@@ -300,7 +298,7 @@
 
   // Send the request.
   worker->SendRequest(std::move(download_params), url_loader_factory_getter_,
-                      url_request_context_getter_, connector_);
+                      url_request_context_getter_);
   DCHECK(workers_.find(offset) == workers_.end());
   workers_[offset] = std::move(worker);
 }
diff --git a/components/download/internal/common/parallel_download_job.h b/components/download/internal/common/parallel_download_job.h
index 71c45c86..1c79129 100644
--- a/components/download/internal/common/parallel_download_job.h
+++ b/components/download/internal/common/parallel_download_job.h
@@ -19,11 +19,7 @@
 
 namespace net {
 class URLRequestContextGetter;
-}  // namespace net
-
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
+}
 
 namespace download {
 
@@ -42,8 +38,7 @@
       const DownloadCreateInfo& create_info,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      net::URLRequestContextGetter* url_request_context_getter,
-      service_manager::Connector* connector);
+      net::URLRequestContextGetter* url_request_context_getter);
   ~ParallelDownloadJob() override;
 
   // DownloadJobImpl implementation.
@@ -127,9 +122,6 @@
   // is disabled.
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
 
-  // Connector used for establishing the connection to the ServiceManager.
-  service_manager::Connector* connector_;
-
   DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJob);
 };
 
diff --git a/components/download/internal/common/parallel_download_job_unittest.cc b/components/download/internal/common/parallel_download_job_unittest.cc
index d227cf42..7e66b75 100644
--- a/components/download/internal/common/parallel_download_job_unittest.cc
+++ b/components/download/internal/common/parallel_download_job_unittest.cc
@@ -69,7 +69,6 @@
                             std::move(request_handle),
                             create_info,
                             nullptr,
-                            nullptr,
                             nullptr),
         request_count_(request_count),
         min_slice_size_(min_slice_size),
diff --git a/components/download/internal/common/resource_downloader.cc b/components/download/internal/common/resource_downloader.cc
index 9d8d4fd..b5b86b0 100644
--- a/components/download/internal/common/resource_downloader.cc
+++ b/components/download/internal/common/resource_downloader.cc
@@ -10,10 +10,7 @@
 #include "components/download/public/common/download_url_loader_factory_getter.h"
 #include "components/download/public/common/stream_handle_input_stream.h"
 #include "components/download/public/common/url_download_request_handle.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace network {
 struct ResourceResponseHead;
@@ -70,14 +67,12 @@
     const GURL& tab_referrer_url,
     bool is_new_download,
     bool is_parallel_request,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = std::make_unique<ResourceDownloader>(
       delegate, std::move(request), params->render_process_host_id(),
       params->render_frame_host_routing_id(), site_url, tab_url,
       tab_referrer_url, is_new_download, task_runner,
-      std::move(url_loader_factory_getter), url_security_policy,
-      std::move(connector));
+      std::move(url_loader_factory_getter), url_security_policy);
 
   downloader->Start(std::move(params), is_parallel_request);
   return downloader;
@@ -100,13 +95,11 @@
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   auto downloader = std::make_unique<ResourceDownloader>(
       delegate, std::move(resource_request), render_process_id, render_frame_id,
       site_url, tab_url, tab_referrer_url, true, task_runner,
-      std::move(url_loader_factory_getter), url_security_policy,
-      std::move(connector));
+      std::move(url_loader_factory_getter), url_security_policy);
   downloader->InterceptResponse(std::move(response), std::move(url_chain),
                                 cert_status,
                                 std::move(url_loader_client_endpoints));
@@ -125,8 +118,7 @@
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     scoped_refptr<download::DownloadURLLoaderFactoryGetter>
         url_loader_factory_getter,
-    const URLSecurityPolicy& url_security_policy,
-    std::unique_ptr<service_manager::Connector> connector)
+    const URLSecurityPolicy& url_security_policy)
     : delegate_(delegate),
       resource_request_(std::move(resource_request)),
       is_new_download_(is_new_download),
@@ -138,9 +130,7 @@
       delegate_task_runner_(task_runner),
       url_loader_factory_getter_(std::move(url_loader_factory_getter)),
       url_security_policy_(url_security_policy),
-      weak_ptr_factory_(this) {
-  RequestWakeLock(connector.get());
-}
+      weak_ptr_factory_(this) {}
 
 ResourceDownloader::~ResourceDownloader() = default;
 
@@ -264,27 +254,10 @@
 }
 
 void ResourceDownloader::Destroy() {
-  if (wake_lock_)
-    wake_lock_->CancelWakeLock();
   delegate_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStopped,
                      delegate_, this));
 }
 
-void ResourceDownloader::RequestWakeLock(
-    service_manager::Connector* connector) {
-  if (!connector)
-    return;
-  device::mojom::WakeLockProviderPtr wake_lock_provider;
-  connector->BindInterface(device::mojom::kServiceName,
-                           mojo::MakeRequest(&wake_lock_provider));
-  wake_lock_provider->GetWakeLockWithoutContext(
-      device::mojom::WakeLockType::kPreventAppSuspension,
-      device::mojom::WakeLockReason::kOther, "Download in progress",
-      mojo::MakeRequest(&wake_lock_));
-
-  wake_lock_->RequestWakeLock();
-}
-
 }  // namespace download
diff --git a/components/download/internal/common/resource_downloader.h b/components/download/internal/common/resource_downloader.h
index b2f8ec7..63664cf 100644
--- a/components/download/internal/common/resource_downloader.h
+++ b/components/download/internal/common/resource_downloader.h
@@ -12,14 +12,9 @@
 #include "components/download/public/common/url_download_handler.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/cert/cert_status_flags.h"
-#include "services/device/public/mojom/wake_lock.mojom.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
-
 namespace download {
 class DownloadURLLoaderFactoryGetter;
 
@@ -41,7 +36,6 @@
       const GURL& tab_referrer_url,
       bool is_new_download,
       bool is_parallel_request,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   // Create a ResourceDownloader from a navigation that turns to be a download.
@@ -62,7 +56,6 @@
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   ResourceDownloader(
@@ -77,8 +70,7 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      const URLSecurityPolicy& url_security_policy,
-      std::unique_ptr<service_manager::Connector> connector);
+      const URLSecurityPolicy& url_security_policy);
   ~ResourceDownloader() override;
 
   // download::DownloadResponseHandler::Delegate
@@ -109,9 +101,6 @@
   // Ask the |delegate_| to destroy this object.
   void Destroy();
 
-  // Requests the wake lock using |connector|.
-  void RequestWakeLock(service_manager::Connector* connector);
-
   base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate_;
 
   // The ResourceRequest for this object.
@@ -165,11 +154,6 @@
   // Used to check if the URL is safe to request.
   URLSecurityPolicy url_security_policy_;
 
-  // Used to keep the system from sleeping while a download is ongoing. If the
-  // system enters power saving mode while a download is alive, it can cause
-  // download to be interrupted.
-  device::mojom::WakeLockPtr wake_lock_;
-
   base::WeakPtrFactory<ResourceDownloader> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourceDownloader);
diff --git a/components/download/internal/common/url_download_handler_factory.cc b/components/download/internal/common/url_download_handler_factory.cc
index c295bc9..b88c1ff 100644
--- a/components/download/internal/common/url_download_handler_factory.cc
+++ b/components/download/internal/common/url_download_handler_factory.cc
@@ -12,7 +12,6 @@
 #include "components/download/public/common/download_utils.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace download {
 
@@ -32,7 +31,6 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) override {
     std::unique_ptr<network::ResourceRequest> request =
         CreateResourceRequest(params.get());
@@ -40,7 +38,7 @@
         download::ResourceDownloader::BeginDownload(
             delegate, std::move(params), std::move(request),
             std::move(url_loader_factory_getter), url_security_policy, GURL(),
-            GURL(), GURL(), true, true, std::move(connector), task_runner)
+            GURL(), GURL(), true, true, task_runner)
             .release(),
         base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
   }
@@ -68,7 +66,6 @@
         url_loader_factory_getter,
     const URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   base::AutoLock auto_lock(GetURLDownloadHandlerFactoryLock());
   if (!g_url_download_handler_factory)
@@ -76,7 +73,7 @@
   return g_url_download_handler_factory->CreateUrlDownloadHandler(
       std::move(params), delegate, std::move(url_loader_factory_getter),
       std::move(url_security_policy), std::move(url_request_context_getter),
-      std::move(connector), task_runner);
+      task_runner);
 }
 
 // static
diff --git a/components/download/public/common/download_item_impl_delegate.h b/components/download/public/common/download_item_impl_delegate.h
index e67be44..a6eb5429 100644
--- a/components/download/public/common/download_item_impl_delegate.h
+++ b/components/download/public/common/download_item_impl_delegate.h
@@ -15,10 +15,6 @@
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/download_url_parameters.h"
 
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
-
 namespace download {
 struct DownloadEntry;
 class DownloadItemImpl;
@@ -117,9 +113,6 @@
   // Report extra bytes wasted during resumption.
   virtual void ReportBytesWasted(DownloadItemImpl* download);
 
-  // Gets the ServiceManager connector that can be used on UI thread.
-  virtual service_manager::Connector* GetServiceManagerConnector();
-
  private:
   // For "Outlives attached DownloadItemImpl" invariant assertion.
   int count_;
diff --git a/components/download/public/common/download_job_factory.h b/components/download/public/common/download_job_factory.h
index d6660c107..cd44f441 100644
--- a/components/download/public/common/download_job_factory.h
+++ b/components/download/public/common/download_job_factory.h
@@ -13,11 +13,7 @@
 
 namespace net {
 class URLRequestContextGetter;
-}  // namespace net
-
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
+}
 
 namespace download {
 
@@ -36,8 +32,7 @@
       bool is_save_package_download,
       scoped_refptr<download::DownloadURLLoaderFactoryGetter>
           url_loader_factory_getter,
-      net::URLRequestContextGetter* url_request_context_getter,
-      service_manager::Connector* connector);
+      net::URLRequestContextGetter* url_request_context_getter);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DownloadJobFactory);
diff --git a/components/download/public/common/in_progress_download_manager.h b/components/download/public/common/in_progress_download_manager.h
index feb59cd..cebda480 100644
--- a/components/download/public/common/in_progress_download_manager.h
+++ b/components/download/public/common/in_progress_download_manager.h
@@ -24,15 +24,11 @@
 
 namespace net {
 class URLRequestContextGetter;
-}  // namespace net
+}
 
 namespace network {
 struct ResourceResponse;
-}  // namespace network
-
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
+}
 
 namespace download {
 
@@ -81,9 +77,6 @@
     // TODO(qinmin): remove this once network service is fully enabled.
     virtual net::URLRequestContextGetter* GetURLRequestContextGetter(
         const DownloadCreateInfo& download_create_info);
-
-    virtual std::unique_ptr<service_manager::Connector>
-    GetServiceConnector() = 0;
   };
 
   using IsOriginSecureCallback = base::RepeatingCallback<bool(const GURL&)>;
diff --git a/components/download/public/common/url_download_handler_factory.h b/components/download/public/common/url_download_handler_factory.h
index 8b30691e..bbe7195 100644
--- a/components/download/public/common/url_download_handler_factory.h
+++ b/components/download/public/common/url_download_handler_factory.h
@@ -11,11 +11,7 @@
 
 namespace net {
 class URLRequestContextGetter;
-}  // namespace net
-
-namespace service_manager {
-class Connector;
-}  // namespace service_manager
+}
 
 namespace download {
 class DownloadURLLoaderFactoryGetter;
@@ -39,7 +35,6 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
 
   virtual ~UrlDownloadHandlerFactory();
@@ -57,7 +52,6 @@
           url_loader_factory_getter,
       const URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) = 0;
 };
 
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm
index e3797d2..d8795e3 100644
--- a/components/favicon/ios/web_favicon_driver.mm
+++ b/components/favicon/ios/web_favicon_driver.mm
@@ -121,6 +121,7 @@
   web::FaviconStatus& favicon_status = item->GetFavicon();
   favicon_status.valid = true;
   favicon_status.image = image;
+  favicon_status.url = icon_url;
 
   NotifyFaviconUpdatedObservers(notification_icon_type, icon_url,
                                 icon_url_changed, image);
diff --git a/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc b/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
index c5e91cb..dfd8109 100644
--- a/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
+++ b/components/password_manager/core/browser/android_affiliation/affiliation_utils.cc
@@ -94,11 +94,8 @@
   // safe" base64 alphabet; plus the padding ('=').
   const char kBase64NonAlphanumericChars[] = "-_=";
 
-  // We need net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS to
-  // unescape the padding ('=').
-  std::string base64_encoded_hash = net::UnescapeURLComponent(
-      input_hash.as_string(),
-      net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
+  std::string base64_encoded_hash;
+  net::UnescapeBinaryURLComponent(input_hash.as_string(), &base64_encoded_hash);
 
   if (!base64_encoded_hash.empty() &&
       CanonicalizeBase64Padding(&base64_encoded_hash) &&
@@ -121,8 +118,9 @@
   // Characters other than alphanumeric that are permitted in the package names.
   const char kPackageNameNonAlphanumericChars[] = "._";
 
-  std::string package_name = net::UnescapeURLComponent(
-      input_package_name.as_string(), net::UnescapeRule::NORMAL);
+  std::string package_name;
+  net::UnescapeBinaryURLComponent(input_package_name.as_string(),
+                                  &package_name);
 
   // TODO(engedy): We might want to use a regex to check this more throughly.
   if (!package_name.empty() &&
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-25.png.sha1
index 4404c52..cdc5d887 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-b35f3cbd8f584bac45c2f8618bb827136adfd957
\ No newline at end of file
+5975ca69e47f605abb4209198914d1dbeddf7790
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-26.png.sha1
index 54fc0f8..5c59227 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-4494408049df80d7edf64c1d39d0a676b348b445
\ No newline at end of file
+f0a353d8b2ea716416d53d1bd43c04410823d7f7
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-25.png.sha1
index 054ff38..cef4693 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-671050041d59f15213880407d57847784dc6688b
\ No newline at end of file
+aaa9d7019810ed97ee68d201f9b0a6eef2c09947
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-26.png.sha1
index 9f1a972..d5efa61a 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-3fbefba834615082936b05c145d735de48225680
\ No newline at end of file
+5621daacea415031e64df4f6cb34f38d60bf948f
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-25.png.sha1
index 665fa23..9ac687b 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-95097302caa8353ab8d680cbeff0a62748b4b7c0
\ No newline at end of file
+24e96b8e0ab0bd7b3d0b8aa113b4511ea281e3b7
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-26.png.sha1
index b84d37e2..056694c 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-135a8992a27da283499890c51343149d27f53514
\ No newline at end of file
+2f50663ed4c8a0dcca3b3cb9e1c43c64fdd5c912
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-25.png.sha1
index fa654279..75c95f2 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-f93bc767631ae5bc2b2c806283e52a2d66972820
\ No newline at end of file
+ed491b6b458395678321830cafa3f7f8fc677275
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-26.png.sha1
index 15959425..42bc9d6 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-7b51ec5fec23ecb51635bf98e4e2ce6a0f053d69
\ No newline at end of file
+f69b277e2937439ad5cc739136508a47ed94df5f
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-25.png.sha1
index 856c45d..71d521fa 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-bcb51742e0788962d58dfa8b7b0ff37100748b11
\ No newline at end of file
+17f916cc47388b615245a650ec600bf01db2d230
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-26.png.sha1
index 8e8af213b..2821be7 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-3474d25341d4daad894fffb515c4a6726b61d040
\ No newline at end of file
+5863f86e8ba1febba151197341cceb2772cde304
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-25.png.sha1
index 9d38513..c6c81ba 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-83f9bc92393fe3a269e61cde586b9a45b1ab4c5f
\ No newline at end of file
+fc46a5230fbc27fd8693b29eba41105d42e7f1c5
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-26.png.sha1
index 9d15c818..c5b5b453 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-82f84f9ff5755656dd2a071f08391055d16d70cc
\ No newline at end of file
+ec73ee4d649e94296172006a073a57abe01d9d8a
\ No newline at end of file
diff --git a/components/variations/field_trial_config/field_trial_testing_config_schema.json b/components/variations/field_trial_config/field_trial_testing_config_schema.json
index 2d115d0b..16f5380b 100644
--- a/components/variations/field_trial_config/field_trial_testing_config_schema.json
+++ b/components/variations/field_trial_config/field_trial_testing_config_schema.json
@@ -63,6 +63,18 @@
               {
                 "field": "forcing_flag",
                 "type": "string"
+              },
+              {
+                "field": "override_ui_string",
+                "type": "array",
+                "contents": {
+                  "type_name": "OverrideUIString",
+                  "type": "struct",
+                  "fields": [
+                    {"field": "name_hash", "type": "int"},
+                    {"field": "value", "type": "string"}
+                  ]
+                }
               }
             ]
           }
diff --git a/components/variations/field_trial_config/field_trial_util.cc b/components/variations/field_trial_config/field_trial_util.cc
index ca28fb0..43f914a 100644
--- a/components/variations/field_trial_config/field_trial_util.cc
+++ b/components/variations/field_trial_config/field_trial_util.cc
@@ -17,9 +17,11 @@
 #include "base/metrics/field_trial.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info.h"
 #include "components/variations/field_trial_config/fieldtrial_testing_config.h"
 #include "components/variations/variations_associated_data.h"
+#include "components/variations/variations_seed_processor.h"
 #include "net/base/escape.h"
 #include "ui/base/device_form_factor.h"
 
@@ -71,9 +73,20 @@
   return experiment.form_factors_size == 0;
 }
 
+// Records the override ui string config. Mainly used for testing.
+void ApplyUIStringOverrides(
+    const FieldTrialTestingExperiment& experiment,
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback) {
+  for (size_t i = 0; i < experiment.override_ui_string_size; ++i) {
+    callback.Run(experiment.override_ui_string[i].name_hash,
+                 base::UTF8ToUTF16(experiment.override_ui_string[i].value));
+  }
+}
+
 void AssociateParamsFromExperiment(
     const std::string& study_name,
     const FieldTrialTestingExperiment& experiment,
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
     base::FeatureList* feature_list) {
   if (experiment.params_size != 0) {
     std::map<std::string, std::string> params;
@@ -103,6 +116,8 @@
         experiment.disable_features[i],
         base::FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
   }
+
+  ApplyUIStringOverrides(experiment, callback);
 }
 
 // Choose an experiment to associate. The rules are:
@@ -115,9 +130,11 @@
 //     a different experiment group for non low_end_device then pick that.
 //   - Otherwise, select the first experiment.
 // - If no experiments match this platform, do not associate any of them.
-void ChooseExperiment(const FieldTrialTestingStudy& study,
-                      base::FeatureList* feature_list,
-                      Study::Platform platform) {
+void ChooseExperiment(
+    const FieldTrialTestingStudy& study,
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
+    Study::Platform platform,
+    base::FeatureList* feature_list) {
   const auto& command_line = *base::CommandLine::ForCurrentProcess();
   const FieldTrialTestingExperiment* chosen_experiment = nullptr;
   for (size_t i = 0; i < study.experiments_size; ++i) {
@@ -125,8 +142,9 @@
     if (HasPlatform(*experiment, platform)) {
       if (!chosen_experiment &&
           !HasDeviceLevelMismatch(*experiment) &&
-          HasFormFactor(*experiment))
+          HasFormFactor(*experiment)) {
         chosen_experiment = experiment;
+    }
 
       if (experiment->forcing_flag &&
           command_line.HasSwitch(experiment->forcing_flag)) {
@@ -135,8 +153,10 @@
       }
     }
   }
-  if (chosen_experiment)
-    AssociateParamsFromExperiment(study.name, *chosen_experiment, feature_list);
+  if (chosen_experiment) {
+    AssociateParamsFromExperiment(study.name, *chosen_experiment, callback,
+                                  feature_list);
+  }
 }
 
 }  // namespace
@@ -219,23 +239,27 @@
   return true;
 }
 
-void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config,
-                                         base::FeatureList* feature_list,
-                                         Study::Platform platform) {
+void AssociateParamsFromFieldTrialConfig(
+    const FieldTrialTestingConfig& config,
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
+    Study::Platform platform,
+    base::FeatureList* feature_list) {
   for (size_t i = 0; i < config.studies_size; ++i) {
     const FieldTrialTestingStudy& study = config.studies[i];
     if (study.experiments_size > 0) {
-      ChooseExperiment(study, feature_list, platform);
+      ChooseExperiment(study, callback, platform, feature_list);
     } else {
       DLOG(ERROR) << "Unexpected empty study: " << study.name;
     }
   }
 }
 
-void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list,
-                                      Study::Platform platform) {
-  AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, feature_list,
-                                      platform);
+void AssociateDefaultFieldTrialConfig(
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
+    Study::Platform platform,
+    base::FeatureList* feature_list) {
+  AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, callback, platform,
+                                      feature_list);
 }
 
 }  // namespace variations
diff --git a/components/variations/field_trial_config/field_trial_util.h b/components/variations/field_trial_config/field_trial_util.h
index 1cbbb39a..9b518af 100644
--- a/components/variations/field_trial_config/field_trial_util.h
+++ b/components/variations/field_trial_config/field_trial_util.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "components/variations/proto/study.pb.h"
+#include "components/variations/variations_seed_processor.h"
 
 namespace base {
 class FeatureList;
@@ -34,15 +35,19 @@
 // multiple groups with the |config| struct. This will also force the selection
 // of FieldTrial groups specified in the |config|. Registers features associated
 // with default field trials with |feature_list|.
-void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config,
-                                         base::FeatureList* feature_list,
-                                         Study::Platform platform);
+void AssociateParamsFromFieldTrialConfig(
+    const FieldTrialTestingConfig& config,
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
+    Study::Platform platform,
+    base::FeatureList* feature_list);
 
 // Associates params and features to FieldTrial groups and forces the selection
 // of groups specified in testing/variations/fieldtrial_testing_config.json.
 // Registers features associated with default field trials with |feature_list|.
-void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list,
-                                      Study::Platform platform);
+void AssociateDefaultFieldTrialConfig(
+    const VariationsSeedProcessor::UIStringOverrideCallback& callback,
+    Study::Platform platform,
+    base::FeatureList* feature_list);
 
 }  // namespace variations
 
diff --git a/components/variations/field_trial_config/field_trial_util_unittest.cc b/components/variations/field_trial_config/field_trial_util_unittest.cc
index 9e2372d6..47f14c4 100644
--- a/components/variations/field_trial_config/field_trial_util_unittest.cc
+++ b/components/variations/field_trial_config/field_trial_util_unittest.cc
@@ -13,14 +13,43 @@
 #include "base/metrics/field_trial.h"
 #include "base/stl_util.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/strings/utf_string_conversions.h"
 #include "components/variations/field_trial_config/fieldtrial_testing_config.h"
 #include "components/variations/variations_associated_data.h"
+#include "components/variations/variations_seed_processor.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/device_form_factor.h"
 
 namespace variations {
 namespace {
 
+class TestOverrideStringCallback {
+ public:
+  typedef std::map<uint32_t, base::string16> OverrideMap;
+
+  TestOverrideStringCallback()
+      : callback_(base::BindRepeating(&TestOverrideStringCallback::Override,
+                                      base::Unretained(this))) {}
+
+  virtual ~TestOverrideStringCallback() {}
+
+  const VariationsSeedProcessor::UIStringOverrideCallback& callback() const {
+    return callback_;
+  }
+
+  const OverrideMap& overrides() const { return overrides_; }
+
+ private:
+  void Override(uint32_t hash, const base::string16& string) {
+    overrides_[hash] = string;
+  }
+
+  VariationsSeedProcessor::UIStringOverrideCallback callback_;
+  OverrideMap overrides_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestOverrideStringCallback);
+};
+
 class FieldTrialUtilTest : public ::testing::Test {
  public:
   FieldTrialUtilTest() : field_trial_list_(nullptr) {}
@@ -45,8 +74,9 @@
     }
   }
 
- private:
+ protected:
   base::FieldTrialList field_trial_list_;
+  TestOverrideStringCallback override_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(FieldTrialUtilTest);
 };
@@ -83,15 +113,18 @@
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
       {"TestGroup1", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params_0, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params_0, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
   };
   const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_1[] =
       {{"x", "3"}, {"y", "4"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
       {"TestGroup2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params_0, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params_0, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
       {"TestGroup2-2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params_1, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params_1, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
       {"TestTrial1", array_kFieldTrialConfig_experiments_0, 1},
@@ -102,7 +135,10 @@
   };
 
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      &feature_list);
 
   EXPECT_EQ("1", GetVariationParamValue("TestTrial1", "x"));
   EXPECT_EQ("2", GetVariationParamValue("TestTrial1", "y"));
@@ -141,7 +177,8 @@
     const Study::Platform platform = all_platforms[i];
     const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
         {"TestGroup", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-         array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr},
+         array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr,
+         nullptr, 0},
     };
     const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
         {"TestTrial", array_kFieldTrialConfig_experiments, 1}
@@ -151,7 +188,10 @@
     };
 
     base::FeatureList feature_list;
-    AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+    AssociateParamsFromFieldTrialConfig(kConfig,
+                                        override_callback_.callback(),
+                                        platform,
+                                        &feature_list);
 
     EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
     EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
@@ -173,7 +213,8 @@
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
       {"TestGroup", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
       {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
@@ -182,8 +223,9 @@
 
   // The platforms don't match, so trial shouldn't be added.
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list,
-                                      Study::PLATFORM_ANDROID_WEBVIEW);
+  AssociateParamsFromFieldTrialConfig(kConfig, override_callback_.callback(),
+                                      Study::PLATFORM_ANDROID_WEBVIEW,
+                                      &feature_list);
 
   EXPECT_EQ("", GetVariationParamValue("TestTrial", "x"));
   EXPECT_EQ("", GetVariationParamValue("TestTrial", "y"));
@@ -202,7 +244,8 @@
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
       {"TestGroup", platforms, 2, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
       {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
@@ -211,8 +254,9 @@
 
   // One of the platforms matches, so trial should be added.
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list,
-                                      Study::PLATFORM_ANDROID_WEBVIEW);
+  AssociateParamsFromFieldTrialConfig(kConfig, override_callback_.callback(),
+                                      Study::PLATFORM_ANDROID_WEBVIEW,
+                                      &feature_list);
 
   EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
   EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
@@ -235,7 +279,8 @@
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
       {"TestGroup", &platform, 1, form_factors, 4, Study::OPTIONAL_BOOL_MISSING,
-       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr},
+       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr,
+       nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
       {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
@@ -244,7 +289,10 @@
 
   // One of the form_factors matches, so trial should be added.
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      &feature_list);
 
   EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
   EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
@@ -267,7 +315,7 @@
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
       {"TestGroup", &platform, 1, &form_factor, 1,
        Study::OPTIONAL_BOOL_MISSING, array_kFieldTrialConfig_params, 2,
-       nullptr, 0, nullptr, 0, nullptr},
+       nullptr, 0, nullptr, 0, nullptr, nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
       {"TestTrial", array_kFieldTrialConfig_experiments, 1}
@@ -278,7 +326,10 @@
 
   // One of the form_factors matches, so trial should be added.
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      &feature_list);
 
   EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
   EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
@@ -307,7 +358,7 @@
     const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
         {"TestGroup", &platform, 1, &form_factor, 1,
          Study::OPTIONAL_BOOL_MISSING, array_kFieldTrialConfig_params, 2,
-         nullptr, 0, nullptr, 0, nullptr},
+         nullptr, 0, nullptr, 0, nullptr, nullptr, 0},
     };
     const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
         {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
@@ -316,8 +367,9 @@
 
     // The form factor don't match, so trial shouldn't be added.
     base::FeatureList feature_list;
-    AssociateParamsFromFieldTrialConfig(kConfig, &feature_list,
-                                        Study::PLATFORM_ANDROID_WEBVIEW);
+    AssociateParamsFromFieldTrialConfig(kConfig, override_callback_.callback(),
+                                        Study::PLATFORM_ANDROID_WEBVIEW,
+                                        &feature_list);
 
     EXPECT_EQ("", GetVariationParamValue("TestTrial", "x"));
     EXPECT_EQ("", GetVariationParamValue("TestTrial", "y"));
@@ -341,13 +393,13 @@
   const Study::Platform platform = Study::PLATFORM_LINUX;
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
       {"TestGroup1", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING, nullptr,
-       0, enable_features, 2, nullptr, 0, nullptr},
+       0, enable_features, 2, nullptr, 0, nullptr, nullptr, 0},
   };
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
       {"TestGroup2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING, nullptr,
-       0, nullptr, 0, disable_features, 2, nullptr},
+       0, nullptr, 0, disable_features, 2, nullptr, nullptr, 0},
       {"TestGroup2-2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
+       nullptr, 0, nullptr, 0, nullptr, 0, nullptr, nullptr, 0},
   };
 
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
@@ -360,7 +412,10 @@
   };
 
   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
-  AssociateParamsFromFieldTrialConfig(kConfig, feature_list.get(), platform);
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      feature_list.get());
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatureList(std::move(feature_list));
 
@@ -381,20 +436,20 @@
   const Study::Platform platform = Study::PLATFORM_LINUX;
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
       {"TestGroup1", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING, nullptr,
-       0, nullptr, 0, nullptr, 0, nullptr}};
+       0, nullptr, 0, nullptr, 0, nullptr, nullptr, 0}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
       {"TestGroup2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING, nullptr,
-       0, nullptr, 0, nullptr, 0, nullptr},
+       0, nullptr, 0, nullptr, 0, nullptr, nullptr, 0},
       {"ForcedGroup2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       nullptr, 0, nullptr, 0, nullptr, 0, "flag-2"},
+       nullptr, 0, nullptr, 0, nullptr, 0, "flag-2", nullptr, 0},
   };
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = {
       {"TestGroup3", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING, nullptr,
-       0, nullptr, 0, nullptr, 0, nullptr},
+       0, nullptr, 0, nullptr, 0, nullptr, nullptr, 0},
       {"ForcedGroup3", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       nullptr, 0, nullptr, 0, nullptr, 0, "flag-3"},
+       nullptr, 0, nullptr, 0, nullptr, 0, "flag-3", nullptr, 0},
       {"ForcedGroup3-2", &platform, 1, {}, 0, Study::OPTIONAL_BOOL_MISSING,
-       nullptr, 0, nullptr, 0, nullptr, 0, "flag-3-2"},
+       nullptr, 0, nullptr, 0, nullptr, 0, "flag-3-2", nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
       {"TestTrial1", array_kFieldTrialConfig_experiments_0, 1},
@@ -409,13 +464,62 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitch("flag-3");
 
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      &feature_list);
 
   EXPECT_EQ("TestGroup1", base::FieldTrialList::FindFullName("TestTrial1"));
   EXPECT_EQ("ForcedGroup2", base::FieldTrialList::FindFullName("TestTrial2"));
   EXPECT_EQ("ForcedGroup3", base::FieldTrialList::FindFullName("TestTrial3"));
 }
 
+TEST_F(FieldTrialUtilTest,
+       AssociateParamsFromFieldTrialConfigWithUIStringOverrides) {
+  const Study::Platform platform = Study::PLATFORM_WINDOWS;
+  const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params[] =
+        {{"x", "1"}, {"y", "2"}};
+  const OverrideUIString array_kFieldTrialConfig_override_ui_string[] =
+        {{1234, "test1"}, {5678, "test2"}};
+  const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
+      {"TestGroup", &platform, 1, nullptr, 0,
+       Study::OPTIONAL_BOOL_MISSING, array_kFieldTrialConfig_params, 2,
+       nullptr, 0, nullptr, 0, nullptr,
+       array_kFieldTrialConfig_override_ui_string, 2},
+  };
+  const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
+      {"TestTrial", array_kFieldTrialConfig_experiments, 1}
+  };
+  const FieldTrialTestingConfig kConfig = {
+      array_kFieldTrialConfig_studies, 1
+  };
+
+  // One of the form_factors matches, so trial should be added.
+  base::FeatureList feature_list;
+  AssociateParamsFromFieldTrialConfig(kConfig,
+                                      override_callback_.callback(),
+                                      platform,
+                                      &feature_list);
+
+  EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
+  EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
+
+  std::map<std::string, std::string> params;
+  EXPECT_TRUE(GetVariationParams("TestTrial", &params));
+  EXPECT_EQ(2U, params.size());
+  EXPECT_EQ("1", params["x"]);
+  EXPECT_EQ("2", params["y"]);
+
+  EXPECT_EQ("TestGroup", base::FieldTrialList::FindFullName("TestTrial"));
+  const TestOverrideStringCallback::OverrideMap& overrides =
+      override_callback_.overrides();
+  EXPECT_EQ(2u, overrides.size());
+  auto it = overrides.find(1234);
+  EXPECT_EQ(base::ASCIIToUTF16("test1"), it->second);
+  it = overrides.find(5678);
+  EXPECT_EQ(base::ASCIIToUTF16("test2"), it->second);
+}
+
 TEST_F(FieldTrialUtilTest, TestEscapeValue) {
   std::string str = "trail.:/,*";
   std::string escaped_str = EscapeValue(str);
diff --git a/components/variations/service/generate_ui_string_overrider.py b/components/variations/service/generate_ui_string_overrider.py
index 7be44c2..0b75bea1 100755
--- a/components/variations/service/generate_ui_string_overrider.py
+++ b/components/variations/service/generate_ui_string_overrider.py
@@ -33,7 +33,7 @@
 Resource = collections.namedtuple("Resource", ['hash', 'name', 'index'])
 
 
-def _HashName(name):
+def HashName(name):
   """Returns the hash id for a name.
 
   Args:
@@ -76,7 +76,7 @@
   Returns:
     A sorted list of |Resource| objects.
   """
-  resources = [Resource(_HashName(name), name, index) for name, index in
+  resources = [Resource(HashName(name), name, index) for name, index in
                _GetNameIndexPairsIter(resources_content)]
 
   # Deduplicate resources. Some name-index pairs appear in both chromium_ and
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
index d91740a..7c6a2a7e 100644
--- a/components/variations/service/variations_field_trial_creator.cc
+++ b/components/variations/service/variations_field_trial_creator.cc
@@ -530,7 +530,12 @@
   if (!command_line->HasSwitch(switches::kDisableFieldTrialTestingConfig) &&
       !command_line->HasSwitch(::switches::kForceFieldTrials) &&
       !command_line->HasSwitch(switches::kVariationsServerURL)) {
-    AssociateDefaultFieldTrialConfig(feature_list.get(), GetPlatform());
+    // Note that passing base::Unretained(this) below is safe because the
+    // callback is executed synchronously.
+    AssociateDefaultFieldTrialConfig(
+        base::BindRepeating(&VariationsFieldTrialCreator::OverrideUIString,
+                            base::Unretained(this)),
+        GetPlatform(), feature_list.get());
     used_testing_config = true;
   }
 #endif  // BUILDFLAG(FIELDTRIAL_TESTING_ENABLED)
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc
index 12b4b1d..75738d1 100644
--- a/components/viz/service/display/direct_renderer.cc
+++ b/components/viz/service/display/direct_renderer.cc
@@ -353,7 +353,7 @@
       render_pass_backdrop_filters_[pass->id] = &pass->backdrop_filters;
       // |backdrop_filter_bounds| only apply if there is a non-empty
       // backdrop-filter to apply.
-      if (!pass->backdrop_filter_bounds.IsEmpty()) {
+      if (!pass->backdrop_filters.IsEmpty()) {
         render_pass_backdrop_filter_bounds_[pass->id] =
             &pass->backdrop_filter_bounds;
       }
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index faa61ce..418ae43 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -222,7 +222,7 @@
   gfx::Transform quad_to_target_transform;
   const cc::FilterOperations* filters = nullptr;
   const cc::FilterOperations* backdrop_filters = nullptr;
-  const gfx::RRectF* backdrop_filter_bounds = nullptr;
+  gfx::RRectF backdrop_filter_bounds;
 
   // Whether the texture to be sampled from needs to be flipped.
   bool source_needs_flip = false;
@@ -721,6 +721,23 @@
   return true;
 }
 
+// This takes a rounded rect and a rect that it lives in, and returns an
+// equivalent rounded rect in the space -0.5->0.5.
+bool GetScaledRRectF(const gfx::Rect& space,
+                     const gfx::RRectF& rect,
+                     gfx::RRectF* scaled_rect) {
+  float x_scale = 1.0f / space.width();
+  float y_scale = 1.0f / space.height();
+  float new_x = (rect.rect().x() - space.x()) * x_scale - 0.5f;
+  float new_y = (rect.rect().y() - space.y()) * y_scale - 0.5f;
+  *scaled_rect = rect;
+  scaled_rect->Scale(x_scale, y_scale);
+  scaled_rect->Offset(-scaled_rect->rect().origin().x(),
+                      -scaled_rect->rect().origin().y());
+  scaled_rect->Offset(new_x, new_y);
+  return true;
+}
+
 // This takes a gfx::Rect and a clip region quad in the same space,
 // and returns the proportional uv's in the space 0->1.
 bool GetScaledUVs(const gfx::Rect& rect, const gfx::QuadF* clip, float uvs[8]) {
@@ -739,41 +756,37 @@
 }
 
 gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
-    const RenderPassDrawQuad* quad,
-    const gfx::Transform& contents_device_transform,
-    const cc::FilterOperations* regular_filters,
-    const cc::FilterOperations* backdrop_filters,
-    const gfx::QuadF* clip_region,
-    const gfx::RRectF* backdrop_filter_bounds_input,
-    bool use_aa,
+    DrawRenderPassDrawQuadParams* params,
+    gfx::Transform* backdrop_filter_bounds_transform,
     gfx::RRectF* backdrop_filter_bounds,
     gfx::Rect* unclipped_rect) {
+  DCHECK(backdrop_filter_bounds_transform);
   DCHECK(backdrop_filter_bounds);
   DCHECK(unclipped_rect);
+
+  const RenderPassDrawQuad* quad = params->quad;
   gfx::QuadF scaled_region;
   // |scaled_region| is a quad in [-0.5,0.5] space that represents |clip_region|
   // as a fraction of the space defined by |quad->rect|. If |clip_region| is
   // nullptr, then scaled_region is [-0.5,0.5].
-  if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) {
+  if (!GetScaledRegion(quad->rect, params->clip_region, &scaled_region)) {
     scaled_region = SharedGeometryQuad().BoundingBox();
   }
+  // |backdrop_filter_bounds| is a rounded rect in [-0.5,0.5] space that
+  // represents |params->backdrop_filter_bounds| as a fraction of the space
+  // defined by |quad->rect|, not including its offset.
+  if (!GetScaledRRectF(gfx::Rect(quad->rect.size()),
+                       params->backdrop_filter_bounds,
+                       backdrop_filter_bounds)) {
+    *backdrop_filter_bounds = gfx::RRectF(SharedGeometryQuad().BoundingBox());
+  }
 
   // |backdrop_rect| is now the bounding box of clip_region, in window pixel
   // coordinates, and with flip applied.
   gfx::Rect backdrop_rect = gfx::ToEnclosingRect(cc::MathUtil::MapClippedRect(
-      contents_device_transform, scaled_region.BoundingBox()));
-  gfx::Rect orig_backdrop_rect = backdrop_rect;
+      params->contents_device_transform, scaled_region.BoundingBox()));
 
-  // |backdrop_filter_bounds_input| can (rarely) be nullptr, if the render pass
-  // was not found. For example, some GLRenderer tests can trigger this case,
-  // e.g. GLRendererShaderTest.DrawRenderPassQuadShaderPermutations.
-  if (backdrop_filter_bounds_input) {
-    *backdrop_filter_bounds = *backdrop_filter_bounds_input;
-  } else {
-    *backdrop_filter_bounds = gfx::RRectF();
-  }
-
-  if (ShouldApplyBackdropFilters(backdrop_filters)) {
+  if (ShouldApplyBackdropFilters(params->backdrop_filters)) {
     SkMatrix matrix;
     // |filters_scale| is the ratio of render pass physical pixels to root layer
     // layer space, including content-to-target-space scale and device pixel
@@ -790,17 +803,18 @@
     // by any backdrop-filter drop-shadow offset (flipped if
     // FlippedFramebuffer()). Note that scale is not applied to the
     // backdrop_rect itself, only the sigma or x/y offset of filters.
-    backdrop_rect = backdrop_filters->MapRectReverse(backdrop_rect, matrix);
+    backdrop_rect =
+        params->backdrop_filters->MapRectReverse(backdrop_rect, matrix);
   }
 
-  if (!backdrop_rect.IsEmpty() && use_aa) {
+  if (!backdrop_rect.IsEmpty() && params->use_aa) {
     const int kOutsetForAntialiasing = 1;
     backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing);
   }
 
-  if (regular_filters) {
-    DCHECK(!regular_filters->IsEmpty());
-    // If we have filters, grab an extra one-pixel border around the
+  if (params->filters) {
+    DCHECK(!params->filters->IsEmpty());
+    // If we have regular filters, grab an extra one-pixel border around the
     // background, so texture edge clamping gives us a transparent border
     // in case the filter expands the result.
     backdrop_rect.Inset(-1, -1, -1, -1);
@@ -809,8 +823,18 @@
   *unclipped_rect = backdrop_rect;
   backdrop_rect.Intersect(MoveFromDrawToWindowSpace(
       current_frame()->current_render_pass->output_rect));
-  backdrop_filter_bounds->Offset(orig_backdrop_rect.origin() -
-                                 backdrop_rect.origin());
+
+  // The frame buffer flip is already included in the captured backdrop image,
+  // and it is included in |contents_device_transform| (through
+  // |projection_matrix|). Don't double-flip.
+  *backdrop_filter_bounds_transform = params->contents_device_transform;
+  float old_y = backdrop_filter_bounds_transform->To2dTranslation().y();
+  backdrop_filter_bounds_transform->PostScale(1, -1);
+  backdrop_filter_bounds_transform->PostTranslate(0, 2 * old_y);
+  // Shift to the space of the captured backdrop image.
+  backdrop_filter_bounds_transform->PostTranslate(-backdrop_rect.x(),
+                                                  -backdrop_rect.y());
+
   return backdrop_rect;
 }
 
@@ -869,25 +893,24 @@
 }
 
 sk_sp<SkImage> GLRenderer::ApplyBackdropFilters(
-    const RenderPassDrawQuad* quad,
-    const cc::FilterOperations* backdrop_filters,
-    const cc::FilterOperations* regular_filters,
-    uint32_t background_texture,
-    const gfx::Rect& background_rect,
+    DrawRenderPassDrawQuadParams* params,
     const gfx::Rect& unclipped_rect,
-    const float backdrop_filter_quality,
-    const gfx::RRectF& backdrop_filter_bounds) {
-  DCHECK(ShouldApplyBackdropFilters(backdrop_filters));
+    const gfx::RRectF& backdrop_filter_bounds,
+    const gfx::Transform& backdrop_filter_bounds_transform) {
+  DCHECK(ShouldApplyBackdropFilters(params->backdrop_filters));
+  DCHECK(params->backdrop_filter_quality);
+  const RenderPassDrawQuad* quad = params->quad;
   auto use_gr_context = ScopedUseGrContext::Create(this);
 
   gfx::Vector2d clipping_offset =
-      (background_rect.top_right() - unclipped_rect.top_right()) +
-      (background_rect.bottom_left() - unclipped_rect.bottom_left());
+      (params->background_rect.top_right() - unclipped_rect.top_right()) +
+      (params->background_rect.bottom_left() - unclipped_rect.bottom_left());
 
   // Update the backdrop filter to include "regular" filters and opacity.
-  cc::FilterOperations backdrop_filters_plus_effects = *backdrop_filters;
-  if (regular_filters) {
-    for (const auto& filter_op : regular_filters->operations())
+  cc::FilterOperations backdrop_filters_plus_effects =
+      *params->backdrop_filters;
+  if (params->filters) {
+    for (const auto& filter_op : params->filters->operations())
       backdrop_filters_plus_effects.Append(filter_op);
   }
   if (quad->shared_quad_state->opacity < 1.0) {
@@ -897,7 +920,7 @@
   }
 
   auto paint_filter = cc::RenderSurfaceFilters::BuildImageFilter(
-      backdrop_filters_plus_effects, gfx::SizeF(background_rect.size()),
+      backdrop_filters_plus_effects, gfx::SizeF(params->background_rect.size()),
       gfx::Vector2dF(clipping_offset));
 
   // TODO(senorblanco): background filters should be moved to the
@@ -908,9 +931,9 @@
 
   auto filter = paint_filter->cached_sk_filter_;
   bool flip_texture = true;
-  sk_sp<SkImage> src_image =
-      WrapTexture(background_texture, GL_TEXTURE_2D, background_rect.size(),
-                  use_gr_context->context(), flip_texture);
+  sk_sp<SkImage> src_image = WrapTexture(
+      params->background_texture, GL_TEXTURE_2D, params->background_rect.size(),
+      use_gr_context->context(), flip_texture);
   if (!src_image) {
     TRACE_EVENT_INSTANT0("cc",
                          "ApplyBackdropFilters wrap background texture failed",
@@ -918,8 +941,8 @@
     return nullptr;
   }
 
-  gfx::Rect quality_adjusted_rect =
-      ScaleToEnclosingRect(background_rect, backdrop_filter_quality);
+  gfx::Rect quality_adjusted_rect = ScaleToEnclosingRect(
+      params->background_rect, params->backdrop_filter_quality);
 
   // Create surface to draw into.
   SkImageInfo dst_info = SkImageInfo::MakeN32Premul(
@@ -940,8 +963,8 @@
   // First paint the backdrop at full opacity. The backdrop-filtered content
   // will not be blended with the backdrop later, it will be rastered over the
   // top. So we need to paint it here, unfiltered.
-  gfx::RectF src_image_rect =
-      gfx::RectF(background_rect.width(), background_rect.height());
+  gfx::RectF src_image_rect = gfx::RectF(params->background_rect.width(),
+                                         params->background_rect.height());
   SkRect dest_rect = RectToSkRect(gfx::Rect(quality_adjusted_rect.size()));
   surface->getCanvas()->drawImageRect(src_image, RectFToSkRect(src_image_rect),
                                       dest_rect, nullptr);
@@ -958,14 +981,15 @@
       gfx::Vector2dF(1, 1), std::move(filter), &offset, &subset,
       quad->filters_origin, true);
 
+  // Clip the filtered image to the (rounded) bounding box of the element.
   if (!backdrop_filter_bounds.IsEmpty()) {
-    // Clip the filtered image to the (rounded) bounding box of the element.
     surface->getCanvas()->save();
     gfx::RRectF clip_rect(backdrop_filter_bounds);
-    DCHECK(backdrop_filter_quality);
-    clip_rect.Scale(backdrop_filter_quality);
+    clip_rect.Scale(params->backdrop_filter_quality);
+    surface->getCanvas()->setMatrix(backdrop_filter_bounds_transform.matrix());
     surface->getCanvas()->clipRRect(SkRRect(clip_rect), SkClipOp::kIntersect,
                                     true /* antialias */);
+    surface->getCanvas()->resetMatrix();
   }
 
   // Now paint the pre-filtered image onto the canvas.
@@ -1063,8 +1087,14 @@
   local_matrix.postScale(quad->filters_scale.x(), quad->filters_scale.y());
   params->filters = FiltersForPass(quad->render_pass_id);
   params->backdrop_filters = BackdropFiltersForPass(quad->render_pass_id);
-  params->backdrop_filter_bounds =
-      BackdropFilterBoundsForPass(quad->render_pass_id);
+  if (ShouldApplyBackdropFilters(params->backdrop_filters)) {
+    params->backdrop_filter_bounds =
+        *BackdropFilterBoundsForPass(quad->render_pass_id);
+    params->backdrop_filter_bounds.Scale(quad->filters_scale.x(),
+                                         quad->filters_scale.y());
+  } else {
+    params->backdrop_filter_bounds = gfx::RRectF();
+  }
   params->backdrop_filter_quality = quad->backdrop_filter_quality;
   gfx::Rect dst_rect = params->filters
                            ? params->filters->MapRect(quad->rect, local_matrix)
@@ -1135,12 +1165,11 @@
     // Compute a bounding box around the pixels that will be visible through
     // the quad.
     gfx::RRectF backdrop_filter_bounds_rect;
+    gfx::Transform backdrop_filter_bounds_transform;
     gfx::Rect unclipped_rect;
     params->background_rect = GetBackdropBoundingBoxForRenderPassQuad(
-        quad, params->contents_device_transform, params->filters,
-        params->backdrop_filters, params->clip_region,
-        params->backdrop_filter_bounds, params->use_aa,
-        &backdrop_filter_bounds_rect, &unclipped_rect);
+        params, &backdrop_filter_bounds_transform, &backdrop_filter_bounds_rect,
+        &unclipped_rect);
 
     if (!params->background_rect.IsEmpty()) {
       // The pixels from the filtered background should completely replace the
@@ -1158,9 +1187,8 @@
         // Apply the background filters to R, so that it is applied in the
         // pixels' coordinate space.
         params->background_image = ApplyBackdropFilters(
-            quad, params->backdrop_filters, params->filters,
-            params->background_texture, params->background_rect, unclipped_rect,
-            params->backdrop_filter_quality, backdrop_filter_bounds_rect);
+            params, unclipped_rect, backdrop_filter_bounds_rect,
+            backdrop_filter_bounds_transform);
         if (params->background_image) {
           params->background_image_id =
               GetGLTextureIDFromSkImage(params->background_image.get());
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h
index 77b3d3e..7b5ed49 100644
--- a/components/viz/service/display/gl_renderer.h
+++ b/components/viz/service/display/gl_renderer.h
@@ -196,23 +196,17 @@
   void RestoreBlendFuncToDefault(SkBlendMode blend_mode);
 
   // Returns the rect that should be sampled from the backdrop texture to be
-  // backdrop filtered. This rect lives in window pixel space. The |clip_region|
-  // input lives in the local quad rect pixel space. The
-  // |backdrop_filter_bounds_input| input lives in the local quad rect pixel
-  // space. The |backdrop_filter_bounds| output lives in the space of the output
-  // rect returned by this function. It will be used to clip the sampled
-  // backdrop texture. The |unclipped_rect| output is the unclipped (full) rect
-  // that the backdrop_filter should be applied to, in window pixel space.
+  // backdrop filtered. This rect lives in window pixel space. The
+  // |backdrop_filter_bounds| output lives in the space of the output rect
+  // returned by this function. It will be used to clip the sampled backdrop
+  // texture. The |unclipped_rect| output is the unclipped (full) rect that the
+  // backdrop_filter should be applied to, in window pixel space.
   gfx::Rect GetBackdropBoundingBoxForRenderPassQuad(
-      const RenderPassDrawQuad* quad,
-      const gfx::Transform& contents_device_transform,
-      const cc::FilterOperations* filters,
-      const cc::FilterOperations* backdrop_filters,
-      const gfx::QuadF* clip_region,
-      const gfx::RRectF* backdrop_filter_bounds_input,
-      bool use_aa,
+      DrawRenderPassDrawQuadParams* params,
+      gfx::Transform* backdrop_filter_bounds_transform,
       gfx::RRectF* backdrop_filter_bounds,
       gfx::Rect* unclipped_rect);
+
   // Allocates and returns a texture id that contains a copy of the contents
   // of the current RenderPass being drawn.
   uint32_t GetBackdropTexture(const gfx::Rect& window_rect);
@@ -228,14 +222,10 @@
   // and filters applied. This is an approximation, but it should be close
   // enough.
   sk_sp<SkImage> ApplyBackdropFilters(
-      const RenderPassDrawQuad* quad,
-      const cc::FilterOperations* backdrop_filters,
-      const cc::FilterOperations* regular_filters,
-      uint32_t background_texture,
-      const gfx::Rect& background_rect,
+      DrawRenderPassDrawQuadParams* params,
       const gfx::Rect& unclipped_rect,
-      const float backdrop_filter_quality,
-      const gfx::RRectF& backdrop_filter_bounds);
+      const gfx::RRectF& backdrop_filter_bounds,
+      const gfx::Transform& backdrop_filter_bounds_transform);
 
   const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass) override;
 
diff --git a/content/browser/accessibility/browser_accessibility_position.cc b/content/browser/accessibility/browser_accessibility_position.cc
index f757f95..6b9564c 100644
--- a/content/browser/accessibility/browser_accessibility_position.cc
+++ b/content/browser/accessibility/browser_accessibility_position.cc
@@ -68,6 +68,17 @@
                      : AXPosition::INVALID_INDEX;
 }
 
+base::stack<BrowserAccessibility*>
+BrowserAccessibilityPosition::GetAncestorAnchors() const {
+  base::stack<BrowserAccessibility*> anchors;
+  BrowserAccessibility* current_anchor = GetAnchor();
+  while (current_anchor) {
+    anchors.push(current_anchor);
+    current_anchor = current_anchor->PlatformGetParent();
+  }
+  return anchors;
+}
+
 void BrowserAccessibilityPosition::AnchorParent(AXTreeID* tree_id,
                                                 int32_t* parent_id) const {
   DCHECK(tree_id);
diff --git a/content/browser/accessibility/browser_accessibility_position.h b/content/browser/accessibility/browser_accessibility_position.h
index 9637aac..e722850 100644
--- a/content/browser/accessibility/browser_accessibility_position.h
+++ b/content/browser/accessibility/browser_accessibility_position.h
@@ -39,6 +39,7 @@
                    int32_t* child_id) const override;
   int AnchorChildCount() const override;
   int AnchorIndexInParent() const override;
+  base::stack<BrowserAccessibility*> GetAncestorAnchors() const override;
   void AnchorParent(AXTreeID* tree_id, int32_t* parent_id) const override;
   BrowserAccessibility* GetNodeInTree(AXTreeID tree_id,
                                       int32_t node_id) const override;
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index d0d8134..64723b1 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -91,7 +91,8 @@
 
 blink::mojom::PermissionStatus GetBackgroundSyncPermissionOnUIThread(
     scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
-    const url::Origin& origin) {
+    const url::Origin& origin,
+    BackgroundSyncType sync_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   BrowserContext* browser_context =
@@ -106,7 +107,10 @@
   // The requesting origin always matches the embedding origin.
   GURL origin_url = origin.GetURL();
   return permission_controller->GetPermissionStatus(
-      PermissionType::BACKGROUND_SYNC, origin_url, origin_url);
+      sync_type == BackgroundSyncType::ONE_SHOT
+          ? PermissionType::BACKGROUND_SYNC
+          : PermissionType::PERIODIC_BACKGROUND_SYNC,
+      origin_url, origin_url);
 }
 
 void NotifyBackgroundSyncRegisteredOnUIThread(
@@ -305,12 +309,26 @@
     return;
   }
 
-  op_scheduler_.ScheduleOperation(
-      CacheStorageSchedulerOp::kBackgroundSync,
-      base::BindOnce(&BackgroundSyncManager::RegisterCheckIfHasMainFrame,
-                     weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
-                     std::move(options),
-                     op_scheduler_.WrapCallbackToRunNext(std::move(callback))));
+  if (GetBackgroundSyncType(options) == BackgroundSyncType::ONE_SHOT) {
+    op_scheduler_.ScheduleOperation(
+        CacheStorageSchedulerOp::kBackgroundSync,
+        base::BindOnce(
+            &BackgroundSyncManager::RegisterCheckIfHasMainFrame,
+            weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
+            std::move(options),
+            op_scheduler_.WrapCallbackToRunNext(std::move(callback))));
+  } else {
+    // Periodic Background Sync events already have a pre-defined cadence which
+    // the user agent decides. Don't block registration if there's no top level
+    // frame at the time of registration.
+    op_scheduler_.ScheduleOperation(
+        CacheStorageSchedulerOp::kBackgroundSync,
+        base::BindOnce(
+            &BackgroundSyncManager::RegisterImpl,
+            weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
+            std::move(options),
+            op_scheduler_.WrapCallbackToRunNext(std::move(callback))));
+  }
 }
 
 void BackgroundSyncManager::DidResolveRegistration(
@@ -605,11 +623,12 @@
     return;
   }
 
+  BackgroundSyncType sync_type = GetBackgroundSyncType(options);
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&GetBackgroundSyncPermissionOnUIThread,
-                     service_worker_context_,
-                     url::Origin::Create(sw_registration->scope().GetOrigin())),
+      base::BindOnce(
+          &GetBackgroundSyncPermissionOnUIThread, service_worker_context_,
+          url::Origin::Create(sw_registration->scope().GetOrigin()), sync_type),
       base::BindOnce(&BackgroundSyncManager::RegisterDidAskForPermission,
                      weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
                      std::move(options), std::move(callback)));
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index 6b7a73f..dccc267 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -116,6 +116,9 @@
     ON_CALL(*mock_permission_manager,
             GetPermissionStatus(PermissionType::BACKGROUND_SYNC, _, _))
         .WillByDefault(Return(blink::mojom::PermissionStatus::GRANTED));
+    ON_CALL(*mock_permission_manager,
+            GetPermissionStatus(PermissionType::PERIODIC_BACKGROUND_SYNC, _, _))
+        .WillByDefault(Return(blink::mojom::PermissionStatus::GRANTED));
     helper_->browser_context()->SetPermissionControllerDelegate(
         std::move(mock_permission_manager));
 
@@ -577,6 +580,13 @@
                                   expected_origin, expected_origin))
       .WillOnce(testing::Return(blink::mojom::PermissionStatus::DENIED));
   EXPECT_FALSE(Register(sync_options_1_));
+
+  sync_options_2_.min_interval = 36000;
+  EXPECT_CALL(*mock_permission_manager,
+              GetPermissionStatus(PermissionType::PERIODIC_BACKGROUND_SYNC,
+                                  expected_origin, expected_origin))
+      .WillOnce(testing::Return(blink::mojom::PermissionStatus::DENIED));
+  EXPECT_FALSE(Register(sync_options_2_));
 }
 
 TEST_F(BackgroundSyncManagerTest, RegisterPermissionGranted) {
@@ -589,6 +599,13 @@
                                   expected_origin, expected_origin))
       .WillOnce(testing::Return(blink::mojom::PermissionStatus::GRANTED));
   EXPECT_TRUE(Register(sync_options_1_));
+
+  sync_options_2_.min_interval = 36000;
+  EXPECT_CALL(*mock_permission_manager,
+              GetPermissionStatus(PermissionType::PERIODIC_BACKGROUND_SYNC,
+                                  expected_origin, expected_origin))
+      .WillOnce(testing::Return(blink::mojom::PermissionStatus::GRANTED));
+  EXPECT_TRUE(Register(sync_options_2_));
 }
 
 TEST_F(BackgroundSyncManagerTest, TwoRegistrations) {
diff --git a/content/browser/devtools/protocol/browser_handler.cc b/content/browser/devtools/protocol/browser_handler.cc
index 17af579..085f1c2 100644
--- a/content/browser/devtools/protocol/browser_handler.cc
+++ b/content/browser/devtools/protocol/browser_handler.cc
@@ -144,6 +144,9 @@
     *out_type = PermissionType::BACKGROUND_FETCH;
   } else if (type == protocol::Browser::PermissionTypeEnum::IdleDetection) {
     *out_type = PermissionType::IDLE_DETECTION;
+  } else if (type ==
+             protocol::Browser::PermissionTypeEnum::PeriodicBackgroundSync) {
+    *out_type = PermissionType::PERIODIC_BACKGROUND_SYNC;
   } else {
     return Response::InvalidParams("Unknown permission type: " + type);
   }
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 9d34dc1..02d54e7 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -81,7 +81,6 @@
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
-#include "services/service_manager/public/cpp/connector.h"
 #include "storage/browser/blob/blob_url_loader_factory.h"
 #include "storage/browser/blob/blob_url_request_job_factory.h"
 #include "url/origin.h"
@@ -673,23 +672,6 @@
                            : nullptr;
 }
 
-std::unique_ptr<service_manager::Connector>
-DownloadManagerImpl::GetServiceConnector() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  service_manager::Connector* connector = GetServiceManagerConnector();
-  if (connector)
-    return connector->Clone();  // Clone for use on a different thread.
-  return nullptr;
-}
-
-service_manager::Connector* DownloadManagerImpl::GetServiceManagerConnector() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (auto* connection = ServiceManagerConnection::GetForProcess())
-    return connection->GetConnector();
-  return nullptr;
-}
-
 void DownloadManagerImpl::StartDownload(
     std::unique_ptr<download::DownloadCreateInfo> info,
     std::unique_ptr<download::InputStream> stream,
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index f2dd1e4..b6859f1 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -207,7 +207,6 @@
       override;
   net::URLRequestContextGetter* GetURLRequestContextGetter(
       const download::DownloadCreateInfo& info) override;
-  std::unique_ptr<service_manager::Connector> GetServiceConnector() override;
 
   // Creates a new download item and call |callback|.
   void CreateNewDownloadItemToStart(
@@ -258,7 +257,6 @@
       download::DownloadItemImpl* download) override;
   bool IsOffTheRecord() const override;
   void ReportBytesWasted(download::DownloadItemImpl* download) override;
-  service_manager::Connector* GetServiceManagerConnector() override;
 
   // Drops a download before it is created.
   void DropDownload();
diff --git a/content/browser/download/url_downloader_factory.cc b/content/browser/download/url_downloader_factory.cc
index 387b79dea..9d2c165 100644
--- a/content/browser/download/url_downloader_factory.cc
+++ b/content/browser/download/url_downloader_factory.cc
@@ -9,7 +9,6 @@
 #include "content/browser/download/download_request_core.h"
 #include "content/browser/download/url_downloader.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace content {
 
@@ -25,7 +24,6 @@
         url_loader_factory_getter,
     const download::URLSecurityPolicy& url_security_policy,
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-    std::unique_ptr<service_manager::Connector> connector,
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
   std::unique_ptr<net::URLRequest> url_request =
       DownloadRequestCore::CreateRequestOnIOThread(
diff --git a/content/browser/download/url_downloader_factory.h b/content/browser/download/url_downloader_factory.h
index 6c70cc8a..23b287f 100644
--- a/content/browser/download/url_downloader_factory.h
+++ b/content/browser/download/url_downloader_factory.h
@@ -35,7 +35,6 @@
           shared_url_loader_factory,
       const download::URLSecurityPolicy& url_security_policy,
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
-      std::unique_ptr<service_manager::Connector> connector,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) override;
 };
 
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 2e00a540..de3b289 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2917,6 +2917,10 @@
       std::move(subresource_loader_factories));
 }
 
+blink::FrameOwnerElementType RenderFrameHostImpl::GetFrameOwnerElementType() {
+  return frame_tree_node_->frame_owner_element_type();
+}
+
 void RenderFrameHostImpl::OnDidAccessInitialDocument() {
   delegate_->DidAccessInitialDocument();
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 636f320..9def072a 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -276,6 +276,7 @@
   void PrepareForInnerWebContentsAttach(
       PrepareForInnerWebContentsAttachCallback callback) override;
   void UpdateSubresourceLoaderFactories() override;
+  blink::FrameOwnerElementType GetFrameOwnerElementType() override;
 
   // IPC::Sender
   bool Send(IPC::Message* msg) override;
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc
index 6d552550..d698c59 100644
--- a/content/browser/permissions/permission_service_impl.cc
+++ b/content/browser/permissions/permission_service_impl.cc
@@ -88,6 +88,9 @@
     case PermissionName::IDLE_DETECTION:
       *permission_type = PermissionType::IDLE_DETECTION;
       return true;
+    case PermissionName::PERIODIC_BACKGROUND_SYNC:
+      *permission_type = PermissionType::PERIODIC_BACKGROUND_SYNC;
+      return true;
   }
 
   NOTREACHED();
diff --git a/content/browser/resources/process/process_internals.html b/content/browser/resources/process/process_internals.html
index 01ac075..07d458c3 100644
--- a/content/browser/resources/process/process_internals.html
+++ b/content/browser/resources/process/process_internals.html
@@ -8,8 +8,9 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome://resources/js/cr.js"></script>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-  <script src="chrome://resources/js/url.mojom-lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js">
+  </script>
+  <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
 
   <link rel="stylesheet" href="chrome://resources/css/tree.css">
   <script src="chrome://resources/js/cr/ui.js"></script>
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc
index 4c68ca1..ee71a1a 100644
--- a/content/browser/webui/shared_resources_data_source.cc
+++ b/content/browser/webui/shared_resources_data_source.cc
@@ -92,20 +92,40 @@
 
 const std::map<int, std::string> CreateContentResourceIdToAliasMap() {
   return std::map<int, std::string>{
-      {IDR_URL_MOJO_JS, "js/url.mojom-lite.js"},
-      {IDR_ORIGIN_MOJO_JS, "js/origin.mojom-lite.js"},
-      {IDR_UNGUESSABLE_TOKEN_MOJO_JS, "js/unguessable_token.mojom-lite.js"},
+      {IDR_ORIGIN_MOJO_HTML, "mojo/url/mojom/origin.mojom.html"},
+      {IDR_ORIGIN_MOJO_JS, "mojo/url/mojom/origin.mojom-lite.js"},
+      {IDR_UNGUESSABLE_TOKEN_MOJO_HTML,
+       "mojo/mojo/public/mojom/base/unguessable_token.mojom.html"},
+      {IDR_UNGUESSABLE_TOKEN_MOJO_JS,
+       "mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js"},
+      {IDR_URL_MOJO_HTML, "mojo/url/mojom/url.mojom.html"},
+      {IDR_URL_MOJO_JS, "mojo/url/mojom/url.mojom-lite.js"},
   };
 }
 
 const std::map<int, std::string> CreateMojoResourceIdToAliasMap() {
   return std::map<int, std::string> {
-    {IDR_MOJO_MOJO_BINDINGS_LITE_JS, "js/mojo_bindings_lite.js"},
-        {IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS, "js/big_buffer.mojom-lite.js"},
-        {IDR_MOJO_FILE_MOJOM_LITE_JS, "js/file.mojom-lite.js"},
-        {IDR_MOJO_STRING16_MOJOM_LITE_JS, "js/string16.mojom-lite.js"},
+    {IDR_MOJO_MOJO_BINDINGS_LITE_HTML,
+     "mojo/mojo/public/js/mojo_bindings_lite.html"},
+        {IDR_MOJO_MOJO_BINDINGS_LITE_JS,
+         "mojo/mojo/public/js/mojo_bindings_lite.js"},
+        {IDR_MOJO_BIG_BUFFER_MOJOM_HTML,
+         "mojo/mojo/public/mojom/base/big_buffer.mojom.html"},
+        {IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS,
+         "mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js"},
+        {IDR_MOJO_FILE_MOJOM_HTML,
+         "mojo/mojo/public/mojom/base/file.mojom.html"},
+        {IDR_MOJO_FILE_MOJOM_LITE_JS,
+         "mojo/mojo/public/mojom/base/file.mojom-lite.js"},
+        {IDR_MOJO_STRING16_MOJOM_HTML,
+         "mojo/mojo/public/mojom/base/string16.mojom.html"},
+        {IDR_MOJO_STRING16_MOJOM_LITE_JS,
+         "mojo/mojo/public/mojom/base/string16.mojom-lite.js"},
 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
-        {IDR_MOJO_TIME_MOJOM_LITE_JS, "js/time.mojom-lite.js"},
+        {IDR_MOJO_TIME_MOJOM_HTML,
+         "mojo/mojo/public/mojom/base/time.mojom.html"},
+        {IDR_MOJO_TIME_MOJOM_LITE_JS,
+         "mojo/mojo/public/mojom/base/time.mojom-lite.js"},
 #endif  // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
   };
 }
@@ -113,14 +133,30 @@
 #if defined(OS_CHROMEOS)
 const std::map<int, std::string> CreateChromeosMojoResourceIdToAliasMap() {
   return std::map<int, std::string>{
+      {IDR_MULTIDEVICE_DEVICE_SYNC_MOJOM_HTML,
+       "mojo/chromeos/services/device_sync/public/mojom/"
+       "device_sync.mojom.html"},
       {IDR_MULTIDEVICE_DEVICE_SYNC_MOJOM_LITE_JS,
-       "js/chromeos/device_sync.mojom-lite.js"},
+       "mojo/chromeos/services/device_sync/public/mojom/"
+       "device_sync.mojom-lite.js"},
+      {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_MOJOM_HTML,
+       "mojo/chromeos/services/multidevice_setup/public/mojom/"
+       "multidevice_setup.mojom.html"},
       {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_MOJOM_LITE_JS,
-       "js/chromeos/multidevice_setup.mojom-lite.js"},
+       "mojo/chromeos/services/multidevice_setup/public/mojom/"
+       "multidevice_setup.mojom-lite.js"},
+      {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_CONSTANTS_MOJOM_HTML,
+       "mojo/chromeos/services/multidevice_setup/public/mojom/"
+       "constants.mojom.html"},
       {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_CONSTANTS_MOJOM_LITE_JS,
-       "js/chromeos/multidevice_setup_constants.mojom-lite.js"},
+       "mojo/chromeos/services/multidevice_setup/public/mojom/"
+       "constants.mojom-lite.js"},
+      {IDR_MULTIDEVICE_MULTIDEVICE_TYPES_MOJOM_HTML,
+       "mojo/chromeos/components/multidevice/mojom/"
+       "multidevice_types.mojom.html"},
       {IDR_MULTIDEVICE_MULTIDEVICE_TYPES_MOJOM_LITE_JS,
-       "js/chromeos/multidevice_types.mojom-lite.js"},
+       "mojo/chromeos/components/multidevice/mojom/"
+       "multidevice_types.mojom-lite.js"},
   };
 }
 #endif  // !defined(OS_CHROMEOS)
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 93087b7..7f09599 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -169,6 +169,9 @@
   WebRuntimeFeatures::EnableReducedReferrerGranularity(
       base::FeatureList::IsEnabled(features::kReducedReferrerGranularity));
 
+  if (base::FeatureList::IsEnabled(features::kPeriodicBackgroundSync))
+    WebRuntimeFeatures::EnablePeriodicBackgroundSync(true);
+
   if (command_line.HasSwitch(switches::kDisablePermissionsAPI))
     WebRuntimeFeatures::EnablePermissionsAPI(false);
 
diff --git a/content/public/browser/permission_type.h b/content/public/browser/permission_type.h
index 16c3c2ad..5082c001 100644
--- a/content/public/browser/permission_type.h
+++ b/content/public/browser/permission_type.h
@@ -31,6 +31,7 @@
   PAYMENT_HANDLER = 16,
   BACKGROUND_FETCH = 17,
   IDLE_DETECTION = 18,
+  PERIODIC_BACKGROUND_SYNC = 19,
 
   // Always keep this at the end.
   NUM,
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index 056aa14b..69821b2 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -19,6 +19,7 @@
 #include "ipc/ipc_sender.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
 #include "third_party/blink/public/common/frame/sandbox_flags.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
 #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-forward.h"
@@ -395,6 +396,12 @@
   // running renderer, or in case of Network Service connection errors.
   virtual void UpdateSubresourceLoaderFactories() = 0;
 
+  // Returns the type of frame owner element for the FrameTreeNode associated
+  // with this RenderFrameHost (e.g., <iframe>, <object>, etc). Note that it
+  // returns blink::FrameOwnerElementType::kNone if the RenderFrameHost is a
+  // main frame.
+  virtual blink::FrameOwnerElementType GetFrameOwnerElementType() = 0;
+
  private:
   // This interface should only be implemented inside content.
   friend class RenderFrameHostImpl;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 3526e40..be0e385 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -330,6 +330,10 @@
 const base::Feature kPdfIsolation = {"PdfIsolation",
                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Whether web apps can run periodic tasks upon network connectivity.
+const base::Feature kPeriodicBackgroundSync{"PeriodicBackgroundSync",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Whether we should use the navigation_client mojo interface for navigations.
 const base::Feature kPerNavigationMojoInterface = {
     "PerNavigationMojoInterface", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index c81bbef0..bce6055 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -81,6 +81,7 @@
 CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
 CONTENT_EXPORT extern const base::Feature kPaymentRequestHasEnrolledInstrument;
 CONTENT_EXPORT extern const base::Feature kPdfIsolation;
+CONTENT_EXPORT extern const base::Feature kPeriodicBackgroundSync;
 CONTENT_EXPORT extern const base::Feature kPerNavigationMojoInterface;
 CONTENT_EXPORT extern const base::Feature kPepper3DImageChromium;
 CONTENT_EXPORT extern const base::Feature kPrioritizeBootstrapTasks;
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 0a6af92..3a4bcba4 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -267,4 +267,8 @@
 
 void ContentRendererClient::DidSetUserAgent(const std::string& user_agent) {}
 
+bool ContentRendererClient::RequiresHtmlImports(const GURL& url) {
+  return false;
+}
+
 }  // namespace content
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index fad5f104..16308aa 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -425,6 +425,12 @@
   // The user agent string is given from the browser process. This is called at
   // most once.
   virtual void DidSetUserAgent(const std::string& user_agent);
+
+  // Returns true if |url| still requires native HTML imports. Used for Web UI
+  // pages.
+  // TODO(https://crbug.com/937747): Remove this function, when all WebUIs have
+  // been migrated to use the HTML Imports Polyfill.
+  virtual bool RequiresHtmlImports(const GURL& url);
 };
 
 }  // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index bafe2572..a6b62dc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3482,7 +3482,7 @@
   // use the old web APIs.
   // After completion of the migration, we should remove this.
   // See crbug.com/924871 for detail.
-  if (common_params.url.SchemeIs(content::kChromeUIScheme)) {
+  if (GetContentClient()->renderer()->RequiresHtmlImports(common_params.url)) {
     blink::WebRuntimeFeatures::EnableShadowDOMV0(true);
     blink::WebRuntimeFeatures::EnableCustomElementsV0(true);
     blink::WebRuntimeFeatures::EnableHTMLImports(true);
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index ba909aa1..4ad0b2f 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -261,6 +261,9 @@
     # #include'ed by renderer/web_test/blink_test_runner.h
     ":mojo_bindings",
 
+    # The generated mojom JS bindings are used by web tests.
+    ":mojo_bindings_js",
+
     # This exposes all public content APIs.
     "//content/public/app:both",
     "//content/public/browser",
@@ -922,6 +925,7 @@
     "//skia/public/interfaces",
     "//ui/gfx/geometry/mojo",
     "//url/mojom:url_mojom_gurl",
+    "//url/mojom:url_mojom_origin",
   ]
 }
 
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc
index 0da00e47..a88c961e 100644
--- a/content/shell/browser/shell.cc
+++ b/content/shell/browser/shell.cc
@@ -487,8 +487,6 @@
 #if defined(OS_ANDROID)
   PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
 #endif
-  if (!switches::IsRunWebTestsSwitchPresent())
-    return;
   if (is_fullscreen_ != enter_fullscreen) {
     is_fullscreen_ = enter_fullscreen;
     web_contents->GetRenderViewHost()
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc
index 46b08216..f521188 100644
--- a/content/shell/browser/shell_permission_manager.cc
+++ b/content/shell/browser/shell_permission_manager.cc
@@ -18,18 +18,36 @@
 namespace {
 
 bool IsWhitelistedPermissionType(PermissionType permission) {
-  return permission == PermissionType::GEOLOCATION ||
-         permission == PermissionType::MIDI ||
-         permission == PermissionType::SENSORS ||
-         permission == PermissionType::PAYMENT_HANDLER ||
-         permission == PermissionType::IDLE_DETECTION ||
-         // Background Sync and Background Fetch browser tests require
-         // permission to be granted by default.
-         // TODO(nsatragno): add a command line flag so that it's only granted
-         // for tests.
-         permission == PermissionType::BACKGROUND_SYNC ||
-         permission == PermissionType::BACKGROUND_FETCH ||
-         permission == PermissionType::ACCESSIBILITY_EVENTS;
+  switch (permission) {
+    case PermissionType::GEOLOCATION:
+    case PermissionType::MIDI:
+    case PermissionType::SENSORS:
+    case PermissionType::ACCESSIBILITY_EVENTS:
+    case PermissionType::PAYMENT_HANDLER:
+
+    // Background Sync and Background Fetch browser tests require
+    // permission to be granted by default.
+    case PermissionType::BACKGROUND_SYNC:
+    case PermissionType::BACKGROUND_FETCH:
+    case PermissionType::PERIODIC_BACKGROUND_SYNC:
+
+    case PermissionType::IDLE_DETECTION:
+      return true;
+    case PermissionType::MIDI_SYSEX:
+    case PermissionType::NOTIFICATIONS:
+    case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+    case PermissionType::DURABLE_STORAGE:
+    case PermissionType::AUDIO_CAPTURE:
+    case PermissionType::VIDEO_CAPTURE:
+    case PermissionType::FLASH:
+    case PermissionType::CLIPBOARD_READ:
+    case PermissionType::CLIPBOARD_WRITE:
+    case PermissionType::NUM:
+      return false;
+  }
+
+  NOTREACHED();
+  return false;
 }
 
 }  // namespace
diff --git a/content/shell/browser/web_test/fake_bluetooth_chooser.cc b/content/shell/browser/web_test/fake_bluetooth_chooser.cc
index 79508bb..d99451e 100644
--- a/content/shell/browser/web_test/fake_bluetooth_chooser.cc
+++ b/content/shell/browser/web_test/fake_bluetooth_chooser.cc
@@ -16,6 +16,8 @@
 FakeBluetoothChooser::~FakeBluetoothChooser() {
   SetTestBluetoothScanDuration(
       BluetoothTestScanDurationSetting::kImmediateTimeout);
+  // TODO(https://crbug.com/719826): Send a
+  // mojom::ChooserEventType::CHOOSER_CLOSED event to the client.
 }
 
 // static
@@ -41,34 +43,35 @@
 }
 
 void FakeBluetoothChooser::SelectPeripheral(
-    const std::string& peripheral_address,
-    SelectPeripheralCallback callback) {
-  // TODO(https://crbug.com/719826): Record the event and send a
-  // BluetoothChooser::SELECTED event to |event_handler_|.
+    const std::string& peripheral_address) {
+  event_handler_.Run(BluetoothChooser::Event::SELECTED, peripheral_address);
+}
+
+void FakeBluetoothChooser::Cancel() {
+  // TODO(https://crbug.com/719826): Send a BluetoothChooser::CANCELLED event to
+  // |event_handler_| and a mojom::ChooserEventType::CHOOSER_CLOSED to the
+  // client.
   NOTREACHED();
 }
 
-void FakeBluetoothChooser::Cancel(CancelCallback callback) {
-  // TODO(https://crbug.com/719826): Record the event and send a
-  // BluetoothChooser::CANCELLED event to |event_handler_|.
-  NOTREACHED();
-}
-
-void FakeBluetoothChooser::Rescan(RescanCallback callback) {
-  // TODO(https://crbug.com/719826): Record the event and send a
-  // BluetoothChooser::RESCAN event to |event_handler_|.
+void FakeBluetoothChooser::Rescan() {
+  // TODO(https://crbug.com/719826): Send a BluetoothChooser::RESCAN event to
+  // |event_handler_| and the appropriate mojom::ChooserEventType to describe
+  // the discovery session.
   NOTREACHED();
 }
 
 // BluetoothChooser overrides
 
 void FakeBluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
-  // TODO(https://crbug.com/719826): Record the event.
+  // TODO(https://crbug.com/719826): Send the appropriate
+  // mojom::ChooserEventType to the client.
   NOTREACHED();
 }
 
 void FakeBluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
-  // TODO(https://crbug.com/719826): Record the event.
+  // TODO(https://crbug.com/719826): Send the appropriate
+  // mojom::ChooserEventType to the client.
   NOTREACHED();
 }
 
@@ -78,7 +81,8 @@
                                              bool is_gatt_connected,
                                              bool is_paired,
                                              int signal_strength_level) {
-  // TODO(https://crbug.com/719826): Record the event.
+  // TODO(https://crbug.com/719826): Send a
+  // mojom::ChooserEventType::ADD_OR_UPDATE_DEVICE to the client.
   NOTREACHED();
 }
 
diff --git a/content/shell/browser/web_test/fake_bluetooth_chooser.h b/content/shell/browser/web_test/fake_bluetooth_chooser.h
index 613f8cb..fe7f6cbf5 100644
--- a/content/shell/browser/web_test/fake_bluetooth_chooser.h
+++ b/content/shell/browser/web_test/fake_bluetooth_chooser.h
@@ -46,10 +46,9 @@
 
   void WaitForEvents(uint32_t num_of_events,
                      WaitForEventsCallback callback) override;
-  void SelectPeripheral(const std::string& peripheral_address,
-                        SelectPeripheralCallback callback) override;
-  void Cancel(CancelCallback callback) override;
-  void Rescan(RescanCallback callback) override;
+  void SelectPeripheral(const std::string& peripheral_address) override;
+  void Cancel() override;
+  void Rescan() override;
 
   // BluetoothChooser overrides:
 
diff --git a/content/shell/browser/web_test/web_test_message_filter.cc b/content/shell/browser/web_test/web_test_message_filter.cc
index fa6615bf..ff3f157 100644
--- a/content/shell/browser/web_test/web_test_message_filter.cc
+++ b/content/shell/browser/web_test/web_test_message_filter.cc
@@ -204,6 +204,8 @@
     type = PermissionType::SENSORS;
   } else if (name == "background-fetch") {
     type = PermissionType::BACKGROUND_FETCH;
+  } else if (name == "periodic-background-sync") {
+    type = PermissionType::PERIODIC_BACKGROUND_SYNC;
   } else {
     NOTREACHED();
     type = PermissionType::NOTIFICATIONS;
diff --git a/content/shell/common/web_test/fake_bluetooth_chooser.mojom b/content/shell/common/web_test/fake_bluetooth_chooser.mojom
index d1b5958..2c16b75 100644
--- a/content/shell/common/web_test/fake_bluetooth_chooser.mojom
+++ b/content/shell/common/web_test/fake_bluetooth_chooser.mojom
@@ -4,6 +4,8 @@
 
 module content.mojom;
 
+import "url/mojom/origin.mojom";
+
 // This interface is being developed to support Web Platform Tests for Web
 // Bluetooth.
 // https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY
@@ -24,15 +26,14 @@
 // Indicates the types of Bluetooth chooser events.
 enum ChooserEventType {
   CHOOSER_OPENED,
-  SCAN_STARTED,
-  DEVICE_UPDATE,
+  CHOOSER_CLOSED,
   ADAPTER_REMOVED,
   ADAPTER_DISABLED,
   ADAPTER_ENABLED,
   DISCOVERY_FAILED_TO_START,
   DISCOVERING,
   DISCOVERY_IDLE,
-  ADD_DEVICE,
+  ADD_OR_UPDATE_DEVICE,
 };
 
 // FakeBluetoothChooser allows clients to control the global state of the
@@ -45,13 +46,13 @@
 
   // Simulates a user selecting the given |peripheral_address| in the Bluetooth
   // chooser.
-  SelectPeripheral(string peripheral_address) => ();
+  SelectPeripheral(string peripheral_address);
 
   // Calls the event handler function with the CANCELLED event.
-  Cancel() => ();
+  Cancel();
 
   // Calls the event handler function with the RESCAN event.
-  Rescan() => ();
+  Rescan();
 };
 
 // FakeBluetoothChooserEvent describes the type of chooser event that has been
@@ -61,7 +62,7 @@
 
   // Describes the origin the chooser is currently displaying.
   // This field will be used by the |CHOOSER_OPENED| event type.
-  string? origin;
+  url.mojom.Origin? origin;
 
   // Describes the MAC address of the Bluetooth device.
   string? peripheral_address;
diff --git a/content/test/data/web_ui_mojo.html b/content/test/data/web_ui_mojo.html
index 519cda1..1c7f02c 100644
--- a/content/test/data/web_ui_mojo.html
+++ b/content/test/data/web_ui_mojo.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-  <script src="chrome://resources/js/mojo_bindings_lite.js"></script>
+  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="content/test/data/web_ui_test_mojo_bindings.mojom-lite.js"></script>
   <script src="web_ui_mojo.js"></script>
 </head>
diff --git a/device/bluetooth/public/mojom/BUILD.gn b/device/bluetooth/public/mojom/BUILD.gn
index 0adcd734..7a8bd86 100644
--- a/device/bluetooth/public/mojom/BUILD.gn
+++ b/device/bluetooth/public/mojom/BUILD.gn
@@ -8,11 +8,6 @@
   sources = [
     "uuid.mojom",
   ]
-
-  # This mojom interface is exposed publicly to layout tests which use
-  # prepackaged redistributable JS bindings. It is therefore not desirable to
-  # scramble these messages.
-  scramble_message_ids = false
 }
 
 mojom("fake_bluetooth_interfaces") {
@@ -23,11 +18,6 @@
   public_deps = [
     ":mojom",
   ]
-
-  # This mojom interface is exposed publicly to layout tests which use
-  # prepackaged redistributable JS bindings. It is therefore not desirable to
-  # scramble these messages.
-  scramble_message_ids = false
 }
 
 # Experimental interfaces are not ready for production use yet. See README.md
diff --git a/device/bluetooth/test/fake_central.cc b/device/bluetooth/test/fake_central.cc
index 61e4490..8a165a4 100644
--- a/device/bluetooth/test/fake_central.cc
+++ b/device/bluetooth/test/fake_central.cc
@@ -66,8 +66,7 @@
 void FakeCentral::SimulateAdvertisementReceived(
     mojom::ScanResultPtr scan_result_ptr,
     SimulateAdvertisementReceivedCallback callback) {
-  // TODO(https://crbug.com/719826): Add a DCHECK to proceed only if a scan is
-  // currently in progress.
+  DCHECK(num_discovery_sessions_ > 0);
   auto* fake_peripheral = GetFakePeripheral(scan_result_ptr->device_address);
   const bool is_new_device = fake_peripheral == nullptr;
   if (is_new_device) {
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
index 594bc2d5..4a476ec 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -153,6 +153,15 @@
     embedder_widget_routing_id_ =
         rfh->GetView()->GetRenderWidgetHost()->GetRoutingID();
   }
+  auto owner_type = rfh ? rfh->GetFrameOwnerElementType()
+                        : blink::FrameOwnerElementType::kNone;
+  // If the embedder frame is the ContentFrame() of a plugin element, then there
+  // could be a MimeHandlerViewFrameContainer in the parent frame. Note that
+  // the MHVFC is only created through HTMLPlugInElement::UpdatePlugin (manually
+  // navigating a plugin element's window would create a MHVFC).
+  maybe_has_frame_container_ =
+      owner_type == blink::FrameOwnerElementType::kEmbed ||
+      owner_type == blink::FrameOwnerElementType::kObject;
   DCHECK_NE(MSG_ROUTING_NONE, embedder_widget_routing_id_);
 }
 
@@ -433,13 +442,12 @@
     // TODO(ekaramad): Verify if the container manager corresponding to the
     // embedder frame itself needs to be notified; possibly for postMessage
     // support from print helpers (https://crbug.com/659750).
-    if (auto* ancestor = GetEmbedderFrame()->GetParent()) {
-      // TODO(ekaramad): We should only send this IPC when the FrameOwner of the
-      // embedder frame is a plugin element (https://crbug.com/957373).
+    if (maybe_has_frame_container_) {
       // For plugin elements, the embedder should be notified so that the queued
       // messages (postMessage) are forwarded to the guest page.
       mojom::MimeHandlerViewContainerManagerPtr container_manager;
-      ancestor->GetRemoteInterfaces()->GetInterface(&container_manager);
+      GetEmbedderFrame()->GetParent()->GetRemoteInterfaces()->GetInterface(
+          &container_manager);
       container_manager->DidLoad(element_instance_id(), original_resource_url_);
     }
   }
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
index 637d6d6..3506eb1 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -187,6 +187,9 @@
   bool is_embedder_fullscreen_ = false;
   bool plugin_can_save_ = false;
   GURL original_resource_url_;
+  // True when the MimeHandlerViewGeust might have a frame container in its
+  // embedder's parent frame to facilitate postMessage.
+  bool maybe_has_frame_container_ = false;
   mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control_;
 
   DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuest);
diff --git a/extensions/common/api/PRESUBMIT.py b/extensions/common/api/PRESUBMIT.py
index 97f4cd4..cfb76f85 100644
--- a/extensions/common/api/PRESUBMIT.py
+++ b/extensions/common/api/PRESUBMIT.py
@@ -22,8 +22,8 @@
 
   join = input_api.os_path.join
   api_root = input_api.PresubmitLocalPath()
-  externs_root = join(api_root, '..', '..', '..', 'third_party',
-      'closure_compiler', 'externs')
+  externs_root = input_api.os_path.abspath(join(
+      api_root, '..', '..', '..', 'third_party', 'closure_compiler', 'externs'))
 
   api_pairs = {
     join(api_root, 'automation.idl'): join(externs_root, 'automation.js'),
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index cf940f9..722fe3e 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -1686,7 +1686,8 @@
           initWithBaseViewController:baseViewController
                         browserState:_mainBrowserState];
   self.googleServicesNavigationCoordinator.delegate = self;
-  self.googleServicesNavigationCoordinator.dispatcher = self;
+  self.googleServicesNavigationCoordinator.dispatcherForSettings =
+      self.dispatcherForSettings;
   [self.googleServicesNavigationCoordinator start];
 }
 
diff --git a/ios/chrome/browser/search_engines/search_engine_tab_helper.mm b/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
index 71eccbc..fb5cf23d 100644
--- a/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
+++ b/ios/chrome/browser/search_engines/search_engine_tab_helper.mm
@@ -235,9 +235,11 @@
   // normally due to a form submit that opened in a new tab.
   if (last_index <= 0)
     return;
-  const web::NavigationItem* item = manager->GetItemAtIndex(last_index - 1);
+  const web::NavigationItem* current_item = manager->GetItemAtIndex(last_index);
+  const web::NavigationItem* previous_item =
+      manager->GetItemAtIndex(last_index - 1);
 
-  base::string16 keyword(GenerateKeywordFromNavigationItem(item));
+  base::string16 keyword(GenerateKeywordFromNavigationItem(previous_item));
   if (keyword.empty())
     return;
 
@@ -251,18 +253,19 @@
     return;
   }
 
-  const TemplateURL* current_url;
+  const TemplateURL* existing_url;
   if (!url_service->CanAddAutogeneratedKeyword(keyword, searchable_url,
-                                               &current_url))
+                                               &existing_url)) {
     return;
+  }
 
-  if (current_url) {
-    if (current_url->originating_url().is_valid()) {
+  if (existing_url) {
+    if (existing_url->originating_url().is_valid()) {
       // The existing keyword was generated from an OpenSearch description
       // document, don't regenerate.
       return;
     }
-    url_service->Remove(current_url);
+    url_service->Remove(existing_url);
   }
 
   TemplateURLData data;
@@ -270,15 +273,17 @@
   data.SetKeyword(keyword);
   data.SetURL(searchable_url.spec());
 
-  const GURL& current_favicon =
-      manager->GetLastCommittedItem()->GetFavicon().url;
-  // If the favicon url isn't valid, it means there really isn't a favicon, or
-  // the favicon url wasn't obtained before the load started. This assumes the
-  // latter.
-  if (current_favicon.is_valid()) {
-    data.favicon_url = current_favicon;
-  } else if (item->GetReferrer().url.is_valid()) {
-    data.favicon_url = TemplateURL::GenerateFaviconURL(item->GetReferrer().url);
+  // Try to get favicon url by following methods:
+  //   1. Get from FaviconStatus of previous NavigationItem;
+  //   2. Create by current NavigationItem's referrer if valid;
+  //   3. Create by previous NavigationItem's URL if valid;
+  if (previous_item->GetFavicon().url.is_valid()) {
+    data.favicon_url = previous_item->GetFavicon().url;
+  } else if (current_item->GetReferrer().url.is_valid()) {
+    data.favicon_url =
+        TemplateURL::GenerateFaviconURL(current_item->GetReferrer().url);
+  } else if (previous_item->GetURL().is_valid()) {
+    data.favicon_url = TemplateURL::GenerateFaviconURL(previous_item->GetURL());
   }
   data.safe_for_autoreplace = true;
   url_service->Add(std::make_unique<TemplateURL>(data));
diff --git a/ios/chrome/browser/search_engines/search_engine_tab_helper_unittest.mm b/ios/chrome/browser/search_engines/search_engine_tab_helper_unittest.mm
index e22a79e..a4c5171 100644
--- a/ios/chrome/browser/search_engines/search_engine_tab_helper_unittest.mm
+++ b/ios/chrome/browser/search_engines/search_engine_tab_helper_unittest.mm
@@ -141,6 +141,8 @@
   EXPECT_EQ(
       "https://chromium.test/index.php?title=chrooome&search={searchTerms}",
       new_url->data().url());
+  EXPECT_EQ(GURL("https://chromium.test/favicon.ico"),
+            new_url->data().favicon_url);
 }
 
 // Tests that SearchEngineTabHelper can add TemplateURL to TemplateURLService
@@ -186,6 +188,8 @@
   EXPECT_EQ(base::UTF8ToUTF16("chromium.test"), new_url->data().keyword());
   EXPECT_EQ(base::UTF8ToUTF16("chromium.test"), new_url->data().short_name());
   EXPECT_EQ(searchable_url.spec(), new_url->data().url());
+  const GURL expected_favicon_url = GURL(page_url.spec() + "favicon.ico");
+  EXPECT_EQ(expected_favicon_url, new_url->data().favicon_url);
 }
 
 // Test fixture for SearchEngineTabHelper class in incognito mode.
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm
index f4c3b716..7b34acf 100644
--- a/ios/chrome/browser/signin/authentication_service.mm
+++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -424,7 +424,7 @@
 }
 
 void AuthenticationService::ResetChromeIdentityServiceObserverForTesting() {
-  identity_service_observer_.RemoveAll();
+  DCHECK(!identity_service_observer_.IsObservingSources());
   identity_service_observer_.Add(
       ios::GetChromeBrowserProvider()->GetChromeIdentityService());
 }
diff --git a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
index 63c1efe..4a53333 100644
--- a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
+++ b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
@@ -8,6 +8,7 @@
     "alert_view_controller.mm",
   ]
   deps = [
+    "//base",
     "//ios/chrome/browser/ui/elements",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/common/ui_util",
@@ -15,3 +16,15 @@
   libs = [ "UIKit.framework" ]
   configs += [ "//build/config/compiler:enable_arc" ]
 }
+
+source_set("unit_tests") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  testonly = true
+  sources = [
+    "alert_view_controller_unittest.mm",
+  ]
+  deps = [
+    ":alert_view_controller",
+    "//testing/gtest:gtest",
+  ]
+}
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
index af54c4b..9472e8f1 100644
--- a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
+++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h"
 
+#include "base/logging.h"
 #import "ios/chrome/browser/ui/elements/gray_highlight_button.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
@@ -37,12 +38,10 @@
 constexpr CGFloat kAlertActionsSpacing = 12;
 
 // Insets for the content in the alert view.
-constexpr CGFloat kTitleInsetTop = 0;
 constexpr CGFloat kTitleInsetLeading = 20;
 constexpr CGFloat kTitleInsetBottom = 9;
 constexpr CGFloat kTitleInsetTrailing = 20;
 
-constexpr CGFloat kMessageInsetTop = 0;
 constexpr CGFloat kMessageInsetLeading = 20;
 constexpr CGFloat kMessageInsetBottom = 6;
 constexpr CGFloat kMessageInsetTrailing = 20;
@@ -54,7 +53,6 @@
 
 constexpr CGFloat kTextfieldStackInsetTop = 12;
 constexpr CGFloat kTextfieldStackInsetLeading = 12;
-constexpr CGFloat kTextfieldStackInsetBottom = 0;
 constexpr CGFloat kTextfieldStackInsetTrailing = 12;
 
 constexpr CGFloat kTextfieldInset = 8;
@@ -163,7 +161,7 @@
       isAccessibilityContentSize ? kAlertWidthAccessibilty : kAlertWidth;
   NSLayoutConstraint* widthConstraint =
       [self.contentView.widthAnchor constraintEqualToConstant:alertWidth];
-  widthConstraint.priority = 999;
+  widthConstraint.priority = UILayoutPriorityRequired - 1;
 
   [NSLayoutConstraint activateConstraints:@[
     widthConstraint,
@@ -198,14 +196,34 @@
 
   ]];
 
+  UIScrollView* scrollView = [[UIScrollView alloc] init];
+  scrollView.showsVerticalScrollIndicator = YES;
+  scrollView.showsHorizontalScrollIndicator = NO;
+  scrollView.translatesAutoresizingMaskIntoConstraints = NO;
+  scrollView.scrollEnabled = YES;
+  scrollView.contentInsetAdjustmentBehavior =
+      UIScrollViewContentInsetAdjustmentAlways;
+  [self.contentView addSubview:scrollView];
+  AddSameConstraints(scrollView, self.contentView);
+
   UIStackView* stackView = [[UIStackView alloc] init];
   stackView.axis = UILayoutConstraintAxisVertical;
   stackView.translatesAutoresizingMaskIntoConstraints = NO;
-  [self.contentView addSubview:stackView];
+  stackView.alignment = UIStackViewAlignmentCenter;
+  [scrollView addSubview:stackView];
+
+  NSLayoutConstraint* heightConstraint = [scrollView.heightAnchor
+      constraintEqualToAnchor:scrollView.contentLayoutGuide.heightAnchor
+                   multiplier:1];
+  // UILayoutPriorityDefaultHigh is the default priority for content
+  // compression. Setting this lower avoids compressing the content of the
+  // scroll view.
+  heightConstraint.priority = UILayoutPriorityDefaultHigh - 1;
+  heightConstraint.active = YES;
 
   ChromeDirectionalEdgeInsets stackViewInsets =
       ChromeDirectionalEdgeInsetsMake(kAlertMarginTop, 0, 0, 0);
-  AddSameConstraintsWithInsets(stackView, self.contentView, stackViewInsets);
+  AddSameConstraintsWithInsets(stackView, scrollView, stackViewInsets);
 
   if (self.title.length) {
     UILabel* titleLabel = [[UILabel alloc] init];
@@ -214,18 +232,14 @@
     titleLabel.textAlignment = NSTextAlignmentCenter;
     titleLabel.text = self.title;
     titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    [stackView addArrangedSubview:titleLabel];
+    [stackView setCustomSpacing:kTitleInsetBottom afterView:titleLabel];
 
-    UIView* titleContainer = [[UIView alloc] init];
-    [titleContainer addSubview:titleLabel];
-    titleContainer.translatesAutoresizingMaskIntoConstraints = NO;
-    [stackView addArrangedSubview:titleContainer];
-
-    ChromeDirectionalEdgeInsets contentInsets =
-        ChromeDirectionalEdgeInsetsMake(kTitleInsetTop, kTitleInsetLeading,
-                                        kTitleInsetBottom, kTitleInsetTrailing);
-    AddSameConstraintsWithInsets(titleLabel, titleContainer, contentInsets);
-    AddSameConstraintsToSides(titleContainer, self.contentView,
-                              LayoutSides::kTrailing | LayoutSides::kLeading);
+    ChromeDirectionalEdgeInsets titleInsets = ChromeDirectionalEdgeInsetsMake(
+        0, kTitleInsetLeading, 0, kTitleInsetTrailing);
+    AddSameConstraintsToSidesWithInsets(
+        titleLabel, self.contentView,
+        LayoutSides::kTrailing | LayoutSides::kLeading, titleInsets);
   }
 
   if (self.message.length) {
@@ -236,28 +250,17 @@
     messageLabel.textAlignment = NSTextAlignmentCenter;
     messageLabel.text = self.message;
     messageLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    [stackView addArrangedSubview:messageLabel];
+    [stackView setCustomSpacing:kMessageInsetBottom afterView:messageLabel];
 
-    UIView* messageContainer = [[UIView alloc] init];
-    [messageContainer addSubview:messageLabel];
-    messageContainer.translatesAutoresizingMaskIntoConstraints = NO;
-    [stackView addArrangedSubview:messageContainer];
-
-    ChromeDirectionalEdgeInsets contentInsets = ChromeDirectionalEdgeInsetsMake(
-        kMessageInsetTop, kMessageInsetLeading, kMessageInsetBottom,
-        kMessageInsetTrailing);
-    AddSameConstraintsWithInsets(messageLabel, messageContainer, contentInsets);
-    AddSameConstraintsToSides(messageContainer, self.contentView,
-                              LayoutSides::kTrailing | LayoutSides::kLeading);
+    ChromeDirectionalEdgeInsets messageInsets = ChromeDirectionalEdgeInsetsMake(
+        0, kMessageInsetLeading, 0, kMessageInsetTrailing);
+    AddSameConstraintsToSidesWithInsets(
+        messageLabel, self.contentView,
+        LayoutSides::kTrailing | LayoutSides::kLeading, messageInsets);
   }
 
   if (self.textFields.count) {
-    // |container| insets |stackHolder|.
-    UIView* container = [[UIView alloc] init];
-    container.translatesAutoresizingMaskIntoConstraints = NO;
-    [stackView addArrangedSubview:container];
-    AddSameConstraintsToSides(container, self.contentView,
-                              LayoutSides::kTrailing | LayoutSides::kLeading);
-
     // |stackHolder| has the background, border and round corners of the stacked
     // fields.
     UIView* stackHolder = [[UIView alloc] init];
@@ -267,13 +270,27 @@
     stackHolder.clipsToBounds = YES;
     stackHolder.backgroundColor = UIColorFromRGB(kTextfieldBackgroundColor);
     stackHolder.translatesAutoresizingMaskIntoConstraints = NO;
-    [container addSubview:stackHolder];
+
+    // Updates the custom space before the text fields to account for their
+    // inset.
+    UIView* previousView = stackView.arrangedSubviews.lastObject;
+    if (previousView) {
+      CGFloat spaceBefore = [stackView customSpacingAfterView:previousView];
+      [stackView setCustomSpacing:kTextfieldStackInsetTop + spaceBefore
+                        afterView:previousView];
+    } else {
+      // There should always be a title or message.
+      NOTREACHED() << "Presenting alert without a title or message.";
+    }
+    [stackView addArrangedSubview:stackHolder];
+
     ChromeDirectionalEdgeInsets stackHolderContentInsets =
-        ChromeDirectionalEdgeInsetsMake(
-            kTextfieldStackInsetTop, kTextfieldStackInsetLeading,
-            kTextfieldStackInsetBottom, kTextfieldStackInsetTrailing);
-    AddSameConstraintsWithInsets(stackHolder, container,
-                                 stackHolderContentInsets);
+        ChromeDirectionalEdgeInsetsMake(0, kTextfieldStackInsetLeading, 0,
+                                        kTextfieldStackInsetTrailing);
+    AddSameConstraintsToSidesWithInsets(
+        stackHolder, self.contentView,
+        LayoutSides::kTrailing | LayoutSides::kLeading,
+        stackHolderContentInsets);
 
     UIStackView* fieldStack = [[UIStackView alloc] init];
     fieldStack.axis = UILayoutConstraintAxisVertical;
@@ -318,6 +335,11 @@
 
   self.buttonAlertActionsDictionary = [[NSMutableDictionary alloc] init];
   for (AlertAction* action in self.actions) {
+    UIView* hairline = [[UIView alloc] init];
+    hairline.backgroundColor = [UIColor lightGrayColor];
+    hairline.translatesAutoresizingMaskIntoConstraints = NO;
+    [stackView addArrangedSubview:hairline];
+
     GrayHighlightButton* button = [[GrayHighlightButton alloc] init];
     UIFont* font = nil;
     UIColor* textColor = nil;
@@ -344,25 +366,14 @@
     button.contentEdgeInsets =
         UIEdgeInsetsMake(kButtonInsetTop, kButtonInsetLeading,
                          kButtonInsetBottom, kButtonInsetTrailing);
-
-    UIView* hairline = [[UIView alloc] init];
-    hairline.backgroundColor = [UIColor lightGrayColor];
-    hairline.translatesAutoresizingMaskIntoConstraints = NO;
-
-    UIView* buttonContainer = [[UIView alloc] init];
-    [buttonContainer addSubview:button];
-    [buttonContainer addSubview:hairline];
-    buttonContainer.translatesAutoresizingMaskIntoConstraints = NO;
-    [stackView addArrangedSubview:buttonContainer];
+    [stackView addArrangedSubview:button];
 
     CGFloat pixelHeight = 1.0 / [UIScreen mainScreen].scale;
     [hairline.heightAnchor constraintEqualToConstant:pixelHeight].active = YES;
-    AddSameConstraintsToSides(
-        hairline, buttonContainer,
-        (LayoutSides::kTrailing | LayoutSides::kTop | LayoutSides::kLeading));
+    AddSameConstraintsToSides(hairline, button,
+                              (LayoutSides::kTrailing | LayoutSides::kLeading));
 
-    AddSameConstraints(button, buttonContainer);
-    AddSameConstraintsToSides(buttonContainer, self.contentView,
+    AddSameConstraintsToSides(button, self.contentView,
                               LayoutSides::kTrailing | LayoutSides::kLeading);
 
     button.tag = action.uniqueIdentifier;
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller_unittest.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller_unittest.mm
new file mode 100644
index 0000000..b6bec48
--- /dev/null
+++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller_unittest.mm
@@ -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.
+
+#import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h"
+
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using AlertViewControllerTest = PlatformTest;
+
+// Tests AlertViewController can be initiliazed.
+TEST_F(AlertViewControllerTest, Init) {
+  AlertViewController* alert = [[AlertViewController alloc] init];
+  EXPECT_TRUE(alert);
+}
+
+// Tests there are no circular references in a simple init.
+TEST_F(AlertViewControllerTest, Dealloc) {
+  __weak AlertViewController* weakAlert = nil;
+  @autoreleasepool {
+    AlertViewController* alert = [[AlertViewController alloc] init];
+    weakAlert = alert;
+  }
+  EXPECT_FALSE(weakAlert);
+}
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 4684baa..1cd4d5d0 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -1235,6 +1235,11 @@
   [self openAuthenticationDialogAddIdentity];
 }
 
+- (void)unifiedConsentCoordinatorNeedPrimaryButtonUpdate:
+    (UnifiedConsentCoordinator*)coordinator {
+  [self updatePrimaryButtonForIdentityPickerState];
+}
+
 @end
 
 @implementation ChromeSigninViewController (Testing)
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
index feb09a14..c89403b 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
@@ -51,6 +51,9 @@
     [self.consumer itemHasChanged:previousSelectedItem];
   }
   _selectedIdentity = selectedIdentity;
+  if (!_selectedIdentity) {
+    return;
+  }
   IdentityChooserItem* selectedItem = [self.consumer
       identityChooserItemWithGaiaID:self.selectedIdentity.gaiaID];
   DCHECK(selectedItem);
@@ -112,7 +115,11 @@
   NSArray* allIdentities =
       self.chromeIdentityService->GetAllIdentitiesSortedForDisplay();
   if (![allIdentities containsObject:self.selectedIdentity]) {
-    self.selectedIdentity = allIdentities[0];
+    if (allIdentities.count) {
+      self.selectedIdentity = allIdentities[0];
+    } else {
+      self.selectedIdentity = nil;
+    }
   }
 }
 
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h
index 2258aa9..f5e7c33f3 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h
@@ -28,6 +28,12 @@
 - (void)unifiedConsentCoordinatorDidTapOnAddAccount:
     (UnifiedConsentCoordinator*)coordinator;
 
+// Called when the primary button needs to update its title (for example if the
+// last identity disappears, the button needs to change from "YES, I'M IN" to
+// "ADD ACCOUNT").
+- (void)unifiedConsentCoordinatorNeedPrimaryButtonUpdate:
+    (UnifiedConsentCoordinator*)coordinator;
+
 @end
 
 // UnifiedConsentCoordinator coordinates UnifiedConsentViewController, which is
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
index 589a82c..c1afbd7 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
@@ -15,8 +15,9 @@
 #error "This file requires ARC support."
 #endif
 
-@interface UnifiedConsentCoordinator ()<IdentityChooserCoordinatorDelegate,
-                                        UnifiedConsentViewControllerDelegate>
+@interface UnifiedConsentCoordinator () <IdentityChooserCoordinatorDelegate,
+                                         UnifiedConsentMediatorDelegate,
+                                         UnifiedConsentViewControllerDelegate>
 
 // Unified consent mediator.
 @property(nonatomic, strong) UnifiedConsentMediator* unifiedConsentMediator;
@@ -40,6 +41,7 @@
     _unifiedConsentViewController.delegate = self;
     _unifiedConsentMediator = [[UnifiedConsentMediator alloc]
         initWithUnifiedConsentViewController:_unifiedConsentViewController];
+    _unifiedConsentMediator.delegate = self;
   }
   return self;
 }
@@ -94,6 +96,14 @@
   self.identityChooserCoordinator.selectedIdentity = self.selectedIdentity;
 }
 
+#pragma mark - UnifiedConsentViewMediatorDelegate
+
+- (void)unifiedConsentViewMediatorDelegateNeedPrimaryButtonUpdate:
+    (UnifiedConsentMediator*)mediator {
+  DCHECK_EQ(self.unifiedConsentMediator, mediator);
+  [self.delegate unifiedConsentCoordinatorNeedPrimaryButtonUpdate:self];
+}
+
 #pragma mark - UnifiedConsentViewControllerDelegate
 
 - (void)unifiedConsentViewControllerViewDidAppear:
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h
index 9a21ac6c..8db26d7d 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h
@@ -8,8 +8,20 @@
 #import <Foundation/Foundation.h>
 
 @class ChromeIdentity;
+@class UnifiedConsentMediator;
 @class UnifiedConsentViewController;
 
+// Delegate protocol for UnifiedConsentMediator class.
+@protocol UnifiedConsentMediatorDelegate <NSObject>
+
+// Called when the primary button needs to update its title (for example if the
+// last identity disappears, the button needs to change from "YES, I'M IN" to
+// "ADD ACCOUNT").
+- (void)unifiedConsentViewMediatorDelegateNeedPrimaryButtonUpdate:
+    (UnifiedConsentMediator*)mediator;
+
+@end
+
 // A mediator object that monitors updates of the selecte chrome identity, and
 // updates the UnifiedConsentViewController.
 @interface UnifiedConsentMediator : NSObject
@@ -19,6 +31,8 @@
 // list, the identity picker will be hidden. Nil is not accepted if at least one
 // identity exists.
 @property(nonatomic, strong) ChromeIdentity* selectedIdentity;
+// Instance delegate.
+@property(nonatomic, weak) id<UnifiedConsentMediatorDelegate> delegate;
 
 - (instancetype)initWithUnifiedConsentViewController:
     (UnifiedConsentViewController*)viewController NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
index 2bfe83e..df7f6ea 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
@@ -139,6 +139,8 @@
       newIdentity = identities[0];
     }
     self.selectedIdentity = newIdentity;
+    [self.delegate
+        unifiedConsentViewMediatorDelegateNeedPrimaryButtonUpdate:self];
   }
 }
 
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.h b/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.h
index 137c8b4..241ff0e 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.h
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.h
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
 @protocol ApplicationCommands;
+@protocol BrowserCommands;
 @class GoogleServicesNavigationCoordinator;
 
 // GoogleServicesNavigationCoordinator delegate.
@@ -26,7 +27,8 @@
 @property(nonatomic, weak) id<GoogleServicesNavigationCoordinatorDelegate>
     delegate;
 // Global dispatcher.
-@property(nonatomic, weak) id<ApplicationCommands> dispatcher;
+@property(nonatomic, weak) id<ApplicationCommands, BrowserCommands>
+    dispatcherForSettings;
 
 // Dismisses the Google services navigation view controller.
 - (void)dismissAnimated:(BOOL)animated;
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.mm
index 8a7c2ee..217ab6cb 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_navigation_coordinator.mm
@@ -9,19 +9,21 @@
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h"
 #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mode.h"
+#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-@interface GoogleServicesNavigationCoordinator ()
+@interface GoogleServicesNavigationCoordinator () <
+    SettingsNavigationControllerDelegate>
 
 // Google services settings coordinator.
 @property(nonatomic, strong)
     GoogleServicesSettingsCoordinator* googleServicesSettingsCoordinator;
 // Main view controller.
-@property(nonatomic, strong) UINavigationController* navigationController;
+@property(nonatomic, strong) SettingsNavigationController* navigationController;
 
 @end
 
@@ -33,7 +35,10 @@
 @synthesize delegate = _delegate;
 
 - (void)start {
-  self.navigationController = [[UINavigationController alloc] init];
+  self.navigationController = [[SettingsNavigationController alloc]
+      initWithRootViewController:nil
+                    browserState:self.browserState
+                        delegate:self];
   self.navigationController.modalPresentationStyle =
       UIModalPresentationFormSheet;
   self.googleServicesSettingsCoordinator =
@@ -41,12 +46,11 @@
           initWithBaseViewController:self.navigationController
                         browserState:self.browserState
                                 mode:GoogleServicesSettingsModeSettings];
-  self.googleServicesSettingsCoordinator.dispatcher = self.dispatcher;
+  self.googleServicesSettingsCoordinator.dispatcher =
+      self.dispatcherForSettings;
   self.googleServicesSettingsCoordinator.navigationController =
       self.navigationController;
   [self.googleServicesSettingsCoordinator start];
-  self.googleServicesSettingsCoordinator.viewController.navigationItem
-      .leftBarButtonItem = [self closeButton];
   [self.baseViewController presentViewController:self.navigationController
                                         animated:YES
                                       completion:nil];
@@ -66,20 +70,9 @@
                                               completion:completion];
 }
 
-#pragma mark - Private
+#pragma mark - SettingsNavigationControllerDelegate
 
-// This method should be moved to the view controller.
-- (UIBarButtonItem*)closeButton {
-  UIBarButtonItem* closeButton =
-      [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
-                                          target:self
-                                          action:@selector(closeButtonAction)];
-  closeButton.accessibilityLabel = l10n_util::GetNSString(IDS_ACCNAME_CLOSE);
-  return closeButton;
-}
-
-// Called by the close button.
-- (void)closeButtonAction {
+- (void)closeSettings {
   [self dismissAnimated:YES];
 }
 
diff --git a/ios/chrome/browser/ui/signin_interaction/BUILD.gn b/ios/chrome/browser/ui/signin_interaction/BUILD.gn
index 4c10906f..1a39be6d 100644
--- a/ios/chrome/browser/ui/signin_interaction/BUILD.gn
+++ b/ios/chrome/browser/ui/signin_interaction/BUILD.gn
@@ -55,3 +55,24 @@
   ]
   libs = [ "XCTest.framework" ]
 }
+
+source_set("unity_eg_tests") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  testonly = true
+  sources = [
+    "signin_interaction_controller_unity_egtest.mm",
+  ]
+  deps = [
+    "//base",
+    "//base/test:test_support",
+    "//components/unified_consent",
+    "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/browser/ui/authentication:eg_test_support",
+    "//ios/chrome/browser/ui/authentication/unified_consent/identity_chooser:identity_chooser_ui",
+    "//ios/chrome/test/earl_grey:test_support",
+    "//ios/public/provider/chrome/browser/signin:test_support",
+    "//ios/testing/earl_grey:earl_grey_support",
+    "//ui/base",
+  ]
+  libs = [ "XCTest.framework" ]
+}
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_unity_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_unity_egtest.mm
new file mode 100644
index 0000000..006ff6e4
--- /dev/null
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_unity_egtest.mm
@@ -0,0 +1,131 @@
+// 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 <EarlGrey/EarlGrey.h>
+#import <XCTest/XCTest.h>
+
+#import "base/test/ios/wait_util.h"
+#include "components/unified_consent/feature.h"
+#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
+#import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_cell.h"
+#include "ios/chrome/grit/ios_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.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/public/provider/chrome/browser/signin/fake_chrome_identity.h"
+#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.h"
+#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h"
+#import "ios/testing/earl_grey/matchers.h"
+#include "ui/base/l10n/l10n_util_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using chrome_test_util::BookmarksNavigationBarDoneButton;
+using chrome_test_util::PrimarySignInButton;
+using chrome_test_util::SecondarySignInButton;
+using chrome_test_util::SettingsDoneButton;
+
+namespace {
+
+// Wait until |matcher| is accessible (not nil)
+void WaitForMatcher(id<GREYMatcher> matcher) {
+  ConditionBlock condition = ^{
+    NSError* error = nil;
+    [[EarlGrey selectElementWithMatcher:matcher] assertWithMatcher:grey_notNil()
+                                                             error:&error];
+    return error == nil;
+  };
+  GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(
+                 base::test::ios::kWaitForUIElementTimeout, condition),
+             @"Waiting for matcher %@ failed.", matcher);
+}
+
+// Returns a matcher for |userEmail| in IdentityChooserViewController.
+id<GREYMatcher> identityChooserButtonMatcherWithEmail(NSString* userEmail) {
+  if (base::FeatureList::IsEnabled(unified_consent::kUnifiedConsent)) {
+    return grey_allOf(grey_accessibilityID(userEmail),
+                      grey_kindOfClass([IdentityChooserCell class]),
+                      grey_sufficientlyVisible(), nil);
+  }
+  return chrome_test_util::ButtonWithAccessibilityLabel(userEmail);
+}
+
+// Returns a matcher for "ADD ACCOUNT" in IdentityChooserViewController.
+id<GREYMatcher> addIdentityButtonInIdentityChooser() {
+  DCHECK(base::FeatureList::IsEnabled(unified_consent::kUnifiedConsent));
+  return chrome_test_util::ButtonWithAccessibilityLabel(
+      l10n_util::GetNSStringWithFixup(
+          IDS_IOS_ACCOUNT_UNIFIED_CONSENT_ADD_ACCOUNT));
+}
+
+}  // namespace
+
+@interface SigninInteractionControllerTestCase : ChromeTestCase
+@end
+
+@implementation SigninInteractionControllerTestCase
+
+// Tests that opening the sign-in screen from the Settings and signing in works
+// correctly when there is already an identity on the device.
+- (void)testSignInOneUser {
+  // Set up a fake identity.
+  ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
+      identity);
+
+  [SigninEarlGreyUI signinWithIdentity:identity];
+
+  // Check |identity| is signed-in.
+  CHROME_EG_ASSERT_NO_ERROR(
+      [SigninEarlGreyUtils checkSignedInWithIdentity:identity]);
+}
+
+// Tests the "ADD ACCOUNT" button in the identity chooser view controller.
+- (void)testAddAccountAutomatcially {
+  [ChromeEarlGreyUI openSettingsMenu];
+  [ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()];
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+  // Tap on "ADD ACCOUNT".
+  [[EarlGrey selectElementWithMatcher:addIdentityButtonInIdentityChooser()]
+      performAction:grey_tap()];
+  // Check for the fake SSO screen.
+  WaitForMatcher(grey_accessibilityID(kFakeAddAccountViewIdentifier));
+  // Close the SSO view controller.
+  id<GREYMatcher> matcher =
+      chrome_test_util::ButtonWithAccessibilityLabel(@"Cancel");
+  [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()];
+  // Make sure the SSO view controller is fully removed before ending the test.
+  // The tear down needs to remove other view controllers, and it cannot be done
+  // during the animation of the SSO view controler.
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+}
+
+// Tests to remove the last identity in the identity chooser.
+- (void)testRemoveLastAccount {
+  // Set up a fake identity.
+  ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
+      identity);
+
+  // Open the identity chooser.
+  [ChromeEarlGreyUI openSettingsMenu];
+  [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()];
+  WaitForMatcher(identityChooserButtonMatcherWithEmail(identity.userEmail));
+
+  // Remove the fake identity.
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()
+      ->RemoveIdentity(identity);
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+
+  // Check that the identity has been removed.
+  [[EarlGrey selectElementWithMatcher:identityChooserButtonMatcherWithEmail(
+                                          identity.userEmail)]
+      assertWithMatcher:grey_notVisible()];
+}
+
+@end
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index e44db561..349794f 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -181,6 +181,7 @@
     "//ios/chrome/browser/u2f:unit_tests",
     "//ios/chrome/browser/ui/activity_services:unit_tests",
     "//ios/chrome/browser/ui/alert_coordinator:unit_tests",
+    "//ios/chrome/browser/ui/alert_view_controller:unit_tests",
     "//ios/chrome/browser/ui/app_launcher:unit_tests",
     "//ios/chrome/browser/ui/authentication:unit_tests",
     "//ios/chrome/browser/ui/authentication/cells:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn
index 834cb20..063080a 100644
--- a/ios/chrome/test/earl_grey/BUILD.gn
+++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -212,6 +212,7 @@
 chrome_ios_eg_test("ios_chrome_unified_consent_egtests") {
   deps = [
     "//ios/chrome/browser/ui/settings/google_services:unified_consent_eg_tests",
+    "//ios/chrome/browser/ui/signin_interaction:unity_eg_tests",
   ]
 }
 
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.h b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.h
index 20804d5..371cba47 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.h
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.h
@@ -7,6 +7,9 @@
 
 #import "ios/public/provider/chrome/browser/signin/chrome_identity_interaction_manager.h"
 
+// Accessibility identifier for FakeChromeIdentityInteractionManager view.
+extern NSString* kFakeAddAccountViewIdentifier;
+
 // A fake ChromeIdentityInteractionManager to use in integration tests.
 @interface FakeChromeIdentityInteractionManager
     : ChromeIdentityInteractionManager
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
index 08e53188..dc831a6 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
@@ -13,6 +13,8 @@
 #error "This file requires ARC support."
 #endif
 
+NSString* kFakeAddAccountViewIdentifier = @"FakeAddAccountViewIdentifier";
+
 @interface FakeAddAccountViewController : UIViewController {
   __weak FakeChromeIdentityInteractionManager* _manager;
   UIButton* _cancelButton;
@@ -57,6 +59,7 @@
 
   // Obnoxious color, this is a test screen.
   self.view.backgroundColor = [UIColor magentaColor];
+  self.view.accessibilityIdentifier = kFakeAddAccountViewIdentifier;
 
   _signInButton = [UIButton buttonWithType:UIButtonTypeCustom];
   [_signInButton setTitle:@"Sign in" forState:UIControlStateNormal];
diff --git a/ios/showcase/alert/sc_alert_coordinator.mm b/ios/showcase/alert/sc_alert_coordinator.mm
index b171c7d..c5552d01 100644
--- a/ios/showcase/alert/sc_alert_coordinator.mm
+++ b/ios/showcase/alert/sc_alert_coordinator.mm
@@ -51,6 +51,12 @@
                  action:@selector(showHTTPAuth)
        forControlEvents:UIControlEventTouchUpInside];
 
+  UIButton* longButton = [UIButton buttonWithType:UIButtonTypeSystem];
+  [longButton setTitle:@"Long Alert" forState:UIControlStateNormal];
+  [longButton addTarget:self
+                 action:@selector(showLongAlert)
+       forControlEvents:UIControlEventTouchUpInside];
+
   UILabel* blockAlertsLabel = [[UILabel alloc] init];
   blockAlertsLabel.text = @"Show \"Block Alerts Button\"";
 
@@ -63,7 +69,8 @@
   switchStack.translatesAutoresizingMaskIntoConstraints = NO;
 
   UIStackView* verticalStack = [[UIStackView alloc] initWithArrangedSubviews:@[
-    alertButton, promptButton, confirmButton, authButton, switchStack
+    alertButton, promptButton, confirmButton, authButton, longButton,
+    switchStack
   ]];
   verticalStack.axis = UILayoutConstraintAxisVertical;
   verticalStack.spacing = 30;
@@ -187,6 +194,46 @@
   [self presentAlertViewController:alert];
 }
 
+- (void)showLongAlert {
+  AlertViewController* alert = [[AlertViewController alloc] init];
+  alert.title = @"Sign in";
+  alert.message =
+      @"It was the best of times, it was the worst of times, it was the age of "
+      @"wisdom, it was the age of foolishness, it was the epoch of belief, it "
+      @"was the epoch of incredulity, it was the season of Light, it was the "
+      @"season of Darkness, it was the spring of hope, it was the winter of "
+      @"despair, we had everything before us, we had nothing before us, we "
+      @"were all going direct to Heaven, we were all going direct the other "
+      @"way.";
+  [alert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
+    textField.placeholder = @"Username";
+  }];
+  [alert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
+    textField.placeholder = @"Password";
+    textField.secureTextEntry = YES;
+  }];
+  __weak __typeof(self) weakSelf = self;
+  AlertAction* OKAction =
+      [AlertAction actionWithTitle:@"Sign In"
+                             style:UIAlertActionStyleDefault
+                           handler:^(AlertAction* action) {
+                             [weakSelf.containerViewController
+                                 dismissViewControllerAnimated:YES
+                                                    completion:nil];
+                           }];
+  AlertAction* cancelAction =
+      [AlertAction actionWithTitle:@"Cancel"
+                             style:UIAlertActionStyleCancel
+                           handler:^(AlertAction* action) {
+                             [weakSelf.containerViewController
+                                 dismissViewControllerAnimated:YES
+                                                    completion:nil];
+                           }];
+  [alert addAction:OKAction];
+  [alert addAction:cancelAction];
+  [self presentAlertViewController:alert];
+}
+
 - (void)presentAlertViewController:(AlertViewController*)alertViewController {
   if (self.blockAlertSwitch.isOn) {
     __weak __typeof(self) weakSelf = self;
diff --git a/ios/web/navigation/wk_navigation_util.mm b/ios/web/navigation/wk_navigation_util.mm
index 77c5005..bc8b0e4 100644
--- a/ios/web/navigation/wk_navigation_util.mm
+++ b/ios/web/navigation/wk_navigation_util.mm
@@ -25,9 +25,9 @@
 
 // Session restoration algorithms uses pushState calls to restore back forward
 // navigation list. WKWebView does not allow pushing more than 100 items per
-// 30 seconds. Limiting max session size to 75 will allow web pages to use push
+// 30 seconds. Limiting max session size to 49 will allow web pages to use push
 // state calls.
-const int kMaxSessionSize = 75;
+const int kMaxSessionSize = 49;
 
 const char kRestoreSessionSessionHashPrefix[] = "session=";
 const char kRestoreSessionTargetUrlHashPrefix[] = "targetUrl=";
diff --git a/ios/web/navigation/wk_navigation_util_unittest.mm b/ios/web/navigation/wk_navigation_util_unittest.mm
index 4b93b53f..ae69b496 100644
--- a/ios/web/navigation/wk_navigation_util_unittest.mm
+++ b/ios/web/navigation/wk_navigation_util_unittest.mm
@@ -157,14 +157,14 @@
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize),
             titles_value->GetList().size());
   ASSERT_EQ("Test0", titles_value->GetList()[0].GetString());
-  ASSERT_EQ("Test74", titles_value->GetList()[kMaxSessionSize - 1].GetString());
+  ASSERT_EQ("Test48", titles_value->GetList()[kMaxSessionSize - 1].GetString());
 
   base::Value* urls_value = value_with_error.value->FindKey("urls");
   ASSERT_TRUE(urls_value);
   ASSERT_TRUE(urls_value->is_list());
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize), urls_value->GetList().size());
   ASSERT_EQ("http:%2F%2Fwww.0.com%2F", urls_value->GetList()[0].GetString());
-  ASSERT_EQ("http:%2F%2Fwww.74.com%2F",
+  ASSERT_EQ("http:%2F%2Fwww.48.com%2F",
             urls_value->GetList()[kMaxSessionSize - 1].GetString());
 
   // Verify the offset is correct.
@@ -185,7 +185,7 @@
   CreateRestoreSessionUrl(
       /*last_committed_item_index=*/kItemCount - 1, items, &restore_session_url,
       &first_index);
-  ASSERT_EQ(150, first_index);
+  ASSERT_EQ(98, first_index);
   ASSERT_TRUE(IsRestoreSessionUrl(restore_session_url));
 
   // Extract session JSON from restoration URL.
@@ -200,16 +200,16 @@
   ASSERT_TRUE(titles_value->is_list());
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize),
             titles_value->GetList().size());
-  ASSERT_EQ("Test150", titles_value->GetList()[0].GetString());
-  ASSERT_EQ("Test224",
+  ASSERT_EQ("Test98", titles_value->GetList()[0].GetString());
+  ASSERT_EQ("Test146",
             titles_value->GetList()[kMaxSessionSize - 1].GetString());
 
   base::Value* urls_value = value_with_error.value->FindKey("urls");
   ASSERT_TRUE(urls_value);
   ASSERT_TRUE(urls_value->is_list());
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize), urls_value->GetList().size());
-  ASSERT_EQ("http:%2F%2Fwww.150.com%2F", urls_value->GetList()[0].GetString());
-  ASSERT_EQ("http:%2F%2Fwww.224.com%2F",
+  ASSERT_EQ("http:%2F%2Fwww.98.com%2F", urls_value->GetList()[0].GetString());
+  ASSERT_EQ("http:%2F%2Fwww.146.com%2F",
             urls_value->GetList()[kMaxSessionSize - 1].GetString());
 
   // Verify the offset is correct.
@@ -230,7 +230,7 @@
   CreateRestoreSessionUrl(
       /*last_committed_item_index=*/kMaxSessionSize, items,
       &restore_session_url, &first_index);
-  ASSERT_EQ(38, first_index);
+  ASSERT_EQ(25, first_index);
   ASSERT_TRUE(IsRestoreSessionUrl(restore_session_url));
 
   // Extract session JSON from restoration URL.
@@ -245,16 +245,15 @@
   ASSERT_TRUE(titles_value->is_list());
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize),
             titles_value->GetList().size());
-  ASSERT_EQ("Test38", titles_value->GetList()[0].GetString());
-  ASSERT_EQ("Test112",
-            titles_value->GetList()[kMaxSessionSize - 1].GetString());
+  ASSERT_EQ("Test25", titles_value->GetList()[0].GetString());
+  ASSERT_EQ("Test73", titles_value->GetList()[kMaxSessionSize - 1].GetString());
 
   base::Value* urls_value = value_with_error.value->FindKey("urls");
   ASSERT_TRUE(urls_value);
   ASSERT_TRUE(urls_value->is_list());
   ASSERT_EQ(static_cast<size_t>(kMaxSessionSize), urls_value->GetList().size());
-  ASSERT_EQ("http:%2F%2Fwww.38.com%2F", urls_value->GetList()[0].GetString());
-  ASSERT_EQ("http:%2F%2Fwww.112.com%2F",
+  ASSERT_EQ("http:%2F%2Fwww.25.com%2F", urls_value->GetList()[0].GetString());
+  ASSERT_EQ("http:%2F%2Fwww.73.com%2F",
             urls_value->GetList()[kMaxSessionSize - 1].GetString());
 
   // Verify the offset is correct.
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm
index ed37c20..587aa88d 100644
--- a/ios/web/web_state/web_state_unittest.mm
+++ b/ios/web/web_state/web_state_unittest.mm
@@ -337,15 +337,6 @@
 // Verifies that large session can be restored. SlimNavigationManagder has max
 // session size limit of |wk_navigation_util::kMaxSessionSize|.
 TEST_P(WebStateTest, RestoreLargeSession) {
-#if !TARGET_IPHONE_SIMULATOR
-  if (@available(iOS 12.2, *)) {
-    if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-      // TODO(crbug.com/957666): Reenable test for this set of conditions
-      return;
-    }
-  }
-#endif
-
   // Create session storage with large number of items.
   const int kItemCount = 150;
   NSMutableArray<CRWNavigationItemStorage*>* item_storages =
diff --git a/remoting/base/grpc_support/grpc_async_executor.cc b/remoting/base/grpc_support/grpc_async_executor.cc
index fdcf123..a6478e54 100644
--- a/remoting/base/grpc_support/grpc_async_executor.cc
+++ b/remoting/base/grpc_support/grpc_async_executor.cc
@@ -14,16 +14,12 @@
 #include "base/threading/thread.h"
 #include "base/time/time.h"
 #include "remoting/base/grpc_support/grpc_async_request.h"
-#include "remoting/base/grpc_support/grpc_util.h"
 #include "third_party/grpc/src/include/grpcpp/completion_queue.h"
 
 namespace remoting {
 
 namespace {
 
-constexpr base::TimeDelta kDefaultRequestTimeout =
-    base::TimeDelta::FromSeconds(30);
-
 using DequeueCallback = base::OnceCallback<void(bool operation_succeeded)>;
 
 struct DispatchTask {
@@ -105,10 +101,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto* unowned_request = request.get();
   DCHECK(FindRequest(unowned_request) == pending_requests_.end());
-  if (GetDeadline(*request->context()).is_max()) {
-    VLOG(1) << "Deadline is not set. Using the default request timeout.";
-    SetDeadline(request->context(), base::Time::Now() + kDefaultRequestTimeout);
-  }
   auto task = std::make_unique<DispatchTask>();
   task->caller_sequence_task_runner = base::SequencedTaskRunnerHandle::Get();
   task->callback =
diff --git a/remoting/base/grpc_support/grpc_async_unary_request.h b/remoting/base/grpc_support/grpc_async_unary_request.h
index e370ee8..10f1caa 100644
--- a/remoting/base/grpc_support/grpc_async_unary_request.h
+++ b/remoting/base/grpc_support/grpc_async_unary_request.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/sequence_checker.h"
 #include "remoting/base/grpc_support/grpc_async_request.h"
+#include "remoting/base/grpc_support/grpc_util.h"
 #include "third_party/grpc/src/include/grpcpp/support/async_unary_call.h"
 
 namespace remoting {
@@ -51,6 +52,14 @@
              grpc::CompletionQueue* cq,
              void* event_tag) override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+    static constexpr base::TimeDelta kDefaultRequestTimeout =
+        base::TimeDelta::FromSeconds(30);
+    if (GetDeadline(*context()).is_max()) {
+      VLOG(1) << "Deadline is not set. Using the default request timeout.";
+      SetDeadline(context(), base::Time::Now() + kDefaultRequestTimeout);
+    }
+
     response_reader_ = std::move(create_reader_cb_).Run(cq);
     response_reader_->Finish(&response_, &status_, event_tag);
     run_task_cb_ = run_task_cb;
diff --git a/services/device/wake_lock/wake_lock_provider.cc b/services/device/wake_lock/wake_lock_provider.cc
index 6ec8a2e..a629a4c95 100644
--- a/services/device/wake_lock/wake_lock_provider.cc
+++ b/services/device/wake_lock/wake_lock_provider.cc
@@ -56,7 +56,7 @@
 
 void WakeLockProvider::GetWakeLockContextForID(
     int context_id,
-    mojo::InterfaceRequest<mojom::WakeLockContext> request) {
+    mojom::WakeLockContextRequest request) {
   DCHECK_GE(context_id, 0);
   mojo::MakeStrongBinding(
       std::make_unique<WakeLockContext>(context_id, file_task_runner_,
diff --git a/services/device/wake_lock/wake_lock_provider.h b/services/device/wake_lock/wake_lock_provider.h
index fb3cb3ac..ac59e17 100644
--- a/services/device/wake_lock/wake_lock_provider.h
+++ b/services/device/wake_lock/wake_lock_provider.h
@@ -33,9 +33,8 @@
   void AddBinding(mojom::WakeLockProviderRequest request);
 
   // mojom::WakeLockProvider overrides.
-  void GetWakeLockContextForID(
-      int context_id,
-      mojo::InterfaceRequest<mojom::WakeLockContext> request) override;
+  void GetWakeLockContextForID(int context_id,
+                               mojom::WakeLockContextRequest request) override;
   void GetWakeLockWithoutContext(mojom::WakeLockType type,
                                  mojom::WakeLockReason reason,
                                  const std::string& description,
diff --git a/services/image_annotation/annotator.cc b/services/image_annotation/annotator.cc
index 7744988..d3750ab4 100644
--- a/services/image_annotation/annotator.cc
+++ b/services/image_annotation/annotator.cc
@@ -680,7 +680,8 @@
     // Populate the result struct for this image and copy it into the cache if
     // necessary.
     if (result_lookup != results.end())
-      cached_results_.insert({request_key, result_lookup->second.Clone()});
+      cached_results_.insert(
+          std::make_pair(request_key, result_lookup->second.Clone()));
 
     // This should not happen, since only this method removes entries of
     // |request_infos_|, and this method should only execute once per request
diff --git a/storage/browser/fileapi/file_system_context.h b/storage/browser/fileapi/file_system_context.h
index b772983b..56b4008 100644
--- a/storage/browser/fileapi/file_system_context.h
+++ b/storage/browser/fileapi/file_system_context.h
@@ -285,9 +285,8 @@
                                            const base::FilePath& path) const;
 
 #if defined(OS_CHROMEOS)
-  // Used only on ChromeOS for now.
-  // TODO(https://crbug.com/93417): Remove this function when incognito file
-  // system is active.
+  // Used only on ChromeOS for now. It can be removed when
+  // kEnableFilesystemInIncognito feature flag is removed.
   void EnableTemporaryFileSystemInIncognito();
 #endif
 
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index ad8fb1d1..6db1736 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -23869,32 +23869,6 @@
           "idempotent": false,
           "shards": 2
         }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=vulkan --use-cmd-decoder=passthrough"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_vulkan_passthrough_tests",
-        "should_retry_with_patch": false,
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:2184",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "expiration": 21600,
-          "idempotent": false,
-          "shards": 2
-        }
       }
     ]
   },
diff --git a/testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter b/testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter
index 031ba8e1..b4ff33c 100644
--- a/testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter
+++ b/testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter
@@ -12,3 +12,45 @@
 PDFExtensionTest.*
 PDFIsolatedExtensionTest.*
 PDFPluginDisabledTest.*
+
+PrintPreviewAdvancedDialogTest.*
+PrintPreviewAdvancedItemTest.*
+PrintPreviewAppTest.*
+PrintPreviewBaseSettingsSectionTest.*
+PrintPreviewButtonStripTest.*
+PrintPreviewColorSettingsTest.*
+PrintPreviewCopiesSettingsTest.*
+PrintPreviewCustomMarginsTest.*
+PrintPreviewDestinationDialogTest.*
+PrintPreviewDestinationItemTest.*
+PrintPreviewDestinationListTest.*
+PrintPreviewDestinationSelectTest.*
+PrintPreviewDestinationSettingsTest.*
+PrintPreviewDpiSettingsTest.*
+PrintPreviewDuplexSettingsTest.*
+PrintPreviewHeaderTest.*
+PrintPreviewHeaderNewTest.*
+PrintPreviewInvalidSettingsBrowserTest.*
+PrintPreviewKeyEventTest.*
+PrintPreviewLayoutSettingsTest.*
+PrintPreviewLinkContainerTest.*
+PrintPreviewMarginsSettingsTest.*
+PrintPreviewMediaSizeSettingsTest.*
+PrintPreviewModelTest.*
+PrintPreviewModelSettingsAvailabilityTest.*
+PrintPreviewModelSettingsPolicyTest.*
+PrintPreviewNewDestinationSearchTest.*
+PrintPreviewNumberSettingsSectionTest.*
+PrintPreviewOtherOptionsSettingsTest.*
+PrintPreviewPagesSettingsTest.*
+PrintPreviewPagesPerSheetSettingsTest.*
+PrintPreviewPinSettingsTest.*
+PrintPreviewPolicyTest.*
+PrintPreviewPreviewGenerationTest.*
+PrintPreviewPrintButtonTest.*
+PrintPreviewRestoreStateTest.*
+PrintPreviewScalingSettingsTest.*
+PrintPreviewSelectBehaviorTest.*
+PrintPreviewSidebarTest.*
+PrintPreviewSettingsSelectTest.*
+PrintPreviewSystemDialogBrowserTest.*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 2ae803d8..1c594d2 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1574,6 +1574,7 @@
       'Optional Win10 Release (NVIDIA)',
       'Win10 FYI Debug (NVIDIA)',
       'Win10 FYI Release (NVIDIA)',
+      'Win10 FYI Release (NVIDIA GeForce GTX 1660)',
       'Win7 FYI Release (NVIDIA)',
       'Win7 FYI x64 Release (NVIDIA)',
     ],
diff --git a/testing/scripts/gyp_flag_compare.py b/testing/scripts/gyp_flag_compare.py
deleted file mode 100755
index 0b777d9..0000000
--- a/testing/scripts/gyp_flag_compare.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 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.
-
-"""Wrap //tools/gn/bin/gyp_flag_compare.py for the bots.
-
-This script wraps the GN test script in the facade needed for the
-'ScriptTest' step class of the chromium recipe_module
-(see scripts/slave/recipe_modules/chromium/steps.py in the build repo.
-
-The script takes N arguments, for the N targets to compare flags for.
-"""
-
-import json
-import os
-import sys
-
-
-import common
-
-
-def main_run(args):
-  rc = common.run_command([sys.executable,
-                           os.path.join(common.SRC_DIR,
-                                        'tools', 'gn', 'bin',
-                                        'gyp_flag_compare.py')] + args.args)
-
-  # TODO(dpranke): Figure out how to get a list of failures out of
-  # gyp_flag_compare?
-  json.dump({
-      'valid': True,
-      'failures': ['compare_failed'] if rc else [],
-  }, args.output)
-
-  return rc
-
-
-def main_compile_targets(args):
-  # TODO(dpranke): Figure out how to get args.args plumbed through to here.
-  json.dump([], args.output)
-
-
-if __name__ == '__main__':
-  funcs = {
-    'run': main_run,
-    'compile_targets': main_compile_targets,
-  }
-  sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/third_party/blink/common/manifest/manifest_mojom_traits.cc b/third_party/blink/common/manifest/manifest_mojom_traits.cc
index 9812092..8cf99a12 100644
--- a/third_party/blink/common/manifest/manifest_mojom_traits.cc
+++ b/third_party/blink/common/manifest/manifest_mojom_traits.cc
@@ -201,4 +201,14 @@
   return data.ReadParams(&out->params);
 }
 
+bool StructTraits<blink::mojom::ManifestFileHandlerDataView,
+                  ::blink::Manifest::FileHandler>::
+    Read(blink::mojom::ManifestFileHandlerDataView data,
+         ::blink::Manifest::FileHandler* out) {
+  if (!data.ReadAction(&out->action))
+    return false;
+
+  return data.ReadFiles(&out->files);
+}
+
 }  // namespace mojo
diff --git a/third_party/blink/public/common/manifest/manifest.h b/third_party/blink/public/common/manifest/manifest.h
index 4229d82c..28657f3 100644
--- a/third_party/blink/public/common/manifest/manifest.h
+++ b/third_party/blink/public/common/manifest/manifest.h
@@ -105,8 +105,12 @@
     ShareTargetParams params;
   };
 
-  // Structure representing a File Handler's query parameter keys.
-  using FileHandler = std::vector<FileFilter>;
+  // Structure representing a File Handler.
+  struct BLINK_COMMON_EXPORT FileHandler {
+    // The URL which will be opened when the file handler is invoked.
+    GURL action;
+    std::vector<FileFilter> files;
+  };
 
   // Structure representing a related application.
   struct BLINK_COMMON_EXPORT RelatedApplication {
diff --git a/third_party/blink/public/common/manifest/manifest_mojom_traits.h b/third_party/blink/public/common/manifest/manifest_mojom_traits.h
index 88ee73e..27e7153 100644
--- a/third_party/blink/public/common/manifest/manifest_mojom_traits.h
+++ b/third_party/blink/public/common/manifest/manifest_mojom_traits.h
@@ -246,6 +246,22 @@
 
 template <>
 struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::ManifestFileHandlerDataView,
+                 ::blink::Manifest::FileHandler> {
+  static const GURL& action(
+      const ::blink::Manifest::FileHandler& file_handler) {
+    return file_handler.action;
+  }
+  static const std::vector<::blink::Manifest::FileFilter>& files(
+      const ::blink::Manifest::FileHandler& file_handler) {
+    return file_handler.files;
+  }
+  static bool Read(blink::mojom::ManifestFileHandlerDataView data,
+                   ::blink::Manifest::FileHandler* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
     EnumTraits<blink::mojom::ManifestImageResource_Purpose,
                ::blink::Manifest::ImageResource::Purpose> {
   static blink::mojom::ManifestImageResource_Purpose ToMojom(
diff --git a/third_party/blink/public/mojom/manifest/manifest.mojom b/third_party/blink/public/mojom/manifest/manifest.mojom
index e852871c..7511df6 100644
--- a/third_party/blink/public/mojom/manifest/manifest.mojom
+++ b/third_party/blink/public/mojom/manifest/manifest.mojom
@@ -38,7 +38,7 @@
   // experiment. See:
   // https://github.com/WICG/file-handling/blob/master/explainer.md
   // As such, this field should not be exposed to the drive-by web.
-  array<ManifestFileFilter>? file_handler;
+  ManifestFileHandler? file_handler;
 
   array<ManifestRelatedApplication>? related_applications;
 
@@ -156,6 +156,12 @@
   ManifestShareTargetParams params;
 };
 
+struct ManifestFileHandler {
+  // The URL that will be opened when the file handler is invoked.
+  url.mojom.Url action;
+  array<ManifestFileFilter> files;
+};
+
 // Debug information for a parsed manifest.
 struct ManifestDebugInfo {
   array<ManifestError> errors;
diff --git a/third_party/blink/public/mojom/payments/payment_request.mojom b/third_party/blink/public/mojom/payments/payment_request.mojom
index 367f9530..66b6cbc 100644
--- a/third_party/blink/public/mojom/payments/payment_request.mojom
+++ b/third_party/blink/public/mojom/payments/payment_request.mojom
@@ -94,24 +94,6 @@
   TEST
 };
 
-enum AndroidPayCardNetwork {
-  AMEX,
-  DISCOVER,
-  MASTERCARD,
-  VISA
-};
-
-enum AndroidPayTokenization {
-  UNSPECIFIED,
-  GATEWAY_TOKEN,
-  NETWORK_TOKEN
-};
-
-struct AndroidPayTokenizationParameter {
-  string? key;
-  string? value;
-};
-
 enum BasicCardNetwork {
   AMEX,
   DINERS,
@@ -146,11 +128,6 @@
   // https://developers.google.com/web/fundamentals/getting-started/primers/payment-request/android-pay
   // TODO(rouslan): Stop parsing Android Pay data. http://crbug.com/620173
   AndroidPayEnvironment environment;
-  string? merchant_name;
-  string? merchant_id;
-  array<AndroidPayCardNetwork> allowed_card_networks;
-  AndroidPayTokenization tokenization_type;
-  array<AndroidPayTokenizationParameter> parameters;
   // Value of 0 means the merchant did not specify or it was an invalid value.
   int32 min_google_play_services_version;
   // Value of 0 means the merchant did not specify or it was an invalid value.
diff --git a/third_party/blink/public/mojom/permissions/permission.mojom b/third_party/blink/public/mojom/permissions/permission.mojom
index b46e7f92..a2fb50c 100644
--- a/third_party/blink/public/mojom/permissions/permission.mojom
+++ b/third_party/blink/public/mojom/permissions/permission.mojom
@@ -22,6 +22,7 @@
   PAYMENT_HANDLER,
   BACKGROUND_FETCH,
   IDLE_DETECTION,
+  PERIODIC_BACKGROUND_SYNC,
 };
 
 struct MidiPermissionDescriptor {
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index 2804a5e4..7c8f6d44 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -148,6 +148,7 @@
       bool);
   BLINK_PLATFORM_EXPORT static void EnablePerformanceManagerInstrumentation(
       bool);
+  BLINK_PLATFORM_EXPORT static void EnablePeriodicBackgroundSync(bool);
   BLINK_PLATFORM_EXPORT static void EnablePermissionsAPI(bool);
   BLINK_PLATFORM_EXPORT static void EnablePictureInPicture(bool);
   BLINK_PLATFORM_EXPORT static void EnablePictureInPictureAPI(bool);
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn
index 7648fa1..780dd18 100644
--- a/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -8,10 +8,6 @@
   split_count = 5
 
   sources = [
-    "animatable/animatable_double.h",
-    "animatable/animatable_filter_operations.h",
-    "animatable/animatable_transform.h",
-    "animatable/animatable_value.h",
     "animation.cc",
     "animation.h",
     "animation_clock.cc",
@@ -30,8 +26,12 @@
     "color_property_functions.h",
     "compositor_animations.cc",
     "compositor_animations.h",
-    "css/css_animatable_value_factory.cc",
-    "css/css_animatable_value_factory.h",
+    "css/compositor_keyframe_double.h",
+    "css/compositor_keyframe_filter_operations.h",
+    "css/compositor_keyframe_transform.h",
+    "css/compositor_keyframe_value.h",
+    "css/compositor_keyframe_value_factory.cc",
+    "css/compositor_keyframe_value_factory.h",
     "css/css_animation_data.cc",
     "css/css_animation_data.h",
     "css/css_animation_update.cc",
diff --git a/third_party/blink/renderer/core/animation/animatable/animatable_double.h b/third_party/blink/renderer/core/animation/animatable/animatable_double.h
deleted file mode 100644
index ea88b224b..0000000
--- a/third_party/blink/renderer/core/animation/animatable/animatable_double.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_DOUBLE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_DOUBLE_H_
-
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
-#include "third_party/blink/renderer/core/core_export.h"
-
-namespace blink {
-
-class CORE_EXPORT AnimatableDouble final : public AnimatableValue {
- public:
-  AnimatableDouble(double number) : number_(number) {}
-  ~AnimatableDouble() override = default;
-
-  static AnimatableDouble* Create(double number) {
-    return MakeGarbageCollected<AnimatableDouble>(number);
-  }
-
-  double ToDouble() const { return number_; }
-
- private:
-  AnimatableType GetType() const override { return kTypeDouble; }
-
-  double number_;
-};
-
-DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableDouble, IsDouble());
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_DOUBLE_H_
diff --git a/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h b/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h
deleted file mode 100644
index a657b0b..0000000
--- a/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_FILTER_OPERATIONS_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_FILTER_OPERATIONS_H_
-
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
-#include "third_party/blink/renderer/core/style/filter_operations.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-
-namespace blink {
-
-class AnimatableFilterOperations final : public AnimatableValue {
- public:
-  static AnimatableFilterOperations* Create(
-      const FilterOperations& operations) {
-    return MakeGarbageCollected<AnimatableFilterOperations>(operations);
-  }
-
-  AnimatableFilterOperations(const FilterOperations& operations)
-      : operation_wrapper_(
-            MakeGarbageCollected<FilterOperationsWrapper>(operations)) {}
-  ~AnimatableFilterOperations() override = default;
-
-  const FilterOperations& Operations() const {
-    return operation_wrapper_->Operations();
-  }
-
-  void Trace(Visitor* visitor) override {
-    visitor->Trace(operation_wrapper_);
-    AnimatableValue::Trace(visitor);
-  }
-
- private:
-  AnimatableType GetType() const override { return kTypeFilterOperations; }
-
-  Member<FilterOperationsWrapper> operation_wrapper_;
-};
-
-DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableFilterOperations,
-                                   IsFilterOperations());
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_FILTER_OPERATIONS_H_
diff --git a/third_party/blink/renderer/core/animation/animatable/animatable_transform.h b/third_party/blink/renderer/core/animation/animatable/animatable_transform.h
deleted file mode 100644
index bda9b7c..0000000
--- a/third_party/blink/renderer/core/animation/animatable/animatable_transform.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_TRANSFORM_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_TRANSFORM_H_
-
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/transforms/transform_operations.h"
-
-namespace blink {
-
-class CORE_EXPORT AnimatableTransform final : public AnimatableValue {
- public:
-  explicit AnimatableTransform(const TransformOperations& transform,
-                               double zoom)
-      : transform_(transform), zoom_(zoom) {}
-  ~AnimatableTransform() override = default;
-
-  static AnimatableTransform* Create(const TransformOperations& transform,
-                                     double zoom) {
-    return MakeGarbageCollected<AnimatableTransform>(transform, zoom);
-  }
-  const TransformOperations& GetTransformOperations() const {
-    return transform_;
-  }
-  double Zoom() const { return zoom_; }
-
- private:
-  AnimatableType GetType() const override { return kTypeTransform; }
-
-  const TransformOperations transform_;
-  const double zoom_;
-};
-
-DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableTransform, IsTransform());
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_TRANSFORM_H_
diff --git a/third_party/blink/renderer/core/animation/animatable/animatable_value.h b/third_party/blink/renderer/core/animation/animatable/animatable_value.h
deleted file mode 100644
index f18b38a..0000000
--- a/third_party/blink/renderer/core/animation/animatable/animatable_value.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_VALUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_VALUE_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/css/css_value.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-class CORE_EXPORT AnimatableValue
-    : public GarbageCollectedFinalized<AnimatableValue> {
- public:
-  virtual ~AnimatableValue() = default;
-
-  bool IsDouble() const { return GetType() == kTypeDouble; }
-  bool IsFilterOperations() const { return GetType() == kTypeFilterOperations; }
-  bool IsTransform() const { return GetType() == kTypeTransform; }
-  bool IsUnknown() const { return GetType() == kTypeUnknown; }
-
-  virtual void Trace(Visitor*) {}
-
- protected:
-  enum AnimatableType {
-    kTypeDouble,
-    kTypeFilterOperations,
-    kTypeTransform,
-    kTypeUnknown,
-  };
-
- private:
-  virtual AnimatableType GetType() const = 0;
-};
-
-#define DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(thisType, predicate)         \
-  DEFINE_TYPE_CASTS(thisType, AnimatableValue, value, value->predicate, \
-                    value.predicate)
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_ANIMATABLE_VALUE_H_
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc
index b9636a5..a719e1c 100644
--- a/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -32,8 +32,8 @@
 
 #include <memory>
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
 #include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -86,7 +86,7 @@
     // Egregious hack: Sideload the compositor value.
     // This is usually set in a part of the rendering process SimulateFrame
     // doesn't call.
-    start_keyframe->SetCompositorValue(AnimatableDouble::Create(1.0));
+    start_keyframe->SetCompositorValue(CompositorKeyframeDouble::Create(1.0));
     TransitionKeyframe* end_keyframe =
         TransitionKeyframe::Create(PropertyHandleOpacity);
     end_keyframe->SetValue(std::make_unique<TypedInterpolationValue>(
@@ -94,7 +94,7 @@
         std::make_unique<InterpolableNumber>(0.0)));
     end_keyframe->SetOffset(1.0);
     // Egregious hack: Sideload the compositor value.
-    end_keyframe->SetCompositorValue(AnimatableDouble::Create(0.0));
+    end_keyframe->SetCompositorValue(CompositorKeyframeDouble::Create(0.0));
 
     TransitionKeyframeVector keyframes;
     keyframes.push_back(start_keyframe);
diff --git a/third_party/blink/renderer/core/animation/compositor_animations.cc b/third_party/blink/renderer/core/animation/compositor_animations.cc
index 49a465b..6bede63 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -34,11 +34,11 @@
 #include <cmath>
 #include <memory>
 #include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_transform.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
 #include "third_party/blink/renderer/core/animation/animation_effect.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
 #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
@@ -226,13 +226,13 @@
             "modes other than 'replace'");
       }
 
-      if (!keyframe->GetAnimatableValue()) {
+      if (!keyframe->GetCompositorKeyframeValue()) {
         return FailureCode::NonActionable(
             "Accelerated keyframe value could not be computed");
       }
 
       // FIXME: Determine candidacy based on the CSSValue instead of a snapshot
-      // AnimatableValue.
+      // CompositorKeyframeValue.
       switch (property.GetCSSProperty().PropertyID()) {
         case CSSPropertyID::kOpacity:
           break;
@@ -240,7 +240,8 @@
         case CSSPropertyID::kScale:
         case CSSPropertyID::kTranslate:
         case CSSPropertyID::kTransform:
-          if (ToAnimatableTransform(keyframe->GetAnimatableValue())
+          if (ToCompositorKeyframeTransform(
+                  keyframe->GetCompositorKeyframeValue())
                   ->GetTransformOperations()
                   .DependsOnBoxSize()) {
             return FailureCode::Actionable(
@@ -251,7 +252,8 @@
         case CSSPropertyID::kFilter:
         case CSSPropertyID::kBackdropFilter: {
           const FilterOperations& operations =
-              ToAnimatableFilterOperations(keyframe->GetAnimatableValue())
+              ToCompositorKeyframeFilterOperations(
+                  keyframe->GetCompositorKeyframeValue())
                   ->Operations();
           if (operations.HasFilterThatMovesPixels()) {
             return FailureCode::Actionable(
@@ -261,7 +263,7 @@
         }
         case CSSPropertyID::kVariable: {
           DCHECK(RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled());
-          if (!keyframe->GetAnimatableValue()->IsDouble()) {
+          if (!keyframe->GetCompositorKeyframeValue()->IsDouble()) {
             // TODO(kevers): Extend support to other custom property types.
             return FailureCode::Actionable(
                 "Accelerated animation cannot be applied to a custom property "
@@ -572,34 +574,34 @@
 
 void AddKeyframeToCurve(CompositorFilterAnimationCurve& curve,
                         Keyframe::PropertySpecificKeyframe* keyframe,
-                        const AnimatableValue* value,
+                        const CompositorKeyframeValue* value,
                         const TimingFunction& keyframe_timing_function) {
   FilterEffectBuilder builder(FloatRect(), 1);
   CompositorFilterKeyframe filter_keyframe(
       keyframe->Offset(),
       builder.BuildFilterOperations(
-          ToAnimatableFilterOperations(value)->Operations()),
+          ToCompositorKeyframeFilterOperations(value)->Operations()),
       keyframe_timing_function);
   curve.AddKeyframe(filter_keyframe);
 }
 
 void AddKeyframeToCurve(CompositorFloatAnimationCurve& curve,
                         Keyframe::PropertySpecificKeyframe* keyframe,
-                        const AnimatableValue* value,
+                        const CompositorKeyframeValue* value,
                         const TimingFunction& keyframe_timing_function) {
-  CompositorFloatKeyframe float_keyframe(keyframe->Offset(),
-                                         ToAnimatableDouble(value)->ToDouble(),
-                                         keyframe_timing_function);
+  CompositorFloatKeyframe float_keyframe(
+      keyframe->Offset(), ToCompositorKeyframeDouble(value)->ToDouble(),
+      keyframe_timing_function);
   curve.AddKeyframe(float_keyframe);
 }
 
 void AddKeyframeToCurve(CompositorTransformAnimationCurve& curve,
                         Keyframe::PropertySpecificKeyframe* keyframe,
-                        const AnimatableValue* value,
+                        const CompositorKeyframeValue* value,
                         const TimingFunction& keyframe_timing_function) {
   CompositorTransformOperations ops;
   ToCompositorTransformOperations(
-      ToAnimatableTransform(value)->GetTransformOperations(), &ops);
+      ToCompositorKeyframeTransform(value)->GetTransformOperations(), &ops);
 
   CompositorTransformKeyframe transform_keyframe(
       keyframe->Offset(), std::move(ops), keyframe_timing_function);
@@ -618,7 +620,8 @@
     else
       keyframe_timing_function = &keyframe->Easing();
 
-    const AnimatableValue* value = keyframe->GetAnimatableValue();
+    const CompositorKeyframeValue* value =
+        keyframe->GetCompositorKeyframeValue();
     AddKeyframeToCurve(curve, keyframe, value, *keyframe_timing_function);
   }
 }
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
index b3f0f03..96c020f 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -41,10 +41,8 @@
 #include "cc/trees/transform_node.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/web/web_settings.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_transform.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
 #include "third_party/blink/renderer/core/animation/keyframe_effect.h"
@@ -149,7 +147,7 @@
 
   bool CanStartEffectOnCompositor(const Timing& timing,
                                   const KeyframeEffectModelBase& effect) {
-    // As the compositor code only understands AnimatableValues, we must
+    // As the compositor code only understands CompositorKeyframeValues, we must
     // snapshot the effect to make those available.
     base::Optional<CompositorElementIdSet> none;
     // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes.
@@ -248,7 +246,7 @@
                                         double offset = 0) {
     String value = "0.1";
     if (id == CSSPropertyID::kTransform)
-      value = "none";  // AnimatableTransform::Create(TransformOperations(), 1);
+      value = "none";
     else if (id == CSSPropertyID::kColor)
       value = "red";
 
@@ -287,22 +285,21 @@
     EXPECT_TRUE(element_->style()->getPropertyValue(name));
   }
 
-  // This class exists to dodge the interlock between creating animatable
-  // values iff we can animate them on the compositor, and hence can
-  // start their animations on it. i.e. two far away switch statements
-  // have matching non-default values, preventing us from testing the
-  // default.
-  class AnimatableMockStringKeyframe : public StringKeyframe {
+  // This class exists to dodge the interlock between creating compositor
+  // keyframe values iff we can animate them on the compositor, and hence can
+  // start their animations on it. i.e. two far away switch statements have
+  // matching non-default values, preventing us from testing the default.
+  class MockStringKeyframe : public StringKeyframe {
    public:
     static StringKeyframe* Create(double offset) {
-      return MakeGarbageCollected<AnimatableMockStringKeyframe>(offset);
+      return MakeGarbageCollected<MockStringKeyframe>(offset);
     }
 
-    AnimatableMockStringKeyframe(double offset)
+    MockStringKeyframe(double offset)
         : StringKeyframe(),
           property_specific_(
-              MakeGarbageCollected<
-                  AnimatableMockPropertySpecificStringKeyframe>(offset)) {
+              MakeGarbageCollected<MockPropertySpecificStringKeyframe>(
+                  offset)) {
       SetOffset(offset);
     }
 
@@ -319,33 +316,30 @@
     }
 
    private:
-    class AnimatableMockPropertySpecificStringKeyframe
-        : public PropertySpecificKeyframe {
+    class MockPropertySpecificStringKeyframe : public PropertySpecificKeyframe {
      public:
-      // Pretend to have an animatable value. Pick the offset for
-      // pure convenience: it matters not what it is.
-      AnimatableMockPropertySpecificStringKeyframe(double offset)
+      // Pretend to have a compositor keyframe value. Pick the offset for pure
+      // convenience: it matters not what it is.
+      MockPropertySpecificStringKeyframe(double offset)
           : PropertySpecificKeyframe(offset,
                                      LinearTimingFunction::Shared(),
                                      EffectModel::kCompositeReplace),
-            animatable_offset_(AnimatableDouble::Create(offset)) {}
+            compositor_keyframe_value_(
+                CompositorKeyframeDouble::Create(offset)) {}
       bool IsNeutral() const final { return true; }
       PropertySpecificKeyframe* CloneWithOffset(double) const final {
         NOTREACHED();
         return nullptr;
       }
-      bool PopulateAnimatableValue(
+      bool PopulateCompositorKeyframeValue(
           const PropertyHandle&,
           Element&,
           const ComputedStyle& base_style,
           const ComputedStyle* parent_style) const final {
         return true;
       }
-      const AnimatableValue* GetAnimatableValue() const final {
-        return animatable_offset_;
-      }
-      bool IsAnimatableValuePropertySpecificKeyframe() const final {
-        return true;
+      const CompositorKeyframeValue* GetCompositorKeyframeValue() const final {
+        return compositor_keyframe_value_;
       }
       PropertySpecificKeyframe* NeutralKeyframe(
           double,
@@ -355,21 +349,21 @@
       }
 
       void Trace(Visitor* visitor) override {
-        visitor->Trace(animatable_offset_);
+        visitor->Trace(compositor_keyframe_value_);
         PropertySpecificKeyframe::Trace(visitor);
       }
 
      private:
-      Member<AnimatableDouble> animatable_offset_;
+      Member<CompositorKeyframeDouble> compositor_keyframe_value_;
     };
 
     Member<PropertySpecificKeyframe> property_specific_;
   };
 
-  StringKeyframe* CreateAnimatableReplaceKeyframe(CSSPropertyID id,
-                                                  const String& value,
-                                                  double offset) {
-    StringKeyframe* keyframe = AnimatableMockStringKeyframe::Create(offset);
+  StringKeyframe* CreateMockReplaceKeyframe(CSSPropertyID id,
+                                            const String& value,
+                                            double offset) {
+    StringKeyframe* keyframe = MockStringKeyframe::Create(offset);
     keyframe->SetCSSPropertyValue(id, value,
                                   SecureContextMode::kInsecureContext, nullptr);
     keyframe->SetComposite(EffectModel::kCompositeReplace);
@@ -428,7 +422,7 @@
   std::unique_ptr<CompositorKeyframeModel> ConvertToCompositorAnimation(
       StringKeyframeEffectModel& effect,
       double animation_playback_rate) {
-    // As the compositor code only understands AnimatableValues, we must
+    // As the compositor code only understands CompositorKeyframeValues, we must
     // snapshot the effect to make those available.
     // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes.
     auto style = GetDocument().EnsureStyleResolver().StyleForElement(element_);
@@ -944,7 +938,7 @@
   EXPECT_EQ(2u,
             effect1->GetPropertySpecificKeyframes(target_property1h).size());
   EXPECT_FALSE(effect1->GetPropertySpecificKeyframes(target_property1h)[0]
-                   ->GetAnimatableValue());
+                   ->GetCompositorKeyframeValue());
   EXPECT_EQ(1u, effect1->Properties().size());
   EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
                                                animation1, *effect1, none));
@@ -966,7 +960,7 @@
   EXPECT_EQ(2u,
             effect2->GetPropertySpecificKeyframes(target_property2h).size());
   EXPECT_TRUE(effect2->GetPropertySpecificKeyframes(target_property2h)[0]
-                  ->GetAnimatableValue());
+                  ->GetCompositorKeyframeValue());
   EXPECT_EQ(1u, effect2->Properties().size());
   EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
                                                animation2, *effect2, none));
@@ -977,10 +971,8 @@
   const CSSProperty& target_property3(GetCSSPropertyWidth());
   PropertyHandle target_property3h(target_property3);
   StringKeyframeEffectModel* effect3 = CreateKeyframeEffectModel(
-      CreateAnimatableReplaceKeyframe(target_property3.PropertyID(), "10px",
-                                      0.0),
-      CreateAnimatableReplaceKeyframe(target_property3.PropertyID(), "20px",
-                                      1.0));
+      CreateMockReplaceKeyframe(target_property3.PropertyID(), "10px", 0.0),
+      CreateMockReplaceKeyframe(target_property3.PropertyID(), "20px", 1.0));
 
   KeyframeEffect* keyframe_effect3 =
       KeyframeEffect::Create(element.Get(), effect3, timing_);
@@ -992,7 +984,7 @@
   EXPECT_EQ(2u,
             effect3->GetPropertySpecificKeyframes(target_property3h).size());
   EXPECT_TRUE(effect3->GetPropertySpecificKeyframes(target_property3h)[0]
-                  ->GetAnimatableValue());
+                  ->GetCompositorKeyframeValue());
   EXPECT_EQ(1u, effect3->Properties().size());
   EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
                                                animation3, *effect3, none));
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h b/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h
new file mode 100644
index 0000000..0133e1a
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.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 THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_DOUBLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_DOUBLE_H_
+
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
+#include "third_party/blink/renderer/core/core_export.h"
+
+namespace blink {
+
+class CORE_EXPORT CompositorKeyframeDouble final
+    : public CompositorKeyframeValue {
+ public:
+  CompositorKeyframeDouble(double number) : number_(number) {}
+  ~CompositorKeyframeDouble() override = default;
+
+  static CompositorKeyframeDouble* Create(double number) {
+    return MakeGarbageCollected<CompositorKeyframeDouble>(number);
+  }
+
+  double ToDouble() const { return number_; }
+
+ private:
+  Type GetType() const override { return Type::kDouble; }
+
+  double number_;
+};
+
+DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeDouble,
+                                            IsDouble());
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_DOUBLE_H_
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h b/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h
new file mode 100644
index 0000000..e85d6ca6
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h
@@ -0,0 +1,47 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_FILTER_OPERATIONS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_FILTER_OPERATIONS_H_
+
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
+#include "third_party/blink/renderer/core/style/filter_operations.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+namespace blink {
+
+class CompositorKeyframeFilterOperations final
+    : public CompositorKeyframeValue {
+ public:
+  static CompositorKeyframeFilterOperations* Create(
+      const FilterOperations& operations) {
+    return MakeGarbageCollected<CompositorKeyframeFilterOperations>(operations);
+  }
+
+  CompositorKeyframeFilterOperations(const FilterOperations& operations)
+      : operation_wrapper_(
+            MakeGarbageCollected<FilterOperationsWrapper>(operations)) {}
+  ~CompositorKeyframeFilterOperations() override = default;
+
+  const FilterOperations& Operations() const {
+    return operation_wrapper_->Operations();
+  }
+
+  void Trace(Visitor* visitor) override {
+    visitor->Trace(operation_wrapper_);
+    CompositorKeyframeValue::Trace(visitor);
+  }
+
+ private:
+  Type GetType() const override { return Type::kFilterOperations; }
+
+  Member<FilterOperationsWrapper> operation_wrapper_;
+};
+
+DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeFilterOperations,
+                                            IsFilterOperations());
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_FILTER_OPERATIONS_H_
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h b/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h
new file mode 100644
index 0000000..6c191b3
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h
@@ -0,0 +1,44 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_TRANSFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_TRANSFORM_H_
+
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/transforms/transform_operations.h"
+
+namespace blink {
+
+class CORE_EXPORT CompositorKeyframeTransform final
+    : public CompositorKeyframeValue {
+ public:
+  explicit CompositorKeyframeTransform(const TransformOperations& transform,
+                                       double zoom)
+      : transform_(transform), zoom_(zoom) {}
+  ~CompositorKeyframeTransform() override = default;
+
+  static CompositorKeyframeTransform* Create(
+      const TransformOperations& transform,
+      double zoom) {
+    return MakeGarbageCollected<CompositorKeyframeTransform>(transform, zoom);
+  }
+  const TransformOperations& GetTransformOperations() const {
+    return transform_;
+  }
+  double Zoom() const { return zoom_; }
+
+ private:
+  Type GetType() const override { return Type::kTransform; }
+
+  const TransformOperations transform_;
+  const double zoom_;
+};
+
+DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeTransform,
+                                            IsTransform());
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_TRANSFORM_H_
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h
new file mode 100644
index 0000000..cec31057
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h
@@ -0,0 +1,44 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class CORE_EXPORT CompositorKeyframeValue
+    : public GarbageCollectedFinalized<CompositorKeyframeValue> {
+ public:
+  virtual ~CompositorKeyframeValue() = default;
+
+  bool IsDouble() const { return GetType() == Type::kDouble; }
+  bool IsFilterOperations() const {
+    return GetType() == Type::kFilterOperations;
+  }
+  bool IsTransform() const { return GetType() == Type::kTransform; }
+
+  virtual void Trace(Visitor*) {}
+
+ protected:
+  enum class Type {
+    kDouble,
+    kFilterOperations,
+    kTransform,
+  };
+
+ private:
+  virtual Type GetType() const = 0;
+};
+
+#define DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(thisType, predicate) \
+  DEFINE_TYPE_CASTS(thisType, CompositorKeyframeValue, value,            \
+                    value->predicate, value.predicate)
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_H_
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc
new file mode 100644
index 0000000..b9ad1f5
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc
@@ -0,0 +1,83 @@
+// 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 "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
+
+#include "third_party/blink/renderer/core/animation/compositor_animations.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h"
+#include "third_party/blink/renderer/core/animation/property_handle.h"
+#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+static CompositorKeyframeValue* CreateFromTransformProperties(
+    scoped_refptr<TransformOperation> transform,
+    double zoom,
+    scoped_refptr<TransformOperation> initial_transform) {
+  TransformOperations operation;
+  bool has_transform = static_cast<bool>(transform);
+  if (has_transform || initial_transform) {
+    operation.Operations().push_back(
+        std::move(has_transform ? transform : initial_transform));
+  }
+  return CompositorKeyframeTransform::Create(operation,
+                                             has_transform ? zoom : 1);
+}
+
+CompositorKeyframeValue* CompositorKeyframeValueFactory::Create(
+    const PropertyHandle& property,
+    const ComputedStyle& style) {
+  const CSSProperty& css_property = property.GetCSSProperty();
+#if DCHECK_IS_ON()
+  // Variables are conditionally interpolable and compositable.
+  if (css_property.PropertyID() != CSSPropertyID::kVariable) {
+    DCHECK(css_property.IsInterpolable());
+    DCHECK(css_property.IsCompositableProperty());
+  }
+#endif
+  switch (css_property.PropertyID()) {
+    case CSSPropertyID::kOpacity:
+      return CompositorKeyframeDouble::Create(style.Opacity());
+    case CSSPropertyID::kFilter:
+      return CompositorKeyframeFilterOperations::Create(style.Filter());
+    case CSSPropertyID::kBackdropFilter:
+      return CompositorKeyframeFilterOperations::Create(style.BackdropFilter());
+    case CSSPropertyID::kTransform:
+      return CompositorKeyframeTransform::Create(style.Transform(),
+                                                 style.EffectiveZoom());
+    case CSSPropertyID::kTranslate: {
+      return CreateFromTransformProperties(style.Translate(),
+                                           style.EffectiveZoom(), nullptr);
+    }
+    case CSSPropertyID::kRotate: {
+      return CreateFromTransformProperties(style.Rotate(),
+                                           style.EffectiveZoom(), nullptr);
+    }
+    case CSSPropertyID::kScale: {
+      return CreateFromTransformProperties(style.Scale(), style.EffectiveZoom(),
+                                           nullptr);
+    }
+    case CSSPropertyID::kVariable: {
+      if (!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()) {
+        return nullptr;
+      }
+      const AtomicString& property_name = property.CustomPropertyName();
+      const CSSValue* value = style.GetRegisteredVariable(property_name);
+      const auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value);
+      if (!primitive_value || !primitive_value->IsNumber())
+        return nullptr;
+
+      return CompositorKeyframeDouble::Create(primitive_value->GetFloatValue());
+    }
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h
new file mode 100644
index 0000000..3a75ba3
--- /dev/null
+++ b/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_FACTORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_FACTORY_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class CompositorKeyframeValue;
+class ComputedStyle;
+class PropertyHandle;
+
+class CompositorKeyframeValueFactory {
+  STATIC_ONLY(CompositorKeyframeValueFactory);
+
+ public:
+  static CompositorKeyframeValue* Create(const PropertyHandle&,
+                                         const ComputedStyle&);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_FACTORY_H_
diff --git a/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc b/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc
deleted file mode 100644
index b55f03b..0000000
--- a/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
-
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_transform.h"
-#include "third_party/blink/renderer/core/animation/compositor_animations.h"
-#include "third_party/blink/renderer/core/animation/property_handle.h"
-#include "third_party/blink/renderer/core/css/properties/css_property.h"
-#include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-static AnimatableValue* CreateFromTransformProperties(
-    scoped_refptr<TransformOperation> transform,
-    double zoom,
-    scoped_refptr<TransformOperation> initial_transform) {
-  TransformOperations operation;
-  bool has_transform = static_cast<bool>(transform);
-  if (has_transform || initial_transform) {
-    operation.Operations().push_back(
-        std::move(has_transform ? transform : initial_transform));
-  }
-  return AnimatableTransform::Create(operation, has_transform ? zoom : 1);
-}
-
-AnimatableValue* CSSAnimatableValueFactory::Create(
-    const PropertyHandle& property,
-    const ComputedStyle& style) {
-  const CSSProperty& css_property = property.GetCSSProperty();
-#if DCHECK_IS_ON()
-  // Variables are conditionally interpolable and compositable.
-  if (css_property.PropertyID() != CSSPropertyID::kVariable) {
-    DCHECK(css_property.IsInterpolable());
-    DCHECK(css_property.IsCompositableProperty());
-  }
-#endif
-  switch (css_property.PropertyID()) {
-    case CSSPropertyID::kOpacity:
-      return AnimatableDouble::Create(style.Opacity());
-    case CSSPropertyID::kFilter:
-      return AnimatableFilterOperations::Create(style.Filter());
-    case CSSPropertyID::kBackdropFilter:
-      return AnimatableFilterOperations::Create(style.BackdropFilter());
-    case CSSPropertyID::kTransform:
-      return AnimatableTransform::Create(style.Transform(),
-                                         style.EffectiveZoom());
-    case CSSPropertyID::kTranslate: {
-      return CreateFromTransformProperties(style.Translate(),
-                                           style.EffectiveZoom(), nullptr);
-    }
-    case CSSPropertyID::kRotate: {
-      return CreateFromTransformProperties(style.Rotate(),
-                                           style.EffectiveZoom(), nullptr);
-    }
-    case CSSPropertyID::kScale: {
-      return CreateFromTransformProperties(style.Scale(), style.EffectiveZoom(),
-                                           nullptr);
-    }
-    case CSSPropertyID::kVariable: {
-      if (!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()) {
-        return nullptr;
-      }
-      const AtomicString& property_name = property.CustomPropertyName();
-      const CSSValue* value = style.GetRegisteredVariable(property_name);
-      const auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value);
-      if (!primitive_value || !primitive_value->IsNumber())
-        return nullptr;
-
-      return AnimatableDouble::Create(primitive_value->GetFloatValue());
-    }
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h b/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h
deleted file mode 100644
index a4e34d54..0000000
--- a/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATABLE_VALUE_FACTORY_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATABLE_VALUE_FACTORY_H_
-
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
-#include "third_party/blink/renderer/core/css/css_property_names.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class ComputedStyle;
-class PropertyHandle;
-
-class CSSAnimatableValueFactory {
-  STATIC_ONLY(CSSAnimatableValueFactory);
-
- public:
-  static AnimatableValue* Create(const PropertyHandle&, const ComputedStyle&);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATABLE_VALUE_FACTORY_H_
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.h b/third_party/blink/renderer/core/animation/css/css_animation_update.h
index d0f7645..bfe0f26 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation_update.h
+++ b/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATION_UPDATE_H_
 
 #include "base/macros.h"
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
 #include "third_party/blink/renderer/core/animation/effect_stack.h"
 #include "third_party/blink/renderer/core/animation/inert_effect.h"
 #include "third_party/blink/renderer/core/animation/interpolation.h"
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index 56498173..15a7ac9 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -35,7 +35,7 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
 #include "third_party/blink/renderer/core/animation/compositor_animations.h"
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
 #include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -809,10 +809,10 @@
   keyframes.push_back(end_keyframe);
 
   if (property.GetCSSProperty().IsCompositableProperty()) {
-    AnimatableValue* from =
-        CSSAnimatableValueFactory::Create(property, state.old_style);
-    AnimatableValue* to =
-        CSSAnimatableValueFactory::Create(property, state.style);
+    CompositorKeyframeValue* from =
+        CompositorKeyframeValueFactory::Create(property, state.old_style);
+    CompositorKeyframeValue* to =
+        CompositorKeyframeValueFactory::Create(property, state.style);
     start_keyframe->SetCompositorValue(from);
     end_keyframe->SetCompositorValue(to);
   }
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
index 5fb7836..7b7fb41 100644
--- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
 #include "third_party/blink/renderer/core/animation/length_interpolation_functions.h"
 #include "third_party/blink/renderer/core/animation/length_property_functions.h"
 #include "third_party/blink/renderer/core/css/css_calculation_value.h"
diff --git a/third_party/blink/renderer/core/animation/effect_stack_test.cc b/third_party/blink/renderer/core/animation/effect_stack_test.cc
index 8f4e6bc..97a96b4 100644
--- a/third_party/blink/renderer/core/animation/effect_stack_test.cc
+++ b/third_party/blink/renderer/core/animation/effect_stack_test.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helper.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.h b/third_party/blink/renderer/core/animation/interpolable_value.h
index 652a2ba..4872365 100644
--- a/third_party/blink/renderer/core/animation/interpolable_value.h
+++ b/third_party/blink/renderer/core/animation/interpolable_value.h
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/third_party/blink/renderer/core/animation/keyframe.h b/third_party/blink/renderer/core/animation/keyframe.h
index 5df8b19..3b28d902 100644
--- a/third_party/blink/renderer/core/animation/keyframe.h
+++ b/third_party/blink/renderer/core/animation/keyframe.h
@@ -8,7 +8,6 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/optional.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
 #include "third_party/blink/renderer/core/animation/animation_effect.h"
 #include "third_party/blink/renderer/core/animation/effect_model.h"
 #include "third_party/blink/renderer/core/animation/property_handle.h"
@@ -23,6 +22,7 @@
 
 class Element;
 class ComputedStyle;
+class CompositorKeyframeValue;
 class V8ObjectBuilder;
 
 // A base class representing an animation keyframe.
@@ -134,8 +134,8 @@
     virtual PropertySpecificKeyframe* CloneWithOffset(double offset) const = 0;
 
     // FIXME: Remove this once CompositorAnimations no longer depends on
-    // AnimatableValues
-    virtual bool PopulateAnimatableValue(
+    // CompositorKeyframeValues
+    virtual bool PopulateCompositorKeyframeValue(
         const PropertyHandle&,
         Element&,
         const ComputedStyle& base_style,
@@ -143,11 +143,9 @@
       return false;
     }
 
-    virtual const AnimatableValue* GetAnimatableValue() const = 0;
+    virtual const CompositorKeyframeValue* GetCompositorKeyframeValue()
+        const = 0;
 
-    virtual bool IsAnimatableValuePropertySpecificKeyframe() const {
-      return false;
-    }
     virtual bool IsCSSPropertySpecificKeyframe() const { return false; }
     virtual bool IsSVGPropertySpecificKeyframe() const { return false; }
     virtual bool IsTransitionPropertySpecificKeyframe() const { return false; }
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
index b291cf9..99f1466 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
@@ -35,7 +35,6 @@
 
 #include "third_party/blink/renderer/core/animation/animation_effect.h"
 #include "third_party/blink/renderer/core/animation/compositor_animations.h"
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
 #include "third_party/blink/renderer/core/css/css_property_equality.h"
 #include "third_party/blink/renderer/core/css/property_registry.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
@@ -233,8 +232,8 @@
     if (!should_snapshot_keyframe_callback(*keyframe))
       continue;
 
-    updated |= keyframe->PopulateAnimatableValue(property, element,
-                                                 computed_style, parent_style);
+    updated |= keyframe->PopulateCompositorKeyframeValue(
+        property, element, computed_style, parent_style);
   }
   return updated;
 }
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
index c571ef1b..8ccdb6d 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
@@ -31,7 +31,6 @@
 #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helper.h"
 #include "third_party/blink/renderer/core/animation/css_default_interpolation_type.h"
 #include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h"
@@ -618,13 +617,13 @@
 
   auto style = GetDocument().EnsureStyleResolver().StyleForElement(element);
 
-  const AnimatableValue* value;
+  const CompositorKeyframeValue* value;
 
-  // Animatable value should be empty before snapshot
+  // Compositor keyframe value should be empty before snapshot
   value = effect
               ->GetPropertySpecificKeyframes(
                   PropertyHandle(GetCSSPropertyOpacity()))[0]
-              ->GetAnimatableValue();
+              ->GetCompositorKeyframeValue();
   EXPECT_FALSE(value);
 
   // Snapshot should update first time after construction
@@ -638,11 +637,11 @@
   EXPECT_TRUE(effect->SnapshotAllCompositorKeyframesIfNecessary(
       *element, *style, nullptr));
 
-  // Animatable value should be available after snapshot
+  // Compositor keyframe value should be available after snapshot
   value = effect
               ->GetPropertySpecificKeyframes(
                   PropertyHandle(GetCSSPropertyOpacity()))[0]
-              ->GetAnimatableValue();
+              ->GetCompositorKeyframeValue();
   EXPECT_TRUE(value);
   EXPECT_TRUE(value->IsDouble());
 }
@@ -659,11 +658,11 @@
   EXPECT_TRUE(effect->SnapshotAllCompositorKeyframesIfNecessary(
       *element, *style, nullptr));
 
-  const AnimatableValue* value;
+  const CompositorKeyframeValue* value;
   value = effect
               ->GetPropertySpecificKeyframes(
                   PropertyHandle(GetCSSPropertyOpacity()))[0]
-              ->GetAnimatableValue();
+              ->GetCompositorKeyframeValue();
   EXPECT_TRUE(value);
   EXPECT_TRUE(value->IsDouble());
 
@@ -677,7 +676,7 @@
   value = effect
               ->GetPropertySpecificKeyframes(
                   PropertyHandle(GetCSSPropertyFilter()))[0]
-              ->GetAnimatableValue();
+              ->GetCompositorKeyframeValue();
   EXPECT_TRUE(value);
   EXPECT_TRUE(value->IsFilterOperations());
 }
@@ -706,17 +705,17 @@
 
   auto style = GetDocument().EnsureStyleResolver().StyleForElement(element);
 
-  const AnimatableValue* value;
+  const CompositorKeyframeValue* value;
 
   // Snapshot should update first time after construction
   EXPECT_TRUE(effect->SnapshotAllCompositorKeyframesIfNecessary(
       *element, *style, nullptr));
 
-  // Animatable value should be available after snapshot
+  // Compositor keyframe value available after snapshot
   value = effect
               ->GetPropertySpecificKeyframes(
                   PropertyHandle(AtomicString("--foo")))[0]
-              ->GetAnimatableValue();
+              ->GetCompositorKeyframeValue();
   EXPECT_TRUE(value);
   EXPECT_TRUE(value->IsDouble());
 }
diff --git a/third_party/blink/renderer/core/animation/length_interpolation_functions.h b/third_party/blink/renderer/core/animation/length_interpolation_functions.h
index a75221a..841ae0ebf 100644
--- a/third_party/blink/renderer/core/animation/length_interpolation_functions.h
+++ b/third_party/blink/renderer/core/animation/length_interpolation_functions.h
@@ -13,6 +13,7 @@
 namespace blink {
 
 class CSSToLengthConversionData;
+class CSSValue;
 
 class LengthInterpolationFunctions {
   STATIC_ONLY(LengthInterpolationFunctions);
diff --git a/third_party/blink/renderer/core/animation/number_property_functions.cc b/third_party/blink/renderer/core/animation/number_property_functions.cc
index d83363c..8f13eb82 100644
--- a/third_party/blink/renderer/core/animation/number_property_functions.cc
+++ b/third_party/blink/renderer/core/animation/number_property_functions.cc
@@ -109,9 +109,6 @@
     case CSSPropertyID::kColumnCount:
       return clampTo<uint16_t>(round(value), 1);
 
-    case CSSPropertyID::kColumnRuleWidth:
-      return clampTo<uint16_t>(round(value));
-
     case CSSPropertyID::kOrder:
     case CSSPropertyID::kZIndex:
       return clampTo<int>(round(value));
diff --git a/third_party/blink/renderer/core/animation/string_keyframe.cc b/third_party/blink/renderer/core/animation/string_keyframe.cc
index cc805aa3..90ad43fb 100644
--- a/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -168,13 +168,14 @@
       offset, &Easing(), SvgPropertyValue(property.SvgAttribute()), composite);
 }
 
-bool StringKeyframe::CSSPropertySpecificKeyframe::PopulateAnimatableValue(
-    const PropertyHandle& property,
-    Element& element,
-    const ComputedStyle& base_style,
-    const ComputedStyle* parent_style) const {
-  animatable_value_cache_ = StyleResolver::CreateAnimatableValueSnapshot(
-      element, base_style, parent_style, property, value_.Get());
+bool StringKeyframe::CSSPropertySpecificKeyframe::
+    PopulateCompositorKeyframeValue(const PropertyHandle& property,
+                                    Element& element,
+                                    const ComputedStyle& base_style,
+                                    const ComputedStyle* parent_style) const {
+  compositor_keyframe_value_cache_ =
+      StyleResolver::CreateCompositorKeyframeValueSnapshot(
+          element, base_style, parent_style, property, value_.Get());
   return true;
 }
 
@@ -187,7 +188,7 @@
 
 void StringKeyframe::CSSPropertySpecificKeyframe::Trace(Visitor* visitor) {
   visitor->Trace(value_);
-  visitor->Trace(animatable_value_cache_);
+  visitor->Trace(compositor_keyframe_value_cache_);
   Keyframe::PropertySpecificKeyframe::Trace(visitor);
 }
 
@@ -196,7 +197,7 @@
     double offset) const {
   CSSPropertySpecificKeyframe* clone =
       Create(offset, easing_, value_.Get(), composite_);
-  clone->animatable_value_cache_ = animatable_value_cache_;
+  clone->compositor_keyframe_value_cache_ = compositor_keyframe_value_cache_;
   return clone;
 }
 
diff --git a/third_party/blink/renderer/core/animation/string_keyframe.h b/third_party/blink/renderer/core/animation/string_keyframe.h
index b8847abae..c4afa7da 100644
--- a/third_party/blink/renderer/core/animation/string_keyframe.h
+++ b/third_party/blink/renderer/core/animation/string_keyframe.h
@@ -112,12 +112,13 @@
 
     const CSSValue* Value() const { return value_.Get(); }
 
-    bool PopulateAnimatableValue(const PropertyHandle&,
-                                 Element&,
-                                 const ComputedStyle& base_style,
-                                 const ComputedStyle* parent_style) const final;
-    const AnimatableValue* GetAnimatableValue() const final {
-      return animatable_value_cache_;
+    bool PopulateCompositorKeyframeValue(
+        const PropertyHandle&,
+        Element&,
+        const ComputedStyle& base_style,
+        const ComputedStyle* parent_style) const final;
+    const CompositorKeyframeValue* GetCompositorKeyframeValue() const final {
+      return compositor_keyframe_value_cache_;
     }
 
     bool IsNeutral() const final { return !value_; }
@@ -133,7 +134,7 @@
     bool IsCSSPropertySpecificKeyframe() const override { return true; }
 
     Member<const CSSValue> value_;
-    mutable Member<AnimatableValue> animatable_value_cache_;
+    mutable Member<CompositorKeyframeValue> compositor_keyframe_value_cache_;
   };
 
   class SVGPropertySpecificKeyframe
@@ -161,7 +162,9 @@
 
     PropertySpecificKeyframe* CloneWithOffset(double offset) const final;
 
-    const AnimatableValue* GetAnimatableValue() const final { return nullptr; }
+    const CompositorKeyframeValue* GetCompositorKeyframeValue() const final {
+      return nullptr;
+    }
 
     bool IsNeutral() const final { return value_.IsNull(); }
     PropertySpecificKeyframe* NeutralKeyframe(
diff --git a/third_party/blink/renderer/core/animation/transition_interpolation.h b/third_party/blink/renderer/core/animation/transition_interpolation.h
index a9d1d49..7718b637 100644
--- a/third_party/blink/renderer/core/animation/transition_interpolation.h
+++ b/third_party/blink/renderer/core/animation/transition_interpolation.h
@@ -26,25 +26,26 @@
 //
 // The TransitionInterpolation subclass stores the start and end keyframes as
 // InterpolationValue objects, with an InterpolationType object that applies to
-// both InterpolationValues. It additionally stores AnimatableValue objects
-// corresponding to start and end keyframes as communicated to the compositor
-// thread. Together, this is equivalent to representing the start and end
-// keyframes as TransitionPropertySpecificKeyframe objects with the added
+// both InterpolationValues. It additionally stores CompositorKeyframeValue
+// objects corresponding to start and end keyframes as communicated to the
+// compositor thread. Together, this is equivalent to representing the start and
+// end keyframes as TransitionPropertySpecificKeyframe objects with the added
 // constraint that they share an InterpolationType.
 // TODO(crbug.com/442163): Store information for communication with the
-// compositor without using AnimatableValue objects.
+// compositor without using CompositorKeyframeValue objects.
 //
 // During the effect application phase of animation computation, the current
 // value of the property is applied to the element by calling the Apply
 // function.
 class CORE_EXPORT TransitionInterpolation : public Interpolation {
  public:
-  static TransitionInterpolation* Create(const PropertyHandle& property,
-                                         const InterpolationType& type,
-                                         InterpolationValue&& start,
-                                         InterpolationValue&& end,
-                                         AnimatableValue* compositor_start,
-                                         AnimatableValue* compositor_end) {
+  static TransitionInterpolation* Create(
+      const PropertyHandle& property,
+      const InterpolationType& type,
+      InterpolationValue&& start,
+      InterpolationValue&& end,
+      CompositorKeyframeValue* compositor_start,
+      CompositorKeyframeValue* compositor_end) {
     return MakeGarbageCollected<TransitionInterpolation>(
         property, type, std::move(start), std::move(end), compositor_start,
         compositor_end);
@@ -54,8 +55,8 @@
                           const InterpolationType& type,
                           InterpolationValue&& start,
                           InterpolationValue&& end,
-                          AnimatableValue* compositor_start,
-                          AnimatableValue* compositor_end)
+                          CompositorKeyframeValue* compositor_start,
+                          CompositorKeyframeValue* compositor_end)
       : property_(property),
         type_(type),
         start_(std::move(start)),
@@ -101,8 +102,8 @@
   const InterpolationValue start_;
   const InterpolationValue end_;
   const PairwiseInterpolationValue merge_;
-  const Member<AnimatableValue> compositor_start_;
-  const Member<AnimatableValue> compositor_end_;
+  const Member<CompositorKeyframeValue> compositor_start_;
+  const Member<CompositorKeyframeValue> compositor_end_;
 
   mutable double cached_fraction_ = 0;
   mutable int cached_iteration_ = 0;
diff --git a/third_party/blink/renderer/core/animation/transition_keyframe.cc b/third_party/blink/renderer/core/animation/transition_keyframe.cc
index 3652383..dad43e8 100644
--- a/third_party/blink/renderer/core/animation/transition_keyframe.cc
+++ b/third_party/blink/renderer/core/animation/transition_keyframe.cc
@@ -12,7 +12,8 @@
 
 namespace blink {
 
-void TransitionKeyframe::SetCompositorValue(AnimatableValue* compositor_value) {
+void TransitionKeyframe::SetCompositorValue(
+    CompositorKeyframeValue* compositor_value) {
   DCHECK_EQ(property_.GetCSSProperty().IsCompositableProperty(),
             static_cast<bool>(compositor_value));
   compositor_value_ = compositor_value;
diff --git a/third_party/blink/renderer/core/animation/transition_keyframe.h b/third_party/blink/renderer/core/animation/transition_keyframe.h
index de9ad80..887f213 100644
--- a/third_party/blink/renderer/core/animation/transition_keyframe.h
+++ b/third_party/blink/renderer/core/animation/transition_keyframe.h
@@ -5,7 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TRANSITION_KEYFRAME_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TRANSITION_KEYFRAME_H_
 
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
 #include "third_party/blink/renderer/core/animation/keyframe.h"
 #include "third_party/blink/renderer/core/animation/typed_interpolation_value.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -41,7 +41,7 @@
     CHECK(!!value->Value());
     value_ = std::move(value);
   }
-  void SetCompositorValue(AnimatableValue*);
+  void SetCompositorValue(CompositorKeyframeValue*);
   PropertyHandleSet Properties() const final;
 
   void AddKeyframePropertiesToV8Object(V8ObjectBuilder&) const override;
@@ -54,14 +54,14 @@
                              scoped_refptr<TimingFunction> easing,
                              EffectModel::CompositeOperation composite,
                              std::unique_ptr<TypedInterpolationValue> value,
-                             AnimatableValue* compositor_value)
+                             CompositorKeyframeValue* compositor_value)
         : Keyframe::PropertySpecificKeyframe(offset,
                                              std::move(easing),
                                              composite),
           value_(std::move(value)),
           compositor_value_(compositor_value) {}
 
-    const AnimatableValue* GetAnimatableValue() const final {
+    const CompositorKeyframeValue* GetCompositorKeyframeValue() const final {
       return compositor_value_;
     }
 
@@ -88,7 +88,7 @@
     }
 
     std::unique_ptr<TypedInterpolationValue> value_;
-    Member<AnimatableValue> compositor_value_;
+    Member<CompositorKeyframeValue> compositor_value_;
   };
 
  private:
@@ -105,7 +105,7 @@
 
   PropertyHandle property_;
   std::unique_ptr<TypedInterpolationValue> value_;
-  Member<AnimatableValue> compositor_value_;
+  Member<CompositorKeyframeValue> compositor_value_;
 };
 
 using TransitionPropertySpecificKeyframe =
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
index 418648d..505531dd 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
@@ -956,8 +956,7 @@
              value_id == CSSValueID::kPreWrap ||
              value_id == CSSValueID::kPreLine ||
              value_id == CSSValueID::kNowrap ||
-             (RuntimeEnabledFeatures::CSS3TextBreakSpacesEnabled() &&
-              value_id == CSSValueID::kBreakSpaces);
+             value_id == CSSValueID::kBreakSpaces;
     case CSSPropertyID::kWordBreak:
       return value_id == CSSValueID::kNormal ||
              value_id == CSSValueID::kBreakAll ||
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
index 3463c419..d9fbad0 100644
--- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -546,13 +546,25 @@
 
   if (offset.IsPercentOrCalc() && layout_object && layout_object->IsBox() &&
       layout_object->IsPositioned()) {
-    LayoutUnit containing_block_size =
-        is_horizontal_property ==
-                layout_object->ContainingBlock()->IsHorizontalWritingMode()
-            ? ToLayoutBox(layout_object)
-                  ->ContainingBlockLogicalWidthForContent()
-            : ToLayoutBox(layout_object)
-                  ->ContainingBlockLogicalHeightForGetComputedStyle();
+    LayoutUnit containing_block_size;
+    if (layout_object->IsStickyPositioned()) {
+      const LayoutBox& enclosing_scrollport_box =
+          ToLayoutBox(layout_object)->EnclosingScrollportBox();
+      bool use_inline_size = is_horizontal_property ==
+                             enclosing_scrollport_box.IsHorizontalWritingMode();
+      containing_block_size =
+          use_inline_size ? enclosing_scrollport_box.ContentLogicalWidth()
+                          : enclosing_scrollport_box.ContentLogicalHeight();
+    } else {
+      containing_block_size =
+          is_horizontal_property ==
+                  layout_object->ContainingBlock()->IsHorizontalWritingMode()
+              ? ToLayoutBox(layout_object)
+                    ->ContainingBlockLogicalWidthForContent()
+              : ToLayoutBox(layout_object)
+                    ->ContainingBlockLogicalHeightForGetComputedStyle();
+    }
+
     return ZoomAdjustedPixelValue(ValueForLength(offset, containing_block_size),
                                   style);
   }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 37d81a9b..8a3f099 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -30,8 +30,7 @@
 
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 
-#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
-#include "third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h"
+#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
 #include "third_party/blink/renderer/core/animation/css/css_animations.h"
 #include "third_party/blink/renderer/core/animation/css_interpolation_environment.h"
 #include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
@@ -852,9 +851,7 @@
   return state.TakeStyle();
 }
 
-// TODO(alancutter): Create compositor keyframe values directly instead of
-// intermediate AnimatableValues.
-AnimatableValue* StyleResolver::CreateAnimatableValueSnapshot(
+CompositorKeyframeValue* StyleResolver::CreateCompositorKeyframeValueSnapshot(
     Element& element,
     const ComputedStyle& base_style,
     const ComputedStyle* parent_style,
@@ -872,7 +869,7 @@
         state.StyleRef());
     CSSVariableResolver(state).ResolveVariableDefinitions();
   }
-  return CSSAnimatableValueFactory::Create(property, *state.Style());
+  return CompositorKeyframeValueFactory::Create(property, *state.Style());
 }
 
 bool StyleResolver::PseudoStyleForElementInternal(
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h
index 673512f..4deba97 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -42,9 +42,9 @@
 
 namespace blink {
 
-class AnimatableValue;
 class CSSRuleList;
 class CSSValue;
+class CompositorKeyframeValue;
 class Document;
 class Element;
 class Interpolation;
@@ -75,7 +75,7 @@
 
   static scoped_refptr<ComputedStyle> InitialStyleForElement(Document&);
 
-  static AnimatableValue* CreateAnimatableValueSnapshot(
+  static CompositorKeyframeValue* CreateCompositorKeyframeValueSnapshot(
       Element&,
       const ComputedStyle& base_style,
       const ComputedStyle* parent_style,
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc
index af3d21e..c03dffa 100644
--- a/third_party/blink/renderer/core/dom/container_node.cc
+++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -1453,7 +1453,7 @@
     if (auto* slot = ToHTMLSlotElementOrNull(this)) {
       slot->RebuildDistributedChildrenLayoutTrees(whitespace_attacher);
     } else {
-      ToV0InsertionPoint(this)->RebuildDistributedChildrenLayoutTrees(
+      To<V0InsertionPoint>(this)->RebuildDistributedChildrenLayoutTrees(
           whitespace_attacher);
     }
     RebuildNonDistributedChildren();
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 30f6773..ebbb2b09 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2968,25 +2968,31 @@
   return Parser() ? Parser()->AsScriptableDocumentParser() : nullptr;
 }
 
+void Document::DisplayNoneChangedForFrame() {
+  if (!documentElement())
+    return;
+  // LayoutView()::CanHaveChildren(), hence the existence of style and
+  // layout tree, depends on the owner being display:none or not. Trigger
+  // detaching or attaching the style/layout-tree as a result of that
+  // changing.
+  documentElement()->SetNeedsStyleRecalc(
+      kLocalStyleChange,
+      StyleChangeReasonForTracing::Create(style_change_reason::kFrame));
+}
+
 void Document::SetPrinting(PrintingState state) {
   bool was_printing = Printing();
   printing_ = state;
   bool is_printing = Printing();
 
-  // Changing the state of Printing() can change whether layout objects are
-  // created for iframes. As such, we need to do a full reattach. See
-  // LayoutView::CanHaveChildren.
-  // https://crbug.com/819327.
   if ((was_printing != is_printing) && documentElement() && GetFrame() &&
       !GetFrame()->IsMainFrame() && GetFrame()->Owner() &&
       GetFrame()->Owner()->IsDisplayNone()) {
-    // LazyReattachIfAttached() is not idempotent. HTMLObjectElements will lose
-    // their contents, which must be asynchronously regenerated. As such, we
-    // avoid calling this method unless we think that this is a display-none
-    // iframe and calling this is necessary.
-    // This still leaves the edge case of a display: none iframe with an
-    // HTMLObjectElement that doesn't print properly. https://crbug.com/838760.
-    documentElement()->LazyReattachIfAttached();
+    // In non-printing mode we do not generate style or layout objects for
+    // display:none iframes, yet we do when printing (see
+    // LayoutView::CanHaveChildren). Trigger a style recalc on the root element
+    // to create a layout tree for printing.
+    DisplayNoneChangedForFrame();
   }
 }
 
@@ -5206,10 +5212,8 @@
   DCHECK(GetFrame() && GetFrame()->Owner());
   FrameOwner* owner = GetFrame()->Owner();
 
-  if (documentElement()) {
-    if (is_display_none != owner->IsDisplayNone())
-      documentElement()->LazyReattachIfAttached();
-  }
+  if (is_display_none != owner->IsDisplayNone())
+    DisplayNoneChangedForFrame();
 
   // body() may become null as a result of modification event listeners, so we
   // check before each call.
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 2d1ac7a4..c092c8d4 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1697,6 +1697,7 @@
 
   void NotifyFocusedElementChanged(Node* old_focused_element,
                                    Node* new_focused_element);
+  void DisplayNoneChangedForFrame();
 
   DocumentLifecycle lifecycle_;
 
diff --git a/third_party/blink/renderer/core/dom/flat_tree_traversal.cc b/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
index ef7fc08..a02d534c 100644
--- a/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
+++ b/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
@@ -134,14 +134,14 @@
                       : sibling->previousSibling())) {
     if (!IsActiveV0InsertionPoint(*sibling))
       return const_cast<Node*>(sibling);
-    const V0InsertionPoint& insertion_point = ToV0InsertionPoint(*sibling);
+    const auto* insertion_point = To<V0InsertionPoint>(sibling);
     if (Node* found = (direction == kTraversalDirectionForward
-                           ? insertion_point.FirstDistributedNode()
-                           : insertion_point.LastDistributedNode()))
+                           ? insertion_point->FirstDistributedNode()
+                           : insertion_point->LastDistributedNode()))
       return found;
-    DCHECK(IsHTMLShadowElement(insertion_point) ||
-           (IsHTMLContentElement(insertion_point) &&
-            !insertion_point.HasChildren()));
+    DCHECK(IsHTMLShadowElement(*insertion_point) ||
+           (IsHTMLContentElement(*insertion_point) &&
+            !insertion_point->HasChildren()));
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/dom/shadow_root_v0.cc b/third_party/blink/renderer/core/dom/shadow_root_v0.cc
index 6296448..dfb57fd9 100644
--- a/third_party/blink/renderer/core/dom/shadow_root_v0.cc
+++ b/third_party/blink/renderer/core/dom/shadow_root_v0.cc
@@ -69,7 +69,7 @@
       continue;
 
     if (IsActiveV0InsertionPoint(*child)) {
-      V0InsertionPoint* insertion_point = ToV0InsertionPoint(child);
+      auto* insertion_point = To<V0InsertionPoint>(child);
       for (wtf_size_t i = 0; i < insertion_point->DistributedNodesSize(); ++i)
         nodes_.push_back(insertion_point->DistributedNodeAt(i));
     } else {
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc
index 4609368..3e0e6c9e 100644
--- a/third_party/blink/renderer/core/dom/text.cc
+++ b/third_party/blink/renderer/core/dom/text.cc
@@ -398,8 +398,9 @@
   if (LayoutText* layout_text = GetLayoutObject()) {
     const ComputedStyle* layout_parent_style =
         GetLayoutObject()->Parent()->Style();
-    if (!new_style || (new_style != layout_parent_style &&
-                       !new_style->InheritedEqual(*layout_parent_style))) {
+    if (!new_style || GetForceReattachLayoutTree() ||
+        (new_style != layout_parent_style &&
+         !new_style->InheritedEqual(*layout_parent_style))) {
       // The computed style or the need for an anonymous inline wrapper for a
       // display:contents text child changed.
       SetNeedsReattachLayoutTree();
@@ -409,6 +410,7 @@
         layout_text->SetText(DataImpl());
     }
   } else if (new_style && (NeedsStyleRecalc() || change.ReattachLayoutTree() ||
+                           GetForceReattachLayoutTree() ||
                            NeedsWhitespaceLayoutObject(*new_style))) {
     SetNeedsReattachLayoutTree();
   }
@@ -425,15 +427,15 @@
   ClearNeedsReattachLayoutTree();
 }
 
-// Passing both |textNode| and its layout object because repeated calls to
-// |Node::layoutObject()| are discouraged.
+// Passing both |text_node| and its layout object because repeated calls to
+// |Node::GetLayoutObject()| are discouraged.
 static bool ShouldUpdateLayoutByReattaching(const Text& text_node,
                                             LayoutText* text_layout_object) {
   DCHECK_EQ(text_node.GetLayoutObject(), text_layout_object);
   if (!text_layout_object)
     return true;
   // In general we do not want to branch on lifecycle states such as
-  // |childNeedsDistributionRecalc|, but this code tries to figure out if we can
+  // |ChildNeedsDistributionRecalc|, but this code tries to figure out if we can
   // use an optimized code path that avoids reattach.
   if (!text_node.GetDocument().ChildNeedsDistributionRecalc() &&
       !text_node.TextLayoutObjectIsNeeded(Node::AttachContext(),
@@ -456,7 +458,7 @@
     return;
   LayoutText* text_layout_object = GetLayoutObject();
   if (ShouldUpdateLayoutByReattaching(*this, text_layout_object)) {
-    LazyReattachIfAttached();
+    SetForceReattachLayoutTree();
     return;
   }
 
diff --git a/third_party/blink/renderer/core/dom/v0_insertion_point.h b/third_party/blink/renderer/core/dom/v0_insertion_point.h
index d83433c..e519ec03 100644
--- a/third_party/blink/renderer/core/dom/v0_insertion_point.h
+++ b/third_party/blink/renderer/core/dom/v0_insertion_point.h
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/css/css_selector_list.h"
 #include "third_party/blink/renderer/core/dom/distributed_nodes.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -100,10 +101,9 @@
 
 using DestinationInsertionPoints = HeapVector<Member<V0InsertionPoint>, 1>;
 
-DEFINE_ELEMENT_TYPE_CASTS(V0InsertionPoint, IsV0InsertionPoint());
-
 inline bool IsActiveV0InsertionPoint(const Node& node) {
-  return node.IsV0InsertionPoint() && ToV0InsertionPoint(node).IsActive();
+  auto* insertion_point = DynamicTo<V0InsertionPoint>(node);
+  return insertion_point && insertion_point->IsActive();
 }
 
 inline ShadowRoot* ShadowRootWhereNodeCanBeDistributedForV0(const Node& node) {
@@ -123,6 +123,16 @@
     const Node&,
     HeapVector<Member<V0InsertionPoint>, 8>& results);
 
+template <>
+inline bool IsElementOfType<const V0InsertionPoint>(const Node& node) {
+  return node.IsV0InsertionPoint();
+}
+
+template <>
+struct DowncastTraits<V0InsertionPoint> {
+  static bool AllowFrom(const Node& node) { return node.IsV0InsertionPoint(); }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_V0_INSERTION_POINT_H_
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
index 30ac731..4eee2b2 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
+++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -77,7 +77,11 @@
           task_runner ? task_runner : base::SequencedTaskRunnerHandle::Get()),
       binding_(this),
       task_runner_(std::move(task_runner)),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  // TODO(https://crbug.com/957651): Change this into a DCHECK once we figured
+  // out where code is passing in a null task runner,
+  CHECK(task_runner_);
+}
 
 FileReaderLoader::~FileReaderLoader() {
   Cleanup();
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 12a24f7f4..d14fe33f 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -415,7 +415,7 @@
 
   input_type_view_->DestroyShadowSubtree();
   DropInnerEditorElement();
-  LazyReattachIfAttached();
+  SetForceReattachLayoutTree();
 
   if (input_type_->SupportsRequired() != new_type->SupportsRequired() &&
       IsRequired()) {
@@ -1941,7 +1941,12 @@
   if (!!should_reveal_password_ == value)
     return;
   should_reveal_password_ = value;
-  LazyReattachIfAttached();
+  if (HTMLElement* inner_editor = InnerEditorElement()) {
+    // Update -webkit-text-security style.
+    inner_editor->SetNeedsStyleRecalc(
+        kLocalStyleChange,
+        StyleChangeReasonForTracing::Create(style_change_reason::kControl));
+  }
 }
 
 bool HTMLInputElement::IsInteractiveContent() const {
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.cc b/third_party/blink/renderer/core/html/forms/image_input_type.cc
index a350424..35a4b1ba 100644
--- a/third_party/blink/renderer/core/html/forms/image_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/image_input_type.cc
@@ -23,6 +23,7 @@
 
 #include "third_party/blink/renderer/core/html/forms/image_input_type.h"
 
+#include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -263,8 +264,14 @@
 }
 
 void ImageInputType::ReattachFallbackContent() {
-  if (!GetElement().GetDocument().InStyleRecalc())
-    GetElement().LazyReattachIfAttached();
+  if (!GetElement().GetDocument().InStyleRecalc()) {
+    // ComputedStyle depends on use_fallback_content_. Trigger recalc.
+    GetElement().SetNeedsStyleRecalc(
+        kLocalStyleChange,
+        StyleChangeReasonForTracing::Create(style_change_reason::kUseFallback));
+    // LayoutObject type depends on use_fallback_content_. Trigger re-attach.
+    GetElement().SetForceReattachLayoutTree();
+  }
 }
 
 void ImageInputType::CreateShadowSubtree() {
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
index 2fd82c2..179b646 100644
--- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
+++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -355,12 +355,6 @@
 void MultipleFieldsTemporalInputTypeView::CreateShadowSubtree() {
   DCHECK(IsShadowHost(GetElement()));
 
-  // Element must not have a layoutObject here, because if it did
-  // DateTimeEditElement::customStyleForLayoutObject() is called in
-  // appendChild() before the field wrapper element is created.
-  // FIXME: This code should not depend on such craziness.
-  DCHECK(!GetElement().GetLayoutObject());
-
   Document& document = GetElement().GetDocument();
   ContainerNode* container = GetElement().UserAgentShadowRoot();
 
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
index 86007a9c..ce81f743 100644
--- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -227,7 +227,13 @@
       return;
   }
 
+  // Style and layout may be dirty at this point. E.g. if an event handler for
+  // the input element has modified its type attribute. If so, the LayoutObject
+  // and the input type is out of sync. Avoid accessing the LayoutObject if we
+  // have scheduled a forced re-attach (GetForceReattachLayoutTree()) for the
+  // input element.
   if (GetElement().GetLayoutObject() &&
+      !GetElement().GetForceReattachLayoutTree() &&
       (event.IsMouseEvent() || event.IsDragEvent() ||
        event.HasInterface(event_interface_names::kWheelEvent) ||
        event.type() == event_type_names::kBlur ||
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 439db3b..0a6cf0d 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -838,7 +838,13 @@
     EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
     EnsureUserAgentShadowRoot();
   }
-  LazyReattachIfAttached();
+
+  // ComputedStyle depends on layout_disposition_. Trigger recalc.
+  SetNeedsStyleRecalc(
+      kLocalStyleChange,
+      StyleChangeReasonForTracing::Create(style_change_reason::kUseFallback));
+  // LayoutObject type depends on layout_disposition_. Trigger re-attach.
+  SetForceReattachLayoutTree();
 }
 
 scoped_refptr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject() {
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index 7071bac..aecc7670 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -578,6 +578,7 @@
       midiSysex
       notifications
       paymentHandler
+      periodicBackgroundSync
       protectedMediaIdentifier
       sensors
       videoCapture
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
index 0151bb8..129b4bb9 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -1523,9 +1523,9 @@
         value->setXmlVersion(element->ownerDocument()->xmlVersion());
     }
 
-    if (element->IsV0InsertionPoint()) {
+    if (auto* insertion_point = DynamicTo<V0InsertionPoint>(element)) {
       value->setDistributedNodes(
-          BuildArrayForDistributedNodes(ToV0InsertionPoint(element)));
+          BuildArrayForDistributedNodes(insertion_point));
       force_push_children = true;
     }
     if (auto* slot = ToHTMLSlotElementOrNull(*element)) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 9fefcdc..74dde66 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -5745,6 +5745,16 @@
   return nullptr;
 }
 
+const LayoutBlock& LayoutBox::EnclosingScrollportBox() const {
+  const LayoutBlock* ancestor = ContainingBlock();
+  for (; ancestor; ancestor = ancestor->ContainingBlock()) {
+    if (ancestor->HasOverflowClip())
+      return *ancestor;
+  }
+  NOTREACHED();
+  return *ancestor;
+}
+
 LayoutRect LayoutBox::LogicalVisualOverflowRectForPropagation() const {
   LayoutRect rect = VisualOverflowRectForPropagation();
   if (!Parent()->StyleRef().IsHorizontalWritingMode())
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index c4739e62..7616f30 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1201,6 +1201,8 @@
 
   PaintLayer* EnclosingFloatPaintingLayer() const;
 
+  const LayoutBlock& EnclosingScrollportBox() const;
+
   virtual LayoutUnit FirstLineBoxBaseline() const { return LayoutUnit(-1); }
   virtual LayoutUnit InlineBlockBaseline(LineDirectionMode) const {
     return LayoutUnit(-1);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index 5c60e62..20d9256 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/page/spatial_navigation.h"
 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/histogram.h"
 
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 
@@ -238,6 +239,8 @@
 
 bool SpatialNavigationController::Advance(
     SpatialNavigationDirection direction) {
+  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.SpatialNavigation.Advance");
+
   Node* interest_node = StartingNode();
   if (!interest_node)
     return false;
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 1f2267d..81dc16d0 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -172,8 +172,6 @@
   // Needed to allow access to private/protected getters of fields to allow diff
   // generation
   friend class ComputedStyleBase;
-  // Used by Web Animations CSS. Gets visited and unvisited colors separately.
-  friend class CSSAnimatableValueFactory;
   // Used by CSS animations. We can't allow them to animate based off visited
   // colors.
   friend class CSSPropertyEquality;
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser.cc b/third_party/blink/renderer/modules/manifest/manifest_parser.cc
index edf0043..90d7348 100644
--- a/third_party/blink/renderer/modules/manifest/manifest_parser.cc
+++ b/third_party/blink/renderer/modules/manifest/manifest_parser.cc
@@ -654,13 +654,22 @@
 
 base::Optional<Manifest::FileHandler> ManifestParser::ParseFileHandler(
     const base::DictionaryValue& dictionary) {
-  constexpr char file_handler_key[] = "file_handler";
-  if (!dictionary.HasKey(file_handler_key))
+  const base::DictionaryValue* file_handler_value;
+  if (!dictionary.GetDictionary("file_handler", &file_handler_value))
     return base::nullopt;
 
-  Manifest::FileHandler file_handler =
-      ParseTargetFiles(file_handler_key, dictionary);
-  if (file_handler.size() == 0) {
+  Manifest::FileHandler file_handler;
+  file_handler.action = ParseURL(*file_handler_value, "action", manifest_url_,
+                                 ParseURLOriginRestrictions::kSameOriginOnly);
+  if (!file_handler.action.is_valid()) {
+    AddErrorInfo(
+        "property 'file_handler' ignored. Property 'action' is "
+        "invalid.");
+    return base::nullopt;
+  }
+
+  file_handler.files = ParseTargetFiles("files", *file_handler_value);
+  if (file_handler.files.size() == 0) {
     AddErrorInfo("no file handlers were specified.");
     return base::nullopt;
   }
diff --git a/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc b/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
index 1d5d0a7..373d8de 100644
--- a/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
+++ b/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc
@@ -1038,32 +1038,82 @@
 }
 
 TEST_F(ManifestParserTest, FileHandlerParseRules) {
-  // Contains file_handler field but no keys.
+  // Does not contain file_handler field.
   {
-    Manifest manifest = ParseManifest("{ \"file_handler\": [] }");
+    Manifest manifest = ParseManifest("{ }");
+    EXPECT_FALSE(manifest.file_handler.has_value());
+    EXPECT_EQ(0u, GetErrorCount());
+  }
+
+  // Contains empty file_handler field.
+  {
+    Manifest manifest = ParseManifest("{ \"file_handler\": { } }");
+    EXPECT_FALSE(manifest.file_handler.has_value());
+    EXPECT_EQ(1u, GetErrorCount());
+    EXPECT_EQ("property 'file_handler' ignored. Property 'action' is invalid.",
+              errors()[0]);
+  }
+
+  // Contains file_handler field but no file handlers.
+  {
+    Manifest manifest =
+        ParseManifest("{ \"file_handler\": { \"action\": \"/files\" } }");
     EXPECT_FALSE(manifest.file_handler.has_value());
     EXPECT_EQ(1u, GetErrorCount());
     EXPECT_EQ("no file handlers were specified.", errors()[0]);
   }
 
+  // Contains file_handler field but files list is empty.
+  {
+    Manifest manifest = ParseManifest(
+        "{ \"file_handler\": { \"action\": \"/files\", \"files\": [] } }");
+    EXPECT_FALSE(manifest.file_handler.has_value());
+    EXPECT_EQ(1u, GetErrorCount());
+    EXPECT_EQ("no file handlers were specified.", errors()[0]);
+  }
+
+  // Invalid action causes parsing to fail.
+  {
+    Manifest manifest = ParseManifest(
+        "{"
+        "  \"file_handler\": {"
+        "    \"files\": ["
+        "      {"
+        "        \"name\": \"name\", "
+        "        \"accept\": \"image/png\""
+        "      }"
+        "    ]"
+        "  }"
+        "}");
+    manifest.scope = GURL("http://frobnicate.notatld");
+    EXPECT_FALSE(manifest.file_handler.has_value());
+    EXPECT_EQ(1u, GetErrorCount());
+    EXPECT_EQ("property 'file_handler' ignored. Property 'action' is invalid.",
+              errors()[0]);
+  }
+
   // Single accept value can be parsed from string.
   {
     Manifest manifest = ParseManifest(
         "{"
-        "  \"file_handler\": ["
-        "    {"
-        "      \"name\": \"name\","
-        "      \"accept\": \"image/png\""
-        "    }"
-        "  ]"
+        "  \"file_handler\": {"
+        "    \"files\": ["
+        "      {"
+        "        \"name\": \"name\", "
+        "        \"accept\": \"image/png\""
+        "      }"
+        "    ], "
+        "    \"action\": \"/files\""
+        "  }"
         "}");
     EXPECT_TRUE(manifest.file_handler.has_value());
 
     auto file_handler = manifest.file_handler.value();
-    EXPECT_EQ(file_handler.size(), 1u);
-    EXPECT_EQ(file_handler[0].name, base::ASCIIToUTF16("name"));
-    EXPECT_EQ(file_handler[0].accept.size(), 1u);
-    EXPECT_EQ(file_handler[0].accept[0], base::ASCIIToUTF16("image/png"));
+    EXPECT_EQ(file_handler.action, GURL("http://foo.com/files"));
+    EXPECT_EQ(file_handler.files.size(), 1u);
+    EXPECT_EQ(file_handler.files[0].name, base::ASCIIToUTF16("name"));
+    EXPECT_EQ(file_handler.files[0].accept.size(), 1u);
+    EXPECT_EQ(file_handler.files[0].accept[0], base::ASCIIToUTF16("image/png"));
     EXPECT_EQ(0u, GetErrorCount());
   }
 
@@ -1071,20 +1121,26 @@
   {
     Manifest manifest = ParseManifest(
         "{"
-        "  \"file_handler\": ["
-        "    {"
-        "      \"name\": \"name\","
-        "      \"accept\": [\"image/png\"]"
-        "    }"
-        "  ]"
+        "  \"file_handler\": {"
+        "    \"action\": \"/files\", "
+        "    \"files\": ["
+        "      {"
+        "        \"name\": \"name\", "
+        "        \"accept\": ["
+        "          \"image/png\""
+        "        ]"
+        "      }"
+        "    ]"
+        "  }"
         "}");
     EXPECT_TRUE(manifest.file_handler.has_value());
 
     auto file_handler = manifest.file_handler.value();
-    EXPECT_EQ(file_handler.size(), 1u);
-    EXPECT_EQ(file_handler[0].name, base::ASCIIToUTF16("name"));
-    EXPECT_EQ(file_handler[0].accept.size(), 1u);
-    EXPECT_EQ(file_handler[0].accept[0], base::ASCIIToUTF16("image/png"));
+    EXPECT_EQ(file_handler.action, GURL("http://foo.com/files"));
+    EXPECT_EQ(file_handler.files.size(), 1u);
+    EXPECT_EQ(file_handler.files[0].name, base::ASCIIToUTF16("name"));
+    EXPECT_EQ(file_handler.files[0].accept.size(), 1u);
+    EXPECT_EQ(file_handler.files[0].accept[0], base::ASCIIToUTF16("image/png"));
     EXPECT_EQ(0u, GetErrorCount());
   }
 
@@ -1092,21 +1148,28 @@
   {
     Manifest manifest = ParseManifest(
         "{"
-        "  \"file_handler\": ["
-        "    {"
-        "      \"name\": \"name\","
-        "      \"accept\": [\"image/png\", \".png\"]"
-        "    }"
-        "  ]"
+        "  \"file_handler\": {"
+        "    \"action\": \"/files\", "
+        "    \"files\": ["
+        "      {"
+        "        \"name\": \"name\", "
+        "        \"accept\": ["
+        "          \"image/png\", "
+        "          \".png\""
+        "        ]"
+        "      }"
+        "    ]"
+        "  }"
         "}");
     EXPECT_TRUE(manifest.file_handler.has_value());
 
     auto file_handler = manifest.file_handler.value();
-    EXPECT_EQ(file_handler.size(), 1u);
-    EXPECT_EQ(file_handler[0].name, base::ASCIIToUTF16("name"));
-    EXPECT_EQ(file_handler[0].accept.size(), 2u);
-    EXPECT_EQ(file_handler[0].accept[0], base::ASCIIToUTF16("image/png"));
-    EXPECT_EQ(file_handler[0].accept[1], base::ASCIIToUTF16(".png"));
+    EXPECT_EQ(file_handler.action, GURL("http://foo.com/files"));
+    EXPECT_EQ(file_handler.files.size(), 1u);
+    EXPECT_EQ(file_handler.files[0].name, base::ASCIIToUTF16("name"));
+    EXPECT_EQ(file_handler.files[0].accept.size(), 2u);
+    EXPECT_EQ(file_handler.files[0].accept[0], base::ASCIIToUTF16("image/png"));
+    EXPECT_EQ(file_handler.files[0].accept[1], base::ASCIIToUTF16(".png"));
     EXPECT_EQ(0u, GetErrorCount());
   }
 
@@ -1114,32 +1177,39 @@
   {
     Manifest manifest = ParseManifest(
         "{"
-        "  \"file_handler\": ["
-        "    {"
-        "      \"name\": \"name\","
-        "      \"accept\": [\"image/png\", \".png\"]"
-        "    },"
-        "    {"
-        "      \"name\": \"svgish\","
-        "      \"accept\": ["
-        "        \".svg\","
-        "        \"xml/svg\""
-        "      ]"
-        "    }"
-        "  ]"
+        "  \"file_handler\": {"
+        "    \"action\": \"/files\", "
+        "    \"files\": ["
+        "      {"
+        "        \"name\": \"name\", "
+        "        \"accept\": ["
+        "          \"image/png\", "
+        "          \".png\""
+        "        ]"
+        "      }, "
+        "      {"
+        "        \"name\": \"svgish\", "
+        "        \"accept\": ["
+        "          \".svg\","
+        "          \"xml/svg\""
+        "        ]"
+        "      }"
+        "    ]"
+        "  }"
         "}");
     EXPECT_TRUE(manifest.file_handler.has_value());
 
     auto file_handler = manifest.file_handler.value();
-    EXPECT_EQ(file_handler.size(), 2u);
-    EXPECT_EQ(file_handler[0].name, base::ASCIIToUTF16("name"));
-    EXPECT_EQ(file_handler[0].accept.size(), 2u);
-    EXPECT_EQ(file_handler[0].accept[0], base::ASCIIToUTF16("image/png"));
-    EXPECT_EQ(file_handler[0].accept[1], base::ASCIIToUTF16(".png"));
-    EXPECT_EQ(file_handler[1].name, base::ASCIIToUTF16("svgish"));
-    EXPECT_EQ(file_handler[1].accept.size(), 2u);
-    EXPECT_EQ(file_handler[1].accept[0], base::ASCIIToUTF16(".svg"));
-    EXPECT_EQ(file_handler[1].accept[1], base::ASCIIToUTF16("xml/svg"));
+    EXPECT_EQ(file_handler.action, GURL("http://foo.com/files"));
+    EXPECT_EQ(file_handler.files.size(), 2u);
+    EXPECT_EQ(file_handler.files[0].name, base::ASCIIToUTF16("name"));
+    EXPECT_EQ(file_handler.files[0].accept.size(), 2u);
+    EXPECT_EQ(file_handler.files[0].accept[0], base::ASCIIToUTF16("image/png"));
+    EXPECT_EQ(file_handler.files[0].accept[1], base::ASCIIToUTF16(".png"));
+    EXPECT_EQ(file_handler.files[1].name, base::ASCIIToUTF16("svgish"));
+    EXPECT_EQ(file_handler.files[1].accept.size(), 2u);
+    EXPECT_EQ(file_handler.files[1].accept[0], base::ASCIIToUTF16(".svg"));
+    EXPECT_EQ(file_handler.files[1].accept[1], base::ASCIIToUTF16("xml/svg"));
     EXPECT_EQ(0u, GetErrorCount());
   }
 }
diff --git a/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc b/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
index 343a184..6175df6 100644
--- a/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
+++ b/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc
@@ -8,6 +8,7 @@
 
 #include "third_party/blink/public/common/manifest/manifest.h"
 #include "third_party/blink/public/common/manifest/manifest_mojom_traits.h"
+#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -48,15 +49,16 @@
         &input->share_target.value());
   }
 
-  if (input->file_handler.has_value() && input->file_handler->size() > 0) {
-    WTF::Vector<blink::mojom::blink::ManifestFileFilterPtr> mojo_file_handler;
-    mojo_file_handler.ReserveInitialCapacity(
-        static_cast<WTF::wtf_size_t>(input->file_handler->size()));
-    for (auto& file_handler : input->file_handler.value()) {
-      mojo_file_handler.push_back(
+  if (input->file_handler.has_value()) {
+    WTF::Vector<blink::mojom::blink::ManifestFileFilterPtr> file_filters;
+    file_filters.ReserveInitialCapacity(
+        static_cast<WTF::wtf_size_t>(input->file_handler->files.size()));
+    for (auto& file_handler : input->file_handler->files) {
+      file_filters.push_back(
           blink::mojom::blink::ManifestFileFilter::From(&file_handler));
     }
-    output->file_handler = std::move(mojo_file_handler);
+    output->file_handler->action = blink::KURL(input->file_handler->action);
+    output->file_handler->files = std::move(file_filters);
   }
 
   if (input->related_applications.size() > 0) {
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
index abd4608..d242848 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -431,9 +431,6 @@
 
   DISALLOW_COPY_AND_ASSIGN(MediaControlsImpl);
 };
-
-DEFINE_ELEMENT_TYPE_CASTS(MediaControlsImpl, IsMediaControls());
-
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index 59dfb45..44c1521 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -368,22 +368,6 @@
   if (android_pay->hasEnvironment() && android_pay->environment() == "TEST")
     output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST;
 
-  if (android_pay->hasMerchantName() &&
-      android_pay->merchantName().length() > PaymentRequest::kMaxStringLength) {
-    exception_state.ThrowTypeError(
-        "Android Pay merchant name cannot be longer than 1024 characters");
-    return;
-  }
-  output->merchant_name = android_pay->merchantName();
-
-  if (android_pay->hasMerchantId() &&
-      android_pay->merchantId().length() > PaymentRequest::kMaxStringLength) {
-    exception_state.ThrowTypeError(
-        "Android Pay merchant id cannot be longer than 1024 characters");
-    return;
-  }
-  output->merchant_id = android_pay->merchantId();
-
   // 0 means the merchant did not specify or it was an invalid value
   output->min_google_play_services_version = 0;
   if (android_pay->hasMinGooglePlayServicesVersion()) {
@@ -400,86 +384,6 @@
   output->api_version = 0;
   if (android_pay->hasApiVersion())
     output->api_version = android_pay->apiVersion();
-
-  if (android_pay->hasAllowedCardNetworks()) {
-    using ::payments::mojom::blink::AndroidPayCardNetwork;
-
-    const struct {
-      const AndroidPayCardNetwork code;
-      const char* const name;
-    } kAndroidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"},
-                              {AndroidPayCardNetwork::DISCOVER, "DISCOVER"},
-                              {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"},
-                              {AndroidPayCardNetwork::VISA, "VISA"}};
-
-    for (const String& allowed_card_network :
-         android_pay->allowedCardNetworks()) {
-      for (size_t i = 0; i < base::size(kAndroidPayNetwork); ++i) {
-        if (allowed_card_network == kAndroidPayNetwork[i].name) {
-          output->allowed_card_networks.push_back(kAndroidPayNetwork[i].code);
-          break;
-        }
-      }
-    }
-  }
-
-  if (android_pay->hasPaymentMethodTokenizationParameters()) {
-    const blink::AndroidPayTokenization* tokenization =
-        android_pay->paymentMethodTokenizationParameters();
-    output->tokenization_type =
-        payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED;
-    if (tokenization->hasTokenizationType()) {
-      using ::payments::mojom::blink::AndroidPayTokenization;
-
-      const struct {
-        const AndroidPayTokenization code;
-        const char* const name;
-      } kAndroidPayTokenization[] = {
-          {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"},
-          {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}};
-
-      for (size_t i = 0; i < base::size(kAndroidPayTokenization); ++i) {
-        if (tokenization->tokenizationType() ==
-            kAndroidPayTokenization[i].name) {
-          output->tokenization_type = kAndroidPayTokenization[i].code;
-          break;
-        }
-      }
-    }
-
-    if (tokenization->hasParameters()) {
-      const Vector<String>& keys =
-          tokenization->parameters().GetPropertyNames(exception_state);
-      if (exception_state.HadException())
-        return;
-      if (keys.size() > PaymentRequest::kMaxListSize) {
-        exception_state.ThrowTypeError(
-            "At most 1024 tokenization parameters allowed for Android Pay");
-        return;
-      }
-      String value;
-      for (const String& key : keys) {
-        if (!DictionaryHelper::Get(tokenization->parameters(), key, value))
-          continue;
-        if (key.length() > PaymentRequest::kMaxStringLength) {
-          exception_state.ThrowTypeError(
-              "Android Pay tokenization parameter key cannot be longer than "
-              "1024 characters");
-          return;
-        }
-        if (value.length() > PaymentRequest::kMaxStringLength) {
-          exception_state.ThrowTypeError(
-              "Android Pay tokenization parameter value cannot be longer than "
-              "1024 characters");
-          return;
-        }
-        output->parameters.push_back(
-            payments::mojom::blink::AndroidPayTokenizationParameter::New());
-        output->parameters.back()->key = key;
-        output->parameters.back()->value = value;
-      }
-    }
-  }
 }
 
 // Parses basic-card data to avoid parsing JSON in the browser.
diff --git a/third_party/blink/renderer/modules/permissions/permission_descriptor.idl b/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
index 5e94009..b7f23ad4 100644
--- a/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
+++ b/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
@@ -28,6 +28,7 @@
     "clipboard-write",
     "payment-handler",
     "idle-detection",
+    "periodic-background-sync",
 };
 
 // The PermissionDescriptor dictionary is a base to describe permissions. Some
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc
index 461d120..c8201dc 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -139,11 +139,18 @@
   }
   if (name == "payment-handler")
     return CreatePermissionDescriptor(PermissionName::PAYMENT_HANDLER);
-  if (name == "background-fetch") {
+  if (name == "background-fetch")
     return CreatePermissionDescriptor(PermissionName::BACKGROUND_FETCH);
-  }
   if (name == "idle-detection")
     return CreatePermissionDescriptor(PermissionName::IDLE_DETECTION);
+  if (name == "periodic-background-sync") {
+    if (!RuntimeEnabledFeatures::PeriodicBackgroundSyncEnabled()) {
+      exception_state.ThrowTypeError(
+          "Periodic Background Sync is not enabled.");
+      return nullptr;
+    }
+    return CreatePermissionDescriptor(PermissionName::PERIODIC_BACKGROUND_SYNC);
+  }
 
   return nullptr;
 }
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index 8d64f78..dc39104 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -345,6 +345,10 @@
   RuntimeEnabledFeatures::SetPermissionsEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnablePeriodicBackgroundSync(bool enable) {
+  RuntimeEnabledFeatures::SetPeriodicBackgroundSyncEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnablePictureInPicture(bool enable) {
   RuntimeEnabledFeatures::SetPictureInPictureEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 4ea1cf7..c76a217 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -292,10 +292,6 @@
       status: "experimental",
     },
     {
-      name: "CSS3TextBreakSpaces",
-      status: "experimental",
-    },
-    {
       name: "CSSAdditiveAnimations",
       depends_on: ["StackedCSSPropertyAnimations"],
       status: "experimental",
@@ -1098,6 +1094,10 @@
       status: "experimental",
     },
     {
+      name: "PeriodicBackgroundSync",
+      settable_from_internals: true,
+    },
+    {
       name: "PerMethodCanMakePaymentQuota",
       origin_trial_feature_name: "PerMethodCanMakePaymentQuota",
       status: "experimental",
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 8519771e..c5e380e 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3037,6 +3037,13 @@
 crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-text/hyphens/hyphens-shaping-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/hyphens/hyphens-shaping-001.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-001.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/line-break/line-break-shaping-001.html [ Failure ]
+crbug.com/626703 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-span-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/hyphens/hyphens-span-001.html [ Failure ]
 crbug.com/626703 [ Mac10.11 ] external/wpt/webrtc/no-media-call.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-writing-modes/writing-mode-vlr-table-001-manual.html [ Skip ]
 crbug.com/626703 external/wpt/css/css-writing-modes/writing-mode-vlr-009-manual.html [ Skip ]
@@ -4364,12 +4371,6 @@
 crbug.com/957458 virtual/threaded/external/wpt/css/css-paint-api/style-before-pseudo.https.html [ Crash ]
 crbug.com/957458 virtual/threaded/external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html [ Crash ]
 
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.html [ Timeout Pass ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.serviceworker.html [ Timeout Pass ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.worker.html [ Timeout Pass ]
-crbug.com/943487 external/wpt/wasm/webapi/origin.sub.any.serviceworker.html [ Timeout Pass ]
-crbug.com/943487 external/wpt/wasm/webapi/rejected-arg.any.sharedworker.html [ Timeout Pass ]
-
 # Shared memory growth temporarily disabled.
 crbug.com/951795 external/wpt/wasm/jsapi/memory/grow.any.html [ Pass Failure ]
 crbug.com/951795 external/wpt/wasm/jsapi/memory/grow.any.worker.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-chooser-test.html b/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-chooser-test.html
deleted file mode 100644
index a8ab899d..0000000
--- a/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-chooser-test.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-<script src="../../../resources/testdriver.js"></script>
-<script src="../../../resources/testdriver-vendor.js"></script>
-<script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script>
-<script>
-'use strict';
-// TODO(https://crbug.com/719826): This is a temporary test to try the
-// FakeBluetoothChooser API as it is implemented. This test should be delete
-// after the feature is completed. The implementation details can be found in
-// the design document.
-// https://docs.google.com/document/d/1XFl_4ZAgO8ddM6U53A9AfUuZeWgJnlYD5wtbXqEpzeg
-const test_desc = 'Ensure that the FakeBluetoothChooser API works correctly.';
-
-bluetooth_test(
-    () => navigator.bluetooth.test.simulateCentral({state: 'powered-on'})
-              .then(() => navigator.bluetooth.test.getManualChooser())
-              .then(chooser => assert_true(typeof chooser !== 'undefined')),
-    test_desc);
-</script>
diff --git a/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-simulate-advertisement-received-test.html b/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-simulate-advertisement-received-test.html
deleted file mode 100644
index 1420d001..0000000
--- a/third_party/blink/web_tests/bluetooth/requestDevice/chooser/fake-bluetooth-simulate-advertisement-received-test.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!DOCTYPE html>
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-<script src="../../../resources/testdriver.js"></script>
-<script src="../../../resources/testdriver-vendor.js"></script>
-<script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script>
-<script>
-'use strict';
-// TODO(https://crbug.com/719826): This is a temporary test to try the
-// FakeBluetoothChooser API as it is implemented. This test should be deleted
-// after the feature is completed.
-const test_desc = 'Ensure that the SimulateAdvertisementReceived API works ' +
-    'correctly.';
-const company_id = '224';
-const data = new TextEncoder().encode('foo');
-const manufacturerDataMap = {
-  [company_id]: data
-};
-const serviceDataMap = {
-  [health_thermometer.uuid]: data
-};
-const scanRecord = {
-  name: 'Health Thermometer',
-  uuids: ['generic_access', health_thermometer.uuid],
-  txPower: 20,
-  appearance: 100,
-  manufacturerData: manufacturerDataMap,
-  serviceData: serviceDataMap,
-};
-let fake_central;
-let scanResult = {
-  deviceAddress: '09:09:09:09:09:09',
-  rssi: 100,
-  scanRecord: {},
-};
-
-bluetooth_test(
-    () =>
-        navigator.bluetooth.test.simulateCentral({state: 'powered-on'})
-            .then(_ => fake_central = _)
-            // Test that scanRecord fields are indeed optional.
-            .then(() => fake_central.simulateAdvertisementReceived(scanResult))
-            .then(
-                fake_peripheral => assert_true(
-                    fake_peripheral.address === '09:09:09:09:09:09'))
-            // Test the scanRecord fields.
-            .then(() => {
-              scanResult.scanRecord = scanRecord;
-              return fake_central.simulateAdvertisementReceived(scanResult);
-            }),
-    test_desc);
-</script>
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-transform-expected.png b/third_party/blink/web_tests/css3/filters/backdrop-filter-transform-expected.png
new file mode 100644
index 0000000..d8412404
--- /dev/null
+++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-transform-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/css3/filters/backdrop-filter-transform.html b/third_party/blink/web_tests/css3/filters/backdrop-filter-transform.html
new file mode 100644
index 0000000..ce43e8f
--- /dev/null
+++ b/third_party/blink/web_tests/css3/filters/backdrop-filter-transform.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>backdrop-filter: backdrop-filter plus transform should be applied correctly</title>
+
+<!--Expected: A green box with an overlapping rotated box that inverts content behind it. -->
+
+<div class="colorbox"></div>
+<div class="filterbox"></div>
+
+<!-- See [1] for an implementation of this test in WPT format. It requires the
+  WPT Fuzzy Matching [2] feature to be implemented, due to AA on the border
+  radii.
+
+  [1] https://chromium-review.googlesource.com/c/chromium/src/+/1521959/15
+  [2] https://github.com/web-platform-tests/wpt/blob/1f570a686843ca10f151a79956ee16110f4a4d42/docs/_writing-tests/reftests.md#fuzzy-matching
+-->
+
+<style>
+div {
+    position: absolute;
+    width: 100px;
+    height: 100px;
+    left: 100px;
+    top: 100px;
+}
+.colorbox {
+    background: green;
+}
+.filterbox {
+    top: 140px;
+    backdrop-filter: invert(1);
+    transform: rotate(30deg);
+    border-radius: 10px;
+}
+</style>
+
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index 29f1c41..d4abaf5 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -62639,6 +62639,70 @@
      {}
     ]
    ],
+   "css/css-text/hyphens/hyphens-shaping-001.html": [
+    [
+     "css/css-text/hyphens/hyphens-shaping-001.html",
+     [
+      [
+       "/css/css-text/hyphens/reference/hyphens-shaping-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/hyphens-shaping-002.html": [
+    [
+     "css/css-text/hyphens/hyphens-shaping-002.html",
+     [
+      [
+       "/css/css-text/hyphens/reference/hyphens-shaping-002-ref.html",
+       "!="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/hyphens-span-001.html": [
+    [
+     "css/css-text/hyphens/hyphens-span-001.html",
+     [
+      [
+       "/css/css-text/hyphens/reference/hyphens-span-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/hyphens-span-002.html": [
+    [
+     "css/css-text/hyphens/hyphens-span-002.html",
+     [
+      [
+       "/css/css-text/hyphens/reference/hyphens-span-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/shy-styling-001.html": [
+    [
+     "css/css-text/hyphens/shy-styling-001.html",
+     [
+      [
+       "/css/css-text/hyphens/reference/shy-styling-001-ref.html",
+       "=="
+      ],
+      [
+       "/css/css-text/hyphens/reference/shy-styling-001-alt-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/i18n/css3-text-line-break-opclns-001.html": [
     [
      "css/css-text/i18n/css3-text-line-break-opclns-001.html",
@@ -64871,6 +64935,18 @@
      {}
     ]
    ],
+   "css/css-text/line-break/line-break-shaping-001.html": [
+    [
+     "css/css-text/line-break/line-break-shaping-001.html",
+     [
+      [
+       "/css/css-text/line-break/reference/line-break-shaping-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/line-break/line-break-strict-011.xht": [
     [
      "css/css-text/line-break/line-break-strict-011.xht",
@@ -65711,6 +65787,30 @@
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/overflow-wrap-shaping-001.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-shaping-001.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/overflow-wrap/overflow-wrap-shaping-002.html": [
+    [
+     "css/css-text/overflow-wrap/overflow-wrap-shaping-002.html",
+     [
+      [
+       "/css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/overflow-wrap/word-wrap-001.html": [
     [
      "css/css-text/overflow-wrap/word-wrap-001.html",
@@ -69288,7 +69388,7 @@
      "css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html",
      [
       [
-       "/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html",
+       "/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html",
        "=="
       ]
      ],
@@ -147549,6 +147649,36 @@
      {}
     ]
    ],
+   "css/css-text/hyphens/reference/hyphens-shaping-001-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/reference/hyphens-shaping-002-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/reference/hyphens-span-001-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/reference/hyphens-span-002-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/reference/shy-styling-001-alt-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/hyphens/reference/shy-styling-001-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/i18n/META.yml": [
     [
      {}
@@ -148624,6 +148754,11 @@
      {}
     ]
    ],
+   "css/css-text/line-break/reference/line-break-shaping-001-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/line-break/reference/line-break-strict-011-ref.xht": [
     [
      {}
@@ -148834,6 +148969,11 @@
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/parsing/hanging-punctuation-valid-expected.txt": [
     [
      {}
@@ -150034,6 +150174,11 @@
      {}
     ]
    ],
+   "css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/white-space/reference/white-space-wrap-after-nowrap-001-ref.html": [
     [
      {}
@@ -183919,6 +184064,26 @@
      {}
     ]
    ],
+   "portals/resources/portal-host-post-message-after-activate.html": [
+    [
+     {}
+    ]
+   ],
+   "portals/resources/portal-host-post-message-navigate-1.html": [
+    [
+     {}
+    ]
+   ],
+   "portals/resources/portal-host-post-message-navigate-2.html": [
+    [
+     {}
+    ]
+   ],
+   "portals/resources/portal-host-post-message.sub.html": [
+    [
+     {}
+    ]
+   ],
    "portals/resources/portal-host.html": [
     [
      {}
@@ -187694,26 +187859,6 @@
      {}
     ]
    ],
-   "resources/chromium/fake_bluetooth.mojom.js": [
-    [
-     {}
-    ]
-   ],
-   "resources/chromium/fake_bluetooth.mojom.js.headers": [
-    [
-     {}
-    ]
-   ],
-   "resources/chromium/fake_bluetooth_chooser.mojom.js": [
-    [
-     {}
-    ]
-   ],
-   "resources/chromium/fake_bluetooth_chooser.mojom.js.headers": [
-    [
-     {}
-    ]
-   ],
    "resources/chromium/generic_sensor_mocks.js": [
     [
      {}
@@ -187804,16 +187949,6 @@
      {}
     ]
    ],
-   "resources/chromium/uuid.mojom.js": [
-    [
-     {}
-    ]
-   ],
-   "resources/chromium/uuid.mojom.js.headers": [
-    [
-     {}
-    ]
-   ],
    "resources/chromium/web-bluetooth-test.js": [
     [
      {}
@@ -240817,6 +240952,12 @@
      {}
     ]
    ],
+   "css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html": [
+    [
+     "css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html",
+     {}
+    ]
+   ],
    "css/cssom/getComputedStyle-insets-sticky.html": [
     [
      "css/cssom/getComputedStyle-insets-sticky.html",
@@ -240829,6 +240970,12 @@
      {}
     ]
    ],
+   "css/cssom/getComputedStyle-sticky-pos-percent.html": [
+    [
+     "css/cssom/getComputedStyle-sticky-pos-percent.html",
+     {}
+    ]
+   ],
    "css/cssom/historical.html": [
     [
      "css/cssom/historical.html",
@@ -245384,6 +245531,12 @@
      {}
     ]
    ],
+   "element-timing/disconnect-image.html": [
+    [
+     "element-timing/disconnect-image.html",
+     {}
+    ]
+   ],
    "element-timing/image-TAO-wildcard.sub.html": [
     [
      "element-timing/image-TAO-wildcard.sub.html",
@@ -290602,6 +290755,14 @@
      {}
     ]
    ],
+   "portals/portals-host-post-message.sub.html": [
+    [
+     "portals/portals-host-post-message.sub.html",
+     {
+      "timeout": "long"
+     }
+    ]
+   ],
    "portals/portals-nested.html": [
     [
      "portals/portals-nested.html",
@@ -344086,7 +344247,7 @@
    "testharness"
   ],
   "bluetooth/resources/bluetooth-helpers.js": [
-   "83643232ae5f5c86b7d180b52c681bef57e27ece",
+   "2d863b16037b3c1bcd5a222409cd7398d1fe078b",
    "support"
   ],
   "bluetooth/resources/bluetooth-scanning-helpers.js": [
@@ -396193,10 +396354,54 @@
    "39814d3e18c622c022d5e3314580ebb187d217da",
    "reftest"
   ],
+  "css/css-text/hyphens/hyphens-shaping-001.html": [
+   "0cd2243bdac0e89add0223c03ba2328cb239c980",
+   "reftest"
+  ],
+  "css/css-text/hyphens/hyphens-shaping-002.html": [
+   "57d23e585e9d819b5e0943f5ef3054ba1230c2a6",
+   "reftest"
+  ],
+  "css/css-text/hyphens/hyphens-span-001.html": [
+   "f7269e1cb946578a414af41d9f09b53867ad4de4",
+   "reftest"
+  ],
+  "css/css-text/hyphens/hyphens-span-002.html": [
+   "07264faa7bba127f72dc006757554abb15bef6e1",
+   "reftest"
+  ],
   "css/css-text/hyphens/reference/hyphens-auto-001-ref.html": [
    "c1355d0abba28491a126533c24039cffc6ee4eb0",
    "support"
   ],
+  "css/css-text/hyphens/reference/hyphens-shaping-001-ref.html": [
+   "9eb1d7fd686e0f9bc1c82baf2235f8f1ef8cbb81",
+   "support"
+  ],
+  "css/css-text/hyphens/reference/hyphens-shaping-002-ref.html": [
+   "d8e31d71e4baa7d4ae4dc6436f4972083c30bee9",
+   "support"
+  ],
+  "css/css-text/hyphens/reference/hyphens-span-001-ref.html": [
+   "cbe37261375a6ab721decbcde802418e5d497ab5",
+   "support"
+  ],
+  "css/css-text/hyphens/reference/hyphens-span-002-ref.html": [
+   "7b3f8206417ffeff05a522c07f1efad9176cde9b",
+   "support"
+  ],
+  "css/css-text/hyphens/reference/shy-styling-001-alt-ref.html": [
+   "c86cb5002867c899f54a59d25c0a0572e7658cd7",
+   "support"
+  ],
+  "css/css-text/hyphens/reference/shy-styling-001-ref.html": [
+   "ad9df16e35d88a43baa5d6b3ff3f2ee18a71b5bb",
+   "support"
+  ],
+  "css/css-text/hyphens/shy-styling-001.html": [
+   "98348d92a6987607cd2d591fd385f9e303a4471a",
+   "reftest"
+  ],
   "css/css-text/i18n/META.yml": [
    "9fa8c3b6c9bdbfa2b9731c89b23ffc6f47ceba2b",
    "support"
@@ -398309,6 +398514,10 @@
    "a1042e858aaa64cf04b1538567c1071df6fdf551",
    "reftest"
   ],
+  "css/css-text/line-break/line-break-shaping-001.html": [
+   "4ce1da2f30afe7254a03352c56c70176b55521c4",
+   "reftest"
+  ],
   "css/css-text/line-break/line-break-strict-011.xht": [
    "d9cecc788ab1d5132a5a69453b715d4145a325ff",
    "reftest"
@@ -398433,6 +398642,10 @@
    "9b23b57dfe62551c90df892b1f297802eaf3517c",
    "support"
   ],
+  "css/css-text/line-break/reference/line-break-shaping-001-ref.html": [
+   "5543ab07294c5f0da73a2473cb093c0907bed3a9",
+   "support"
+  ],
   "css/css-text/line-break/reference/line-break-strict-011-ref.xht": [
    "ec17a31ec55e5c95aed8a7423ba0bcbff2edfa7d",
    "support"
@@ -398805,6 +399018,14 @@
    "8047aba133af1e4ece4b66fffcec48fa853da386",
    "reftest"
   ],
+  "css/css-text/overflow-wrap/overflow-wrap-shaping-001.html": [
+   "8846038d0fcdb3385b0aa94165f423d0a2bea007",
+   "reftest"
+  ],
+  "css/css-text/overflow-wrap/overflow-wrap-shaping-002.html": [
+   "adb25c78b7a64e6f7fd00410b25cfe6c519f5fe8",
+   "reftest"
+  ],
   "css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html": [
    "0e0300a72dc920a5ffb54cda6fbe84a2f517d010",
    "support"
@@ -398849,6 +399070,10 @@
    "f0b41134fa0b84e6fce29ed5596598a358b2c2a9",
    "support"
   ],
+  "css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html": [
+   "5543ab07294c5f0da73a2473cb093c0907bed3a9",
+   "support"
+  ],
   "css/css-text/overflow-wrap/word-wrap-001.html": [
    "af326a6cdf2d02aa51e6eccfd11b90fcc4c16456",
    "reftest"
@@ -401158,7 +401383,7 @@
    "support"
   ],
   "css/css-text/white-space/reference/white-space-intrinsic-size-004-ref.html": [
-   "34757067b15b6a30e8273a93df7f68a7cfb4a686",
+   "490d61be712d2878ab76bf40ca025e5334e50d7c",
    "support"
   ],
   "css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-001-ref.html": [
@@ -401166,7 +401391,11 @@
    "support"
   ],
   "css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html": [
-   "53cb2a083b0825a749d178d5093c1a105958143d",
+   "5f94d076e840080f8cc855e013039ef16f1d993c",
+   "support"
+  ],
+  "css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html": [
+   "736a2d5607b92e47fd2e927892a2b6d4cc6f2a9e",
    "support"
   ],
   "css/css-text/white-space/reference/white-space-wrap-after-nowrap-001-ref.html": [
@@ -401398,7 +401627,7 @@
    "reftest"
   ],
   "css/css-text/white-space/white-space-intrinsic-size-004.html": [
-   "510a5c5d14188e9dc042ee061f6cb91bb169b73c",
+   "42b94a72a5ce6e70ad6b888603efcd8466bb8a95",
    "reftest"
   ],
   "css/css-text/white-space/white-space-pre-wrap-trailing-spaces-001.html": [
@@ -401406,11 +401635,11 @@
    "reftest"
   ],
   "css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html": [
-   "d8e7c8278a917c00bc99a60511137b52a935f215",
+   "76ca5ef77dbb5ab32c9da92c7a2c4f181a1f98ff",
    "reftest"
   ],
   "css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html": [
-   "6b21df62c5cbdfa2cce9e52d91c7a792d94354e8",
+   "4b6df8e93e009933090e29c98149971a2ccc52eb",
    "reftest"
   ],
   "css/css-text/white-space/white-space-wrap-after-nowrap-001.html": [
@@ -420597,8 +420826,12 @@
    "aa7dbee95667a5e3b829b7d3774311da49c01deb",
    "testharness"
   ],
+  "css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html": [
+   "7f5ec3064837f4af37cf33050917768eb8ee0584",
+   "testharness"
+  ],
   "css/cssom/getComputedStyle-insets-sticky.html": [
-   "6149acc6d7d0391d7a4d7ece12b9ec9c4b39041d",
+   "6b23fabcb1407c00ab1d35bbae77f6501b17f73f",
    "testharness"
   ],
   "css/cssom/getComputedStyle-pseudo-expected.txt": [
@@ -420609,6 +420842,10 @@
    "340f9eed9b955467eb39c957222328baf2c41d4a",
    "testharness"
   ],
+  "css/cssom/getComputedStyle-sticky-pos-percent.html": [
+   "12ad5e89653564f91006c78baeac353c12865c00",
+   "testharness"
+  ],
   "css/cssom/historical.html": [
    "44f3f6c8f15a13b2c32dad2672ea9383330e8082",
    "testharness"
@@ -420842,7 +421079,7 @@
    "support"
   ],
   "css/cssom/support/getComputedStyle-insets.js": [
-   "beec32e76bc5fcef4640193e321805975c8554b9",
+   "723990cafbca5aef05a32294d5db28b899a226cc",
    "support"
   ],
   "css/cssom/support/import-charset.css": [
@@ -432390,43 +432627,47 @@
    "testharness"
   ],
   "element-timing/background-image-data-uri.html": [
-   "696f34ff14e8bad8ec68a8687cdbf0949ef6fdef",
+   "16d6dfcba037f77453c38ae1273fdb9182d6a531",
    "testharness"
   ],
   "element-timing/background-image-multiple-elements.html": [
-   "669f94d6b0189ba387cf90c1b49c7d4120319673",
+   "22b4158cbe7289afb6a1ce038ef840933c92a7f0",
    "testharness"
   ],
   "element-timing/background-image-stretched.html": [
-   "8f93b43524f7b3d051af90d9807a3f30ad299ae7",
+   "28c355398245252c536a247910f56ec6aba6ac58",
    "testharness"
   ],
   "element-timing/buffer-before-onload.html": [
-   "805777f29c297a22497d3e4f07b6ea462b0a0b7c",
+   "03c7048be1134b45c6c966404ce27f9ed5c8204e",
    "testharness"
   ],
   "element-timing/cross-origin-element.sub.html": [
-   "b1a5b7ccd7acd221daef9bbc259a4cf972075553",
+   "0af0ae96413eb8c22383b5e676f9a4f3a994aeb0",
    "testharness"
   ],
   "element-timing/cross-origin-iframe-element.sub.html": [
    "a369d25bd43c6565ab4367b0a381ab39ec8664b7",
    "testharness"
   ],
+  "element-timing/disconnect-image.html": [
+   "4ee0516fffecfe2f4c89ce4f789e7c6bb269ddd2",
+   "testharness"
+  ],
   "element-timing/image-TAO-wildcard.sub.html": [
-   "0e24af068a6d93920c268846442ab89b4a1b65ee",
+   "4ec8aa7d8dad99da4e183c6d9b0dd719199e28d9",
    "testharness"
   ],
   "element-timing/image-carousel.html": [
-   "9f0ef79e354dfe8e505e8308561a1b0a1a33167c",
+   "404eca3b208cd0c77e454a0f9ae12f500d3d0f57",
    "testharness"
   ],
   "element-timing/image-clipped-svg.html": [
-   "36cf1b15e0df0f99b8312ef56cde211f7c1358dd",
+   "3007bf726a6812d1fa607162999310da837f221e",
    "testharness"
   ],
   "element-timing/image-data-uri.html": [
-   "22ff91189b1370b703f89f55d83cde014b6d367d",
+   "2b5d04e45a3f4cdf2277cc302574c62b6476f0af",
    "testharness"
   ],
   "element-timing/image-not-added.html": [
@@ -432434,31 +432675,31 @@
    "testharness"
   ],
   "element-timing/image-not-fully-visible.html": [
-   "279fa03cc2b42029ed01a68f670829c13b282a5c",
+   "57162491a7927ddf3d4625750fbce6bf7537493a",
    "testharness"
   ],
   "element-timing/image-rect-iframe.html": [
-   "94c872e8e02fe16e22b105c04cd1c9cc4e1cf9d8",
+   "f0511308c7192b26949c6855fbf4a779ce48a871",
    "testharness"
   ],
   "element-timing/image-with-css-scale.html": [
-   "6d77429e485ede047122eb3c25221d5e394c2d98",
+   "bdffdb26b29e50ff73b8ca70a0e959bb031018ec",
    "testharness"
   ],
   "element-timing/image-with-rotation.html": [
-   "70b635e012a6825bf5832594bd9e385173ab1878",
+   "4433ecbc5f114604fec821622673ecf15bf6030d",
    "testharness"
   ],
   "element-timing/images-repeated-resource.html": [
-   "dbcad248e3aea0d148416275adeec93e20d8c267",
+   "fbb2d6a12cd39e9bcd96a610e87076d9d3d6f2d4",
    "testharness"
   ],
   "element-timing/multiple-background-images.html": [
-   "ca349fec45f6ae4bde53dbe03de673d19d295794",
+   "f3fbe767303f91328a892686a6d0d5761b1b3575",
    "testharness"
   ],
   "element-timing/observe-background-image.html": [
-   "0669b4c4d83b6c2e81de94beb7db15c6ca775d1b",
+   "680c5e475aad49b1963a7f45d908b47b04a3b77f",
    "testharness"
   ],
   "element-timing/observe-child-element.html": [
@@ -432466,35 +432707,35 @@
    "testharness"
   ],
   "element-timing/observe-elementtiming.html": [
-   "39fea05431107efc251f820de1cc476aa8a3f37e",
+   "73f93519cdaecdce0bf8466a7473231f9b3ffef2",
    "testharness"
   ],
   "element-timing/observe-large-image.html": [
-   "a08274caa52542f71a14002b4063cc9dc9736bb2",
+   "13fc71bc4e3316b23be58b71620f5aa3cba658c3",
    "testharness"
   ],
   "element-timing/observe-multiple-images.html": [
-   "05c54ac050fe8caf5581dcbd1de5e30bb8681fd1",
+   "b9e82ed10b1c01b01be8a155f48ee3d610f3910b",
    "testharness"
   ],
   "element-timing/observe-shadow-image.html": [
-   "1fa6dd41a95e9b610412a5ee22cbdb0c3cad5c3e",
+   "a4d21bea80892384ece7c8049c894bed23f739bb",
    "testharness"
   ],
   "element-timing/observe-svg-image.html": [
-   "45e800d25da14d7052b42dab939ca49167bfedc3",
+   "c3c178e9b647752086248e4853d324940769c6f3",
    "testharness"
   ],
   "element-timing/observe-video-poster.html": [
-   "d3a69937d3c3c0815f4f86e4b09acc1517aec491",
+   "500fcedcccf2682f15b4bb2aeffe046aa9eeb085",
    "testharness"
   ],
   "element-timing/progressively-loaded-image.html": [
-   "c0a7d4f1fb76ffdade7df5f2663f1e33de84e7f3",
+   "c534621ccf86ae88daf96893373a0f691df804ad",
    "testharness"
   ],
   "element-timing/rectangular-image.html": [
-   "b02808456a3de05fb2ac1ede3af33c056bfd77ad",
+   "a1af9616ea115a3686ce09a06853a8efc8adefa2",
    "testharness"
   ],
   "element-timing/resources/TAOImage.py": [
@@ -432506,11 +432747,11 @@
    "support"
   ],
   "element-timing/resources/element-timing-helpers.js": [
-   "b0ddf308df2514bed7c14c3d83382afbc1ad0a21",
+   "e378d617f20f0d2c5d815d366b9c937ab46e6bd0",
    "support"
   ],
   "element-timing/resources/iframe-with-square-sends-entry.html": [
-   "25bd67935a1a3b493233451da9f9cf89742275ec",
+   "b8af505d32bc68d7f98b79bf2d2575778a49b26e",
    "support"
   ],
   "element-timing/resources/iframe-with-square.html": [
@@ -473853,6 +474094,10 @@
    "e0f1d63743c54c687d62f86abe278873fa823430",
    "testharness"
   ],
+  "portals/portals-host-post-message.sub.html": [
+   "a142f5570c5c9e6cd8e095b81f2cacd7e9f97dff",
+   "testharness"
+  ],
   "portals/portals-nested.html": [
    "26b264ee0509844141b9e8e4ae6999fa20ba04ef",
    "testharness"
@@ -473917,6 +474162,22 @@
    "586929e31d0efde5865b7416009ebcc1882d071c",
    "support"
   ],
+  "portals/resources/portal-host-post-message-after-activate.html": [
+   "07db1a0d8341a88cc7918f56112ecf52f9f9e3fc",
+   "support"
+  ],
+  "portals/resources/portal-host-post-message-navigate-1.html": [
+   "3b36eaed05e95ad2b251d65598b1950d0f26e37e",
+   "support"
+  ],
+  "portals/resources/portal-host-post-message-navigate-2.html": [
+   "163c42e655d6aa69a8ba8ccfb8474072eac9d349",
+   "support"
+  ],
+  "portals/resources/portal-host-post-message.sub.html": [
+   "8df9830d175ee546264f1f611b0341007a7c21a8",
+   "support"
+  ],
   "portals/resources/portal-host.html": [
    "5043a158ea74ef173f166c0580f9c1a27242bd14",
    "support"
@@ -474290,7 +474551,7 @@
    "manual"
   ],
   "presentation-api/controlling-ua/getAvailability.https.html": [
-   "b6d8736f51a07e4af7911408b6a9184b918d3e16",
+   "71b19e6a4eb819c088020a17241851d5e01f756c",
    "testharness"
   ],
   "presentation-api/controlling-ua/getAvailability_sandboxing_success.https.html": [
@@ -484165,22 +484426,6 @@
    "6c61a34a4ec2e75096db0eb9f7748b142f0db7bb",
    "support"
   ],
-  "resources/chromium/fake_bluetooth.mojom.js": [
-   "da443362248a1ae60e4412ec48141cce40fe34bf",
-   "support"
-  ],
-  "resources/chromium/fake_bluetooth.mojom.js.headers": [
-   "6805c323df5a975231648b830e33ce183c3cbbd3",
-   "support"
-  ],
-  "resources/chromium/fake_bluetooth_chooser.mojom.js": [
-   "42739393c10984ad6b8890123eb4fa66671cde78",
-   "support"
-  ],
-  "resources/chromium/fake_bluetooth_chooser.mojom.js.headers": [
-   "6805c323df5a975231648b830e33ce183c3cbbd3",
-   "support"
-  ],
   "resources/chromium/generic_sensor_mocks.js": [
    "531c3b8fe0542b280806b82658acc0ff888f6c5b",
    "support"
@@ -484253,16 +484498,8 @@
    "c5eee1f2aeb4069c595914ee022a9e509b9da545",
    "support"
   ],
-  "resources/chromium/uuid.mojom.js": [
-   "3b1b616ee3450f5ceb94f3f7e74ce5eea7af1bf9",
-   "support"
-  ],
-  "resources/chromium/uuid.mojom.js.headers": [
-   "6805c323df5a975231648b830e33ce183c3cbbd3",
-   "support"
-  ],
   "resources/chromium/web-bluetooth-test.js": [
-   "f0eba0f0c6c3b6ec1b2b4ace33b957f4e23e1be2",
+   "db8f5480b8399775b8a4e3fad709eb28bf2ecd8b",
    "support"
   ],
   "resources/chromium/web-bluetooth-test.js.headers": [
@@ -505754,7 +505991,7 @@
    "reftest"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_end-ref.html": [
-   "247e6e24bf3aa2fd5de4614ee954114f8136b8f6",
+   "e16f4afa0aa5a82e51868c63a4bcad4d2b4c356b",
    "support"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_end.html": [
@@ -505762,7 +505999,7 @@
    "reftest"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html": [
-   "f26b3a0761f2aaeadcbde9d0181f6d4e7db30160",
+   "ad69c500916f8ddb389bfdb67340a687f30b686f",
    "support"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html": [
@@ -505770,7 +506007,7 @@
    "reftest"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_start-ref.html": [
-   "15f24fb74b958c082695cb5b71cc23fc5514523c",
+   "6c1120ca11d7d4eafc62e6e6de1ee58b2d0556e7",
    "support"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_start.html": [
@@ -505778,7 +506015,7 @@
    "reftest"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html": [
-   "6f5b6335235867bb8c5c0ce5c428f790155af50d",
+   "866ddb153bcd61f68ebf569dac9031755239ba94",
    "support"
   ],
   "webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html": [
diff --git a/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js
index 8364323..2d863b1 100644
--- a/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js
+++ b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js
@@ -25,6 +25,7 @@
 
   // Load the Chromium-specific resources.
   let prefix = '/resources/chromium';
+  let genPrefix = '/gen';
   let extra = [];
   const pathname = window.location.pathname;
   if (pathname.includes('/LayoutTests/') || pathname.includes('/web_tests/')) {
@@ -33,17 +34,19 @@
     extra = [
       `${root}/resources/bluetooth/bluetooth-fake-adapter.js`,
     ];
+    genPrefix = 'file:///gen';
   } else if (window.location.pathname.startsWith('/bluetooth/https/')) {
     extra = [
       '/js-test-resources/bluetooth/bluetooth-fake-adapter.js',
     ];
   }
   return loadScripts([
-    `${prefix}/mojo_bindings.js`,
-    `${prefix}/mojo_web_test_helper_test.mojom.js`,
-    `${prefix}/uuid.mojom.js`,
-    `${prefix}/fake_bluetooth.mojom.js`,
-    `${prefix}/fake_bluetooth_chooser.mojom.js`,
+    `${genPrefix}/layout_test_data/mojo/public/js/mojo_bindings.js`,
+    `${genPrefix}/content/test/data/mojo_web_test_helper_test.mojom.js`,
+    `${genPrefix}/device/bluetooth/public/mojom/uuid.mojom.js`,
+    `${genPrefix}/url/mojom/origin.mojom.js`,
+    `${genPrefix}/device/bluetooth/public/mojom/test/fake_bluetooth.mojom.js`,
+    `${genPrefix}/content/shell/common/web_test/fake_bluetooth_chooser.mojom.js`,
     `${prefix}/web-bluetooth-test.js`,
   ].concat(extra))
       // Call setBluetoothFakeAdapter() to clean up any fake adapters left over
@@ -498,6 +501,15 @@
     }));
 }
 
+const health_thermometer_ad_packet = {
+  deviceAddress: '09:09:09:09:09:09',
+  rssi: -10,
+  scanRecord: {
+    name: 'Health Thermometer',
+    uuids: [health_thermometer.uuid],
+  },
+};
+
 // Returns a FakePeripheral that corresponds to a simulated pre-connected device
 // called 'Health Thermometer'. The device has two known serviceUUIDs:
 // 'generic_access' and 'health_thermometer'.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-001.html
new file mode 100644
index 0000000..0cd2243b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-001.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: hyphenation and text-shaping</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#word-break-shaping">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#hyphens-property">
+<link rel="match" href="reference/hyphens-shaping-001-ref.html">
+<meta name="assert" content="Shaping characters are still shaped as if the word were not broken when the word is hyphenated.">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 3em;
+    line-height: 1; /* Not strictly needed, but it gets quite tall otherwise, so this helps fit the screen. */
+    width: 0;
+    hyphens: manual;
+    margin: 1em auto;
+  }
+  .ref { color: orange; }
+  span { color: transparent; }
+</style>
+
+<p>Test passes if the black text is identical to the orange text (except the color).
+
+<div dir=rtl lang=ug class=ref>&#xFEA9;&#xFE8D;&#xFEE3;&#xFEF4;<br>&#xFEAA;&#xFEEF;</div>
+
+<div dir=rtl lang=ug id=test>دامي<span>&shy;</span>دى</div>
+<!--
+Using an invisible hyphen because it isn't certain what character the UA will actually use,
+and we shouldn't fail the reftest because of a mismatch there.
+See also hyphens-shaping-002.html to check that some character is inserted.
+-->
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-002.html
new file mode 100644
index 0000000..57d23e5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-shaping-002.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: hyphenation and text-shaping</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#word-break-shaping">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#hyphens-property">
+<link rel="mismatch" href="reference/hyphens-shaping-002-ref.html">
+<meta name="assert" content="Checks that some kind of hyphen does get inserted in Uyghur. (Complement fo hyphens-shaping-001.html)">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  /* The main text is invisible,
+     but we want to give the UA a chance to use the right hyphen,
+     which may be font dependent.
+   */
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+    hyphens: manual;
+    margin: auto;
+    width: 0;
+  }
+  #test { color: transparent; }
+  span { color: black; }
+</style>
+
+<p>Test passes if there is something below:
+
+<div dir=rtl lang=ug id=test>دامي<span>&shy;</span>دى</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-001.html
new file mode 100644
index 0000000..f7269e1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: manual hyphen and span</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#hyphens-property">
+<meta name="flags" content="">
+<link rel="match" href="reference/hyphens-span-001-ref.html">
+<meta name="assert" content="the presence of an unstyled inline element has no effect on text in general and on manual hyhenation in particular">
+<style>
+div {
+  border: solid orange;
+  margin: 5px;
+  width: 6ch;
+  hyphens: manual;
+}
+</style>
+
+<p>Test passes if the text in all orange boxes below is identical (including the presence and position of a hyphen).
+
+<div>high&shy;way</div>
+<div><span>high</span>&shy;way</div>
+<div><span>high&shy;</span>way</div>
+<div>high<span>&shy;</span>way</div>
+<div>high<span>&shy;way</span></div>
+<div>high&shy;<span>way</span></div>
+<div><span>high</span>&shy;<span>way</span></div>
+<div><span>high&shy;wa</span>y</div>
+<div><span>hi</span>gh&shy;way</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-002.html
new file mode 100644
index 0000000..07264fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/hyphens-span-002.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: auto hyphen and span</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#hyphens-property">
+<meta name="flags" content="">
+<link rel="match" href="reference/hyphens-span-002-ref.html">
+<meta name="assert" content="the presence of an unstyled inline element has no effect on text in general and on manual hyhenation in particular">
+<style>
+div {
+  border: solid orange;
+  margin: 5px;
+  width: 6ch;
+  hyphens: auto;
+}
+</style>
+
+<p>Test passes if the text in all orange boxes below is identical (including the presence and position of a hyphen).
+
+<div lang=en>highway</div>
+<div lang=en><span>high</span>way</div>
+<div lang=en>high<span></span>way</div>
+<div lang=en>high<span>way</span></div>
+<div lang=en><span>high</span><span>way</span></div>
+<div lang=en><span>highwa</span>y</div>
+<div lang=en><span>hi</span>ghway</div>
+
+<!--
+This test assumes the presence of "highway"
+with a hyphenation point between "high" and "way"
+in the hyphenation dictionary for English
+in order to be useful,
+but that assumption is not necessary for the test to be correct:
+if the word doesn't hyphenate,
+it will not hyphenate in any of the cases.
+-->
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-001-ref.html
new file mode 100644
index 0000000..9eb1d7fd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-001-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test reference</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 3em;
+    line-height: 1; /* Not strictly needed, but it gets quite tall otherwise, so this helps fit the screen. */
+    width: 0;
+    hyphens: manual;
+    margin: 1em auto;
+  }
+  .ref { color: orange; }
+</style>
+
+<p>Test passes if the black text is identical to the orange text (except the color).
+
+<div dir=rtl lang=ug class=ref>&#xFEA9;&#xFE8D;&#xFEE3;&#xFEF4;<br>&#xFEAA;&#xFEEF;</div>
+
+<div dir=rtl lang=ug>&#xFEA9;&#xFE8D;&#xFEE3;&#xFEF4;<br>&#xFEAA;&#xFEEF;</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-002-ref.html
new file mode 100644
index 0000000..d8e31d71
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-shaping-002-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test reference</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+
+<p>Test passes if there is something below:
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-001-ref.html
new file mode 100644
index 0000000..cbe3726
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-001-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test reference</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+div {
+  border: solid orange;
+  margin: 5px;
+  width: 6ch;
+  hyphens: manual;
+}
+</style>
+
+<p>Test passes if the text in all orange boxes below is identical (including the presence and position of a hyphen).
+
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
+<div>high&shy;way</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-002-ref.html
new file mode 100644
index 0000000..7b3f8206
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/hyphens-span-002-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test reference</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+div {
+  border: solid orange;
+  margin: 5px;
+  width: 6ch;
+  hyphens: auto;
+}
+</style>
+
+<p>Test passes if the text in all orange boxes below is identical (including the presence and position of a hyphen).
+
+<div lang=en>highway</div>
+<div lang=en>highway</div>
+<div lang=en>highway</div>
+<div lang=en>highway</div>
+<div lang=en>highway</div>
+<div lang=en>highway</div>
+<div lang=en>highway</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-alt-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-alt-ref.html
new file mode 100644
index 0000000..c86cb50
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-alt-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>test reference</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+span {
+  font-size: 3em;
+  color: red;
+  text-shadow: 3px 3px 3px black;
+}
+</style>
+
+<p>Test passes if the word “example” below is hyphenated, and the hyphen is large, red, and has a shadow
+
+<div>ex<span>&#x2010;</span><br>ample</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-ref.html
new file mode 100644
index 0000000..ad9df16
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/reference/shy-styling-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>test reference</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+span {
+  font-size: 3em;
+  color: red;
+  text-shadow: 3px 3px 3px black;
+}
+</style>
+
+<p>Test passes if the word “example” below is hyphenated, and the hyphen is large, red, and has a shadow
+
+<div>ex<span>&#x002D;</span><br>ample</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/shy-styling-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/shy-styling-001.html
new file mode 100644
index 0000000..98348d9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/hyphens/shy-styling-001.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: soft hyphen styling</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#hyphens-property">
+<meta name="flags" content="">
+<link rel="match" href="reference/shy-styling-001-ref.html">
+<link rel="match" href="reference/shy-styling-001-alt-ref.html">
+<meta name="assert" content="hypens inserted where there was a soft-hyphen take on the styles that would have applied to the soft hyphen">
+<style>
+div {
+  width: 0ch;
+  hyphens: manual;
+}
+span {
+  font-size: 3em;
+  color: red;
+  text-shadow: 3px 3px 3px black;
+}
+</style>
+
+<p>Test passes if the word “example” below is hyphenated, and the hyphen is large, red, and has a shadow
+
+<div>ex<span>&shy;</span>ample</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-shaping-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-shaping-001.html
new file mode 100644
index 0000000..4ce1da2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/line-break-shaping-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: line-break:anywhere and text-shaping</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#word-break-shaping">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#line-break-property">
+<link rel="match" href="reference/line-break-shaping-001-ref.html">
+<meta name="assert" content="Shaping characters are still shaped as if the word were not broken when a line is broken by line-break:anywhere">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+  }
+  section {
+    float: left; /* to sizing to the intrinsic min of the ref box*/
+    position: relative;
+  }
+  #ref {
+    border: solid orange;
+    margin: 1rem;
+  }
+  #test {
+    border: solid blue;
+    position: absolute; /* to avoid influencing the size of the section */
+    left: 1rem;
+    right: 1rem;
+    line-break: anywhere;
+  }
+</style>
+
+<p>Test passes if the blue and organge boxes are identical. Pay attention to characters at the left of the first line, and on the second line.
+<section>
+<div dir=rtl lang=ar id=ref>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+<div dir=rtl lang=ar id=test>عائلة</div>
+</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-shaping-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-shaping-001-ref.html
new file mode 100644
index 0000000..5543ab0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-break/reference/line-break-shaping-001-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test ref</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+    margin: 1rem;
+  }
+  section {
+    float: left; /* to sizing to the intrinsic min of the ref box*/
+  }
+  #ref { border: solid orange; }
+  #test { border: solid blue; }
+</style>
+
+<p>Test passes if the blue and organge boxes are identical. Pay attention to characters at the left of the first line, and on the second line.
+<section>
+<div dir=rtl lang=ar id=ref>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+<div dir=rtl lang=ar id=test>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-001.html
new file mode 100644
index 0000000..8846038
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: overflow-wrap:break-word and text-shaping</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#word-break-shaping">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#overflow-wrap-property">
+<link rel="match" href="reference/overflow-wrap-shaping-001-ref.html">
+<meta name="assert" content="Shaping characters are still shaped as if the word were not broken when a line is broken by overflow-wrap:break-word">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+  }
+  section {
+    float: left; /* to sizing to the intrinsic min of the ref box*/
+    position: relative;
+  }
+  #ref {
+    border: solid orange;
+    margin: 1rem;
+  }
+  #test {
+    border: solid blue;
+    position: absolute; /* to avoid influencing the size of the section */
+    left: 1rem;
+    right: 1rem;
+    overflow-wrap: break-word;
+  }
+</style>
+
+<p>Test passes if the blue and organge boxes are identical. Pay attention to characters at the left of the first line, and on the second line.
+<section>
+<div dir=rtl lang=ar id=ref>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+<div dir=rtl lang=ar id=test>عائلة</div>
+</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-002.html
new file mode 100644
index 0000000..adb25c7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-shaping-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: overflow-wrap:anywhere and text-shaping</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#word-break-shaping">
+<link rel="help" href="https://www.w3.org/TR/css-text-3/#overflow-wrap-property">
+<link rel="match" href="reference/overflow-wrap-shaping-001-ref.html">
+<meta name="assert" content="Shaping characters are still shaped as if the word were not broken when a line is broken by overflow-wrap:anywhere">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+  }
+  section {
+    float: left; /* to sizing to the intrinsic min of the ref box*/
+    position: relative;
+  }
+  #ref {
+    border: solid orange;
+    margin: 1rem;
+  }
+  #test {
+    border: solid blue;
+    position: absolute; /* to avoid influencing the size of the section */
+    left: 1rem;
+    right: 1rem;
+    overflow-wrap: anywhere;
+  }
+</style>
+
+<p>Test passes if the blue and organge boxes are identical. Pay attention to characters at the left of the first line, and on the second line.
+<section>
+<div dir=rtl lang=ar id=ref>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+<div dir=rtl lang=ar id=test>عائلة</div>
+</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html
new file mode 100644
index 0000000..5543ab0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-shaping-001-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test ref</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<style>
+  @font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+  }
+  div {
+    font-family: 'csstest_noto';
+    font-size: 4em;
+    margin: 1rem;
+  }
+  section {
+    float: left; /* to sizing to the intrinsic min of the ref box*/
+  }
+  #ref { border: solid orange; }
+  #test { border: solid blue; }
+</style>
+
+<p>Test passes if the blue and organge boxes are identical. Pay attention to characters at the left of the first line, and on the second line.
+<section>
+<div dir=rtl lang=ar id=ref>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+<div dir=rtl lang=ar id=test>&#xFECB;&#xFE8E;&#xFE8B;&#xFEE0;<br>&#xFE94;</div>
+</section>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-intrinsic-size-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-intrinsic-size-004-ref.html
index 34757067..490d61b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-intrinsic-size-004-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-intrinsic-size-004-ref.html
@@ -3,20 +3,16 @@
 <title>test reference</title>
 <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
 <style>
-aside {
-  float: left;
-  background: blue;
-}
 div {
   color: transparent;
   font-family: Ahem;
   font-size: 50px;
-  width: 5ch;
+  width: 3ch;
+  height: 2ch;
+  background: green;
 }
 </style>
 
-<p>Test passes if there is a single blue rectangle below.
+<p>Test passes if there is a single green rectangle below and no red.
 <div>
-  <aside class=own>X</aside>
-  <aside class=owbw>X</aside>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html
index 53cb2a0..5f94d07 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-002-ref.html
@@ -3,6 +3,6 @@
 <title>CSS test Reference</title>
 <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
 
-<p>This test passes if you can see the word PASS below, without any extra spaces.
+<p>This test passes if the letters below are spaced equally.
 
-<div>PASS</div>
+<div>X X X X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html
new file mode 100644
index 0000000..736a2d56
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/reference/white-space-pre-wrap-trailing-spaces-003-ref.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSS test Reference</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+
+<style>
+div {
+  font: 25px/1 Ahem;
+  color: green;
+}
+</style>
+
+<p>This test passes if there is a green rectangle and no red.
+
+<div>X<br>X<br>X<br>X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-intrinsic-size-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-intrinsic-size-004.html
index 510a5c5..42b94a72 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-intrinsic-size-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-intrinsic-size-004.html
@@ -6,25 +6,25 @@
 <link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
 <meta name="flags" content="">
 <link rel="match" href="reference/white-space-intrinsic-size-004-ref.html">
-<meta name="assert" content="Preserved spaces at the end of the line do not affect the intrinsic max-content size when white-space is pre-wrap. The value of overflow-wrap makes no difference.">
+<meta name="assert" content="Preserved spaces at the end of the line do affect the intrinsic max-content size when white-space is pre-wrap, as hanging does not prevent contributing to the max-content size. The value of overflow-wrap makes no difference.">
 <style>
 aside {
   float: left;
   white-space: pre-wrap;
-  background: blue;
-  margin-bottom: 1em;
+  background: green;
 }
 aside:last-of-type { overflow-wrap: break-word; }
 div {
+  background: red;
   color: transparent;
   font-family: Ahem;
   font-size: 50px;
-  width: 3ch; /* enough room for both floats if their max-content size does not include the preserved spaces,
-		 but not enough if they do, causing a line break in that case. */
+  width: 3ch;
+  height: 2em;
 }
 </style>
 
-<p>Test passes if there is a single blue rectangle below.
+<p>Test passes if there is a single green rectangle below and no red.
 <div>
   <aside>X  </aside>
   <aside>X  </aside>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html
index d8e7c82..76ca5ef7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html
@@ -4,7 +4,7 @@
 <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
 <link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
 <link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-002-ref.html">
-<meta name="assert" content="Preserved white space at the end of the line is hanged when white-space is pre-wrap, and therefore does not count when computing the (maximum) intrinsic size.">
+<meta name="assert" content="Hanging preserved white space at the end of the line when white-space is pre-wrap has no effect on the max-content size.">
 
 <style>
 span {
@@ -15,6 +15,6 @@
 #s2 { text-align: center; }
 </style>
 
-<p>This test passes if you can see the word PASS below, without any extra spaces.
+<p>This test passes if the letters below are spaced equally.
 
-<div><span id=s1>P                                 </span><span id=s2>A                                    </span>SS</div>
+<div><span id=s1>X </span><span id=s2>X </span>X X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html
index 6b21df6..4b6df8e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-003.html
@@ -3,25 +3,19 @@
 <title>CSS Text test: intrinsic minimum sizing of trailing spaces with white-space:pre-wrap</title>
 <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
 <link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2">
-<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-002-ref.html">
+<link rel="match" href="reference/white-space-pre-wrap-trailing-spaces-003-ref.html">
 <meta name="assert" content="Preserved white space at the end of the line is hanged when white-space is pre-wrap, and therefore does not count when computing the (minimum) intrinsic size.">
 
 <style>
-/* Make the table invisible */
-table { border-collapse: collapse; }
-td { padding: 0; }
-
-/* for the content of the table to be sized to their mininum intrinsic size */
-table { width: 0; }
-
-span {
-  display: inline-block;
+div {
+  font: 25px/1 Ahem;
   white-space: pre-wrap;
+  width: min-content;
+  color: green;
+  background: red;
 }
-#s1 { text-align: right; }
-#s2 { text-align: center; }
 </style>
 
-<p>This test passes if you can see the word PASS below, without any extra spaces.
+<p>This test passes if there is a green rectangle and no red.
 
-<table><td><span id=s1>P                                 </span><td><span id=s2>A                                    </span><td>SS</table>
+<div>X    X X X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html
new file mode 100644
index 0000000..7f5ec30
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky-container-for-abspos.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSSOM: resolved values of the inset properties for sticky positioning</title>
+<link rel="help" href="https://drafts.csswg.org/cssom/#resolved-value">
+<link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos">
+<link rel="author" title="Joonghun Park" href="mailto:pjh0718@gmail.com">
+<style>
+    #container-for-abspos {
+        height: 200px;
+        width: 400px;
+        overflow: hidden;
+    }
+</style>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script type="module">
+import {runTests, containerForAbspos} from "./support/getComputedStyle-insets.js";
+runTests({
+  style: "position: sticky;",
+  containingBlockElement: containerForAbspos,
+  containingBlockArea: "content",
+  preservesPercentages: false,
+  preservesAuto: true,
+  canStretchAutoSize: false,
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky.html b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky.html
index 6149acc6..6b23fab 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky.html
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-insets-sticky.html
@@ -4,12 +4,15 @@
 <link rel="help" href="https://drafts.csswg.org/cssom/#resolved-value">
 <link rel="help" href="https://drafts.csswg.org/css-position/#pos-sch">
 <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<style>
+    #container-for-inflow { overflow: hidden; }
+</style>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script type="module">
 import {runTests, containerForInflow} from "./support/getComputedStyle-insets.js";
 runTests({
-  style: "position: sticky; position: -webkit-sticky",
+  style: "position: sticky;",
   containingBlockElement: containerForInflow,
   containingBlockArea: "content",
   preservesPercentages: false,
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-sticky-pos-percent.html b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-sticky-pos-percent.html
new file mode 100644
index 0000000..12ad5e8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/getComputedStyle-sticky-pos-percent.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>CSS Test: resolve top percentage value against proper box</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3115" />
+<link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos" />
+<link rel="help" href="https://drafts.csswg.org/cssom/#resolved-values" />
+<meta name="assert" content="Test that the sticky percentage insets are
+resolved against the right ancestor, i.e. the nearest scrollport." />
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div style="height: 500px; background: purple; overflow: hidden;">
+  <div style="height: 400px; background: yellow;">
+    <div id="target" style="height: 100px; position: sticky; left: 0; top: 50%; background: blue;">
+    </div>
+  </div>
+</div>
+<script>
+test(() => {
+  assert_equals(getComputedStyle(target).top, '250px');
+}, "Sticky element's top property percentage value should be resolved against the div with overflow: hidden");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/support/getComputedStyle-insets.js b/third_party/blink/web_tests/external/wpt/css/cssom/support/getComputedStyle-insets.js
index beec32e7..723990ca 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/support/getComputedStyle-insets.js
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/support/getComputedStyle-insets.js
@@ -22,7 +22,6 @@
     padding: 1px 2px;
     border-width: 2px 4px;
     margin: 4px 8px;
-    overflow: hidden;
   }
   #container-for-abspos {
     /* Padding area: 200px tall, 400px wide */
@@ -48,7 +47,7 @@
     border-style: solid;
   }
 `;
-document.head.appendChild(stylesheet);
+document.head.prepend(stylesheet);
 
 function runTestsWithWM(data, testWM, cbWM) {
   const {
@@ -149,10 +148,10 @@
       bottom: "50%",
       right: "75%",
     }, {
-      top: .1 * cbHeight + "px",
-      left: .25 * cbWidth + "px",
-      bottom: .5 * cbHeight + "px",
-      right: .75 * cbWidth + "px",
+      top: cbHeight * 10 / 100 + "px",
+      left: cbWidth * 25 / 100 + "px",
+      bottom: cbHeight * 50 / 100 + "px",
+      right: cbWidth * 75 / 100 + "px",
     }, "Percentages are absolutized into pixels");
 
     checkStyle({
@@ -161,10 +160,10 @@
       bottom: "calc(50% - 3px)",
       right: "calc(75% - 4px)",
     }, {
-      top: .1 * cbHeight - 1 + "px",
-      left: .25 * cbWidth - 2 + "px",
-      bottom: .5 * cbHeight - 3 + "px",
-      right: .75 * cbWidth - 4 + "px",
+      top: cbHeight * 10 / 100 - 1 + "px",
+      left: cbWidth * 25 / 100 - 2 + "px",
+      bottom: cbHeight * 50 / 100 - 3 + "px",
+      right: cbWidth * 75 / 100 - 4 + "px",
     }, "calc() is absolutized into pixels");
   }
 
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt
deleted file mode 100644
index ec61ea6..0000000
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt
+++ /dev/null
@@ -1,141 +0,0 @@
-This is a testharness.js-based test.
-Found 137 tests; 129 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Test driver
-PASS Partial interface NavigatorUserMedia: original interface defined
-PASS Partial interface MediaDevices: original interface defined
-PASS MediaStream interface: existence and properties of interface object
-PASS MediaStream interface object length
-PASS MediaStream interface object name
-PASS MediaStream interface: existence and properties of interface prototype object
-PASS MediaStream interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStream interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStream interface: attribute id
-PASS Unscopable handled correctly for id property on MediaStream
-PASS MediaStream interface: operation getAudioTracks()
-PASS Unscopable handled correctly for getAudioTracks() on MediaStream
-PASS MediaStream interface: operation getVideoTracks()
-PASS Unscopable handled correctly for getVideoTracks() on MediaStream
-PASS MediaStream interface: operation getTracks()
-PASS Unscopable handled correctly for getTracks() on MediaStream
-PASS MediaStream interface: operation getTrackById(DOMString)
-PASS Unscopable handled correctly for getTrackById(DOMString) on MediaStream
-PASS MediaStream interface: operation addTrack(MediaStreamTrack)
-PASS Unscopable handled correctly for addTrack(MediaStreamTrack) on MediaStream
-PASS MediaStream interface: operation removeTrack(MediaStreamTrack)
-PASS Unscopable handled correctly for removeTrack(MediaStreamTrack) on MediaStream
-PASS MediaStream interface: operation clone()
-PASS Unscopable handled correctly for clone() on MediaStream
-PASS MediaStream interface: attribute active
-PASS Unscopable handled correctly for active property on MediaStream
-PASS MediaStream interface: attribute onaddtrack
-PASS Unscopable handled correctly for onaddtrack property on MediaStream
-PASS MediaStream interface: attribute onremovetrack
-PASS Unscopable handled correctly for onremovetrack property on MediaStream
-PASS MediaStreamTrack interface: existence and properties of interface object
-PASS MediaStreamTrack interface object length
-PASS MediaStreamTrack interface object name
-PASS MediaStreamTrack interface: existence and properties of interface prototype object
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrack interface: attribute kind
-PASS Unscopable handled correctly for kind property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute id
-PASS Unscopable handled correctly for id property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute label
-PASS Unscopable handled correctly for label property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute enabled
-PASS Unscopable handled correctly for enabled property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute muted
-PASS Unscopable handled correctly for muted property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onmute
-PASS Unscopable handled correctly for onmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onunmute
-PASS Unscopable handled correctly for onunmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute readyState
-PASS Unscopable handled correctly for readyState property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onended
-PASS Unscopable handled correctly for onended property on MediaStreamTrack
-PASS MediaStreamTrack interface: operation clone()
-PASS Unscopable handled correctly for clone() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation stop()
-PASS Unscopable handled correctly for stop() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getCapabilities()
-PASS Unscopable handled correctly for getCapabilities() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getConstraints()
-PASS Unscopable handled correctly for getConstraints() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getSettings()
-PASS Unscopable handled correctly for getSettings() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation applyConstraints(MediaTrackConstraints)
-PASS Unscopable handled correctly for applyConstraints(MediaTrackConstraints) on MediaStreamTrack
-FAIL MediaStreamTrack interface: attribute onoverconstrained assert_true: The prototype object must have a property "onoverconstrained" expected true got false
-PASS Unscopable handled correctly for onoverconstrained property on MediaStreamTrack
-PASS MediaStreamTrackEvent interface: existence and properties of interface object
-PASS MediaStreamTrackEvent interface object length
-PASS MediaStreamTrackEvent interface object name
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrackEvent interface: attribute track
-PASS Unscopable handled correctly for track property on MediaStreamTrackEvent
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface object assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface object length assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface object name assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: attribute error assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-PASS Unscopable handled correctly for error property on OverconstrainedErrorEvent
-PASS MediaDevices interface: existence and properties of interface object
-PASS MediaDevices interface object length
-PASS MediaDevices interface object name
-PASS MediaDevices interface: existence and properties of interface prototype object
-PASS MediaDevices interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDevices interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDevices interface: attribute ondevicechange
-PASS Unscopable handled correctly for ondevicechange property on MediaDevices
-PASS MediaDevices interface: operation enumerateDevices()
-PASS Unscopable handled correctly for enumerateDevices() on MediaDevices
-PASS MediaDevices interface: operation getSupportedConstraints()
-PASS Unscopable handled correctly for getSupportedConstraints() on MediaDevices
-PASS MediaDevices interface: operation getUserMedia(MediaStreamConstraints)
-PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints) on MediaDevices
-PASS MediaDevices must be primary interface of navigator.mediaDevices
-PASS Stringification of navigator.mediaDevices
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "ondevicechange" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "enumerateDevices()" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "getSupportedConstraints()" with the proper type
-PASS MediaDevices interface: navigator.mediaDevices must inherit property "getUserMedia(MediaStreamConstraints)" with the proper type
-PASS MediaDevices interface: calling getUserMedia(MediaStreamConstraints) on navigator.mediaDevices with too few arguments must throw TypeError
-PASS MediaDeviceInfo interface: existence and properties of interface object
-PASS MediaDeviceInfo interface object length
-PASS MediaDeviceInfo interface object name
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDeviceInfo interface: attribute deviceId
-PASS Unscopable handled correctly for deviceId property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute kind
-PASS Unscopable handled correctly for kind property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute label
-PASS Unscopable handled correctly for label property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute groupId
-PASS Unscopable handled correctly for groupId property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: operation toJSON()
-PASS Unscopable handled correctly for toJSON() on MediaDeviceInfo
-PASS InputDeviceInfo interface: existence and properties of interface object
-PASS InputDeviceInfo interface object length
-PASS InputDeviceInfo interface object name
-PASS InputDeviceInfo interface: existence and properties of interface prototype object
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS InputDeviceInfo interface: operation getCapabilities()
-PASS Unscopable handled correctly for getCapabilities() on InputDeviceInfo
-PASS Navigator interface: attribute mediaDevices
-PASS Unscopable handled correctly for mediaDevices property on Navigator
-PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)
-PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on Navigator
-PASS Navigator interface: navigator must inherit property "mediaDevices" with the proper type
-PASS Navigator interface: navigator must inherit property "getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)" with the proper type
-PASS Navigator interface: calling getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on navigator with too few arguments must throw TypeError
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt
deleted file mode 100644
index 686371c..0000000
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt
+++ /dev/null
@@ -1,140 +0,0 @@
-This is a testharness.js-based test.
-Found 136 tests; 128 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Test MediaDevices.enumerateDevices call and result. Types only.
-PASS Partial interface NavigatorUserMedia: original interface defined
-PASS Partial interface MediaDevices: original interface defined
-PASS MediaStream interface: existence and properties of interface object
-PASS MediaStream interface object length
-PASS MediaStream interface object name
-PASS MediaStream interface: existence and properties of interface prototype object
-PASS MediaStream interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStream interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStream interface: attribute id
-PASS Unscopable handled correctly for id property on MediaStream
-PASS MediaStream interface: operation getAudioTracks()
-PASS Unscopable handled correctly for getAudioTracks() on MediaStream
-PASS MediaStream interface: operation getVideoTracks()
-PASS Unscopable handled correctly for getVideoTracks() on MediaStream
-PASS MediaStream interface: operation getTracks()
-PASS Unscopable handled correctly for getTracks() on MediaStream
-PASS MediaStream interface: operation getTrackById(DOMString)
-PASS Unscopable handled correctly for getTrackById(DOMString) on MediaStream
-PASS MediaStream interface: operation addTrack(MediaStreamTrack)
-PASS Unscopable handled correctly for addTrack(MediaStreamTrack) on MediaStream
-PASS MediaStream interface: operation removeTrack(MediaStreamTrack)
-PASS Unscopable handled correctly for removeTrack(MediaStreamTrack) on MediaStream
-PASS MediaStream interface: operation clone()
-PASS Unscopable handled correctly for clone() on MediaStream
-PASS MediaStream interface: attribute active
-PASS Unscopable handled correctly for active property on MediaStream
-PASS MediaStream interface: attribute onaddtrack
-PASS Unscopable handled correctly for onaddtrack property on MediaStream
-PASS MediaStream interface: attribute onremovetrack
-PASS Unscopable handled correctly for onremovetrack property on MediaStream
-PASS MediaStreamTrack interface: existence and properties of interface object
-PASS MediaStreamTrack interface object length
-PASS MediaStreamTrack interface object name
-PASS MediaStreamTrack interface: existence and properties of interface prototype object
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrack interface: attribute kind
-PASS Unscopable handled correctly for kind property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute id
-PASS Unscopable handled correctly for id property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute label
-PASS Unscopable handled correctly for label property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute enabled
-PASS Unscopable handled correctly for enabled property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute muted
-PASS Unscopable handled correctly for muted property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onmute
-PASS Unscopable handled correctly for onmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onunmute
-PASS Unscopable handled correctly for onunmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute readyState
-PASS Unscopable handled correctly for readyState property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onended
-PASS Unscopable handled correctly for onended property on MediaStreamTrack
-PASS MediaStreamTrack interface: operation clone()
-PASS Unscopable handled correctly for clone() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation stop()
-PASS Unscopable handled correctly for stop() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getCapabilities()
-PASS Unscopable handled correctly for getCapabilities() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getConstraints()
-PASS Unscopable handled correctly for getConstraints() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getSettings()
-PASS Unscopable handled correctly for getSettings() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation applyConstraints(MediaTrackConstraints)
-PASS Unscopable handled correctly for applyConstraints(MediaTrackConstraints) on MediaStreamTrack
-FAIL MediaStreamTrack interface: attribute onoverconstrained assert_true: The prototype object must have a property "onoverconstrained" expected true got false
-PASS Unscopable handled correctly for onoverconstrained property on MediaStreamTrack
-PASS MediaStreamTrackEvent interface: existence and properties of interface object
-PASS MediaStreamTrackEvent interface object length
-PASS MediaStreamTrackEvent interface object name
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrackEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrackEvent interface: attribute track
-PASS Unscopable handled correctly for track property on MediaStreamTrackEvent
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface object assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface object length assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface object name assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-FAIL OverconstrainedErrorEvent interface: attribute error assert_own_property: self does not have own property "OverconstrainedErrorEvent" expected property "OverconstrainedErrorEvent" missing
-PASS Unscopable handled correctly for error property on OverconstrainedErrorEvent
-PASS MediaDevices interface: existence and properties of interface object
-PASS MediaDevices interface object length
-PASS MediaDevices interface object name
-PASS MediaDevices interface: existence and properties of interface prototype object
-PASS MediaDevices interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDevices interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDevices interface: attribute ondevicechange
-PASS Unscopable handled correctly for ondevicechange property on MediaDevices
-PASS MediaDevices interface: operation enumerateDevices()
-PASS Unscopable handled correctly for enumerateDevices() on MediaDevices
-PASS MediaDevices interface: operation getSupportedConstraints()
-PASS Unscopable handled correctly for getSupportedConstraints() on MediaDevices
-PASS MediaDevices interface: operation getUserMedia(MediaStreamConstraints)
-PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints) on MediaDevices
-PASS MediaDeviceInfo interface: existence and properties of interface object
-PASS MediaDeviceInfo interface object length
-PASS MediaDeviceInfo interface object name
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaDeviceInfo interface: attribute deviceId
-PASS Unscopable handled correctly for deviceId property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute kind
-PASS Unscopable handled correctly for kind property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute label
-PASS Unscopable handled correctly for label property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: attribute groupId
-PASS Unscopable handled correctly for groupId property on MediaDeviceInfo
-PASS MediaDeviceInfo interface: operation toJSON()
-PASS Unscopable handled correctly for toJSON() on MediaDeviceInfo
-PASS InputDeviceInfo interface: existence and properties of interface object
-PASS InputDeviceInfo interface object length
-PASS InputDeviceInfo interface object name
-PASS InputDeviceInfo interface: existence and properties of interface prototype object
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's "constructor" property
-PASS InputDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property
-PASS InputDeviceInfo interface: operation getCapabilities()
-PASS Unscopable handled correctly for getCapabilities() on InputDeviceInfo
-PASS InputDeviceInfo must be primary interface of [object InputDeviceInfo]
-PASS Stringification of [object InputDeviceInfo]
-PASS InputDeviceInfo interface: [object InputDeviceInfo] must inherit property "getCapabilities()" with the proper type
-PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "deviceId" with the proper type
-PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "kind" with the proper type
-PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "label" with the proper type
-PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "groupId" with the proper type
-PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "toJSON()" with the proper type
-PASS Test default toJSON operation of InputDeviceInfo
-PASS Navigator interface: attribute mediaDevices
-PASS Unscopable handled correctly for mediaDevices property on Navigator
-PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)
-PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on Navigator
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-idl.https-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-idl.https-expected.txt
deleted file mode 100644
index 124aa42..0000000
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStreamTrack-idl.https-expected.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-This is a testharness.js-based test.
-PASS Test driver
-PASS MediaStreamTrack interface: existence and properties of interface object
-PASS MediaStreamTrack interface object length
-PASS MediaStreamTrack interface object name
-PASS MediaStreamTrack interface: existence and properties of interface prototype object
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaStreamTrack interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaStreamTrack interface: attribute kind
-PASS Unscopable handled correctly for kind property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute id
-PASS Unscopable handled correctly for id property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute label
-PASS Unscopable handled correctly for label property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute enabled
-PASS Unscopable handled correctly for enabled property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute muted
-PASS Unscopable handled correctly for muted property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onmute
-PASS Unscopable handled correctly for onmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onunmute
-PASS Unscopable handled correctly for onunmute property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute readyState
-PASS Unscopable handled correctly for readyState property on MediaStreamTrack
-PASS MediaStreamTrack interface: attribute onended
-PASS Unscopable handled correctly for onended property on MediaStreamTrack
-FAIL MediaStreamTrack interface: attribute onoverconstrained assert_true: The prototype object must have a property "onoverconstrained" expected true got false
-PASS Unscopable handled correctly for onoverconstrained property on MediaStreamTrack
-PASS MediaStreamTrack interface: operation clone()
-PASS Unscopable handled correctly for clone() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation stop()
-PASS Unscopable handled correctly for stop() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getCapabilities()
-PASS Unscopable handled correctly for getCapabilities() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getConstraints()
-PASS Unscopable handled correctly for getConstraints() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation getSettings()
-PASS Unscopable handled correctly for getSettings() on MediaStreamTrack
-PASS MediaStreamTrack interface: operation applyConstraints(MediaTrackConstraints)
-PASS Unscopable handled correctly for applyConstraints(MediaTrackConstraints) on MediaStreamTrack
-PASS MediaStreamTrack must be primary interface of track
-PASS Stringification of track
-PASS MediaStreamTrack interface: track must inherit property "kind" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "id" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "label" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "enabled" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "muted" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onmute" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onunmute" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "readyState" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "onended" with the proper type
-FAIL MediaStreamTrack interface: track must inherit property "onoverconstrained" with the proper type assert_inherits: property "onoverconstrained" not found in prototype chain
-PASS MediaStreamTrack interface: track must inherit property "clone()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "stop()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getCapabilities()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getConstraints()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "getSettings()" with the proper type
-PASS MediaStreamTrack interface: track must inherit property "applyConstraints(MediaTrackConstraints)" with the proper type
-PASS MediaStreamTrack interface: calling applyConstraints(MediaTrackConstraints) on track with too few arguments must throw TypeError
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window.js
index 441a64e3..976d31b6 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window.js
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window.js
@@ -54,7 +54,6 @@
     MediaDevices: ['navigator.mediaDevices'],
     MediaStreamTrack: [track],
     MediaStreamTrackEvent: [trackEvent],
-    OverconstrainedErrorEvent: ['new OverconstrainedErrorEvent("type", {})'],
   });
   idl_array.test();
 }, 'mediacapture-streams interfaces.');
diff --git a/third_party/blink/web_tests/external/wpt/permissions/interfaces.any.js b/third_party/blink/web_tests/external/wpt/permissions/interfaces.any.js
index 77fa909a..b9345388 100644
--- a/third_party/blink/web_tests/external/wpt/permissions/interfaces.any.js
+++ b/third_party/blink/web_tests/external/wpt/permissions/interfaces.any.js
@@ -22,7 +22,7 @@
 
   try {
     self.permissionStatus = await navigator.permissions.query({ name: "geolocation" });
-    self.permissionStatus = await navigator.permissions.query({ name: "background-fetch"});
+    self.permissionStatus = await navigator.permissions.query({ name: "background-fetch" });
   } catch (e) {
     // Will be surfaced in idlharness.js's test_object below.
   }
diff --git a/third_party/blink/web_tests/external/wpt/permissions/test-background-fetch-permission.html b/third_party/blink/web_tests/external/wpt/permissions/test-background-fetch-permission.html
index c3da77d..c824ecf 100644
--- a/third_party/blink/web_tests/external/wpt/permissions/test-background-fetch-permission.html
+++ b/third_party/blink/web_tests/external/wpt/permissions/test-background-fetch-permission.html
@@ -7,7 +7,6 @@
 
 <script>
   promise_test(function(test) {
-    internals.runtimeFlags.backgroundFetchEnabled = true;
     return navigator.permissions.query({name:'background-fetch'}).then(function(result) {
       assert_true(result instanceof PermissionStatus);
     });
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js b/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js
deleted file mode 100644
index da44336..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js
+++ /dev/null
@@ -1,5323 +0,0 @@
-// Copyright 2014 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.
-
-'use strict';
-
-(function() {
-  var mojomId = 'device/bluetooth/public/mojom/test/fake_bluetooth.mojom';
-  if (mojo.internal.isMojomLoaded(mojomId)) {
-    console.warn('The following mojom is loaded multiple times: ' + mojomId);
-    return;
-  }
-  mojo.internal.markMojomLoaded(mojomId);
-  var bindings = mojo;
-  var associatedBindings = mojo;
-  var codec = mojo.internal;
-  var validator = mojo.internal;
-
-  var exports = mojo.internal.exposeNamespace('bluetooth.mojom');
-  var uuid$ =
-      mojo.internal.exposeNamespace('bluetooth.mojom');
-  if (mojo.config.autoLoadMojomDeps) {
-    mojo.internal.loadMojomIfNecessary(
-        'device/bluetooth/public/mojom/uuid.mojom', '../uuid.mojom.js');
-  }
-
-
-  var kHCISuccess = 0x0000;
-  var kHCIConnectionTimeout = 0x0008;
-  var kGATTSuccess = 0x0000;
-  var kGATTInvalidHandle = 0x0001;
-  var CentralState = {};
-  CentralState.ABSENT = 0;
-  CentralState.POWERED_ON = CentralState.ABSENT + 1;
-  CentralState.POWERED_OFF = CentralState.POWERED_ON + 1;
-
-  CentralState.isKnownEnumValue = function(value) {
-    switch (value) {
-    case 0:
-    case 1:
-    case 2:
-      return true;
-    }
-    return false;
-  };
-
-  CentralState.validate = function(enumValue) {
-    var isExtensible = false;
-    if (isExtensible || this.isKnownEnumValue(enumValue))
-      return validator.validationError.NONE;
-
-    return validator.validationError.UNKNOWN_ENUM_VALUE;
-  };
-
-  function Appearance(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  Appearance.prototype.initDefaults_ = function() {
-    this.hasValue = false;
-    this.value = 0;
-  };
-  Appearance.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  Appearance.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    return validator.validationError.NONE;
-  };
-
-  Appearance.encodedSize = codec.kStructHeaderSize + 8;
-
-  Appearance.decode = function(decoder) {
-    var packed;
-    var val = new Appearance();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.hasValue = (packed >> 0) & 1 ? true : false;
-    val.value = decoder.decodeStruct(codec.Int8);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  Appearance.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(Appearance.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.hasValue & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.encodeStruct(codec.Int8, val.value);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function Power(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  Power.prototype.initDefaults_ = function() {
-    this.hasValue = false;
-    this.value = 0;
-  };
-  Power.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  Power.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    return validator.validationError.NONE;
-  };
-
-  Power.encodedSize = codec.kStructHeaderSize + 8;
-
-  Power.decode = function(decoder) {
-    var packed;
-    var val = new Power();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.hasValue = (packed >> 0) & 1 ? true : false;
-    val.value = decoder.decodeStruct(codec.Int8);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  Power.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(Power.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.hasValue & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.encodeStruct(codec.Int8, val.value);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function ServiceDataMap(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  ServiceDataMap.prototype.initDefaults_ = function() {
-    this.serviceData = null;
-  };
-  ServiceDataMap.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  ServiceDataMap.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ServiceDataMap.serviceData
-    err = messageValidator.validateMapPointer(offset + codec.kStructHeaderSize + 0, false, codec.String, new codec.ArrayOf(codec.Uint8), false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  ServiceDataMap.encodedSize = codec.kStructHeaderSize + 8;
-
-  ServiceDataMap.decode = function(decoder) {
-    var packed;
-    var val = new ServiceDataMap();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.serviceData = decoder.decodeMapPointer(codec.String, new codec.ArrayOf(codec.Uint8));
-    return val;
-  };
-
-  ServiceDataMap.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(ServiceDataMap.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeMapPointer(codec.String, new codec.ArrayOf(codec.Uint8), val.serviceData);
-  };
-  function ScanRecord(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  ScanRecord.prototype.initDefaults_ = function() {
-    this.name = null;
-    this.uuids = null;
-    this.appearance = null;
-    this.txPower = null;
-    this.manufacturerData = null;
-    this.serviceData = null;
-  };
-  ScanRecord.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  ScanRecord.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 56}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.name
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.uuids
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(uuid$.UUID), true, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.appearance
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, Appearance, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.txPower
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, Power, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.manufacturerData
-    err = messageValidator.validateMapPointer(offset + codec.kStructHeaderSize + 32, true, codec.Uint8, new codec.ArrayOf(codec.Uint8), false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanRecord.serviceData
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, ServiceDataMap, true);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  ScanRecord.encodedSize = codec.kStructHeaderSize + 48;
-
-  ScanRecord.decode = function(decoder) {
-    var packed;
-    var val = new ScanRecord();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.name = decoder.decodeStruct(codec.NullableString);
-    val.uuids = decoder.decodeArrayPointer(new codec.PointerTo(uuid$.UUID));
-    val.appearance = decoder.decodeStructPointer(Appearance);
-    val.txPower = decoder.decodeStructPointer(Power);
-    val.manufacturerData = decoder.decodeMapPointer(codec.Uint8, new codec.ArrayOf(codec.Uint8));
-    val.serviceData = decoder.decodeStructPointer(ServiceDataMap);
-    return val;
-  };
-
-  ScanRecord.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(ScanRecord.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.NullableString, val.name);
-    encoder.encodeArrayPointer(new codec.PointerTo(uuid$.UUID), val.uuids);
-    encoder.encodeStructPointer(Appearance, val.appearance);
-    encoder.encodeStructPointer(Power, val.txPower);
-    encoder.encodeMapPointer(codec.Uint8, new codec.ArrayOf(codec.Uint8), val.manufacturerData);
-    encoder.encodeStructPointer(ServiceDataMap, val.serviceData);
-  };
-  function ScanResult(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  ScanResult.prototype.initDefaults_ = function() {
-    this.deviceAddress = null;
-    this.rssi = 0;
-    this.scanRecord = null;
-  };
-  ScanResult.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  ScanResult.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate ScanResult.deviceAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate ScanResult.scanRecord
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, ScanRecord, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  ScanResult.encodedSize = codec.kStructHeaderSize + 24;
-
-  ScanResult.decode = function(decoder) {
-    var packed;
-    var val = new ScanResult();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.deviceAddress = decoder.decodeStruct(codec.String);
-    val.rssi = decoder.decodeStruct(codec.Int8);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.scanRecord = decoder.decodeStructPointer(ScanRecord);
-    return val;
-  };
-
-  ScanResult.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(ScanResult.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.deviceAddress);
-    encoder.encodeStruct(codec.Int8, val.rssi);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStructPointer(ScanRecord, val.scanRecord);
-  };
-  function CharacteristicProperties(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  CharacteristicProperties.prototype.initDefaults_ = function() {
-    this.broadcast = false;
-    this.read = false;
-    this.writeWithoutResponse = false;
-    this.write = false;
-    this.notify = false;
-    this.indicate = false;
-    this.authenticatedSignedWrites = false;
-    this.extendedProperties = false;
-  };
-  CharacteristicProperties.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  CharacteristicProperties.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-
-
-
-
-
-
-    return validator.validationError.NONE;
-  };
-
-  CharacteristicProperties.encodedSize = codec.kStructHeaderSize + 8;
-
-  CharacteristicProperties.decode = function(decoder) {
-    var packed;
-    var val = new CharacteristicProperties();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.broadcast = (packed >> 0) & 1 ? true : false;
-    val.read = (packed >> 1) & 1 ? true : false;
-    val.writeWithoutResponse = (packed >> 2) & 1 ? true : false;
-    val.write = (packed >> 3) & 1 ? true : false;
-    val.notify = (packed >> 4) & 1 ? true : false;
-    val.indicate = (packed >> 5) & 1 ? true : false;
-    val.authenticatedSignedWrites = (packed >> 6) & 1 ? true : false;
-    val.extendedProperties = (packed >> 7) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  CharacteristicProperties.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(CharacteristicProperties.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.broadcast & 1) << 0
-    packed |= (val.read & 1) << 1
-    packed |= (val.writeWithoutResponse & 1) << 2
-    packed |= (val.write & 1) << 3
-    packed |= (val.notify & 1) << 4
-    packed |= (val.indicate & 1) << 5
-    packed |= (val.authenticatedSignedWrites & 1) << 6
-    packed |= (val.extendedProperties & 1) << 7
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeBluetooth_SetLESupported_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_SetLESupported_Params.prototype.initDefaults_ = function() {
-    this.available = false;
-  };
-  FakeBluetooth_SetLESupported_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_SetLESupported_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_SetLESupported_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetooth_SetLESupported_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_SetLESupported_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.available = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeBluetooth_SetLESupported_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_SetLESupported_Params.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.available & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeBluetooth_SetLESupported_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_SetLESupported_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeBluetooth_SetLESupported_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_SetLESupported_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_SetLESupported_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetooth_SetLESupported_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_SetLESupported_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetooth_SetLESupported_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_SetLESupported_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetooth_SimulateCentral_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_SimulateCentral_Params.prototype.initDefaults_ = function() {
-    this.state = 0;
-  };
-  FakeBluetooth_SimulateCentral_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_SimulateCentral_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetooth_SimulateCentral_Params.state
-    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, CentralState);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_SimulateCentral_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetooth_SimulateCentral_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_SimulateCentral_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.state = decoder.decodeStruct(codec.Int32);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeBluetooth_SimulateCentral_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_SimulateCentral_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Int32, val.state);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeBluetooth_SimulateCentral_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_SimulateCentral_ResponseParams.prototype.initDefaults_ = function() {
-    this.fakeCentral = new FakeCentralPtr();
-  };
-  FakeBluetooth_SimulateCentral_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_SimulateCentral_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetooth_SimulateCentral_ResponseParams.fakeCentral
-    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_SimulateCentral_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetooth_SimulateCentral_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_SimulateCentral_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.fakeCentral = decoder.decodeStruct(new codec.Interface(FakeCentralPtr));
-    return val;
-  };
-
-  FakeBluetooth_SimulateCentral_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_SimulateCentral_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(new codec.Interface(FakeCentralPtr), val.fakeCentral);
-  };
-  function FakeBluetooth_AllResponsesConsumed_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_AllResponsesConsumed_Params.prototype.initDefaults_ = function() {
-  };
-  FakeBluetooth_AllResponsesConsumed_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_AllResponsesConsumed_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_AllResponsesConsumed_Params.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetooth_AllResponsesConsumed_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_AllResponsesConsumed_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetooth_AllResponsesConsumed_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_AllResponsesConsumed_Params.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetooth_AllResponsesConsumed_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initDefaults_ = function() {
-    this.consumed = false;
-  };
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetooth_AllResponsesConsumed_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.consumed = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeBluetooth_AllResponsesConsumed_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.consumed & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SimulatePreconnectedPeripheral_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initDefaults_ = function() {
-    this.address = null;
-    this.name = null;
-    this.knownServiceUuids = null;
-  };
-  FakeCentral_SimulatePreconnectedPeripheral_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulatePreconnectedPeripheral_Params.address
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulatePreconnectedPeripheral_Params.name
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulatePreconnectedPeripheral_Params.knownServiceUuids
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(uuid$.UUID), false, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize = codec.kStructHeaderSize + 24;
-
-  FakeCentral_SimulatePreconnectedPeripheral_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulatePreconnectedPeripheral_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.address = decoder.decodeStruct(codec.String);
-    val.name = decoder.decodeStruct(codec.String);
-    val.knownServiceUuids = decoder.decodeArrayPointer(new codec.PointerTo(uuid$.UUID));
-    return val;
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.address);
-    encoder.encodeStruct(codec.String, val.name);
-    encoder.encodeArrayPointer(new codec.PointerTo(uuid$.UUID), val.knownServiceUuids);
-  };
-  function FakeCentral_SimulatePreconnectedPeripheral_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulatePreconnectedPeripheral_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeCentral_SimulateAdvertisementReceived_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateAdvertisementReceived_Params.prototype.initDefaults_ = function() {
-    this.result = null;
-  };
-  FakeCentral_SimulateAdvertisementReceived_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulateAdvertisementReceived_Params.result
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ScanResult, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SimulateAdvertisementReceived_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateAdvertisementReceived_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.result = decoder.decodeStructPointer(ScanResult);
-    return val;
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateAdvertisementReceived_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStructPointer(ScanResult, val.result);
-  };
-  function FakeCentral_SimulateAdvertisementReceived_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateAdvertisementReceived_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeCentral_SimulateAdvertisementReceived_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeCentral_SetNextGATTConnectionResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initDefaults_ = function() {
-    this.address = null;
-    this.code = 0;
-  };
-  FakeCentral_SetNextGATTConnectionResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextGATTConnectionResponse_Params.address
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_SetNextGATTConnectionResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextGATTConnectionResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.address = decoder.decodeStruct(codec.String);
-    val.code = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.address);
-    encoder.encodeStruct(codec.Uint16, val.code);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextGATTConnectionResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextGATTConnectionResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextGATTDiscoveryResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initDefaults_ = function() {
-    this.address = null;
-    this.code = 0;
-  };
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextGATTDiscoveryResponse_Params.address
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextGATTDiscoveryResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.address = decoder.decodeStruct(codec.String);
-    val.code = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.address);
-    encoder.encodeStruct(codec.Uint16, val.code);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SimulateGATTDisconnection_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateGATTDisconnection_Params.prototype.initDefaults_ = function() {
-    this.address = null;
-  };
-  FakeCentral_SimulateGATTDisconnection_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateGATTDisconnection_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulateGATTDisconnection_Params.address
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateGATTDisconnection_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SimulateGATTDisconnection_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateGATTDisconnection_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.address = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SimulateGATTDisconnection_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateGATTDisconnection_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.address);
-  };
-  function FakeCentral_SimulateGATTDisconnection_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateGATTDisconnection_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SimulateGATTDisconnection_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SimulateGATTServicesChanged_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateGATTServicesChanged_Params.prototype.initDefaults_ = function() {
-    this.address = null;
-  };
-  FakeCentral_SimulateGATTServicesChanged_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SimulateGATTServicesChanged_Params.address
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SimulateGATTServicesChanged_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateGATTServicesChanged_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.address = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateGATTServicesChanged_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.address);
-  };
-  function FakeCentral_SimulateGATTServicesChanged_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SimulateGATTServicesChanged_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SimulateGATTServicesChanged_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_AddFakeService_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeService_Params.prototype.initDefaults_ = function() {
-    this.peripheralAddress = null;
-    this.serviceUuid = null;
-  };
-  FakeCentral_AddFakeService_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeService_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeService_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeService_Params.serviceUuid
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, uuid$.UUID, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeService_Params.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_AddFakeService_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeService_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    val.serviceUuid = decoder.decodeStructPointer(uuid$.UUID);
-    return val;
-  };
-
-  FakeCentral_AddFakeService_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeService_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-    encoder.encodeStructPointer(uuid$.UUID, val.serviceUuid);
-  };
-  function FakeCentral_AddFakeService_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeService_ResponseParams.prototype.initDefaults_ = function() {
-    this.serviceId = null;
-  };
-  FakeCentral_AddFakeService_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeService_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeService_ResponseParams.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeService_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_AddFakeService_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeService_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.serviceId = decoder.decodeStruct(codec.NullableString);
-    return val;
-  };
-
-  FakeCentral_AddFakeService_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeService_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.NullableString, val.serviceId);
-  };
-  function FakeCentral_RemoveFakeService_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeService_Params.prototype.initDefaults_ = function() {
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_RemoveFakeService_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeService_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeService_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeService_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeService_Params.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_RemoveFakeService_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeService_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeService_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeService_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_RemoveFakeService_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeService_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_RemoveFakeService_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeService_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeService_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_RemoveFakeService_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeService_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeService_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeService_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_AddFakeCharacteristic_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeCharacteristic_Params.prototype.initDefaults_ = function() {
-    this.characteristicUuid = null;
-    this.properties = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_AddFakeCharacteristic_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeCharacteristic_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeCharacteristic_Params.characteristicUuid
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, uuid$.UUID, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeCharacteristic_Params.properties
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, CharacteristicProperties, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeCharacteristic_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeCharacteristic_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeCharacteristic_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_AddFakeCharacteristic_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeCharacteristic_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.characteristicUuid = decoder.decodeStructPointer(uuid$.UUID);
-    val.properties = decoder.decodeStructPointer(CharacteristicProperties);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_AddFakeCharacteristic_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeCharacteristic_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStructPointer(uuid$.UUID, val.characteristicUuid);
-    encoder.encodeStructPointer(CharacteristicProperties, val.properties);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_AddFakeCharacteristic_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initDefaults_ = function() {
-    this.characteristicId = null;
-  };
-  FakeCentral_AddFakeCharacteristic_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeCharacteristic_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeCharacteristic_ResponseParams.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_AddFakeCharacteristic_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeCharacteristic_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.characteristicId = decoder.decodeStruct(codec.NullableString);
-    return val;
-  };
-
-  FakeCentral_AddFakeCharacteristic_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.NullableString, val.characteristicId);
-  };
-  function FakeCentral_RemoveFakeCharacteristic_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeCharacteristic_Params.prototype.initDefaults_ = function() {
-    this.identifier = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_RemoveFakeCharacteristic_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeCharacteristic_Params.identifier
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeCharacteristic_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeCharacteristic_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_Params.encodedSize = codec.kStructHeaderSize + 24;
-
-  FakeCentral_RemoveFakeCharacteristic_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeCharacteristic_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.identifier = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeCharacteristic_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.identifier);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_RemoveFakeCharacteristic_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeCharacteristic_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeCharacteristic_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_AddFakeDescriptor_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeDescriptor_Params.prototype.initDefaults_ = function() {
-    this.descriptorUuid = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_AddFakeDescriptor_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeDescriptor_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeDescriptor_Params.descriptorUuid
-    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, uuid$.UUID, false);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeDescriptor_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeDescriptor_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeDescriptor_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeDescriptor_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_AddFakeDescriptor_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeDescriptor_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.descriptorUuid = decoder.decodeStructPointer(uuid$.UUID);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_AddFakeDescriptor_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeDescriptor_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStructPointer(uuid$.UUID, val.descriptorUuid);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_AddFakeDescriptor_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initDefaults_ = function() {
-    this.descriptorId = null;
-  };
-  FakeCentral_AddFakeDescriptor_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_AddFakeDescriptor_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_AddFakeDescriptor_ResponseParams.descriptorId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_AddFakeDescriptor_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_AddFakeDescriptor_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.descriptorId = decoder.decodeStruct(codec.NullableString);
-    return val;
-  };
-
-  FakeCentral_AddFakeDescriptor_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.NullableString, val.descriptorId);
-  };
-  function FakeCentral_RemoveFakeDescriptor_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeDescriptor_Params.prototype.initDefaults_ = function() {
-    this.descriptorId = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_RemoveFakeDescriptor_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeDescriptor_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeDescriptor_Params.descriptorId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeDescriptor_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeDescriptor_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_RemoveFakeDescriptor_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeDescriptor_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_RemoveFakeDescriptor_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeDescriptor_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.descriptorId = decoder.decodeStruct(codec.String);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeDescriptor_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeDescriptor_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.descriptorId);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_RemoveFakeDescriptor_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_RemoveFakeDescriptor_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_RemoveFakeDescriptor_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextReadCharacteristicResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.value = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextReadCharacteristicResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 48}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextReadCharacteristicResponse_Params.value
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadCharacteristicResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadCharacteristicResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadCharacteristicResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize = codec.kStructHeaderSize + 40;
-
-  FakeCentral_SetNextReadCharacteristicResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextReadCharacteristicResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.value = decoder.decodeArrayPointer(codec.Uint8);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeArrayPointer(codec.Uint8, val.value);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextReadCharacteristicResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextReadCharacteristicResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextWriteCharacteristicResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextWriteCharacteristicResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextWriteCharacteristicResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextSubscribeToNotificationsResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextSubscribeToNotificationsResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextSubscribeToNotificationsResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_IsNotifying_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_IsNotifying_Params.prototype.initDefaults_ = function() {
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_IsNotifying_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_IsNotifying_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_IsNotifying_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_IsNotifying_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_IsNotifying_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_IsNotifying_Params.encodedSize = codec.kStructHeaderSize + 24;
-
-  FakeCentral_IsNotifying_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_IsNotifying_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_IsNotifying_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_IsNotifying_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_IsNotifying_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_IsNotifying_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-    this.isNotifying = false;
-  };
-  FakeCentral_IsNotifying_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_IsNotifying_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_IsNotifying_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_IsNotifying_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_IsNotifying_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    val.isNotifying = (packed >> 1) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_IsNotifying_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_IsNotifying_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    packed |= (val.isNotifying & 1) << 1
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_GetLastWrittenCharacteristicValue_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initDefaults_ = function() {
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenCharacteristicValue_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize = codec.kStructHeaderSize + 24;
-
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_GetLastWrittenCharacteristicValue_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-    this.value = null;
-  };
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.value
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.value = decoder.decodeArrayPointer(codec.Uint8);
-    return val;
-  };
-
-  FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeArrayPointer(codec.Uint8, val.value);
-  };
-  function FakeCentral_SetNextReadDescriptorResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.value = null;
-    this.descriptorId = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextReadDescriptorResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 56}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextReadDescriptorResponse_Params.value
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadDescriptorResponse_Params.descriptorId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadDescriptorResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadDescriptorResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextReadDescriptorResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 40, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize = codec.kStructHeaderSize + 48;
-
-  FakeCentral_SetNextReadDescriptorResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextReadDescriptorResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.value = decoder.decodeArrayPointer(codec.Uint8);
-    val.descriptorId = decoder.decodeStruct(codec.String);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeArrayPointer(codec.Uint8, val.value);
-    encoder.encodeStruct(codec.String, val.descriptorId);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextReadDescriptorResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextReadDescriptorResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_SetNextWriteDescriptorResponse_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initDefaults_ = function() {
-    this.gattCode = 0;
-    this.descriptorId = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_SetNextWriteDescriptorResponse_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 48}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_SetNextWriteDescriptorResponse_Params.descriptorId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextWriteDescriptorResponse_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextWriteDescriptorResponse_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_SetNextWriteDescriptorResponse_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize = codec.kStructHeaderSize + 40;
-
-  FakeCentral_SetNextWriteDescriptorResponse_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextWriteDescriptorResponse_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.gattCode = decoder.decodeStruct(codec.Uint16);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.descriptorId = decoder.decodeStruct(codec.String);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint16, val.gattCode);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStruct(codec.String, val.descriptorId);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_SetNextWriteDescriptorResponse_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-  };
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_SetNextWriteDescriptorResponse_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeCentral_GetLastWrittenDescriptorValue_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initDefaults_ = function() {
-    this.descriptorId = null;
-    this.characteristicId = null;
-    this.serviceId = null;
-    this.peripheralAddress = null;
-  };
-  FakeCentral_GetLastWrittenDescriptorValue_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 40}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenDescriptorValue_Params.descriptorId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenDescriptorValue_Params.characteristicId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenDescriptorValue_Params.serviceId
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeCentral_GetLastWrittenDescriptorValue_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize = codec.kStructHeaderSize + 32;
-
-  FakeCentral_GetLastWrittenDescriptorValue_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_GetLastWrittenDescriptorValue_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.descriptorId = decoder.decodeStruct(codec.String);
-    val.characteristicId = decoder.decodeStruct(codec.String);
-    val.serviceId = decoder.decodeStruct(codec.String);
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.descriptorId);
-    encoder.encodeStruct(codec.String, val.characteristicId);
-    encoder.encodeStruct(codec.String, val.serviceId);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeCentral_GetLastWrittenDescriptorValue_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initDefaults_ = function() {
-    this.success = false;
-    this.value = null;
-  };
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 24}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-
-    // validate FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.value
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, true, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize = codec.kStructHeaderSize + 16;
-
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeCentral_GetLastWrittenDescriptorValue_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    packed = decoder.readUint8();
-    val.success = (packed >> 0) & 1 ? true : false;
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.value = decoder.decodeArrayPointer(codec.Uint8);
-    return val;
-  };
-
-  FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    packed = 0;
-    packed |= (val.success & 1) << 0
-    encoder.writeUint8(packed);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeArrayPointer(codec.Uint8, val.value);
-  };
-  var kFakeBluetooth_SetLESupported_Name = 0;
-  var kFakeBluetooth_SimulateCentral_Name = 1;
-  var kFakeBluetooth_AllResponsesConsumed_Name = 2;
-
-  function FakeBluetoothPtr(handleOrPtrInfo) {
-    this.ptr = new bindings.InterfacePtrController(FakeBluetooth,
-                                                   handleOrPtrInfo);
-  }
-
-  function FakeBluetoothAssociatedPtr(associatedInterfacePtrInfo) {
-    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
-        FakeBluetooth, associatedInterfacePtrInfo);
-  }
-
-  FakeBluetoothAssociatedPtr.prototype =
-      Object.create(FakeBluetoothPtr.prototype);
-  FakeBluetoothAssociatedPtr.prototype.constructor =
-      FakeBluetoothAssociatedPtr;
-
-  function FakeBluetoothProxy(receiver) {
-    this.receiver_ = receiver;
-  }
-  FakeBluetoothPtr.prototype.setLESupported = function() {
-    return FakeBluetoothProxy.prototype.setLESupported
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothProxy.prototype.setLESupported = function(available) {
-    var params = new FakeBluetooth_SetLESupported_Params();
-    params.available = available;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetooth_SetLESupported_Name,
-          codec.align(FakeBluetooth_SetLESupported_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetooth_SetLESupported_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetooth_SetLESupported_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeBluetoothPtr.prototype.simulateCentral = function() {
-    return FakeBluetoothProxy.prototype.simulateCentral
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothProxy.prototype.simulateCentral = function(state) {
-    var params = new FakeBluetooth_SimulateCentral_Params();
-    params.state = state;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetooth_SimulateCentral_Name,
-          codec.align(FakeBluetooth_SimulateCentral_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetooth_SimulateCentral_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetooth_SimulateCentral_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeBluetoothPtr.prototype.allResponsesConsumed = function() {
-    return FakeBluetoothProxy.prototype.allResponsesConsumed
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothProxy.prototype.allResponsesConsumed = function() {
-    var params = new FakeBluetooth_AllResponsesConsumed_Params();
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetooth_AllResponsesConsumed_Name,
-          codec.align(FakeBluetooth_AllResponsesConsumed_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetooth_AllResponsesConsumed_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetooth_AllResponsesConsumed_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-
-  function FakeBluetoothStub(delegate) {
-    this.delegate_ = delegate;
-  }
-  FakeBluetoothStub.prototype.setLESupported = function(available) {
-    return this.delegate_ && this.delegate_.setLESupported && this.delegate_.setLESupported(available);
-  }
-  FakeBluetoothStub.prototype.simulateCentral = function(state) {
-    return this.delegate_ && this.delegate_.simulateCentral && this.delegate_.simulateCentral(state);
-  }
-  FakeBluetoothStub.prototype.allResponsesConsumed = function() {
-    return this.delegate_ && this.delegate_.allResponsesConsumed && this.delegate_.allResponsesConsumed();
-  }
-
-  FakeBluetoothStub.prototype.accept = function(message) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    default:
-      return false;
-    }
-  };
-
-  FakeBluetoothStub.prototype.acceptWithResponder =
-      function(message, responder) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    case kFakeBluetooth_SetLESupported_Name:
-      var params = reader.decodeStruct(FakeBluetooth_SetLESupported_Params);
-      this.setLESupported(params.available).then(function(response) {
-        var responseParams =
-            new FakeBluetooth_SetLESupported_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetooth_SetLESupported_Name,
-            codec.align(FakeBluetooth_SetLESupported_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetooth_SetLESupported_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeBluetooth_SimulateCentral_Name:
-      var params = reader.decodeStruct(FakeBluetooth_SimulateCentral_Params);
-      this.simulateCentral(params.state).then(function(response) {
-        var responseParams =
-            new FakeBluetooth_SimulateCentral_ResponseParams();
-        responseParams.fakeCentral = response.fakeCentral;
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetooth_SimulateCentral_Name,
-            codec.align(FakeBluetooth_SimulateCentral_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetooth_SimulateCentral_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeBluetooth_AllResponsesConsumed_Name:
-      var params = reader.decodeStruct(FakeBluetooth_AllResponsesConsumed_Params);
-      this.allResponsesConsumed().then(function(response) {
-        var responseParams =
-            new FakeBluetooth_AllResponsesConsumed_ResponseParams();
-        responseParams.consumed = response.consumed;
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetooth_AllResponsesConsumed_Name,
-            codec.align(FakeBluetooth_AllResponsesConsumed_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetooth_AllResponsesConsumed_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    default:
-      return false;
-    }
-  };
-
-  function validateFakeBluetoothRequest(messageValidator) {
-    var message = messageValidator.message;
-    var paramsClass = null;
-    switch (message.getName()) {
-      case kFakeBluetooth_SetLESupported_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetooth_SetLESupported_Params;
-      break;
-      case kFakeBluetooth_SimulateCentral_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetooth_SimulateCentral_Params;
-      break;
-      case kFakeBluetooth_AllResponsesConsumed_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetooth_AllResponsesConsumed_Params;
-      break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  function validateFakeBluetoothResponse(messageValidator) {
-   var message = messageValidator.message;
-   var paramsClass = null;
-   switch (message.getName()) {
-      case kFakeBluetooth_SetLESupported_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetooth_SetLESupported_ResponseParams;
-        break;
-      case kFakeBluetooth_SimulateCentral_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetooth_SimulateCentral_ResponseParams;
-        break;
-      case kFakeBluetooth_AllResponsesConsumed_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetooth_AllResponsesConsumed_ResponseParams;
-        break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  var FakeBluetooth = {
-    name: 'bluetooth.mojom.FakeBluetooth',
-    kVersion: 0,
-    ptrClass: FakeBluetoothPtr,
-    proxyClass: FakeBluetoothProxy,
-    stubClass: FakeBluetoothStub,
-    validateRequest: validateFakeBluetoothRequest,
-    validateResponse: validateFakeBluetoothResponse,
-  };
-  FakeBluetoothStub.prototype.validator = validateFakeBluetoothRequest;
-  FakeBluetoothProxy.prototype.validator = validateFakeBluetoothResponse;
-  var kFakeCentral_SimulatePreconnectedPeripheral_Name = 0;
-  var kFakeCentral_SimulateAdvertisementReceived_Name = 1;
-  var kFakeCentral_SetNextGATTConnectionResponse_Name = 2;
-  var kFakeCentral_SetNextGATTDiscoveryResponse_Name = 3;
-  var kFakeCentral_SimulateGATTDisconnection_Name = 4;
-  var kFakeCentral_SimulateGATTServicesChanged_Name = 5;
-  var kFakeCentral_AddFakeService_Name = 6;
-  var kFakeCentral_RemoveFakeService_Name = 7;
-  var kFakeCentral_AddFakeCharacteristic_Name = 8;
-  var kFakeCentral_RemoveFakeCharacteristic_Name = 9;
-  var kFakeCentral_AddFakeDescriptor_Name = 10;
-  var kFakeCentral_RemoveFakeDescriptor_Name = 11;
-  var kFakeCentral_SetNextReadCharacteristicResponse_Name = 12;
-  var kFakeCentral_SetNextWriteCharacteristicResponse_Name = 13;
-  var kFakeCentral_SetNextSubscribeToNotificationsResponse_Name = 14;
-  var kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name = 15;
-  var kFakeCentral_IsNotifying_Name = 16;
-  var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 17;
-  var kFakeCentral_SetNextReadDescriptorResponse_Name = 18;
-  var kFakeCentral_SetNextWriteDescriptorResponse_Name = 19;
-  var kFakeCentral_GetLastWrittenDescriptorValue_Name = 20;
-
-  function FakeCentralPtr(handleOrPtrInfo) {
-    this.ptr = new bindings.InterfacePtrController(FakeCentral,
-                                                   handleOrPtrInfo);
-  }
-
-  function FakeCentralAssociatedPtr(associatedInterfacePtrInfo) {
-    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
-        FakeCentral, associatedInterfacePtrInfo);
-  }
-
-  FakeCentralAssociatedPtr.prototype =
-      Object.create(FakeCentralPtr.prototype);
-  FakeCentralAssociatedPtr.prototype.constructor =
-      FakeCentralAssociatedPtr;
-
-  function FakeCentralProxy(receiver) {
-    this.receiver_ = receiver;
-  }
-  FakeCentralPtr.prototype.simulatePreconnectedPeripheral = function() {
-    return FakeCentralProxy.prototype.simulatePreconnectedPeripheral
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.simulatePreconnectedPeripheral = function(address, name, knownServiceUuids) {
-    var params = new FakeCentral_SimulatePreconnectedPeripheral_Params();
-    params.address = address;
-    params.name = name;
-    params.knownServiceUuids = knownServiceUuids;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SimulatePreconnectedPeripheral_Name,
-          codec.align(FakeCentral_SimulatePreconnectedPeripheral_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SimulatePreconnectedPeripheral_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.simulateAdvertisementReceived = function() {
-    return FakeCentralProxy.prototype.simulateAdvertisementReceived
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.simulateAdvertisementReceived = function(result) {
-    var params = new FakeCentral_SimulateAdvertisementReceived_Params();
-    params.result = result;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SimulateAdvertisementReceived_Name,
-          codec.align(FakeCentral_SimulateAdvertisementReceived_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SimulateAdvertisementReceived_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SimulateAdvertisementReceived_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextGATTConnectionResponse = function() {
-    return FakeCentralProxy.prototype.setNextGATTConnectionResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextGATTConnectionResponse = function(address, code) {
-    var params = new FakeCentral_SetNextGATTConnectionResponse_Params();
-    params.address = address;
-    params.code = code;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextGATTConnectionResponse_Name,
-          codec.align(FakeCentral_SetNextGATTConnectionResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextGATTConnectionResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextGATTConnectionResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextGATTDiscoveryResponse = function() {
-    return FakeCentralProxy.prototype.setNextGATTDiscoveryResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextGATTDiscoveryResponse = function(address, code) {
-    var params = new FakeCentral_SetNextGATTDiscoveryResponse_Params();
-    params.address = address;
-    params.code = code;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextGATTDiscoveryResponse_Name,
-          codec.align(FakeCentral_SetNextGATTDiscoveryResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.simulateGATTDisconnection = function() {
-    return FakeCentralProxy.prototype.simulateGATTDisconnection
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.simulateGATTDisconnection = function(address) {
-    var params = new FakeCentral_SimulateGATTDisconnection_Params();
-    params.address = address;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SimulateGATTDisconnection_Name,
-          codec.align(FakeCentral_SimulateGATTDisconnection_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SimulateGATTDisconnection_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SimulateGATTDisconnection_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.simulateGATTServicesChanged = function() {
-    return FakeCentralProxy.prototype.simulateGATTServicesChanged
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.simulateGATTServicesChanged = function(address) {
-    var params = new FakeCentral_SimulateGATTServicesChanged_Params();
-    params.address = address;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SimulateGATTServicesChanged_Name,
-          codec.align(FakeCentral_SimulateGATTServicesChanged_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SimulateGATTServicesChanged_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SimulateGATTServicesChanged_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.addFakeService = function() {
-    return FakeCentralProxy.prototype.addFakeService
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.addFakeService = function(peripheralAddress, serviceUuid) {
-    var params = new FakeCentral_AddFakeService_Params();
-    params.peripheralAddress = peripheralAddress;
-    params.serviceUuid = serviceUuid;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_AddFakeService_Name,
-          codec.align(FakeCentral_AddFakeService_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_AddFakeService_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_AddFakeService_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.removeFakeService = function() {
-    return FakeCentralProxy.prototype.removeFakeService
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.removeFakeService = function(serviceId, peripheralAddress) {
-    var params = new FakeCentral_RemoveFakeService_Params();
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_RemoveFakeService_Name,
-          codec.align(FakeCentral_RemoveFakeService_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_RemoveFakeService_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_RemoveFakeService_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.addFakeCharacteristic = function() {
-    return FakeCentralProxy.prototype.addFakeCharacteristic
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.addFakeCharacteristic = function(characteristicUuid, properties, serviceId, peripheralAddress) {
-    var params = new FakeCentral_AddFakeCharacteristic_Params();
-    params.characteristicUuid = characteristicUuid;
-    params.properties = properties;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_AddFakeCharacteristic_Name,
-          codec.align(FakeCentral_AddFakeCharacteristic_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_AddFakeCharacteristic_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_AddFakeCharacteristic_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.removeFakeCharacteristic = function() {
-    return FakeCentralProxy.prototype.removeFakeCharacteristic
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.removeFakeCharacteristic = function(identifier, serviceId, peripheralAddress) {
-    var params = new FakeCentral_RemoveFakeCharacteristic_Params();
-    params.identifier = identifier;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_RemoveFakeCharacteristic_Name,
-          codec.align(FakeCentral_RemoveFakeCharacteristic_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_RemoveFakeCharacteristic_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_RemoveFakeCharacteristic_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.addFakeDescriptor = function() {
-    return FakeCentralProxy.prototype.addFakeDescriptor
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.addFakeDescriptor = function(descriptorUuid, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_AddFakeDescriptor_Params();
-    params.descriptorUuid = descriptorUuid;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_AddFakeDescriptor_Name,
-          codec.align(FakeCentral_AddFakeDescriptor_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_AddFakeDescriptor_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_AddFakeDescriptor_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.removeFakeDescriptor = function() {
-    return FakeCentralProxy.prototype.removeFakeDescriptor
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.removeFakeDescriptor = function(descriptorId, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_RemoveFakeDescriptor_Params();
-    params.descriptorId = descriptorId;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_RemoveFakeDescriptor_Name,
-          codec.align(FakeCentral_RemoveFakeDescriptor_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_RemoveFakeDescriptor_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_RemoveFakeDescriptor_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextReadCharacteristicResponse = function() {
-    return FakeCentralProxy.prototype.setNextReadCharacteristicResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextReadCharacteristicResponse = function(gattCode, value, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextReadCharacteristicResponse_Params();
-    params.gattCode = gattCode;
-    params.value = value;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextReadCharacteristicResponse_Name,
-          codec.align(FakeCentral_SetNextReadCharacteristicResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextReadCharacteristicResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextWriteCharacteristicResponse = function() {
-    return FakeCentralProxy.prototype.setNextWriteCharacteristicResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextWriteCharacteristicResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextWriteCharacteristicResponse_Params();
-    params.gattCode = gattCode;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextWriteCharacteristicResponse_Name,
-          codec.align(FakeCentral_SetNextWriteCharacteristicResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextSubscribeToNotificationsResponse = function() {
-    return FakeCentralProxy.prototype.setNextSubscribeToNotificationsResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextSubscribeToNotificationsResponse_Params();
-    params.gattCode = gattCode;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextSubscribeToNotificationsResponse_Name,
-          codec.align(FakeCentral_SetNextSubscribeToNotificationsResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextUnsubscribeFromNotificationsResponse = function() {
-    return FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params();
-    params.gattCode = gattCode;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name,
-          codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.isNotifying = function() {
-    return FakeCentralProxy.prototype.isNotifying
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_IsNotifying_Params();
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_IsNotifying_Name,
-          codec.align(FakeCentral_IsNotifying_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_IsNotifying_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_IsNotifying_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.getLastWrittenCharacteristicValue = function() {
-    return FakeCentralProxy.prototype.getLastWrittenCharacteristicValue
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_GetLastWrittenCharacteristicValue_Params();
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_GetLastWrittenCharacteristicValue_Name,
-          codec.align(FakeCentral_GetLastWrittenCharacteristicValue_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextReadDescriptorResponse = function() {
-    return FakeCentralProxy.prototype.setNextReadDescriptorResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextReadDescriptorResponse = function(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextReadDescriptorResponse_Params();
-    params.gattCode = gattCode;
-    params.value = value;
-    params.descriptorId = descriptorId;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextReadDescriptorResponse_Name,
-          codec.align(FakeCentral_SetNextReadDescriptorResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextReadDescriptorResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextReadDescriptorResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.setNextWriteDescriptorResponse = function() {
-    return FakeCentralProxy.prototype.setNextWriteDescriptorResponse
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.setNextWriteDescriptorResponse = function(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_SetNextWriteDescriptorResponse_Params();
-    params.gattCode = gattCode;
-    params.descriptorId = descriptorId;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_SetNextWriteDescriptorResponse_Name,
-          codec.align(FakeCentral_SetNextWriteDescriptorResponse_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_SetNextWriteDescriptorResponse_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeCentralPtr.prototype.getLastWrittenDescriptorValue = function() {
-    return FakeCentralProxy.prototype.getLastWrittenDescriptorValue
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeCentralProxy.prototype.getLastWrittenDescriptorValue = function(descriptorId, characteristicId, serviceId, peripheralAddress) {
-    var params = new FakeCentral_GetLastWrittenDescriptorValue_Params();
-    params.descriptorId = descriptorId;
-    params.characteristicId = characteristicId;
-    params.serviceId = serviceId;
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeCentral_GetLastWrittenDescriptorValue_Name,
-          codec.align(FakeCentral_GetLastWrittenDescriptorValue_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeCentral_GetLastWrittenDescriptorValue_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-
-  function FakeCentralStub(delegate) {
-    this.delegate_ = delegate;
-  }
-  FakeCentralStub.prototype.simulatePreconnectedPeripheral = function(address, name, knownServiceUuids) {
-    return this.delegate_ && this.delegate_.simulatePreconnectedPeripheral && this.delegate_.simulatePreconnectedPeripheral(address, name, knownServiceUuids);
-  }
-  FakeCentralStub.prototype.simulateAdvertisementReceived = function(result) {
-    return this.delegate_ && this.delegate_.simulateAdvertisementReceived && this.delegate_.simulateAdvertisementReceived(result);
-  }
-  FakeCentralStub.prototype.setNextGATTConnectionResponse = function(address, code) {
-    return this.delegate_ && this.delegate_.setNextGATTConnectionResponse && this.delegate_.setNextGATTConnectionResponse(address, code);
-  }
-  FakeCentralStub.prototype.setNextGATTDiscoveryResponse = function(address, code) {
-    return this.delegate_ && this.delegate_.setNextGATTDiscoveryResponse && this.delegate_.setNextGATTDiscoveryResponse(address, code);
-  }
-  FakeCentralStub.prototype.simulateGATTDisconnection = function(address) {
-    return this.delegate_ && this.delegate_.simulateGATTDisconnection && this.delegate_.simulateGATTDisconnection(address);
-  }
-  FakeCentralStub.prototype.simulateGATTServicesChanged = function(address) {
-    return this.delegate_ && this.delegate_.simulateGATTServicesChanged && this.delegate_.simulateGATTServicesChanged(address);
-  }
-  FakeCentralStub.prototype.addFakeService = function(peripheralAddress, serviceUuid) {
-    return this.delegate_ && this.delegate_.addFakeService && this.delegate_.addFakeService(peripheralAddress, serviceUuid);
-  }
-  FakeCentralStub.prototype.removeFakeService = function(serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.removeFakeService && this.delegate_.removeFakeService(serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.addFakeCharacteristic = function(characteristicUuid, properties, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.addFakeCharacteristic && this.delegate_.addFakeCharacteristic(characteristicUuid, properties, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.removeFakeCharacteristic = function(identifier, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.removeFakeCharacteristic && this.delegate_.removeFakeCharacteristic(identifier, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.addFakeDescriptor = function(descriptorUuid, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.addFakeDescriptor && this.delegate_.addFakeDescriptor(descriptorUuid, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.removeFakeDescriptor = function(descriptorId, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.removeFakeDescriptor && this.delegate_.removeFakeDescriptor(descriptorId, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextReadCharacteristicResponse = function(gattCode, value, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextReadCharacteristicResponse && this.delegate_.setNextReadCharacteristicResponse(gattCode, value, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextWriteCharacteristicResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextWriteCharacteristicResponse && this.delegate_.setNextWriteCharacteristicResponse(gattCode, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextSubscribeToNotificationsResponse && this.delegate_.setNextSubscribeToNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextUnsubscribeFromNotificationsResponse && this.delegate_.setNextUnsubscribeFromNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.isNotifying && this.delegate_.isNotifying(characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.getLastWrittenCharacteristicValue && this.delegate_.getLastWrittenCharacteristicValue(characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextReadDescriptorResponse = function(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextReadDescriptorResponse && this.delegate_.setNextReadDescriptorResponse(gattCode, value, descriptorId, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.setNextWriteDescriptorResponse = function(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.setNextWriteDescriptorResponse && this.delegate_.setNextWriteDescriptorResponse(gattCode, descriptorId, characteristicId, serviceId, peripheralAddress);
-  }
-  FakeCentralStub.prototype.getLastWrittenDescriptorValue = function(descriptorId, characteristicId, serviceId, peripheralAddress) {
-    return this.delegate_ && this.delegate_.getLastWrittenDescriptorValue && this.delegate_.getLastWrittenDescriptorValue(descriptorId, characteristicId, serviceId, peripheralAddress);
-  }
-
-  FakeCentralStub.prototype.accept = function(message) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    default:
-      return false;
-    }
-  };
-
-  FakeCentralStub.prototype.acceptWithResponder =
-      function(message, responder) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    case kFakeCentral_SimulatePreconnectedPeripheral_Name:
-      var params = reader.decodeStruct(FakeCentral_SimulatePreconnectedPeripheral_Params);
-      this.simulatePreconnectedPeripheral(params.address, params.name, params.knownServiceUuids).then(function(response) {
-        var responseParams =
-            new FakeCentral_SimulatePreconnectedPeripheral_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SimulatePreconnectedPeripheral_Name,
-            codec.align(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SimulatePreconnectedPeripheral_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SimulateAdvertisementReceived_Name:
-      var params = reader.decodeStruct(FakeCentral_SimulateAdvertisementReceived_Params);
-      this.simulateAdvertisementReceived(params.result).then(function(response) {
-        var responseParams =
-            new FakeCentral_SimulateAdvertisementReceived_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SimulateAdvertisementReceived_Name,
-            codec.align(FakeCentral_SimulateAdvertisementReceived_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SimulateAdvertisementReceived_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextGATTConnectionResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextGATTConnectionResponse_Params);
-      this.setNextGATTConnectionResponse(params.address, params.code).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextGATTConnectionResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextGATTConnectionResponse_Name,
-            codec.align(FakeCentral_SetNextGATTConnectionResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextGATTConnectionResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextGATTDiscoveryResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_Params);
-      this.setNextGATTDiscoveryResponse(params.address, params.code).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextGATTDiscoveryResponse_Name,
-            codec.align(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SimulateGATTDisconnection_Name:
-      var params = reader.decodeStruct(FakeCentral_SimulateGATTDisconnection_Params);
-      this.simulateGATTDisconnection(params.address).then(function(response) {
-        var responseParams =
-            new FakeCentral_SimulateGATTDisconnection_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SimulateGATTDisconnection_Name,
-            codec.align(FakeCentral_SimulateGATTDisconnection_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SimulateGATTDisconnection_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SimulateGATTServicesChanged_Name:
-      var params = reader.decodeStruct(FakeCentral_SimulateGATTServicesChanged_Params);
-      this.simulateGATTServicesChanged(params.address).then(function(response) {
-        var responseParams =
-            new FakeCentral_SimulateGATTServicesChanged_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SimulateGATTServicesChanged_Name,
-            codec.align(FakeCentral_SimulateGATTServicesChanged_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SimulateGATTServicesChanged_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_AddFakeService_Name:
-      var params = reader.decodeStruct(FakeCentral_AddFakeService_Params);
-      this.addFakeService(params.peripheralAddress, params.serviceUuid).then(function(response) {
-        var responseParams =
-            new FakeCentral_AddFakeService_ResponseParams();
-        responseParams.serviceId = response.serviceId;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_AddFakeService_Name,
-            codec.align(FakeCentral_AddFakeService_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_AddFakeService_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_RemoveFakeService_Name:
-      var params = reader.decodeStruct(FakeCentral_RemoveFakeService_Params);
-      this.removeFakeService(params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_RemoveFakeService_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_RemoveFakeService_Name,
-            codec.align(FakeCentral_RemoveFakeService_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_RemoveFakeService_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_AddFakeCharacteristic_Name:
-      var params = reader.decodeStruct(FakeCentral_AddFakeCharacteristic_Params);
-      this.addFakeCharacteristic(params.characteristicUuid, params.properties, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_AddFakeCharacteristic_ResponseParams();
-        responseParams.characteristicId = response.characteristicId;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_AddFakeCharacteristic_Name,
-            codec.align(FakeCentral_AddFakeCharacteristic_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_AddFakeCharacteristic_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_RemoveFakeCharacteristic_Name:
-      var params = reader.decodeStruct(FakeCentral_RemoveFakeCharacteristic_Params);
-      this.removeFakeCharacteristic(params.identifier, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_RemoveFakeCharacteristic_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_RemoveFakeCharacteristic_Name,
-            codec.align(FakeCentral_RemoveFakeCharacteristic_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_RemoveFakeCharacteristic_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_AddFakeDescriptor_Name:
-      var params = reader.decodeStruct(FakeCentral_AddFakeDescriptor_Params);
-      this.addFakeDescriptor(params.descriptorUuid, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_AddFakeDescriptor_ResponseParams();
-        responseParams.descriptorId = response.descriptorId;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_AddFakeDescriptor_Name,
-            codec.align(FakeCentral_AddFakeDescriptor_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_AddFakeDescriptor_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_RemoveFakeDescriptor_Name:
-      var params = reader.decodeStruct(FakeCentral_RemoveFakeDescriptor_Params);
-      this.removeFakeDescriptor(params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_RemoveFakeDescriptor_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_RemoveFakeDescriptor_Name,
-            codec.align(FakeCentral_RemoveFakeDescriptor_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_RemoveFakeDescriptor_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextReadCharacteristicResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextReadCharacteristicResponse_Params);
-      this.setNextReadCharacteristicResponse(params.gattCode, params.value, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextReadCharacteristicResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextReadCharacteristicResponse_Name,
-            codec.align(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextReadCharacteristicResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextWriteCharacteristicResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_Params);
-      this.setNextWriteCharacteristicResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextWriteCharacteristicResponse_Name,
-            codec.align(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_Params);
-      this.setNextSubscribeToNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextSubscribeToNotificationsResponse_Name,
-            codec.align(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params);
-      this.setNextUnsubscribeFromNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name,
-            codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_IsNotifying_Name:
-      var params = reader.decodeStruct(FakeCentral_IsNotifying_Params);
-      this.isNotifying(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_IsNotifying_ResponseParams();
-        responseParams.success = response.success;
-        responseParams.isNotifying = response.isNotifying;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_IsNotifying_Name,
-            codec.align(FakeCentral_IsNotifying_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_IsNotifying_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
-      var params = reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params);
-      this.getLastWrittenCharacteristicValue(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams();
-        responseParams.success = response.success;
-        responseParams.value = response.value;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_GetLastWrittenCharacteristicValue_Name,
-            codec.align(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextReadDescriptorResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextReadDescriptorResponse_Params);
-      this.setNextReadDescriptorResponse(params.gattCode, params.value, params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextReadDescriptorResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextReadDescriptorResponse_Name,
-            codec.align(FakeCentral_SetNextReadDescriptorResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextReadDescriptorResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_SetNextWriteDescriptorResponse_Name:
-      var params = reader.decodeStruct(FakeCentral_SetNextWriteDescriptorResponse_Params);
-      this.setNextWriteDescriptorResponse(params.gattCode, params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_SetNextWriteDescriptorResponse_ResponseParams();
-        responseParams.success = response.success;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_SetNextWriteDescriptorResponse_Name,
-            codec.align(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_SetNextWriteDescriptorResponse_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeCentral_GetLastWrittenDescriptorValue_Name:
-      var params = reader.decodeStruct(FakeCentral_GetLastWrittenDescriptorValue_Params);
-      this.getLastWrittenDescriptorValue(params.descriptorId, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeCentral_GetLastWrittenDescriptorValue_ResponseParams();
-        responseParams.success = response.success;
-        responseParams.value = response.value;
-        var builder = new codec.MessageV1Builder(
-            kFakeCentral_GetLastWrittenDescriptorValue_Name,
-            codec.align(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeCentral_GetLastWrittenDescriptorValue_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    default:
-      return false;
-    }
-  };
-
-  function validateFakeCentralRequest(messageValidator) {
-    var message = messageValidator.message;
-    var paramsClass = null;
-    switch (message.getName()) {
-      case kFakeCentral_SimulatePreconnectedPeripheral_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SimulatePreconnectedPeripheral_Params;
-      break;
-      case kFakeCentral_SimulateAdvertisementReceived_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SimulateAdvertisementReceived_Params;
-      break;
-      case kFakeCentral_SetNextGATTConnectionResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextGATTConnectionResponse_Params;
-      break;
-      case kFakeCentral_SetNextGATTDiscoveryResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextGATTDiscoveryResponse_Params;
-      break;
-      case kFakeCentral_SimulateGATTDisconnection_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SimulateGATTDisconnection_Params;
-      break;
-      case kFakeCentral_SimulateGATTServicesChanged_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SimulateGATTServicesChanged_Params;
-      break;
-      case kFakeCentral_AddFakeService_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_AddFakeService_Params;
-      break;
-      case kFakeCentral_RemoveFakeService_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_RemoveFakeService_Params;
-      break;
-      case kFakeCentral_AddFakeCharacteristic_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_AddFakeCharacteristic_Params;
-      break;
-      case kFakeCentral_RemoveFakeCharacteristic_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_RemoveFakeCharacteristic_Params;
-      break;
-      case kFakeCentral_AddFakeDescriptor_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_AddFakeDescriptor_Params;
-      break;
-      case kFakeCentral_RemoveFakeDescriptor_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_RemoveFakeDescriptor_Params;
-      break;
-      case kFakeCentral_SetNextReadCharacteristicResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextReadCharacteristicResponse_Params;
-      break;
-      case kFakeCentral_SetNextWriteCharacteristicResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextWriteCharacteristicResponse_Params;
-      break;
-      case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_Params;
-      break;
-      case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params;
-      break;
-      case kFakeCentral_IsNotifying_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_IsNotifying_Params;
-      break;
-      case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_Params;
-      break;
-      case kFakeCentral_SetNextReadDescriptorResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextReadDescriptorResponse_Params;
-      break;
-      case kFakeCentral_SetNextWriteDescriptorResponse_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_SetNextWriteDescriptorResponse_Params;
-      break;
-      case kFakeCentral_GetLastWrittenDescriptorValue_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeCentral_GetLastWrittenDescriptorValue_Params;
-      break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  function validateFakeCentralResponse(messageValidator) {
-   var message = messageValidator.message;
-   var paramsClass = null;
-   switch (message.getName()) {
-      case kFakeCentral_SimulatePreconnectedPeripheral_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SimulatePreconnectedPeripheral_ResponseParams;
-        break;
-      case kFakeCentral_SimulateAdvertisementReceived_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SimulateAdvertisementReceived_ResponseParams;
-        break;
-      case kFakeCentral_SetNextGATTConnectionResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextGATTConnectionResponse_ResponseParams;
-        break;
-      case kFakeCentral_SetNextGATTDiscoveryResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextGATTDiscoveryResponse_ResponseParams;
-        break;
-      case kFakeCentral_SimulateGATTDisconnection_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SimulateGATTDisconnection_ResponseParams;
-        break;
-      case kFakeCentral_SimulateGATTServicesChanged_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SimulateGATTServicesChanged_ResponseParams;
-        break;
-      case kFakeCentral_AddFakeService_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_AddFakeService_ResponseParams;
-        break;
-      case kFakeCentral_RemoveFakeService_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_RemoveFakeService_ResponseParams;
-        break;
-      case kFakeCentral_AddFakeCharacteristic_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_AddFakeCharacteristic_ResponseParams;
-        break;
-      case kFakeCentral_RemoveFakeCharacteristic_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_RemoveFakeCharacteristic_ResponseParams;
-        break;
-      case kFakeCentral_AddFakeDescriptor_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_AddFakeDescriptor_ResponseParams;
-        break;
-      case kFakeCentral_RemoveFakeDescriptor_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_RemoveFakeDescriptor_ResponseParams;
-        break;
-      case kFakeCentral_SetNextReadCharacteristicResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextReadCharacteristicResponse_ResponseParams;
-        break;
-      case kFakeCentral_SetNextWriteCharacteristicResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextWriteCharacteristicResponse_ResponseParams;
-        break;
-      case kFakeCentral_SetNextSubscribeToNotificationsResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams;
-        break;
-      case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams;
-        break;
-      case kFakeCentral_IsNotifying_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_IsNotifying_ResponseParams;
-        break;
-      case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams;
-        break;
-      case kFakeCentral_SetNextReadDescriptorResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextReadDescriptorResponse_ResponseParams;
-        break;
-      case kFakeCentral_SetNextWriteDescriptorResponse_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_SetNextWriteDescriptorResponse_ResponseParams;
-        break;
-      case kFakeCentral_GetLastWrittenDescriptorValue_Name:
-        if (message.isResponse())
-          paramsClass = FakeCentral_GetLastWrittenDescriptorValue_ResponseParams;
-        break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  var FakeCentral = {
-    name: 'bluetooth.mojom.FakeCentral',
-    kVersion: 0,
-    ptrClass: FakeCentralPtr,
-    proxyClass: FakeCentralProxy,
-    stubClass: FakeCentralStub,
-    validateRequest: validateFakeCentralRequest,
-    validateResponse: validateFakeCentralResponse,
-  };
-  FakeCentralStub.prototype.validator = validateFakeCentralRequest;
-  FakeCentralProxy.prototype.validator = validateFakeCentralResponse;
-  exports.kHCISuccess = kHCISuccess;
-  exports.kHCIConnectionTimeout = kHCIConnectionTimeout;
-  exports.kGATTSuccess = kGATTSuccess;
-  exports.kGATTInvalidHandle = kGATTInvalidHandle;
-  exports.CentralState = CentralState;
-  exports.Appearance = Appearance;
-  exports.Power = Power;
-  exports.ServiceDataMap = ServiceDataMap;
-  exports.ScanRecord = ScanRecord;
-  exports.ScanResult = ScanResult;
-  exports.CharacteristicProperties = CharacteristicProperties;
-  exports.FakeBluetooth = FakeBluetooth;
-  exports.FakeBluetoothPtr = FakeBluetoothPtr;
-  exports.FakeBluetoothAssociatedPtr = FakeBluetoothAssociatedPtr;
-  exports.FakeCentral = FakeCentral;
-  exports.FakeCentralPtr = FakeCentralPtr;
-  exports.FakeCentralAssociatedPtr = FakeCentralAssociatedPtr;
-})();
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js.headers b/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js.headers
deleted file mode 100644
index 6805c323..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth.mojom.js.headers
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/javascript; charset=utf-8
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js b/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js
deleted file mode 100644
index 4273939..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js
+++ /dev/null
@@ -1,822 +0,0 @@
-// Copyright 2014 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.
-
-'use strict';
-
-(function() {
-  var mojomId = 'content/shell/common/layout_test/fake_bluetooth_chooser.mojom';
-  if (mojo.internal.isMojomLoaded(mojomId)) {
-    console.warn('The following mojom is loaded multiple times: ' + mojomId);
-    return;
-  }
-  mojo.internal.markMojomLoaded(mojomId);
-  var bindings = mojo;
-  var associatedBindings = mojo;
-  var codec = mojo.internal;
-  var validator = mojo.internal;
-
-  var exports = mojo.internal.exposeNamespace('content.mojom');
-
-
-  var ChooserEventType = {};
-  ChooserEventType.CHOOSER_OPENED = 0;
-  ChooserEventType.SCAN_STARTED = ChooserEventType.CHOOSER_OPENED + 1;
-  ChooserEventType.DEVICE_UPDATE = ChooserEventType.SCAN_STARTED + 1;
-  ChooserEventType.ADAPTER_REMOVED = ChooserEventType.DEVICE_UPDATE + 1;
-  ChooserEventType.ADAPTER_DISABLED = ChooserEventType.ADAPTER_REMOVED + 1;
-  ChooserEventType.ADAPTER_ENABLED = ChooserEventType.ADAPTER_DISABLED + 1;
-  ChooserEventType.DISCOVERY_FAILED_TO_START = ChooserEventType.ADAPTER_ENABLED + 1;
-  ChooserEventType.DISCOVERING = ChooserEventType.DISCOVERY_FAILED_TO_START + 1;
-  ChooserEventType.DISCOVERY_IDLE = ChooserEventType.DISCOVERING + 1;
-  ChooserEventType.ADD_DEVICE = ChooserEventType.DISCOVERY_IDLE + 1;
-
-  ChooserEventType.isKnownEnumValue = function(value) {
-    switch (value) {
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-    case 4:
-    case 5:
-    case 6:
-    case 7:
-    case 8:
-    case 9:
-      return true;
-    }
-    return false;
-  };
-
-  ChooserEventType.validate = function(enumValue) {
-    var isExtensible = false;
-    if (isExtensible || this.isKnownEnumValue(enumValue))
-      return validator.validationError.NONE;
-
-    return validator.validationError.UNKNOWN_ENUM_VALUE;
-  };
-
-  function FakeBluetoothChooserEvent(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooserEvent.prototype.initDefaults_ = function() {
-    this.type = 0;
-    this.origin = null;
-    this.peripheralAddress = null;
-  };
-  FakeBluetoothChooserEvent.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooserEvent.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 32}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetoothChooserEvent.type
-    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ChooserEventType);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetoothChooserEvent.origin
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetoothChooserEvent.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooserEvent.encodedSize = codec.kStructHeaderSize + 24;
-
-  FakeBluetoothChooserEvent.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooserEvent();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.type = decoder.decodeStruct(codec.Int32);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    val.origin = decoder.decodeStruct(codec.NullableString);
-    val.peripheralAddress = decoder.decodeStruct(codec.NullableString);
-    return val;
-  };
-
-  FakeBluetoothChooserEvent.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooserEvent.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Int32, val.type);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.encodeStruct(codec.NullableString, val.origin);
-    encoder.encodeStruct(codec.NullableString, val.peripheralAddress);
-  };
-  function FakeBluetoothChooser_WaitForEvents_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_WaitForEvents_Params.prototype.initDefaults_ = function() {
-    this.numOfEvents = 0;
-  };
-  FakeBluetoothChooser_WaitForEvents_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_WaitForEvents_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_WaitForEvents_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetoothChooser_WaitForEvents_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_WaitForEvents_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.numOfEvents = decoder.decodeStruct(codec.Uint32);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    decoder.skip(1);
-    return val;
-  };
-
-  FakeBluetoothChooser_WaitForEvents_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.Uint32, val.numOfEvents);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-    encoder.skip(1);
-  };
-  function FakeBluetoothChooser_WaitForEvents_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initDefaults_ = function() {
-    this.events = null;
-  };
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetoothChooser_WaitForEvents_ResponseParams.events
-    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(FakeBluetoothChooserEvent), false, [0], 0);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_WaitForEvents_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.events = decoder.decodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent));
-    return val;
-  };
-
-  FakeBluetoothChooser_WaitForEvents_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeArrayPointer(new codec.PointerTo(FakeBluetoothChooserEvent), val.events);
-  };
-  function FakeBluetoothChooser_SelectPeripheral_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_SelectPeripheral_Params.prototype.initDefaults_ = function() {
-    this.peripheralAddress = null;
-  };
-  FakeBluetoothChooser_SelectPeripheral_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate FakeBluetoothChooser_SelectPeripheral_Params.peripheralAddress
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_Params.encodedSize = codec.kStructHeaderSize + 8;
-
-  FakeBluetoothChooser_SelectPeripheral_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_SelectPeripheral_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.peripheralAddress = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.peripheralAddress);
-  };
-  function FakeBluetoothChooser_SelectPeripheral_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_SelectPeripheral_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetoothChooser_SelectPeripheral_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetoothChooser_Cancel_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_Cancel_Params.prototype.initDefaults_ = function() {
-  };
-  FakeBluetoothChooser_Cancel_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_Cancel_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_Cancel_Params.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetoothChooser_Cancel_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_Cancel_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetoothChooser_Cancel_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_Cancel_Params.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetoothChooser_Cancel_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_Cancel_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeBluetoothChooser_Cancel_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_Cancel_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_Cancel_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetoothChooser_Cancel_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_Cancel_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetoothChooser_Cancel_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetoothChooser_Rescan_Params(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_Rescan_Params.prototype.initDefaults_ = function() {
-  };
-  FakeBluetoothChooser_Rescan_Params.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_Rescan_Params.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_Rescan_Params.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetoothChooser_Rescan_Params.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_Rescan_Params();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetoothChooser_Rescan_Params.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_Rescan_Params.encodedSize);
-    encoder.writeUint32(0);
-  };
-  function FakeBluetoothChooser_Rescan_ResponseParams(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  FakeBluetoothChooser_Rescan_ResponseParams.prototype.initDefaults_ = function() {
-  };
-  FakeBluetoothChooser_Rescan_ResponseParams.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  FakeBluetoothChooser_Rescan_ResponseParams.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 8}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  FakeBluetoothChooser_Rescan_ResponseParams.encodedSize = codec.kStructHeaderSize + 0;
-
-  FakeBluetoothChooser_Rescan_ResponseParams.decode = function(decoder) {
-    var packed;
-    var val = new FakeBluetoothChooser_Rescan_ResponseParams();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    return val;
-  };
-
-  FakeBluetoothChooser_Rescan_ResponseParams.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize);
-    encoder.writeUint32(0);
-  };
-  var kFakeBluetoothChooser_WaitForEvents_Name = 457051710;
-  var kFakeBluetoothChooser_SelectPeripheral_Name = 1924310743;
-  var kFakeBluetoothChooser_Cancel_Name = 1388880682;
-  var kFakeBluetoothChooser_Rescan_Name = 2112671529;
-
-  function FakeBluetoothChooserPtr(handleOrPtrInfo) {
-    this.ptr = new bindings.InterfacePtrController(FakeBluetoothChooser,
-                                                   handleOrPtrInfo);
-  }
-
-  function FakeBluetoothChooserAssociatedPtr(associatedInterfacePtrInfo) {
-    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
-        FakeBluetoothChooser, associatedInterfacePtrInfo);
-  }
-
-  FakeBluetoothChooserAssociatedPtr.prototype =
-      Object.create(FakeBluetoothChooserPtr.prototype);
-  FakeBluetoothChooserAssociatedPtr.prototype.constructor =
-      FakeBluetoothChooserAssociatedPtr;
-
-  function FakeBluetoothChooserProxy(receiver) {
-    this.receiver_ = receiver;
-  }
-  FakeBluetoothChooserPtr.prototype.waitForEvents = function() {
-    return FakeBluetoothChooserProxy.prototype.waitForEvents
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothChooserProxy.prototype.waitForEvents = function(numOfEvents) {
-    var params = new FakeBluetoothChooser_WaitForEvents_Params();
-    params.numOfEvents = numOfEvents;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetoothChooser_WaitForEvents_Name,
-          codec.align(FakeBluetoothChooser_WaitForEvents_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeBluetoothChooserPtr.prototype.selectPeripheral = function() {
-    return FakeBluetoothChooserProxy.prototype.selectPeripheral
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothChooserProxy.prototype.selectPeripheral = function(peripheralAddress) {
-    var params = new FakeBluetoothChooser_SelectPeripheral_Params();
-    params.peripheralAddress = peripheralAddress;
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetoothChooser_SelectPeripheral_Name,
-          codec.align(FakeBluetoothChooser_SelectPeripheral_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeBluetoothChooserPtr.prototype.cancel = function() {
-    return FakeBluetoothChooserProxy.prototype.cancel
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothChooserProxy.prototype.cancel = function() {
-    var params = new FakeBluetoothChooser_Cancel_Params();
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetoothChooser_Cancel_Name,
-          codec.align(FakeBluetoothChooser_Cancel_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetoothChooser_Cancel_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetoothChooser_Cancel_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-  FakeBluetoothChooserPtr.prototype.rescan = function() {
-    return FakeBluetoothChooserProxy.prototype.rescan
-        .apply(this.ptr.getProxy(), arguments);
-  };
-
-  FakeBluetoothChooserProxy.prototype.rescan = function() {
-    var params = new FakeBluetoothChooser_Rescan_Params();
-    return new Promise(function(resolve, reject) {
-      var builder = new codec.MessageV1Builder(
-          kFakeBluetoothChooser_Rescan_Name,
-          codec.align(FakeBluetoothChooser_Rescan_Params.encodedSize),
-          codec.kMessageExpectsResponse, 0);
-      builder.encodeStruct(FakeBluetoothChooser_Rescan_Params, params);
-      var message = builder.finish();
-      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
-        var reader = new codec.MessageReader(message);
-        var responseParams =
-            reader.decodeStruct(FakeBluetoothChooser_Rescan_ResponseParams);
-        resolve(responseParams);
-      }).catch(function(result) {
-        reject(Error("Connection error: " + result));
-      });
-    }.bind(this));
-  };
-
-  function FakeBluetoothChooserStub(delegate) {
-    this.delegate_ = delegate;
-  }
-  FakeBluetoothChooserStub.prototype.waitForEvents = function(numOfEvents) {
-    return this.delegate_ && this.delegate_.waitForEvents && this.delegate_.waitForEvents(numOfEvents);
-  }
-  FakeBluetoothChooserStub.prototype.selectPeripheral = function(peripheralAddress) {
-    return this.delegate_ && this.delegate_.selectPeripheral && this.delegate_.selectPeripheral(peripheralAddress);
-  }
-  FakeBluetoothChooserStub.prototype.cancel = function() {
-    return this.delegate_ && this.delegate_.cancel && this.delegate_.cancel();
-  }
-  FakeBluetoothChooserStub.prototype.rescan = function() {
-    return this.delegate_ && this.delegate_.rescan && this.delegate_.rescan();
-  }
-
-  FakeBluetoothChooserStub.prototype.accept = function(message) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    default:
-      return false;
-    }
-  };
-
-  FakeBluetoothChooserStub.prototype.acceptWithResponder =
-      function(message, responder) {
-    var reader = new codec.MessageReader(message);
-    switch (reader.messageName) {
-    case kFakeBluetoothChooser_WaitForEvents_Name:
-      var params = reader.decodeStruct(FakeBluetoothChooser_WaitForEvents_Params);
-      this.waitForEvents(params.numOfEvents).then(function(response) {
-        var responseParams =
-            new FakeBluetoothChooser_WaitForEvents_ResponseParams();
-        responseParams.events = response.events;
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetoothChooser_WaitForEvents_Name,
-            codec.align(FakeBluetoothChooser_WaitForEvents_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetoothChooser_WaitForEvents_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeBluetoothChooser_SelectPeripheral_Name:
-      var params = reader.decodeStruct(FakeBluetoothChooser_SelectPeripheral_Params);
-      this.selectPeripheral(params.peripheralAddress).then(function(response) {
-        var responseParams =
-            new FakeBluetoothChooser_SelectPeripheral_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetoothChooser_SelectPeripheral_Name,
-            codec.align(FakeBluetoothChooser_SelectPeripheral_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetoothChooser_SelectPeripheral_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeBluetoothChooser_Cancel_Name:
-      var params = reader.decodeStruct(FakeBluetoothChooser_Cancel_Params);
-      this.cancel().then(function(response) {
-        var responseParams =
-            new FakeBluetoothChooser_Cancel_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetoothChooser_Cancel_Name,
-            codec.align(FakeBluetoothChooser_Cancel_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetoothChooser_Cancel_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    case kFakeBluetoothChooser_Rescan_Name:
-      var params = reader.decodeStruct(FakeBluetoothChooser_Rescan_Params);
-      this.rescan().then(function(response) {
-        var responseParams =
-            new FakeBluetoothChooser_Rescan_ResponseParams();
-        var builder = new codec.MessageV1Builder(
-            kFakeBluetoothChooser_Rescan_Name,
-            codec.align(FakeBluetoothChooser_Rescan_ResponseParams.encodedSize),
-            codec.kMessageIsResponse, reader.requestID);
-        builder.encodeStruct(FakeBluetoothChooser_Rescan_ResponseParams,
-                             responseParams);
-        var message = builder.finish();
-        responder.accept(message);
-      });
-      return true;
-    default:
-      return false;
-    }
-  };
-
-  function validateFakeBluetoothChooserRequest(messageValidator) {
-    var message = messageValidator.message;
-    var paramsClass = null;
-    switch (message.getName()) {
-      case kFakeBluetoothChooser_WaitForEvents_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetoothChooser_WaitForEvents_Params;
-      break;
-      case kFakeBluetoothChooser_SelectPeripheral_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetoothChooser_SelectPeripheral_Params;
-      break;
-      case kFakeBluetoothChooser_Cancel_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetoothChooser_Cancel_Params;
-      break;
-      case kFakeBluetoothChooser_Rescan_Name:
-        if (message.expectsResponse())
-          paramsClass = FakeBluetoothChooser_Rescan_Params;
-      break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  function validateFakeBluetoothChooserResponse(messageValidator) {
-   var message = messageValidator.message;
-   var paramsClass = null;
-   switch (message.getName()) {
-      case kFakeBluetoothChooser_WaitForEvents_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetoothChooser_WaitForEvents_ResponseParams;
-        break;
-      case kFakeBluetoothChooser_SelectPeripheral_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetoothChooser_SelectPeripheral_ResponseParams;
-        break;
-      case kFakeBluetoothChooser_Cancel_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetoothChooser_Cancel_ResponseParams;
-        break;
-      case kFakeBluetoothChooser_Rescan_Name:
-        if (message.isResponse())
-          paramsClass = FakeBluetoothChooser_Rescan_ResponseParams;
-        break;
-    }
-    if (paramsClass === null)
-      return validator.validationError.NONE;
-    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
-  }
-
-  var FakeBluetoothChooser = {
-    name: 'content.mojom.FakeBluetoothChooser',
-    kVersion: 0,
-    ptrClass: FakeBluetoothChooserPtr,
-    proxyClass: FakeBluetoothChooserProxy,
-    stubClass: FakeBluetoothChooserStub,
-    validateRequest: validateFakeBluetoothChooserRequest,
-    validateResponse: validateFakeBluetoothChooserResponse,
-  };
-  FakeBluetoothChooserStub.prototype.validator = validateFakeBluetoothChooserRequest;
-  FakeBluetoothChooserProxy.prototype.validator = validateFakeBluetoothChooserResponse;
-  exports.ChooserEventType = ChooserEventType;
-  exports.FakeBluetoothChooserEvent = FakeBluetoothChooserEvent;
-  exports.FakeBluetoothChooser = FakeBluetoothChooser;
-  exports.FakeBluetoothChooserPtr = FakeBluetoothChooserPtr;
-  exports.FakeBluetoothChooserAssociatedPtr = FakeBluetoothChooserAssociatedPtr;
-})();
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js.headers b/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js.headers
deleted file mode 100644
index 6805c323..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/fake_bluetooth_chooser.mojom.js.headers
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/javascript; charset=utf-8
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js b/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js
deleted file mode 100644
index 3b1b616..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 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.
-
-'use strict';
-
-(function() {
-  var mojomId = 'device/bluetooth/public/mojom/uuid.mojom';
-  if (mojo.internal.isMojomLoaded(mojomId)) {
-    console.warn('The following mojom is loaded multiple times: ' + mojomId);
-    return;
-  }
-  mojo.internal.markMojomLoaded(mojomId);
-  var bindings = mojo;
-  var associatedBindings = mojo;
-  var codec = mojo.internal;
-  var validator = mojo.internal;
-
-  var exports = mojo.internal.exposeNamespace('bluetooth.mojom');
-
-
-
-  function UUID(values) {
-    this.initDefaults_();
-    this.initFields_(values);
-  }
-
-
-  UUID.prototype.initDefaults_ = function() {
-    this.uuid = null;
-  };
-  UUID.prototype.initFields_ = function(fields) {
-    for(var field in fields) {
-        if (this.hasOwnProperty(field))
-          this[field] = fields[field];
-    }
-  };
-
-  UUID.validate = function(messageValidator, offset) {
-    var err;
-    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    var kVersionSizes = [
-      {version: 0, numBytes: 16}
-    ];
-    err = messageValidator.validateStructVersion(offset, kVersionSizes);
-    if (err !== validator.validationError.NONE)
-        return err;
-
-
-    // validate UUID.uuid
-    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
-    if (err !== validator.validationError.NONE)
-        return err;
-
-    return validator.validationError.NONE;
-  };
-
-  UUID.encodedSize = codec.kStructHeaderSize + 8;
-
-  UUID.decode = function(decoder) {
-    var packed;
-    var val = new UUID();
-    var numberOfBytes = decoder.readUint32();
-    var version = decoder.readUint32();
-    val.uuid = decoder.decodeStruct(codec.String);
-    return val;
-  };
-
-  UUID.encode = function(encoder, val) {
-    var packed;
-    encoder.writeUint32(UUID.encodedSize);
-    encoder.writeUint32(0);
-    encoder.encodeStruct(codec.String, val.uuid);
-  };
-  exports.UUID = UUID;
-})();
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js.headers b/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js.headers
deleted file mode 100644
index 6805c323..0000000
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/uuid.mojom.js.headers
+++ /dev/null
@@ -1 +0,0 @@
-Content-Type: text/javascript; charset=utf-8
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/web-bluetooth-test.js b/third_party/blink/web_tests/external/wpt/resources/chromium/web-bluetooth-test.js
index f0eba0f..db8f5480 100644
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/web-bluetooth-test.js
+++ b/third_party/blink/web_tests/external/wpt/resources/chromium/web-bluetooth-test.js
@@ -513,6 +513,13 @@
     Mojo.bindInterface(content.mojom.FakeBluetoothChooser.name,
         mojo.makeRequest(this.fake_bluetooth_chooser_ptr_).handle, 'process');
   }
+
+  async selectPeripheral(peripheral) {
+    if (!(peripheral instanceof FakePeripheral)) {
+      throw '|peripheral| must be an instance of FakePeripheral';
+    }
+    await this.fake_bluetooth_chooser_ptr_.selectPeripheral(peripheral.address);
+  }
 }
 
 // If this line fails, it means that current environment does not support the
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end-ref.html b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end-ref.html
index 247e6e24..e16f4afa 100644
--- a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end-ref.html
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end-ref.html
@@ -15,7 +15,6 @@
     bottom: 0;
     left: 0;
     right: 0;
-    width: 50%;
     text-align: right;
 }
 .cue > span {
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html
index f26b3a076..ad69c50 100644
--- a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html
@@ -15,7 +15,6 @@
     bottom: 0;
     left: 0;
     right: 0;
-    width: 50%;
     text-align: right
 }
 .cue > span {
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start-ref.html b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start-ref.html
index 15f24fb..6c1120ca 100644
--- a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start-ref.html
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start-ref.html
@@ -13,8 +13,9 @@
 .cue {
     position: absolute;
     bottom: 0;
-    left: 50%;
+    left: 0;
     right: 0;
+    text-align: left;
 }
 .cue > span {
     font-family: Ahem, sans-serif;
diff --git a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html
index 6f5b6335..866ddb15 100644
--- a/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html
+++ b/third_party/blink/web_tests/external/wpt/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html
@@ -13,8 +13,9 @@
 .cue {
     position: absolute;
     bottom: 0;
-    left: 50%;
+    left: 0;
     right: 0;
+    text-align: left;
 }
 .cue > span {
     font-family: Ahem, sans-serif;
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
index 44c7f9d..6fd24de 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
@@ -9,7 +9,7 @@
         {
           "object": "LayoutBlockFlow DIV id='root' class='editing'",
           "rect": [7, 7, 786, 20],
-          "reason": "full"
+          "reason": "style change"
         },
         {
           "object": "InlineTextBox '1'",
diff --git a/third_party/blink/web_tests/http/tests/background_sync/test-periodic-background-sync-permission.html b/third_party/blink/web_tests/http/tests/background_sync/test-periodic-background-sync-permission.html
new file mode 100644
index 0000000..6917d0c
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/background_sync/test-periodic-background-sync-permission.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test Periodic Background Sync Permission.</title>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<script>
+  promise_test(test => {
+    internals.runtimeFlags.periodicBackgroundSyncEnabled = true;
+    return navigator.permissions.query({name:'periodic-background-sync'})
+      .then(result => assert_true(result instanceof PermissionStatus));
+  });
+</script>
diff --git a/third_party/blink/web_tests/http/tests/resources/permissions-helper.js b/third_party/blink/web_tests/http/tests/resources/permissions-helper.js
index 788571a..fd8b11b8 100644
--- a/third_party/blink/web_tests/http/tests/resources/permissions-helper.js
+++ b/third_party/blink/web_tests/http/tests/resources/permissions-helper.js
@@ -35,6 +35,8 @@
         return {name: "payment-handler"};
       case "background-fetch":
         return {name: "background-fetch"};
+      case "periodic-background-sync":
+        return {name: "periodic-background-sync"};
       default:
         throw "Invalid permission name provided";
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
index 634c332a..7c12924 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
@@ -20,7 +20,7 @@
         {
           "object": "LayoutBlockFlow DIV id='root' class='editing'",
           "rect": [3, 3, 794, 28],
-          "reason": "full"
+          "reason": "style change"
         },
         {
           "object": "InlineTextBox '1'",
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
index a390805..c16d76565 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/invalidate-caret-before-text-node-update-expected.txt
@@ -20,7 +20,7 @@
         {
           "object": "LayoutBlockFlow DIV id='root' class='editing'",
           "rect": [7, 7, 786, 20],
-          "reason": "full"
+          "reason": "style change"
         },
         {
           "object": "InlineTextBox '1'",
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 68f5e50..3a06d79 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -1563,6 +1563,14 @@
   </description>
 </action>
 
+<action name="Android.DarkTheme.Preference">
+  <owner>huayinz@chromium.org</owner>
+  <owner>chrome-android-app@chromium.org</owner>
+  <description>
+    User changed preference to use system default, light, or dark theme.
+  </description>
+</action>
+
 <action name="Android.Download.InfoBar.Accelerated">
   <owner>shaktisahu@chromium.org</owner>
   <description>
@@ -21924,4 +21932,12 @@
   <affected-action name="MobileTabReturnedToCurrentTab"/>
 </action-suffix>
 
+<action-suffix separator="." ordering="suffix">
+  <suffix name="Dark" label="Users selected dark theme preference."/>
+  <suffix name="Light" label="Users selected light theme preference."/>
+  <suffix name="SystemDefault"
+      label="Users selected system default theme preference."/>
+  <affected-action name="Android.DarkTheme.Preference"/>
+</action-suffix>
+
 </actions>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 3b140bd1..d0d32b2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -9142,8 +9142,10 @@
   <int value="44" label="USB guard"/>
   <int value="45" label="Background fetch"/>
   <int value="46" label="Intent picker display"/>
-  <int value="47" label="Serial guard"/>
-  <int value="48" label="Serial permission data"/>
+  <int value="47" label="Idle detection"/>
+  <int value="48" label="Serial guard"/>
+  <int value="49" label="Serial permission data"/>
+  <int value="50" label="Periodic background sync"/>
 </enum>
 
 <enum name="ContentTypeParseableResult">
@@ -11229,6 +11231,18 @@
   <int value="3" label="SSID"/>
 </enum>
 
+<enum name="DarkThemeEnabledReason">
+  <int value="0" label="User preference is set to force dark theme."/>
+  <int value="1" label="Power save mode is on."/>
+  <int value="2" label="Other."/>
+</enum>
+
+<enum name="DarkThemePreferences">
+  <int value="0" label="System default"/>
+  <int value="1" label="Light theme"/>
+  <int value="2" label="Dark theme"/>
+</enum>
+
 <enum name="DataChannelCounters">
   <int value="0" label="Channel created."/>
   <int value="1" label="Channel reached Open state."/>
@@ -33706,6 +33720,7 @@
     Command-line flag doesn't start with two dashes.
   </int>
   <int value="1558582" label="ResamplingInputEvents:enabled"/>
+  <int value="5654819" label="CrostiniGpuSupport:disabled"/>
   <int value="7444737" label="NTPSuggestionsStandaloneUI:disabled"/>
   <int value="7533886" label="disable-offer-store-unmasked-wallet-cards"/>
   <int value="10458238" label="disable-print-preview-simplify"/>
@@ -34360,6 +34375,7 @@
   <int value="1064288458" label="OfflineRecentPages:enabled"/>
   <int value="1067618884" label="enable-experimental-input-view-features"/>
   <int value="1067990299" label="enable-ui-devtools"/>
+  <int value="1069325321" label="CrostiniGpuSupport:enabled"/>
   <int value="1070164693" label="MidiManagerDynamicInstantiation:disabled"/>
   <int value="1070300488" label="disable-webgl"/>
   <int value="1070449228" label="ContextualSuggestionsCarousel:enabled"/>
@@ -44753,6 +44769,14 @@
   <int value="9" label="PERMISSION_VIDEO_CAPTURE"/>
   <int value="10" label="PERMISSION_BACKGROUND_SYNC"/>
   <int value="11" label="PERMISSION_FLASH"/>
+  <int value="12" label="PERMISSION_SENSORS"/>
+  <int value="13" label="PERMISSION_ACCESSIBILITY_EVENTS"/>
+  <int value="14" label="PERMISSION_CLIPBOARD_READ"/>
+  <int value="15" label="PERMISSION_CLIPBOARD_WRITE"/>
+  <int value="16" label="PERMISSION_PAYMENT_HANDLER"/>
+  <int value="17" label="PERMISSION_BACKGROUND_FETCH"/>
+  <int value="18" label="PERMISSION_IDLE_DETECTION"/>
+  <int value="19" label="PERMISSION_PERIODIC_BACKGROUND_SYNC"/>
 </enum>
 
 <enum name="PersistedLogsLogReadStatus">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 1df53ff..f2a1c2c 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -1755,6 +1755,36 @@
   </summary>
 </histogram>
 
+<histogram name="Android.DarkTheme.EnabledReason" enum="DarkThemeEnabledReason"
+    expires_after="M78">
+  <owner>huayinz@chromium.org</owner>
+  <owner>chrome-android-app@chromium.org</owner>
+  <summary>
+    Records the reason why dark theme is enabled when dark theme is visible to
+    user.
+  </summary>
+</histogram>
+
+<histogram name="Android.DarkTheme.EnabledState" enum="BooleanEnabled"
+    expires_after="M78">
+  <owner>huayinz@chromium.org</owner>
+  <owner>chrome-android-app@chromium.org</owner>
+  <summary>
+    Records whether dark theme is enabled or not on cold start and when the
+    enabled state changes.
+  </summary>
+</histogram>
+
+<histogram name="Android.DarkTheme.Preference.State"
+    enum="DarkThemePreferences" expires_after="M78">
+  <owner>huayinz@chromium.org</owner>
+  <owner>chrome-android-app@chromium.org</owner>
+  <summary>
+    Records user theme preference of system default, light or dark theme on cold
+    start and when the theme preference changes.
+  </summary>
+</histogram>
+
 <histogram name="Android.DeviceSize.LargestDisplaySize" units="dp">
   <owner>twellington@chromium.org</owner>
   <owner>tedchoc@chromium.org</owner>
@@ -12909,6 +12939,14 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.SpatialNavigation.Advance" units="microseconds">
+  <owner>bokan@chromium.org</owner>
+  <summary>
+    Time it takes to find best candidate element, set focus or scroll for given
+    directional input.
+  </summary>
+</histogram>
+
 <histogram name="Blink.StyleAndLayout.UpdateTime" units="microseconds"
     expires_after="2020-3-1">
   <owner>layout-dev@chromium.org</owner>
diff --git a/tools/perf/BUILD.gn b/tools/perf/BUILD.gn
index d646f6f..188a426 100644
--- a/tools/perf/BUILD.gn
+++ b/tools/perf/BUILD.gn
@@ -18,6 +18,7 @@
     # Field trial dependencies
     "//tools/json_comment_eater/",
     "//tools/json_to_struct/",
+    "//components/variations/service/generate_ui_string_overrider.py",
 
     # For blink_perf benchmarks.
     "//third_party/blink/perf_tests/",
diff --git a/tools/variations/fieldtrial_to_struct.py b/tools/variations/fieldtrial_to_struct.py
index 41128753..b1d92de 100755
--- a/tools/variations/fieldtrial_to_struct.py
+++ b/tools/variations/fieldtrial_to_struct.py
@@ -7,6 +7,7 @@
 import os.path
 import sys
 import optparse
+
 _script_path = os.path.realpath(__file__)
 
 sys.path.insert(0, os.path.normpath(_script_path + "/../../json_comment_eater"))
@@ -21,6 +22,14 @@
 finally:
   sys.path.pop(0)
 
+sys.path.insert(
+    0,
+    os.path.normpath(_script_path + "/../../../components/variations/service"))
+try:
+  import generate_ui_string_overrider
+finally:
+  sys.path.pop(0)
+
 _platforms = [
   'android',
   'android_webview',
@@ -61,6 +70,16 @@
   """
   return _FieldTrialConfigToDescription(_Load(filename), platforms)
 
+def _ConvertOverrideUIStrings(override_ui_strings):
+  """Converts override_ui_strings to formatted dicts."""
+  overrides = []
+  for ui_string, override in override_ui_strings.iteritems():
+    overrides.append({
+        'name_hash': generate_ui_string_overrider.HashName(ui_string),
+        'value': override
+    })
+  return overrides
+
 def _CreateExperiment(experiment_data,
                       platforms,
                       is_low_end_device,
@@ -84,6 +103,10 @@
   disable_features_data = experiment_data.get('disable_features')
   if disable_features_data:
     experiment['disable_features'] = disable_features_data
+  override_ui_strings = experiment_data.get('override_ui_strings')
+  if override_ui_strings:
+    experiment['override_ui_string'] = _ConvertOverrideUIStrings(
+        override_ui_strings)
   return experiment
 
 def _CreateTrial(study_name, experiment_configs, platforms):
diff --git a/tools/variations/fieldtrial_to_struct_unittest.py b/tools/variations/fieldtrial_to_struct_unittest.py
index 4314b94..57c090f 100644
--- a/tools/variations/fieldtrial_to_struct_unittest.py
+++ b/tools/variations/fieldtrial_to_struct_unittest.py
@@ -297,6 +297,91 @@
     self.maxDiff = None
     self.assertEqual(expected, result)
 
+  _MULTIPLE_OVERRIDE_UI_STRING_CONFIG = {
+    'Trial1': [
+      {
+        'platforms': ['windows'],
+        'experiments': [
+          {
+            'name': 'Group1',
+            'override_ui_strings': {
+              'IDS_NEW_TAB_TITLE': 'test1',
+              'IDS_SAD_TAB_TITLE': 'test2',
+            },
+          },
+        ]
+      }
+    ],
+    'Trial2': [
+      {
+        'platforms': ['windows'],
+        'experiments': [
+          {
+            'name': 'Group2',
+            'override_ui_strings': {
+              'IDS_DEFAULT_TAB_TITLE': 'test3',
+            },
+          }
+        ]
+      }
+    ]
+  }
+
+  def test_FieldTrialToDescriptionMultipleOverrideUIStringTrial(self):
+    result = fieldtrial_to_struct._FieldTrialConfigToDescription(
+        self._MULTIPLE_OVERRIDE_UI_STRING_CONFIG, ['windows'])
+    expected = {
+      'elements': {
+        'kFieldTrialConfig': {
+          'studies': [
+            {
+              'name': 'Trial1',
+              'experiments': [
+                {
+                  'name': 'Group1',
+                  'platforms': ['Study::PLATFORM_WINDOWS'],
+                  'override_ui_string': [
+                    {
+                      'name_hash':
+                        4045341670,
+                      'value': 'test1'
+                    },
+                    {
+                      'name_hash':
+                        1173727369,
+                      'value': 'test2'
+                    },
+                  ],
+                  'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
+                  'form_factors': [],
+                },
+              ],
+            },
+            {
+              'name': 'Trial2',
+              'experiments': [
+                {
+                  'name': 'Group2',
+                  'platforms': ['Study::PLATFORM_WINDOWS'],
+                  'override_ui_string': [
+                    {
+                      'name_hash':
+                        3477264953,
+                      'value': 'test3'
+                    },
+                  ],
+                  'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
+                  'form_factors': [],
+                },
+              ],
+            }
+          ]
+        }
+      }
+    }
+    self.maxDiff = None
+    self.assertEqual(expected, result)
+
   def test_FieldTrialToStructMain(self):
 
     schema = self.FullRelativePath(
diff --git a/tools/variations/unittest_data/expected_output.cc b/tools/variations/unittest_data/expected_output.cc
index 933ab9e2..54ca24e 100644
--- a/tools/variations/unittest_data/expected_output.cc
+++ b/tools/variations/unittest_data/expected_output.cc
@@ -10,6 +10,36 @@
 #include "test_output.h"
 
 
+const OverrideUIString array_kFieldTrialConfig_override_ui_string[] = {
+      {
+        4045341670,
+        "test",
+      },
+};
+const Study::FormFactor array_kFieldTrialConfig_form_factors_8[] = {
+};
+const Study::Platform array_kFieldTrialConfig_platforms_8[] = {
+      Study::PLATFORM_WINDOWS,
+};
+const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_5[] = {
+    {
+      "TestGroup",
+      array_kFieldTrialConfig_platforms_8,
+      1,
+      array_kFieldTrialConfig_form_factors_8,
+      0,
+      Study::OPTIONAL_BOOL_MISSING,
+      NULL,
+      0,
+      NULL,
+      0,
+      NULL,
+      0,
+      NULL,
+      array_kFieldTrialConfig_override_ui_string,
+      1,
+    },
+};
 const Study::FormFactor array_kFieldTrialConfig_form_factors_7[] = {
       Study::TABLET,
 };
@@ -38,6 +68,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
     {
       "TestGroup2",
@@ -53,6 +85,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
 };
 const Study::FormFactor array_kFieldTrialConfig_form_factors_5[] = {
@@ -75,6 +109,8 @@
       NULL,
       0,
       "my-forcing-flag",
+      NULL,
+      0,
     },
 };
 const Study::FormFactor array_kFieldTrialConfig_form_factors_4[] = {
@@ -102,6 +138,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
     {
       "TestGroup2",
@@ -117,6 +155,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
 };
 const char* const array_kFieldTrialConfig_enable_features_1[] = {
@@ -142,6 +182,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
 };
 const char* const array_kFieldTrialConfig_disable_features_0[] = {
@@ -203,6 +245,8 @@
       array_kFieldTrialConfig_disable_features,
       1,
       NULL,
+      NULL,
+      0,
     },
     {
       "TestGroup2-2",
@@ -218,6 +262,8 @@
       array_kFieldTrialConfig_disable_features_0,
       1,
       NULL,
+      NULL,
+      0,
     },
 };
 const Study::FormFactor array_kFieldTrialConfig_form_factors[] = {
@@ -240,6 +286,8 @@
       NULL,
       0,
       NULL,
+      NULL,
+      0,
     },
 };
 const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
@@ -273,8 +321,13 @@
     array_kFieldTrialConfig_experiments_4,
     2,
   },
+  {
+    "TrialWithOverrideUIString",
+    array_kFieldTrialConfig_experiments_5,
+    1,
+  },
 };
 const FieldTrialTestingConfig kFieldTrialConfig = {
   array_kFieldTrialConfig_studies,
-  6,
+  7,
 };
diff --git a/tools/variations/unittest_data/expected_output.h b/tools/variations/unittest_data/expected_output.h
index e01eee7c..891823f 100644
--- a/tools/variations/unittest_data/expected_output.h
+++ b/tools/variations/unittest_data/expected_output.h
@@ -14,6 +14,11 @@
 
 #include "components/variations/proto/study.pb.h"
 
+struct OverrideUIString {
+  const int name_hash;
+  const char* const value;
+};
+
 struct FieldTrialTestingExperimentParams {
   const char* const key;
   const char* const value;
@@ -33,6 +38,8 @@
   const char* const * disable_features;
   const size_t disable_features_size;
   const char* const forcing_flag;
+  const OverrideUIString * override_ui_string;
+  const size_t override_ui_string_size;
 };
 
 struct FieldTrialTestingStudy {
diff --git a/tools/variations/unittest_data/test_config.json b/tools/variations/unittest_data/test_config.json
index 8b34c79..0c5e72d 100644
--- a/tools/variations/unittest_data/test_config.json
+++ b/tools/variations/unittest_data/test_config.json
@@ -70,5 +70,16 @@
       "form_factors": ["tablet"],
       "experiments": [{"name": "TestGroup2"}]
     }
+  ],
+  "TrialWithOverrideUIString": [
+    {
+      "platforms": ["windows"],
+      "experiments": [
+        {
+          "name": "TestGroup",
+          "override_ui_strings": {"IDS_NEW_TAB_TITLE": "test"}
+        }
+      ]
+    }
   ]
 }
diff --git a/ui/accessibility/ax_node_position.cc b/ui/accessibility/ax_node_position.cc
index b0521ce..4c21472d 100644
--- a/ui/accessibility/ax_node_position.cc
+++ b/ui/accessibility/ax_node_position.cc
@@ -69,6 +69,16 @@
   return GetAnchor() ? GetAnchor()->index_in_parent() : INVALID_INDEX;
 }
 
+base::stack<AXNode*> AXNodePosition::GetAncestorAnchors() const {
+  base::stack<AXNode*> anchors;
+  AXNode* current_anchor = GetAnchor();
+  while (current_anchor) {
+    anchors.push(current_anchor);
+    current_anchor = current_anchor->parent();
+  }
+  return anchors;
+}
+
 void AXNodePosition::AnchorParent(AXTreeID* tree_id, int32_t* parent_id) const {
   DCHECK(tree_id);
   DCHECK(parent_id);
diff --git a/ui/accessibility/ax_node_position.h b/ui/accessibility/ax_node_position.h
index b4ba2f2..0e08eb3b 100644
--- a/ui/accessibility/ax_node_position.h
+++ b/ui/accessibility/ax_node_position.h
@@ -38,6 +38,7 @@
                    int32_t* child_id) const override;
   int AnchorChildCount() const override;
   int AnchorIndexInParent() const override;
+  base::stack<AXNode*> GetAncestorAnchors() const override;
   void AnchorParent(AXTreeID* tree_id, int32_t* parent_id) const override;
   AXNode* GetNodeInTree(AXTreeID tree_id, int32_t node_id) const override;
   bool IsInWhiteSpace() const override;
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h
index 7ea8f13..f2575bbd 100644
--- a/ui/accessibility/ax_position.h
+++ b/ui/accessibility/ax_position.h
@@ -358,22 +358,23 @@
     if (GetAnchor() == second.GetAnchor())
       return Clone();
 
-    base::stack<AXPositionInstance> ancestors1;
-    ancestors1.push(std::move(Clone()));
-    while (!ancestors1.top()->IsNullPosition())
-      ancestors1.push(std::move(ancestors1.top()->CreateParentPosition()));
+    base::stack<AXNodeType*> our_ancestors = GetAncestorAnchors();
+    base::stack<AXNodeType*> other_ancestors = second.GetAncestorAnchors();
 
-    base::stack<AXPositionInstance> ancestors2;
-    ancestors2.push(std::move(second.Clone()));
-    while (!ancestors2.top()->IsNullPosition())
-      ancestors2.push(std::move(ancestors2.top()->CreateParentPosition()));
+    AXNodeType* common_anchor = nullptr;
+    while (!our_ancestors.empty() && !other_ancestors.empty() &&
+           our_ancestors.top() == other_ancestors.top()) {
+      common_anchor = our_ancestors.top();
+      our_ancestors.pop();
+      other_ancestors.pop();
+    }
+    if (!common_anchor)
+      return CreateNullPosition();
 
-    AXPositionInstance common_ancestor;
-    while (!ancestors1.empty() && !ancestors2.empty() &&
-           ancestors1.top()->GetAnchor() == ancestors2.top()->GetAnchor()) {
-      common_ancestor = std::move(ancestors1.top());
-      ancestors1.pop();
-      ancestors2.pop();
+    AXPositionInstance common_ancestor = Clone();
+    while (!common_ancestor->IsNullPosition() &&
+           common_ancestor->GetAnchor() != common_anchor) {
+      common_ancestor = common_ancestor->CreateParentPosition();
     }
     return common_ancestor;
   }
@@ -1459,6 +1460,7 @@
                            int32_t* child_id) const = 0;
   virtual int AnchorChildCount() const = 0;
   virtual int AnchorIndexInParent() const = 0;
+  virtual base::stack<AXNodeType*> GetAncestorAnchors() const = 0;
   virtual void AnchorParent(AXTreeID* tree_id, int32_t* parent_id) const = 0;
   virtual AXNodeType* GetNodeInTree(AXTreeID tree_id,
                                     int32_t node_id) const = 0;
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index 445cd7b..d154a67f5 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -394,7 +394,6 @@
     "../compositor_extra/shadow_unittest.cc",
     "gestures/gesture_recognizer_unittest.cc",
     "mouse_location_manager_unittest.cc",
-    "mus/client_side_window_move_handler_unittest.cc",
     "mus/client_surface_embedder_unittest.cc",
     "mus/drag_drop_controller_mus_unittest.cc",
     "mus/focus_synchronizer_unittest.cc",
diff --git a/ui/aura/client/aura_constants.cc b/ui/aura/client/aura_constants.cc
index 615dc85..e255ead 100644
--- a/ui/aura/client/aura_constants.cc
+++ b/ui/aura/client/aura_constants.cc
@@ -57,9 +57,6 @@
                                    kEmbeddedWindowEnsureNotInRect,
                                    nullptr)
 DEFINE_UI_CLASS_PROPERTY_KEY(FocusClient*, kFocusClientKey, nullptr)
-DEFINE_UI_CLASS_PROPERTY_KEY(bool,
-                             kGestureDragFromClientAreaTopMovesWindow,
-                             false)
 DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kHostWindowKey, nullptr)
 DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Size, kMaximumSize, nullptr)
 DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Size, kMinimumSize, nullptr)
diff --git a/ui/aura/client/aura_constants.h b/ui/aura/client/aura_constants.h
index 637c24b..a0ab763 100644
--- a/ui/aura/client/aura_constants.h
+++ b/ui/aura/client/aura_constants.h
@@ -97,12 +97,6 @@
 // A property key to store the focus client on the window.
 AURA_EXPORT extern const WindowProperty<FocusClient*>* const kFocusClientKey;
 
-// Should be set to true for fullscreen/maximized windows that want to be
-// drag-moved in response to gesture events in the top of the client
-// area/screen.
-AURA_EXPORT extern const WindowProperty<bool>* const
-    kGestureDragFromClientAreaTopMovesWindow;
-
 // A property key to store the host window of a window. This lets
 // WebContentsViews find the windows that should constrain NPAPI plugins.
 AURA_EXPORT extern const WindowProperty<Window*>* const kHostWindowKey;
diff --git a/ui/aura/mus/client_side_window_move_handler.cc b/ui/aura/mus/client_side_window_move_handler.cc
index 827f401..96f12cd 100644
--- a/ui/aura/mus/client_side_window_move_handler.cc
+++ b/ui/aura/mus/client_side_window_move_handler.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(estade,mukai): Delete this file.
+
 #include "ui/aura/mus/client_side_window_move_handler.h"
 
 #include "base/bind.h"
@@ -22,56 +24,7 @@
 
 namespace {
 
-// TODO(estade,mukai): De-dupe this constant and the following logic with
-// WmToplevelWindowEventHandler.
-constexpr int kDragStartTopEdgeInset = 8;
-
 Window* GetToplevelTargetForEvent(ui::LocatedEvent* event, int* component) {
-  DCHECK(!event->handled());
-  auto* window = static_cast<Window*>(event->target());
-
-  if (!window || !window->delegate())
-    return nullptr;
-
-  *component = window->delegate()->GetNonClientComponent(event->location());
-
-  if (ui::CanPerformDragOrResize(*component)) {
-    DCHECK_EQ(window, window->GetToplevelWindow());
-    return window;
-  }
-
-  // Gestures can sometimes trigger drags from the client area. All other events
-  // and hit locations will not trigger a drag.
-  if (event->type() != ui::ET_GESTURE_SCROLL_BEGIN || *component != HTCLIENT)
-    return nullptr;
-
-  window = window->GetToplevelWindow();
-  if (!window->GetRootWindow()->GetProperty(
-          client::kGestureDragFromClientAreaTopMovesWindow)) {
-    return nullptr;
-  }
-
-  if (event->AsGestureEvent()->details().scroll_y_hint() < 0)
-    return nullptr;
-
-  const gfx::Point location_in_screen =
-      event->target()->GetScreenLocation(*event);
-  const gfx::Rect work_area_bounds =
-      display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
-
-  gfx::Rect hit_bounds_in_screen(work_area_bounds);
-  hit_bounds_in_screen.set_height(kDragStartTopEdgeInset);
-
-  // There may be a bezel sensor off screen logically above
-  // |hit_bounds_in_screen|. Handles the ET_GESTURE_SCROLL_BEGIN event
-  // triggered in the bezel area too.
-  bool in_bezel = location_in_screen.y() < hit_bounds_in_screen.y() &&
-                  location_in_screen.x() >= hit_bounds_in_screen.x() &&
-                  location_in_screen.x() < hit_bounds_in_screen.right();
-
-  if (hit_bounds_in_screen.Contains(location_in_screen) || in_bezel)
-    return window;
-
   return nullptr;
 }
 
diff --git a/ui/aura/mus/client_side_window_move_handler_unittest.cc b/ui/aura/mus/client_side_window_move_handler_unittest.cc
deleted file mode 100644
index d9062f20..0000000
--- a/ui/aura/mus/client_side_window_move_handler_unittest.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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 "testing/gtest/include/gtest/gtest.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/mus/in_flight_change.h"
-#include "ui/aura/mus/window_tree_client_test_observer.h"
-#include "ui/aura/mus/window_tree_host_mus.h"
-#include "ui/aura/mus/window_tree_host_mus_init_params.h"
-#include "ui/aura/test/aura_mus_test_base.h"
-#include "ui/aura/test/mus/test_window_tree.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window.h"
-#include "ui/base/hit_test.h"
-#include "ui/events/test/event_generator.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace aura {
-
-namespace {
-
-const int kBorderThickness = 5;
-const int kClientAreaRadius = 10;
-
-class WindowMoveTestDelegate : public test::TestWindowDelegate {
- public:
-  WindowMoveTestDelegate() = default;
-  ~WindowMoveTestDelegate() override = default;
-
-  // Makes the window behave as if fullscreened: the entire window is HTCLIENT,
-  // and the flag to enable drags from the top of the screen/window is enabled.
-  void Fullscreen() {
-    fullscreen_ = true;
-    window_->GetRootWindow()->SetProperty(
-        aura::client::kGestureDragFromClientAreaTopMovesWindow, true);
-  }
-
-  void set_window(Window* window) { window_ = window; }
-
- private:
-  int GetNonClientComponent(const gfx::Point& point) const override {
-    if (fullscreen_)
-      return HTCLIENT;
-
-    gfx::Size size = window_->bounds().size();
-    if (point.y() < kBorderThickness) {
-      if (point.x() < kBorderThickness)
-        return HTTOPLEFT;
-      if (point.x() > size.width() - kBorderThickness)
-        return HTTOPRIGHT;
-      return HTTOP;
-    }
-    if (point.y() > size.height() - kBorderThickness) {
-      if (point.x() < kBorderThickness)
-        return HTBOTTOMLEFT;
-      if (point.x() > size.width() - kBorderThickness)
-        return HTBOTTOMRIGHT;
-      return HTBOTTOM;
-    }
-    if (point.x() < kBorderThickness)
-      return HTLEFT;
-    if (point.x() > size.width() - kBorderThickness)
-      return HTRIGHT;
-
-    if ((point - (gfx::Rect(size).CenterPoint())).LengthSquared() <
-        kClientAreaRadius * kClientAreaRadius) {
-      return HTCLIENT;
-    }
-    return HTCAPTION;
-  }
-
-  bool fullscreen_ = false;
-  Window* window_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowMoveTestDelegate);
-};
-
-class WindowMoveObserver : public WindowTreeClientTestObserver {
- public:
-  WindowMoveObserver(WindowTreeClient* client) : client_(client) {
-    client_->AddTestObserver(this);
-  }
-  ~WindowMoveObserver() override { client_->RemoveTestObserver(this); }
-
-  bool in_window_move() const { return window_move_count_ > 0; }
-  int window_move_count() const { return window_move_count_; }
-
- private:
-  // WindowTreeClientTestObserver:
-  void OnChangeStarted(uint32_t change_id, ChangeType type) override {
-    if (type == ChangeType::MOVE_LOOP)
-      window_move_count_++;
-  }
-  void OnChangeCompleted(uint32_t change_id,
-                         ChangeType type,
-                         bool success) override {
-    if (type == ChangeType::MOVE_LOOP)
-      window_move_count_--;
-  }
-
-  WindowTreeClient* client_;
-  int window_move_count_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowMoveObserver);
-};
-
-}  // namespace
-
-class ClientSideWindowMoveHandlerTest
-    : public test::AuraMusClientTestBase,
-      public ::testing::WithParamInterface<const char*> {
- public:
-  ClientSideWindowMoveHandlerTest() = default;
-  ~ClientSideWindowMoveHandlerTest() override = default;
-
-  void SetUp() override {
-    test::AuraMusClientTestBase::SetUp();
-    test_window_.reset(CreateNormalWindow(10, root_window(), &test_delegate_));
-    test_delegate_.set_window(test_window_.get());
-    event_generator_ =
-        std::make_unique<ui::test::EventGenerator>(root_window());
-  }
-
-  void TearDown() override {
-    test_window_.reset();
-    test_delegate_.set_window(nullptr);
-    event_generator_.reset();
-    test::AuraMusClientTestBase::TearDown();
-  }
-
- protected:
-  bool IsInputMouse() { return GetParam() == std::string("mouse"); }
-
-  void MoveInputTo(const gfx::Point& point) {
-    if (IsInputMouse())
-      event_generator_->MoveMouseTo(point);
-    else
-      event_generator_->MoveTouch(point);
-  }
-
-  void MoveInputBy(int x, int y) {
-    if (IsInputMouse())
-      event_generator_->MoveMouseBy(x, y);
-    else
-      event_generator_->MoveTouchBy(x, y);
-  }
-
-  void PressInput() {
-    if (IsInputMouse())
-      event_generator_->PressLeftButton();
-    else
-      event_generator_->PressTouch();
-  }
-
-  void ReleaseInput() {
-    if (IsInputMouse())
-      event_generator_->ReleaseLeftButton();
-    else
-      event_generator_->ReleaseTouch();
-  }
-
-  gfx::Rect GetWindowBounds() { return test_window_->GetBoundsInScreen(); }
-
-  WindowMoveTestDelegate test_delegate_;
-  std::unique_ptr<Window> test_window_;
-  std::unique_ptr<ui::test::EventGenerator> event_generator_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ClientSideWindowMoveHandlerTest);
-};
-
-TEST_P(ClientSideWindowMoveHandlerTest, ResizeShadow) {
-  if (!IsInputMouse())
-    return;
-
-  gfx::Rect bounds = GetWindowBounds();
-  MoveInputTo(bounds.origin());
-
-  EXPECT_EQ(1u, window_tree()->get_and_clear_window_resize_shadow_count());
-  EXPECT_EQ(HTTOPLEFT, window_tree()->last_window_resize_shadow());
-
-  MoveInputBy(1, 1);
-  EXPECT_EQ(0u, window_tree()->get_and_clear_window_resize_shadow_count());
-
-  MoveInputBy(10, 0);
-  EXPECT_EQ(1u, window_tree()->get_and_clear_window_resize_shadow_count());
-  EXPECT_EQ(HTTOP, window_tree()->last_window_resize_shadow());
-
-  MoveInputBy(0, 10);
-  EXPECT_EQ(1u, window_tree()->get_and_clear_window_resize_shadow_count());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-
-  MoveInputTo(bounds.CenterPoint());
-  EXPECT_EQ(0u, window_tree()->get_and_clear_window_resize_shadow_count());
-
-  // Moves the input outside of the window bounds.
-  MoveInputTo(bounds.bottom_right() + gfx::Vector2d(-2, -2));
-  EXPECT_EQ(1u, window_tree()->get_and_clear_window_resize_shadow_count());
-  EXPECT_EQ(HTBOTTOMRIGHT, window_tree()->last_window_resize_shadow());
-
-  MoveInputBy(10, 10);
-  EXPECT_EQ(1u, window_tree()->get_and_clear_window_resize_shadow_count());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest, PerformWindowMove) {
-  WindowMoveObserver observer(window_tree_client_impl());
-
-  MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(10, 10));
-
-  PressInput();
-  MoveInputBy(10, 10);
-  EXPECT_TRUE(observer.in_window_move());
-  EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-  window_tree()->AckAllChanges();
-  EXPECT_FALSE(observer.in_window_move());
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest, WindowResize) {
-  WindowMoveObserver observer(window_tree_client_impl());
-
-  MoveInputTo(GetWindowBounds().bottom_right() + gfx::Vector2d(-3, -3));
-
-  PressInput();
-  MoveInputBy(-10, -10);
-  EXPECT_TRUE(observer.in_window_move());
-  EXPECT_EQ(HTBOTTOMRIGHT, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTBOTTOMRIGHT, window_tree()->last_window_resize_shadow());
-  window_tree()->AckAllChanges();
-  EXPECT_FALSE(observer.in_window_move());
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest, ClientAreaDoesntStartMove) {
-  WindowMoveObserver observer(window_tree_client_impl());
-
-  MoveInputTo(GetWindowBounds().CenterPoint());
-
-  PressInput();
-  MoveInputBy(20, 20);
-  EXPECT_FALSE(observer.in_window_move());
-  window_tree()->AckAllChanges();
-
-  // Simulate fullscreen; the events still don't trigger a drag because the y
-  // coordinate is too great.
-  test_delegate_.Fullscreen();
-  MoveInputTo(GetWindowBounds().CenterPoint());
-
-  PressInput();
-  MoveInputBy(20, 20);
-  EXPECT_FALSE(observer.in_window_move());
-  window_tree()->AckAllChanges();
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest, ClientAreaCanStartMove) {
-  WindowMoveObserver observer(window_tree_client_impl());
-  test_delegate_.Fullscreen();
-
-  MoveInputTo(GetWindowBounds().top_center());
-
-  PressInput();
-  MoveInputBy(0, 20);
-  // The window will be moved for a gesture sequence but not a mouse sequence.
-  EXPECT_NE(IsInputMouse(), observer.in_window_move());
-  window_tree()->AckAllChanges();
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest, MouseExitDoesNotCancelResize) {
-  // Create another window-tree-host and sets the capture there.
-  auto host2 = std::make_unique<WindowTreeHostMus>(
-      CreateInitParamsForTopLevel(window_tree_client_impl()));
-  host2->InitHost();
-  gfx::Rect host2_bounds = host()->GetBoundsInPixels();
-  host2_bounds.Offset(30, 30);
-  static_cast<WindowTreeHost*>(host2.get())->SetBoundsInPixels(host2_bounds);
-  host2->window()->Show();
-
-  test::TestWindowDelegate test_delegate;
-  std::unique_ptr<Window> window2(
-      CreateNormalWindow(12, host2->window(), &test_delegate));
-  window2->SetCapture();
-  window_tree()->AckAllChanges();
-
-  WindowMoveObserver observer(window_tree_client_impl());
-
-  // Makes the mouse event to cause window resize; since |window2| has the
-  // capture, this should cause MOUSE_EXITED on |window2|, but that shouldn't
-  // affect the behavior of resizing on the target window.
-  MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(1, 1));
-  PressInput();
-  MoveInputBy(-10, -10);
-  EXPECT_TRUE(observer.in_window_move());
-  EXPECT_EQ(HTTOPLEFT, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTTOPLEFT, window_tree()->last_window_resize_shadow());
-  window_tree()->AckAllChanges();
-  EXPECT_FALSE(observer.in_window_move());
-}
-
-TEST_P(ClientSideWindowMoveHandlerTest,
-       AdditionalEventsShouldntTriggerAnotherMove) {
-  WindowMoveObserver observer(window_tree_client_impl());
-
-  MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(10, 10));
-
-  PressInput();
-  MoveInputBy(10, 10);
-  EXPECT_EQ(1, observer.window_move_count());
-  EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-
-  // Nothing should happen for additional move events.
-  MoveInputBy(10, 10);
-  EXPECT_EQ(1, observer.window_move_count());
-  EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-  window_tree()->AckAllChanges();
-  EXPECT_FALSE(observer.in_window_move());
-  ReleaseInput();
-
-  // Restarting a move should start a new move.
-  MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(10, 10));
-  PressInput();
-  MoveInputBy(10, 10);
-  EXPECT_EQ(1, observer.window_move_count());
-  EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test());
-  EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow());
-  window_tree()->AckAllChanges();
-  EXPECT_FALSE(observer.in_window_move());
-}
-
-INSTANTIATE_TEST_SUITE_P(,
-                         ClientSideWindowMoveHandlerTest,
-                         ::testing::Values("mouse", "touch"));
-}  // namespace aura
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index 8701b96..ca665af7 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -139,11 +139,8 @@
                         ui::EF_LEFT_MOUSE_BUTTON);
   DispatchEventUsingWindowDispatcher(&event1);
 
-  // Event was tested for non-client area for the target window. The expected
-  // value is 2 when mode is MUS, since ClientSideWindowMoveHandler also invokes
-  // it.
-  EXPECT_EQ((Env::GetInstance()->mode() == Env::Mode::MUS) ? 2 : 1,
-            delegate1->non_client_count());
+  // Event was tested for non-client area for the target window.
+  EXPECT_EQ(1, delegate1->non_client_count());
   EXPECT_EQ(0, delegate2->non_client_count());
   // The non-client component test was in local coordinates.
   EXPECT_EQ(gfx::Point(1, 1), delegate1->non_client_location());
diff --git a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
index 9290429..9f7f2d9 100644
--- a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
+++ b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
@@ -89,8 +89,14 @@
   await remoteCall.waitForFiles(
       appId, expectedEntryRows, {ignoreLastModifiedTime: true});
   const files = await remoteCall.callRemoteTestUtil('getFileList', appId, []);
-  // The mtimes should not match.
-  chrome.test.assertTrue(files[0][3] != files[1][3], files[1][3]);
+  if (path == RootPath.DRIVE &&
+      await sendTestMessage({name: 'getDriveFsEnabled'}) === 'true') {
+    // DriveFs doesn't preserve mtimes so they shouldn't match.
+    chrome.test.assertTrue(files[0][3] != files[1][3], files[0][3]);
+  } else {
+    // The mtimes should match for Local files.
+    chrome.test.assertTrue(files[0][3] == files[1][3], files[0][3]);
+  }
 }
 
 /**
diff --git a/ui/gfx/transform.cc b/ui/gfx/transform.cc
index b42890ec3..4612850 100644
--- a/ui/gfx/transform.cc
+++ b/ui/gfx/transform.cc
@@ -164,6 +164,10 @@
 
 void Transform::Scale(SkMScalar x, SkMScalar y) { matrix_.preScale(x, y, 1); }
 
+void Transform::PostScale(SkMScalar x, SkMScalar y) {
+  matrix_.postScale(x, y, 1);
+}
+
 void Transform::Scale3d(SkMScalar x, SkMScalar y, SkMScalar z) {
   matrix_.preScale(x, y, z);
 }
@@ -176,6 +180,14 @@
   matrix_.preTranslate(x, y, 0);
 }
 
+void Transform::PostTranslate(const Vector2dF& offset) {
+  PostTranslate(offset.x(), offset.y());
+}
+
+void Transform::PostTranslate(SkMScalar x, SkMScalar y) {
+  matrix_.postTranslate(x, y, 0);
+}
+
 void Transform::Translate3d(const Vector3dF& offset) {
   Translate3d(offset.x(), offset.y(), offset.z());
 }
diff --git a/ui/gfx/transform.h b/ui/gfx/transform.h
index 433a545d..62930a6 100644
--- a/ui/gfx/transform.h
+++ b/ui/gfx/transform.h
@@ -99,6 +99,10 @@
     return gfx::Vector2dF(matrix_.get(0, 0), matrix_.get(1, 1));
   }
 
+  // Applies a scale to the current transformation and assigns the result to
+  // |this|.
+  void PostScale(SkMScalar x, SkMScalar y);
+
   // Applies the current transformation on a translation and assigns the result
   // to |this|.
   void Translate(const Vector2dF& offset);
@@ -106,6 +110,11 @@
   void Translate3d(const Vector3dF& offset);
   void Translate3d(SkMScalar x, SkMScalar y, SkMScalar z);
 
+  // Applies a translation to the current transformation and assigns the result
+  // to |this|.
+  void PostTranslate(const Vector2dF& offset);
+  void PostTranslate(SkMScalar x, SkMScalar y);
+
   // Applies the current transformation on a skew and assigns the result
   // to |this|.
   void Skew(double angle_x, double angle_y);
diff --git a/ui/views/accessibility/ax_aura_window_utils.h b/ui/views/accessibility/ax_aura_window_utils.h
index 20df81f6..cd160f1 100644
--- a/ui/views/accessibility/ax_aura_window_utils.h
+++ b/ui/views/accessibility/ax_aura_window_utils.h
@@ -17,6 +17,7 @@
 // to its corresponding client window. This is just a temporary solution to
 // that issue and should be removed once Mash is fully launched.
 // crbug.com/911945
+// TODO(jamescook): Delete this.
 class VIEWS_EXPORT AXAuraWindowUtils {
  public:
   virtual ~AXAuraWindowUtils();
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
index e774feca..ada070f7 100644
--- a/ui/views/bubble/bubble_frame_view.cc
+++ b/ui/views/bubble/bubble_frame_view.cc
@@ -113,10 +113,9 @@
 std::unique_ptr<Button> BubbleFrameView::CreateCloseButton(
     ButtonListener* listener,
     bool is_dark_mode) {
-  ImageButton* close_button = nullptr;
-  close_button = CreateVectorImageButton(listener);
+  auto close_button = CreateVectorImageButton(listener);
   SetImageFromVectorIconWithColor(
-      close_button, vector_icons::kCloseRoundedIcon,
+      close_button.get(), vector_icons::kCloseRoundedIcon,
       is_dark_mode ? SkColorSetA(SK_ColorWHITE, 0xDD) : gfx::kGoogleGrey700);
   close_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_CLOSE));
   close_button->SizeToPreferredSize();
@@ -131,7 +130,7 @@
   // access to the close button when not using a screen reader is done via the
   // ESC key handler in DialogClientView.
   close_button->SetFocusBehavior(View::FocusBehavior::NEVER);
-  return base::WrapUnique(close_button);
+  return close_button;
 }
 
 gfx::Rect BubbleFrameView::GetBoundsForClientView() const {
diff --git a/ui/views/controls/button/image_button_factory.cc b/ui/views/controls/button/image_button_factory.cc
index 7ee5b3b7..e5f56eb 100644
--- a/ui/views/controls/button/image_button_factory.cc
+++ b/ui/views/controls/button/image_button_factory.cc
@@ -28,9 +28,9 @@
 
 }  // namespace
 
-ImageButton* CreateVectorImageButton(ButtonListener* listener) {
-  ImageButton* button = new ImageButton(listener);
-  ConfigureVectorImageButton(button);
+std::unique_ptr<ImageButton> CreateVectorImageButton(ButtonListener* listener) {
+  auto button = std::make_unique<ImageButton>(listener);
+  ConfigureVectorImageButton(button.get());
   return button;
 }
 
diff --git a/ui/views/controls/button/image_button_factory.h b/ui/views/controls/button/image_button_factory.h
index 94d2dfe..38abccf7 100644
--- a/ui/views/controls/button/image_button_factory.h
+++ b/ui/views/controls/button/image_button_factory.h
@@ -21,7 +21,8 @@
 
 // Creates an ImageButton with an ink drop and a centered image in preparation
 // for applying a vector icon with SetImageFromVectorIcon below.
-VIEWS_EXPORT ImageButton* CreateVectorImageButton(ButtonListener* listener);
+VIEWS_EXPORT std::unique_ptr<ImageButton> CreateVectorImageButton(
+    ButtonListener* listener);
 
 // Creates a ToggleImageButton with an ink drop and a centered image in
 // preperation for applying a vector icon from SetImageFromVectorIcon and
diff --git a/ui/views/controls/button/image_button_factory_unittest.cc b/ui/views/controls/button/image_button_factory_unittest.cc
index 5a610414..6d022452d 100644
--- a/ui/views/controls/button/image_button_factory_unittest.cc
+++ b/ui/views/controls/button/image_button_factory_unittest.cc
@@ -18,28 +18,26 @@
 using ImageButtonFactoryTest = ViewsTestBase;
 
 TEST_F(ImageButtonFactoryTest, CreateVectorImageButton) {
-  ImageButton* button = CreateVectorImageButton(nullptr);
+  auto button = CreateVectorImageButton(nullptr);
   EXPECT_EQ(ImageButton::ALIGN_CENTER, button->h_alignment_);
   EXPECT_EQ(ImageButton::ALIGN_MIDDLE, button->v_alignment_);
-  delete button;
 }
 
 TEST_F(ImageButtonFactoryTest, SetImageFromVectorIcon) {
-  ImageButton* button = CreateVectorImageButton(nullptr);
-  SetImageFromVectorIcon(button, vector_icons::kCloseRoundedIcon, SK_ColorRED);
+  auto button = CreateVectorImageButton(nullptr);
+  SetImageFromVectorIcon(button.get(), vector_icons::kCloseRoundedIcon,
+                         SK_ColorRED);
   EXPECT_FALSE(button->GetImage(Button::STATE_NORMAL).isNull());
   EXPECT_FALSE(button->GetImage(Button::STATE_DISABLED).isNull());
   EXPECT_EQ(color_utils::DeriveDefaultIconColor(SK_ColorRED),
             button->GetInkDropBaseColor());
-  delete button;
 }
 
 TEST_F(ImageButtonFactoryTest, SetImageFromVectorIcon_Default) {
-  ImageButton* button = CreateVectorImageButton(nullptr);
-  SetImageFromVectorIcon(button, vector_icons::kCloseRoundedIcon);
+  auto button = CreateVectorImageButton(nullptr);
+  SetImageFromVectorIcon(button.get(), vector_icons::kCloseRoundedIcon);
   EXPECT_EQ(button->GetNativeTheme()->GetSystemColor(
                 ui::NativeTheme::kColorId_DefaultIconColor),
             button->GetInkDropBaseColor());
-  delete button;
 }
 }  // namespace views
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html
index 5d3946d..2f44ddb6 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html
@@ -1,12 +1,4 @@
 <link rel="import" href="chrome://resources/html/cr.html">
-<script src="chrome://resources/js/mojo_bindings_lite.js"></script>
-<script src="chrome://resources/js/time.mojom-lite.js"></script>
-<script src="chrome://resources/js/chromeos/multidevice_types.mojom-lite.js">
-</script>
-<script src="chrome://resources/js/chromeos/device_sync.mojom-lite.js"></script>
-<script src="chrome://resources/js/chromeos/multidevice_setup.mojom-lite.js">
-</script>
-<script src="chrome://resources/js/chromeos/multidevice_setup_constants.mojom-lite.js">
-</script>
-<script src="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api.js">
-</script>
+<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
+<link rel="import" href="chrome://resources/mojo/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.html">
+<script src="mojo_api.js"></script>
\ No newline at end of file
diff --git a/ui/webui/resources/cr_polymer_resources.grdp b/ui/webui/resources/cr_polymer_resources.grdp
index f3b5b550..2c1f69b 100644
--- a/ui/webui/resources/cr_polymer_resources.grdp
+++ b/ui/webui/resources/cr_polymer_resources.grdp
@@ -32,6 +32,8 @@
   <structure name="IDR_WEBUI_HTML_SEARCH_HIGHLIGHT_UTILS"
              file="html/search_highlight_utils.html" type="chrome_html"
              compress="gzip" />
+  <structure name="IDR_WEBUI_HTML_SUBPAGE_LOADER"
+             file="html/subpage_loader.html" type="chrome_html" />
 
   <!-- CSS resources -->
   <structure name="IDR_WEBUI_CSS_MD_COLORS"
@@ -64,4 +66,6 @@
   <structure name="IDR_WEBUI_JS_SEARCH_HIGHLIGHT_UTILS"
              file="js/search_highlight_utils.js" type="chrome_html"
              compress="gzip" />
+  <structure name="IDR_WEBUI_JS_SUBPAGE_LOADER"
+             file="js/subpage_loader.js" type="chrome_html" />
 </grit-part>
diff --git a/ui/webui/resources/html/subpage_loader.html b/ui/webui/resources/html/subpage_loader.html
new file mode 100644
index 0000000..f87964d
--- /dev/null
+++ b/ui/webui/resources/html/subpage_loader.html
@@ -0,0 +1,3 @@
+<script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js">
+</script>
+<script src="subpage_loader.js"></script>
diff --git a/ui/webui/resources/js/subpage_loader.js b/ui/webui/resources/js/subpage_loader.js
new file mode 100644
index 0000000..8dd3dd9
--- /dev/null
+++ b/ui/webui/resources/js/subpage_loader.js
@@ -0,0 +1,9 @@
+// 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.
+
+const subpageImport = document.createElement('link');
+subpageImport.rel = 'import';
+const params = new URLSearchParams(window.location.search.substring(1));
+subpageImport.href = params.get('file');
+document.head.appendChild(subpageImport);