diff --git a/DEPS b/DEPS
index 35052cb..935db656 100644
--- a/DEPS
+++ b/DEPS
@@ -127,11 +127,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': '18e5841c0daea74657d22dbff2694e5026b8bb52',
+  'skia_revision': '8546335d2d40c31e7c3a3672aad583ccf08beff3',
   # 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': '045e76296f66cba2ef67bcfb39fd3ff38236f282',
+  'v8_revision': '6b0fdfceb1d6b3c73a1e84d510307ef965601465',
   # 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.
@@ -139,15 +139,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'cf9b2853a7e71e67c1197ebafcb7c0f1e4ca6b68',
+  'angle_revision': 'd09546e1ec906c5027c25ba0ba3a49e5affb6643',
   # 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': '7aafb27453d352a704ccae3805b43fc6422edaca',
+  'swiftshader_revision': 'e53533d6fdf9838ecc16842b5e071c132881676a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'd6b7287745c6f60ddb2d91a64e9c91d2f297a76a',
+  'pdfium_revision': '36e541ccbf9f30b0ae2604bd0ac4b3bd9e853d6b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -158,7 +158,7 @@
   #
   # Note this revision should be updated with
   # third_party/boringssl/roll_boringssl.py, not roll-dep.
-  'boringssl_revision': '7ef4223fb32431529a797c5b8d3bf26ece6c138b',
+  'boringssl_revision': 'c18353d214c04da5349e97283d6d70b8176a96f8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -190,7 +190,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'b4fdbb737c9841960237a182dc531b1fafb3c2d1',
+  'catapult_revision': 'e4abf4c59be62c98f05d62d9a5dd8418c6d92cdb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -238,7 +238,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': 'fde69dcd80cc1ca548300702adf01eeb25441f3e',
+  'spv_tools_revision': 'a006cbc1d04c0bd51489ef9b56976507ff72511e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -258,7 +258,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'e72b8874b23a8219c68fd7f1d7db097fa4811114',
+  'quiche_revision': '3cab5a95cea82094e5599d07a5e4f1f9aeb551bb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling clang format
   # and whatever else without interference from each other.
@@ -634,17 +634,6 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/androidx': {
-      'packages': [
-          {
-              'package': 'chromium/third_party/androidx',
-              'version': 'Z2TKYlinmuC0HUW4ulv89ataKxbXJDsnPYgylLVzuBEC',
-          },
-      ],
-      'condition': 'checkout_android',
-      'dep_type': 'cipd',
-  },
-
   'src/third_party/angle':
     Var('chromium_git') + '/angle/angle.git' + '@' +  Var('angle_revision'),
 
@@ -738,7 +727,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '202f8887f83f2b5acc9be38ddac66475faa0ffd9',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c08d404a452b5d55b99fb665ace0435ba4d6e198',
       'condition': 'checkout_linux',
   },
 
@@ -763,7 +752,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e83100437106c8303aa955d2bafb6b8b1978ed59',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '298f2cf820dfe45dff53b0e41b11441dbf72b48c',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -832,7 +821,7 @@
   },
 
   'src/third_party/glslang/src':
-    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'a51d3d9f223361165127ded3cd2e59d81e22d91f',
+    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'ec484527b6438438cb4fe2ffa22fd1ebb3cb0378',
 
   'src/third_party/google_toolbox_for_mac/src': {
       'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
@@ -1276,7 +1265,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '8aa00f03714806b74f7f47d951b91af8e0f49968',
+    Var('webrtc_git') + '/src.git' + '@' + '487c09bb73c18fd7ae8c2efc746531422c324c1f',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1317,7 +1306,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@67e798b11f20401e6132adc5bff499de28291978',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d2b61f7238c15ebf2d920476f1b7b734b4acdee8',
     'condition': 'checkout_src_internal',
   },
 
@@ -1367,6 +1356,61 @@
       'dep_type': 'cipd',
   },
 
+  'src/third_party/android_deps/libs/androidx_annotation_annotation': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_annotation_annotation',
+              'version': 'version:1.0.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common',
+              'version': 'version:2.0.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/androidx_test_core': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_test_core',
+              'version': 'version:1.0.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/androidx_test_ext_junit': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_test_ext_junit',
+              'version': 'version:1.0.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/androidx_test_monitor': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/androidx_test_monitor',
+              'version': 'version:1.1.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   'src/third_party/android_deps/libs/com_android_support_animated_vector_drawable': {
       'packages': [
           {
diff --git a/WATCHLISTS b/WATCHLISTS
index b52b697..2fae907b 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -804,6 +804,13 @@
     'crostini': {
       'filepath': 'crostini',
     },
+    'cups_printing' : {
+      'filepath': 'chrome/browser/resources/settings/printing_page/'\
+                  '|chrome/test/data/webui/settings/cups_printer_page_tests.js'\
+                  '|chrome/browser/ui/webui/settings/chromeos/cups_printers_handler'\
+                  '|chrome/browser/chromeos/printing/'\
+                  '|printing/',
+    },
     'custom_tabs': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/customtabs/|'\
                   'chrome/android/java/src/org/chromium/chrome/browser/browseractions/|'\
@@ -2158,6 +2165,9 @@
                         'cywang@chromium.org',
                         'vovoy@chromium.org'],
     'crostini': ['crostini-ui@chromium.org'],
+    'cups_printing': ['baileyberro+watch-printers@chromium.org',
+                      'jimmyxgong+watch-printers@chromium.org',
+                      'zentaro+watch-printers@chromium.org'],
     'custom_tabs': ['amalova+watch@chromium.org',
                     'lizeb+watch-custom-tabs@chromium.org',
                     'peconn+watch@chromium.org',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 334711cc..349ca35 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -531,8 +531,6 @@
     "browser/aw_devtools_server.h",
     "browser/aw_download_manager_delegate.cc",
     "browser/aw_download_manager_delegate.h",
-    "browser/aw_draw_fn_impl.cc",
-    "browser/aw_draw_fn_impl.h",
     "browser/aw_feature_list.cc",
     "browser/aw_feature_list.h",
     "browser/aw_feature_list_creator.cc",
@@ -540,10 +538,6 @@
     "browser/aw_form_database.cc",
     "browser/aw_form_database_service.cc",
     "browser/aw_form_database_service.h",
-    "browser/aw_gl_functor.cc",
-    "browser/aw_gl_functor.h",
-    "browser/aw_gl_surface.cc",
-    "browser/aw_gl_surface.h",
     "browser/aw_http_auth_handler.cc",
     "browser/aw_http_auth_handler.h",
     "browser/aw_javascript_dialog_manager.cc",
@@ -560,8 +554,6 @@
     "browser/aw_pdf_exporter.h",
     "browser/aw_permission_manager.cc",
     "browser/aw_permission_manager.h",
-    "browser/aw_picture.cc",
-    "browser/aw_picture.h",
     "browser/aw_print_manager.cc",
     "browser/aw_print_manager.h",
     "browser/aw_proxy_controller.cc",
@@ -574,8 +566,6 @@
     "browser/aw_render_process.cc",
     "browser/aw_render_process.h",
     "browser/aw_render_process_gone_delegate.h",
-    "browser/aw_render_thread_context_provider.cc",
-    "browser/aw_render_thread_context_provider.h",
     "browser/aw_renderer_priority.h",
     "browser/aw_resource_context.cc",
     "browser/aw_resource_context.h",
@@ -597,31 +587,51 @@
     "browser/aw_web_contents_view_delegate.h",
     "browser/aw_web_ui_controller_factory.cc",
     "browser/aw_web_ui_controller_factory.h",
-    "browser/browser_view_renderer.cc",
-    "browser/browser_view_renderer.h",
-    "browser/browser_view_renderer_client.h",
-    "browser/child_frame.cc",
-    "browser/child_frame.h",
     "browser/command_line_helper.cc",
     "browser/command_line_helper.h",
-    "browser/compositor_frame_consumer.h",
-    "browser/compositor_frame_producer.h",
-    "browser/compositor_id.cc",
-    "browser/compositor_id.h",
     "browser/cookie_manager.cc",
     "browser/cookie_manager.h",
-    "browser/deferred_gpu_command_service.cc",
-    "browser/deferred_gpu_command_service.h",
     "browser/find_helper.cc",
     "browser/find_helper.h",
-    "browser/hardware_renderer.cc",
-    "browser/hardware_renderer.h",
+    "browser/gfx/aw_draw_fn_impl.cc",
+    "browser/gfx/aw_draw_fn_impl.h",
+    "browser/gfx/aw_gl_functor.cc",
+    "browser/gfx/aw_gl_functor.h",
+    "browser/gfx/aw_gl_surface.cc",
+    "browser/gfx/aw_gl_surface.h",
+    "browser/gfx/aw_picture.cc",
+    "browser/gfx/aw_picture.h",
+    "browser/gfx/aw_render_thread_context_provider.cc",
+    "browser/gfx/aw_render_thread_context_provider.h",
+    "browser/gfx/browser_view_renderer.cc",
+    "browser/gfx/browser_view_renderer.h",
+    "browser/gfx/browser_view_renderer_client.h",
+    "browser/gfx/child_frame.cc",
+    "browser/gfx/child_frame.h",
+    "browser/gfx/compositor_frame_consumer.h",
+    "browser/gfx/compositor_frame_producer.h",
+    "browser/gfx/compositor_id.cc",
+    "browser/gfx/compositor_id.h",
+    "browser/gfx/deferred_gpu_command_service.cc",
+    "browser/gfx/deferred_gpu_command_service.h",
+    "browser/gfx/hardware_renderer.cc",
+    "browser/gfx/hardware_renderer.h",
+    "browser/gfx/java_browser_view_renderer_helper.cc",
+    "browser/gfx/java_browser_view_renderer_helper.h",
+    "browser/gfx/parent_compositor_draw_constraints.cc",
+    "browser/gfx/parent_compositor_draw_constraints.h",
+    "browser/gfx/parent_output_surface.cc",
+    "browser/gfx/parent_output_surface.h",
+    "browser/gfx/render_thread_manager.cc",
+    "browser/gfx/render_thread_manager.h",
+    "browser/gfx/scoped_app_gl_state_restore.cc",
+    "browser/gfx/scoped_app_gl_state_restore.h",
+    "browser/gfx/surfaces_instance.cc",
+    "browser/gfx/surfaces_instance.h",
     "browser/icon_helper.cc",
     "browser/icon_helper.h",
     "browser/input_stream.cc",
     "browser/input_stream.h",
-    "browser/java_browser_view_renderer_helper.cc",
-    "browser/java_browser_view_renderer_helper.h",
     "browser/net/android_stream_reader_url_request_job.cc",
     "browser/net/android_stream_reader_url_request_job.h",
     "browser/net/aw_cookie_change_dispatcher_wrapper.cc",
@@ -656,10 +666,6 @@
     "browser/net_network_service/android_stream_reader_url_loader.h",
     "browser/net_network_service/aw_cookie_manager_wrapper.cc",
     "browser/net_network_service/aw_cookie_manager_wrapper.h",
-    "browser/parent_compositor_draw_constraints.cc",
-    "browser/parent_compositor_draw_constraints.h",
-    "browser/parent_output_surface.cc",
-    "browser/parent_output_surface.h",
     "browser/permission/aw_permission_request.cc",
     "browser/permission/aw_permission_request.h",
     "browser/permission/aw_permission_request_delegate.cc",
@@ -674,8 +680,6 @@
     "browser/permission/simple_permission_request.h",
     "browser/popup_touch_handle_drawable.cc",
     "browser/popup_touch_handle_drawable.h",
-    "browser/render_thread_manager.cc",
-    "browser/render_thread_manager.h",
     "browser/renderer_host/auto_login_parser.cc",
     "browser/renderer_host/auto_login_parser.h",
     "browser/renderer_host/aw_render_view_host_ext.cc",
@@ -692,12 +696,8 @@
     "browser/safe_browsing/aw_safe_browsing_whitelist_manager.h",
     "browser/safe_browsing/aw_url_checker_delegate_impl.cc",
     "browser/safe_browsing/aw_url_checker_delegate_impl.h",
-    "browser/scoped_app_gl_state_restore.cc",
-    "browser/scoped_app_gl_state_restore.h",
     "browser/state_serializer.cc",
     "browser/state_serializer.h",
-    "browser/surfaces_instance.cc",
-    "browser/surfaces_instance.h",
     "browser/tracing/aw_trace_event_args_whitelist.cc",
     "browser/tracing/aw_trace_event_args_whitelist.h",
     "browser/tracing/aw_tracing_controller.cc",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index ad8baca..4648ed7 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -4,7 +4,6 @@
   "+android_webview/common",
   "+android_webview/grit",
   "+android_webview/jni",
-  "+android_webview/public/browser",
   "+cc",
   "+components/autofill/android",
   "+components/autofill/content/browser",
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index c585f63..658e19f 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -14,29 +14,28 @@
 #include "android_webview/browser/aw_contents_client_bridge.h"
 #include "android_webview/browser/aw_contents_io_thread_client.h"
 #include "android_webview/browser/aw_contents_lifecycle_notifier.h"
-#include "android_webview/browser/aw_gl_functor.h"
 #include "android_webview/browser/aw_pdf_exporter.h"
-#include "android_webview/browser/aw_picture.h"
 #include "android_webview/browser/aw_render_process.h"
 #include "android_webview/browser/aw_renderer_priority.h"
 #include "android_webview/browser/aw_resource_context.h"
 #include "android_webview/browser/aw_settings.h"
 #include "android_webview/browser/aw_web_contents_delegate.h"
-#include "android_webview/browser/browser_view_renderer.h"
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/deferred_gpu_command_service.h"
-#include "android_webview/browser/java_browser_view_renderer_helper.h"
+#include "android_webview/browser/gfx/aw_gl_functor.h"
+#include "android_webview/browser/gfx/aw_picture.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/java_browser_view_renderer_helper.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
+#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
 #include "android_webview/browser/permission/aw_permission_request.h"
 #include "android_webview/browser/permission/permission_request_handler.h"
 #include "android_webview/browser/permission/simple_permission_request.h"
-#include "android_webview/browser/render_thread_manager.h"
 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
-#include "android_webview/browser/scoped_app_gl_state_restore.h"
 #include "android_webview/browser/state_serializer.h"
 #include "android_webview/common/aw_hit_test_data.h"
 #include "android_webview/common/aw_switches.h"
 #include "android_webview/common/devtools_instrumentation.h"
-#include "android_webview/public/browser/draw_gl.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h
index 6645f050..bc7e248 100644
--- a/android_webview/browser/aw_contents.h
+++ b/android_webview/browser/aw_contents.h
@@ -12,9 +12,9 @@
 
 #include "android_webview/browser/aw_browser_permission_request_delegate.h"
 #include "android_webview/browser/aw_render_process_gone_delegate.h"
-#include "android_webview/browser/browser_view_renderer.h"
-#include "android_webview/browser/browser_view_renderer_client.h"
 #include "android_webview/browser/find_helper.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/browser_view_renderer_client.h"
 #include "android_webview/browser/icon_helper.h"
 #include "android_webview/browser/permission/permission_request_handler_client.h"
 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
diff --git a/android_webview/browser/aw_devtools_manager_delegate.cc b/android_webview/browser/aw_devtools_manager_delegate.cc
index ffa4ce9..ffd5f4e0 100644
--- a/android_webview/browser/aw_devtools_manager_delegate.cc
+++ b/android_webview/browser/aw_devtools_manager_delegate.cc
@@ -4,7 +4,7 @@
 
 #include "android_webview/browser/aw_devtools_manager_delegate.h"
 
-#include "android_webview/browser/browser_view_renderer.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
 #include "android_webview/common/aw_content_client.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
diff --git a/android_webview/browser/aw_devtools_server.cc b/android_webview/browser/aw_devtools_server.cc
index 86107a3..8ab1b929 100644
--- a/android_webview/browser/aw_devtools_server.cc
+++ b/android_webview/browser/aw_devtools_server.cc
@@ -7,7 +7,7 @@
 #include <utility>
 
 #include "android_webview/browser/aw_contents.h"
-#include "android_webview/browser/browser_view_renderer.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
 #include "android_webview/common/aw_content_client.h"
 #include "base/bind.h"
 #include "base/files/file_path.h"
diff --git a/android_webview/browser/aw_download_manager_delegate.cc b/android_webview/browser/aw_download_manager_delegate.cc
index a9617c09..891d00d 100644
--- a/android_webview/browser/aw_download_manager_delegate.cc
+++ b/android_webview/browser/aw_download_manager_delegate.cc
@@ -4,14 +4,15 @@
 
 #include "android_webview/browser/aw_download_manager_delegate.h"
 
+#include "android_webview/browser/aw_content_browser_client.h"
+#include "android_webview/browser/aw_contents_client_bridge.h"
 #include "base/files/file_path.h"
+#include "base/task/post_task.h"
 #include "components/download/public/common/download_danger_type.h"
 #include "components/download/public/common/download_item.h"
-
-#include "android_webview/browser/aw_contents_client_bridge.h"
-#include "base/task/post_task.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
 
 namespace android_webview {
 
@@ -70,10 +71,16 @@
     const std::string& request_origin,
     int64_t content_length,
     content::WebContents* web_contents) {
+  std::string aw_user_agent = web_contents->GetUserAgentOverride();
+  if (aw_user_agent.empty()) {
+    // use default user agent if nothing is provided
+    aw_user_agent = user_agent.empty() ? GetUserAgent() : user_agent;
+  }
   base::PostTaskWithTraits(
       FROM_HERE, {content::BrowserThread::UI},
-      base::BindOnce(&DownloadStartingOnUIThread, web_contents, url, user_agent,
-                     content_disposition, mime_type, content_length));
+      base::BindOnce(&DownloadStartingOnUIThread, web_contents, url,
+                     aw_user_agent, content_disposition, mime_type,
+                     content_length));
   return true;
 }
 
diff --git a/android_webview/browser/aw_download_manager_delegate.h b/android_webview/browser/aw_download_manager_delegate.h
index d62cfc7..a2280aa2e 100644
--- a/android_webview/browser/aw_download_manager_delegate.h
+++ b/android_webview/browser/aw_download_manager_delegate.h
@@ -10,6 +10,12 @@
 #include "base/supports_user_data.h"
 #include "content/public/browser/download_manager_delegate.h"
 
+namespace content {
+
+class WebContents;
+
+}  // namespace content
+
 namespace android_webview {
 
 // Android WebView does not use Chromium downloads, so implement methods here to
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc
index af9f731..f8175890 100644
--- a/android_webview/browser/aw_settings.cc
+++ b/android_webview/browser/aw_settings.cc
@@ -142,7 +142,7 @@
   UpdateFormDataPreferencesLocked(env, obj);
   UpdateRendererPreferencesLocked(env, obj);
   UpdateOffscreenPreRasterLocked(env, obj);
-  UpdateShouldSuppressErrorStateLocked(env, obj);
+  UpdateWillSuppressErrorStateLocked(env, obj);
 }
 
 void AwSettings::UpdateUserAgentLocked(JNIEnv* env,
@@ -198,15 +198,15 @@
   }
 }
 
-void AwSettings::UpdateShouldSuppressErrorStateLocked(
+void AwSettings::UpdateWillSuppressErrorStateLocked(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) {
   AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
   if (!rvhe)
     return;
 
-  bool suppress = Java_AwSettings_getShouldSuppressErrorPageLocked(env, obj);
-  rvhe->SetShouldSuppressErrorPage(suppress);
+  bool suppress = Java_AwSettings_getWillSuppressErrorPageLocked(env, obj);
+  rvhe->SetWillSuppressErrorPage(suppress);
 }
 
 void AwSettings::UpdateFormDataPreferencesLocked(
diff --git a/android_webview/browser/aw_settings.h b/android_webview/browser/aw_settings.h
index 59b39a3..0337890 100644
--- a/android_webview/browser/aw_settings.h
+++ b/android_webview/browser/aw_settings.h
@@ -51,7 +51,7 @@
   void UpdateInitialPageScaleLocked(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
-  void UpdateShouldSuppressErrorStateLocked(
+  void UpdateWillSuppressErrorStateLocked(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
   void UpdateUserAgentLocked(JNIEnv* env,
diff --git a/android_webview/browser/gfx/DEPS b/android_webview/browser/gfx/DEPS
new file mode 100644
index 0000000..e7494c97
--- /dev/null
+++ b/android_webview/browser/gfx/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+  "-android_webview",
+  "-android_webview/browser",
+  "+android_webview/browser/gfx",
+  "+android_webview/public/browser",
+]
+
diff --git a/android_webview/browser/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc
similarity index 99%
rename from android_webview/browser/aw_draw_fn_impl.cc
rename to android_webview/browser/gfx/aw_draw_fn_impl.cc
index f5345be..efa4b5f 100644
--- a/android_webview/browser/aw_draw_fn_impl.cc
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/aw_draw_fn_impl.h"
+#include "android_webview/browser/gfx/aw_draw_fn_impl.h"
 
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/android/android_hardware_buffer_compat.h"
diff --git a/android_webview/browser/aw_draw_fn_impl.h b/android_webview/browser/gfx/aw_draw_fn_impl.h
similarity index 89%
rename from android_webview/browser/aw_draw_fn_impl.h
rename to android_webview/browser/gfx/aw_draw_fn_impl.h
index 924d6af..5936a5f 100644
--- a/android_webview/browser/aw_draw_fn_impl.h
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_AW_DRAW_FN_IMPL_H_
-#define ANDROID_WEBVIEW_BROWSER_AW_DRAW_FN_IMPL_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
 
 #include <deque>
 
-#include "android_webview/browser/compositor_frame_consumer.h"
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/compositor_frame_consumer.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 #include "android_webview/public/browser/draw_fn.h"
 #include "base/android/jni_weak_ref.h"
 #include "gpu/vulkan/init/vulkan_factory.h"
@@ -88,4 +88,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_AW_DRAW_FN_IMPL_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
diff --git a/android_webview/browser/aw_gl_functor.cc b/android_webview/browser/gfx/aw_gl_functor.cc
similarity index 98%
rename from android_webview/browser/aw_gl_functor.cc
rename to android_webview/browser/gfx/aw_gl_functor.cc
index ecc2b68..34a5646 100644
--- a/android_webview/browser/aw_gl_functor.cc
+++ b/android_webview/browser/gfx/aw_gl_functor.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/aw_gl_functor.h"
+#include "android_webview/browser/gfx/aw_gl_functor.h"
 
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/stl_util.h"
diff --git a/android_webview/browser/aw_gl_functor.h b/android_webview/browser/gfx/aw_gl_functor.h
similarity index 81%
rename from android_webview/browser/aw_gl_functor.h
rename to android_webview/browser/gfx/aw_gl_functor.h
index 17d2294..68fa7f2f 100644
--- a/android_webview/browser/aw_gl_functor.h
+++ b/android_webview/browser/gfx/aw_gl_functor.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_AW_GL_FUNCTOR_H_
-#define ANDROID_WEBVIEW_BROWSER_AW_GL_FUNCTOR_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_FUNCTOR_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_FUNCTOR_H_
 
-#include "android_webview/browser/compositor_frame_consumer.h"
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/compositor_frame_consumer.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 #include "base/android/jni_weak_ref.h"
 
 struct AwDrawGLInfo;
@@ -45,4 +45,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_AW_GL_FUNCTOR_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_FUNCTOR_H_
diff --git a/android_webview/browser/aw_gl_surface.cc b/android_webview/browser/gfx/aw_gl_surface.cc
similarity index 90%
rename from android_webview/browser/aw_gl_surface.cc
rename to android_webview/browser/gfx/aw_gl_surface.cc
index 073faa21..9536a8e 100644
--- a/android_webview/browser/aw_gl_surface.cc
+++ b/android_webview/browser/gfx/aw_gl_surface.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/aw_gl_surface.h"
+#include "android_webview/browser/gfx/aw_gl_surface.h"
 
-#include "android_webview/browser/scoped_app_gl_state_restore.h"
+#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
 
 namespace android_webview {
 
diff --git a/android_webview/browser/aw_gl_surface.h b/android_webview/browser/gfx/aw_gl_surface.h
similarity index 87%
rename from android_webview/browser/aw_gl_surface.h
rename to android_webview/browser/gfx/aw_gl_surface.h
index 3640c8e..ccc2b21 100644
--- a/android_webview/browser/aw_gl_surface.h
+++ b/android_webview/browser/gfx/aw_gl_surface.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
-#define ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_SURFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_SURFACE_H_
 
 #include "base/macros.h"
 #include "ui/gl/gl_surface.h"
@@ -41,4 +41,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_AW_GL_SURFACE_H_
diff --git a/android_webview/browser/aw_picture.cc b/android_webview/browser/gfx/aw_picture.cc
similarity index 91%
rename from android_webview/browser/aw_picture.cc
rename to android_webview/browser/gfx/aw_picture.cc
index 2181b65..4fa249df 100644
--- a/android_webview/browser/aw_picture.cc
+++ b/android_webview/browser/gfx/aw_picture.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/aw_picture.h"
+#include "android_webview/browser/gfx/aw_picture.h"
 
-#include "android_webview/browser/java_browser_view_renderer_helper.h"
+#include "android_webview/browser/gfx/java_browser_view_renderer_helper.h"
 #include "jni/AwPicture_jni.h"
 #include "third_party/skia/include/core/SkPicture.h"
 
diff --git a/android_webview/browser/aw_picture.h b/android_webview/browser/gfx/aw_picture.h
similarity index 86%
rename from android_webview/browser/aw_picture.h
rename to android_webview/browser/gfx/aw_picture.h
index db3566d..eac03b2 100644
--- a/android_webview/browser/aw_picture.h
+++ b/android_webview/browser/gfx/aw_picture.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_AW_PICTURE_H_
-#define ANDROID_WEBVIEW_BROWSER_AW_PICTURE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_PICTURE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_AW_PICTURE_H_
 
 #include <memory>
 
@@ -36,4 +36,4 @@
 
 }  // android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_AW_PICTURE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_AW_PICTURE_H_
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/gfx/aw_render_thread_context_provider.cc
similarity index 98%
rename from android_webview/browser/aw_render_thread_context_provider.cc
rename to android_webview/browser/gfx/aw_render_thread_context_provider.cc
index 95e06d5..39f0439 100644
--- a/android_webview/browser/aw_render_thread_context_provider.cc
+++ b/android_webview/browser/gfx/aw_render_thread_context_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/aw_render_thread_context_provider.h"
+#include "android_webview/browser/gfx/aw_render_thread_context_provider.h"
 
 #include <utility>
 
diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/gfx/aw_render_thread_context_provider.h
similarity index 92%
rename from android_webview/browser/aw_render_thread_context_provider.h
rename to android_webview/browser/gfx/aw_render_thread_context_provider.h
index 3767baff..b34b8fd6 100644
--- a/android_webview/browser/aw_render_thread_context_provider.h
+++ b/android_webview/browser/gfx/aw_render_thread_context_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
-#define ANDROID_WEBVIEW_BROWSER_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
 
 #include <stdint.h>
 
@@ -82,4 +82,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc
similarity index 99%
rename from android_webview/browser/browser_view_renderer.cc
rename to android_webview/browser/gfx/browser_view_renderer.cc
index bcacb607..d61008b 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/browser_view_renderer.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
 
 #include <memory>
 #include <utility>
 
-#include "android_webview/browser/browser_view_renderer_client.h"
-#include "android_webview/browser/compositor_frame_consumer.h"
+#include "android_webview/browser/gfx/browser_view_renderer_client.h"
+#include "android_webview/browser/gfx/compositor_frame_consumer.h"
 #include "base/auto_reset.h"
 #include "base/command_line.h"
 #include "base/logging.h"
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/gfx/browser_view_renderer.h
similarity index 95%
rename from android_webview/browser/browser_view_renderer.h
rename to android_webview/browser/gfx/browser_view_renderer.h
index 177c1c9e..1919ccd 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/gfx/browser_view_renderer.h
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
-#define ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_
 
 #include <stddef.h>
 
 #include <map>
 #include <set>
 
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/compositor_frame_producer.h"
-#include "android_webview/browser/compositor_id.h"
-#include "android_webview/browser/parent_compositor_draw_constraints.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/compositor_frame_producer.h"
+#include "android_webview/browser/gfx/compositor_id.h"
+#include "android_webview/browser/gfx/parent_compositor_draw_constraints.h"
 #include "base/callback.h"
 #include "base/cancelable_callback.h"
 #include "base/macros.h"
@@ -260,4 +260,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_H_
diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/gfx/browser_view_renderer_client.h
similarity index 90%
rename from android_webview/browser/browser_view_renderer_client.h
rename to android_webview/browser/gfx/browser_view_renderer_client.h
index d717bfc..0b575a5 100644
--- a/android_webview/browser/browser_view_renderer_client.h
+++ b/android_webview/browser/gfx/browser_view_renderer_client.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_CLIENT_H_
-#define ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_CLIENT_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_CLIENT_H_
 
 #include "base/android/scoped_java_ref.h"
 #include "ui/gfx/geometry/point.h"
@@ -62,4 +62,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_CLIENT_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_BROWSER_VIEW_RENDERER_CLIENT_H_
diff --git a/android_webview/browser/browser_view_renderer_unittest.cc b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
similarity index 98%
rename from android_webview/browser/browser_view_renderer_unittest.cc
rename to android_webview/browser/gfx/browser_view_renderer_unittest.cc
index 552a702..7b084b1 100644
--- a/android_webview/browser/browser_view_renderer_unittest.cc
+++ b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
@@ -7,11 +7,11 @@
 #include <queue>
 #include <utility>
 
-#include "android_webview/browser/browser_view_renderer.h"
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/compositor_frame_consumer.h"
-#include "android_webview/browser/render_thread_manager.h"
-#include "android_webview/browser/test/rendering_test.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/compositor_frame_consumer.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
+#include "android_webview/browser/gfx/test/rendering_test.h"
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
diff --git a/android_webview/browser/child_frame.cc b/android_webview/browser/gfx/child_frame.cc
similarity index 95%
rename from android_webview/browser/child_frame.cc
rename to android_webview/browser/gfx/child_frame.cc
index 551aba8..9855691 100644
--- a/android_webview/browser/child_frame.cc
+++ b/android_webview/browser/gfx/child_frame.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/child_frame.h"
+#include "android_webview/browser/gfx/child_frame.h"
 
 #include <utility>
 
diff --git a/android_webview/browser/child_frame.h b/android_webview/browser/gfx/child_frame.h
similarity index 87%
rename from android_webview/browser/child_frame.h
rename to android_webview/browser/gfx/child_frame.h
index 8832225..aeb839a 100644
--- a/android_webview/browser/child_frame.h
+++ b/android_webview/browser/gfx/child_frame.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_CHILD_FRAME_H_
-#define ANDROID_WEBVIEW_BROWSER_CHILD_FRAME_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_CHILD_FRAME_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_CHILD_FRAME_H_
 
 #include <memory>
 
-#include "android_webview/browser/compositor_id.h"
+#include "android_webview/browser/gfx/compositor_id.h"
 #include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "content/public/browser/android/synchronous_compositor.h"
@@ -53,4 +53,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_CHILD_FRAME_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_CHILD_FRAME_H_
diff --git a/android_webview/browser/compositor_frame_consumer.h b/android_webview/browser/gfx/compositor_frame_consumer.h
similarity index 80%
rename from android_webview/browser/compositor_frame_consumer.h
rename to android_webview/browser/gfx/compositor_frame_consumer.h
index 9022083..e79bd79 100644
--- a/android_webview/browser/compositor_frame_consumer.h
+++ b/android_webview/browser/gfx/compositor_frame_consumer.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_CONSUMER_H_
-#define ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_CONSUMER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_CONSUMER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_CONSUMER_H_
 
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/parent_compositor_draw_constraints.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/parent_compositor_draw_constraints.h"
 #include "ui/gfx/geometry/vector2d.h"
 
 namespace android_webview {
@@ -39,4 +39,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_CONSUMER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_CONSUMER_H_
diff --git a/android_webview/browser/compositor_frame_producer.h b/android_webview/browser/gfx/compositor_frame_producer.h
similarity index 80%
rename from android_webview/browser/compositor_frame_producer.h
rename to android_webview/browser/gfx/compositor_frame_producer.h
index 65260fc..08945c8d 100644
--- a/android_webview/browser/compositor_frame_producer.h
+++ b/android_webview/browser/gfx/compositor_frame_producer.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_PRODUCER_H_
-#define ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_PRODUCER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_PRODUCER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_PRODUCER_H_
 
 #include <vector>
 
-#include "android_webview/browser/compositor_id.h"
+#include "android_webview/browser/gfx/compositor_id.h"
 #include "base/memory/weak_ptr.h"
 #include "components/viz/common/resources/returned_resource.h"
 
@@ -35,4 +35,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_PRODUCER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_FRAME_PRODUCER_H_
diff --git a/android_webview/browser/compositor_id.cc b/android_webview/browser/gfx/compositor_id.cc
similarity index 95%
rename from android_webview/browser/compositor_id.cc
rename to android_webview/browser/gfx/compositor_id.cc
index 7b199fb..b6ffec0 100644
--- a/android_webview/browser/compositor_id.cc
+++ b/android_webview/browser/gfx/compositor_id.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/compositor_id.h"
+#include "android_webview/browser/gfx/compositor_id.h"
 #include "content/public/common/child_process_host.h"
 
 namespace android_webview {
diff --git a/android_webview/browser/compositor_id.h b/android_webview/browser/gfx/compositor_id.h
similarity index 78%
rename from android_webview/browser/compositor_id.h
rename to android_webview/browser/gfx/compositor_id.h
index 0afe3d7..987d5ad 100644
--- a/android_webview/browser/compositor_id.h
+++ b/android_webview/browser/gfx/compositor_id.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_COMPOSITOR_ID_H_
-#define ANDROID_WEBVIEW_BROWSER_COMPOSITOR_ID_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_ID_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_ID_H_
 
 namespace android_webview {
 
@@ -24,4 +24,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_COMPOSITOR_ID_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_COMPOSITOR_ID_H_
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/gfx/deferred_gpu_command_service.cc
similarity index 98%
rename from android_webview/browser/deferred_gpu_command_service.cc
rename to android_webview/browser/gfx/deferred_gpu_command_service.cc
index e3abc92..8ecf1c3d 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/gfx/deferred_gpu_command_service.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
 
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/command_line.h"
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/gfx/deferred_gpu_command_service.h
similarity index 93%
rename from android_webview/browser/deferred_gpu_command_service.h
rename to android_webview/browser/gfx/deferred_gpu_command_service.h
index 5e4c07b..fd12814a 100644
--- a/android_webview/browser/deferred_gpu_command_service.h
+++ b/android_webview/browser/gfx/deferred_gpu_command_service.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_DEFERRED_GPU_COMMAND_SERVICE_H_
-#define ANDROID_WEBVIEW_BROWSER_DEFERRED_GPU_COMMAND_SERVICE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_DEFERRED_GPU_COMMAND_SERVICE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_DEFERRED_GPU_COMMAND_SERVICE_H_
 
 #include <stddef.h>
 
@@ -110,4 +110,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_DEFERRED_GPU_COMMAND_SERVICE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_DEFERRED_GPU_COMMAND_SERVICE_H_
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/gfx/hardware_renderer.cc
similarity index 96%
rename from android_webview/browser/hardware_renderer.cc
rename to android_webview/browser/gfx/hardware_renderer.cc
index 37a82d4..bf7baa6 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/gfx/hardware_renderer.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/hardware_renderer.h"
+#include "android_webview/browser/gfx/hardware_renderer.h"
 
 #include <memory>
 #include <utility>
 
-#include "android_webview/browser/aw_gl_surface.h"
-#include "android_webview/browser/aw_render_thread_context_provider.h"
-#include "android_webview/browser/parent_compositor_draw_constraints.h"
-#include "android_webview/browser/render_thread_manager.h"
-#include "android_webview/browser/surfaces_instance.h"
+#include "android_webview/browser/gfx/aw_gl_surface.h"
+#include "android_webview/browser/gfx/aw_render_thread_context_provider.h"
+#include "android_webview/browser/gfx/parent_compositor_draw_constraints.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
+#include "android_webview/browser/gfx/surfaces_instance.h"
 #include "base/trace_event/trace_event.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/gfx/hardware_renderer.h
similarity index 92%
rename from android_webview/browser/hardware_renderer.h
rename to android_webview/browser/gfx/hardware_renderer.h
index 642475d..462921a4 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/gfx/hardware_renderer.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_
-#define ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_HARDWARE_RENDERER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_HARDWARE_RENDERER_H_
 
 #include <memory>
 
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/compositor_id.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/compositor_id.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
@@ -117,4 +117,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_HARDWARE_RENDERER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_HARDWARE_RENDERER_H_
diff --git a/android_webview/browser/java_browser_view_renderer_helper.cc b/android_webview/browser/gfx/java_browser_view_renderer_helper.cc
similarity index 98%
rename from android_webview/browser/java_browser_view_renderer_helper.cc
rename to android_webview/browser/gfx/java_browser_view_renderer_helper.cc
index 6b1ea5c75..b0c5fda 100644
--- a/android_webview/browser/java_browser_view_renderer_helper.cc
+++ b/android_webview/browser/gfx/java_browser_view_renderer_helper.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/java_browser_view_renderer_helper.h"
+#include "android_webview/browser/gfx/java_browser_view_renderer_helper.h"
 
 #include <android/bitmap.h>
 #include <memory>
diff --git a/android_webview/browser/java_browser_view_renderer_helper.h b/android_webview/browser/gfx/java_browser_view_renderer_helper.h
similarity index 79%
rename from android_webview/browser/java_browser_view_renderer_helper.h
rename to android_webview/browser/gfx/java_browser_view_renderer_helper.h
index 623fa41..02ac38a 100644
--- a/android_webview/browser/java_browser_view_renderer_helper.h
+++ b/android_webview/browser/gfx/java_browser_view_renderer_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
-#define ANDROID_WEBVIEW_BROWSER_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
 
 #include <jni.h>
 
@@ -35,4 +35,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_JAVA_BROWSER_VIEW_RENDERER_HELPER_H_
diff --git a/android_webview/browser/parent_compositor_draw_constraints.cc b/android_webview/browser/gfx/parent_compositor_draw_constraints.cc
similarity index 90%
rename from android_webview/browser/parent_compositor_draw_constraints.cc
rename to android_webview/browser/gfx/parent_compositor_draw_constraints.cc
index f897f5f..2d6cd58f 100644
--- a/android_webview/browser/parent_compositor_draw_constraints.cc
+++ b/android_webview/browser/gfx/parent_compositor_draw_constraints.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/parent_compositor_draw_constraints.h"
+#include "android_webview/browser/gfx/parent_compositor_draw_constraints.h"
 
-#include "android_webview/browser/child_frame.h"
+#include "android_webview/browser/gfx/child_frame.h"
 
 namespace android_webview {
 
diff --git a/android_webview/browser/parent_compositor_draw_constraints.h b/android_webview/browser/gfx/parent_compositor_draw_constraints.h
similarity index 76%
rename from android_webview/browser/parent_compositor_draw_constraints.h
rename to android_webview/browser/gfx/parent_compositor_draw_constraints.h
index 390a070..c5bb094 100644
--- a/android_webview/browser/parent_compositor_draw_constraints.h
+++ b/android_webview/browser/gfx/parent_compositor_draw_constraints.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
-#define ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
 
 #include "ui/gfx/transform.h"
 
@@ -27,4 +27,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/gfx/parent_output_surface.cc
similarity index 94%
rename from android_webview/browser/parent_output_surface.cc
rename to android_webview/browser/gfx/parent_output_surface.cc
index 67b4f127..80bb93c 100644
--- a/android_webview/browser/parent_output_surface.cc
+++ b/android_webview/browser/gfx/parent_output_surface.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/parent_output_surface.h"
+#include "android_webview/browser/gfx/parent_output_surface.h"
 
-#include "android_webview/browser/aw_render_thread_context_provider.h"
-#include "android_webview/browser/scoped_app_gl_state_restore.h"
+#include "android_webview/browser/gfx/aw_render_thread_context_provider.h"
+#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/gfx/parent_output_surface.h
similarity index 89%
rename from android_webview/browser/parent_output_surface.h
rename to android_webview/browser/gfx/parent_output_surface.h
index 973e2c8..9e1a471 100644
--- a/android_webview/browser/parent_output_surface.h
+++ b/android_webview/browser/gfx/parent_output_surface.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_
-#define ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_PARENT_OUTPUT_SURFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_PARENT_OUTPUT_SURFACE_H_
 
 #include "base/macros.h"
 #include "components/viz/service/display/output_surface.h"
@@ -47,4 +47,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_PARENT_OUTPUT_SURFACE_H_
diff --git a/android_webview/browser/render_thread_manager.cc b/android_webview/browser/gfx/render_thread_manager.cc
similarity index 95%
rename from android_webview/browser/render_thread_manager.cc
rename to android_webview/browser/gfx/render_thread_manager.cc
index f679567..71b7474ef 100644
--- a/android_webview/browser/render_thread_manager.cc
+++ b/android_webview/browser/gfx/render_thread_manager.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 
 #include <utility>
 
-#include "android_webview/browser/compositor_frame_producer.h"
-#include "android_webview/browser/compositor_id.h"
-#include "android_webview/browser/deferred_gpu_command_service.h"
-#include "android_webview/browser/scoped_app_gl_state_restore.h"
+#include "android_webview/browser/gfx/compositor_frame_producer.h"
+#include "android_webview/browser/gfx/compositor_id.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/bind.h"
 #include "base/lazy_instance.h"
diff --git a/android_webview/browser/render_thread_manager.h b/android_webview/browser/gfx/render_thread_manager.h
similarity index 90%
rename from android_webview/browser/render_thread_manager.h
rename to android_webview/browser/gfx/render_thread_manager.h
index 7aaa544..68b70ea 100644
--- a/android_webview/browser/render_thread_manager.h
+++ b/android_webview/browser/gfx/render_thread_manager.h
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_RENDER_THREAD_MANAGER_H_
-#define ANDROID_WEBVIEW_BROWSER_RENDER_THREAD_MANAGER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_RENDER_THREAD_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_RENDER_THREAD_MANAGER_H_
 
 #include <map>
 
-#include "android_webview/browser/compositor_frame_consumer.h"
-#include "android_webview/browser/hardware_renderer.h"
-#include "android_webview/browser/parent_compositor_draw_constraints.h"
+#include "android_webview/browser/gfx/compositor_frame_consumer.h"
+#include "android_webview/browser/gfx/hardware_renderer.h"
+#include "android_webview/browser/gfx/parent_compositor_draw_constraints.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -116,4 +116,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_RENDER_THREAD_MANAGER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_RENDER_THREAD_MANAGER_H_
diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc
similarity index 99%
rename from android_webview/browser/scoped_app_gl_state_restore.cc
rename to android_webview/browser/gfx/scoped_app_gl_state_restore.cc
index 696a946..5025c40 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.cc
+++ b/android_webview/browser/gfx/scoped_app_gl_state_restore.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/scoped_app_gl_state_restore.h"
+#include "android_webview/browser/gfx/scoped_app_gl_state_restore.h"
 
 #include <string>
 
diff --git a/android_webview/browser/scoped_app_gl_state_restore.h b/android_webview/browser/gfx/scoped_app_gl_state_restore.h
similarity index 86%
rename from android_webview/browser/scoped_app_gl_state_restore.h
rename to android_webview/browser/gfx/scoped_app_gl_state_restore.h
index 6635a5fa..aba8283f 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.h
+++ b/android_webview/browser/gfx/scoped_app_gl_state_restore.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
-#define ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_SCOPED_APP_GL_STATE_RESTORE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_SCOPED_APP_GL_STATE_RESTORE_H_
 
 #include <memory>
 #include <vector>
@@ -59,4 +59,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_SCOPED_APP_GL_STATE_RESTORE_H_
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/gfx/surfaces_instance.cc
similarity index 97%
rename from android_webview/browser/surfaces_instance.cc
rename to android_webview/browser/gfx/surfaces_instance.cc
index b9b0c80..2e9de86 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/gfx/surfaces_instance.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/surfaces_instance.h"
+#include "android_webview/browser/gfx/surfaces_instance.h"
 
 #include <algorithm>
 #include <memory>
 #include <utility>
 
-#include "android_webview/browser/aw_gl_surface.h"
-#include "android_webview/browser/aw_render_thread_context_provider.h"
-#include "android_webview/browser/deferred_gpu_command_service.h"
-#include "android_webview/browser/parent_output_surface.h"
+#include "android_webview/browser/gfx/aw_gl_surface.h"
+#include "android_webview/browser/gfx/aw_render_thread_context_provider.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/parent_output_surface.h"
 #include "base/stl_util.h"
 #include "components/viz/common/display/renderer_settings.h"
 #include "components/viz/common/features.h"
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/gfx/surfaces_instance.h
similarity index 95%
rename from android_webview/browser/surfaces_instance.h
rename to android_webview/browser/gfx/surfaces_instance.h
index b2cc5cb..4ffe51d 100644
--- a/android_webview/browser/surfaces_instance.h
+++ b/android_webview/browser/gfx/surfaces_instance.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_SURFACES_INSTANCE_H_
-#define ANDROID_WEBVIEW_BROWSER_SURFACES_INSTANCE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_SURFACES_INSTANCE_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_SURFACES_INSTANCE_H_
 
 #include <memory>
 #include <vector>
@@ -112,4 +112,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_SURFACES_INSTANCE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_SURFACES_INSTANCE_H_
diff --git a/android_webview/browser/test/fake_window.cc b/android_webview/browser/gfx/test/fake_window.cc
similarity index 97%
rename from android_webview/browser/test/fake_window.cc
rename to android_webview/browser/gfx/test/fake_window.cc
index c52a81a..9c8ced56 100644
--- a/android_webview/browser/test/fake_window.cc
+++ b/android_webview/browser/gfx/test/fake_window.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/test/fake_window.h"
+#include "android_webview/browser/gfx/test/fake_window.h"
 
-#include "android_webview/browser/browser_view_renderer.h"
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/synchronization/waitable_event.h"
diff --git a/android_webview/browser/test/fake_window.h b/android_webview/browser/gfx/test/fake_window.h
similarity index 93%
rename from android_webview/browser/test/fake_window.h
rename to android_webview/browser/gfx/test/fake_window.h
index 7dd90fe..dd6f2ee 100644
--- a/android_webview/browser/test/fake_window.h
+++ b/android_webview/browser/gfx/test/fake_window.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_TEST_FAKE_WINDOW_H_
-#define ANDROID_WEBVIEW_BROWSER_TEST_FAKE_WINDOW_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_TEST_FAKE_WINDOW_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_TEST_FAKE_WINDOW_H_
 
 #include <map>
 
-#include "android_webview/browser/hardware_renderer.h"
+#include "android_webview/browser/gfx/hardware_renderer.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
@@ -127,4 +127,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_TEST_FAKE_WINDOW_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_TEST_FAKE_WINDOW_H_
diff --git a/android_webview/browser/test/rendering_test.cc b/android_webview/browser/gfx/test/rendering_test.cc
similarity index 95%
rename from android_webview/browser/test/rendering_test.cc
rename to android_webview/browser/gfx/test/rendering_test.cc
index 3251ca6c..25bc5d5 100644
--- a/android_webview/browser/test/rendering_test.cc
+++ b/android_webview/browser/gfx/test/rendering_test.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/test/rendering_test.h"
+#include "android_webview/browser/gfx/test/rendering_test.h"
 
 #include <memory>
 #include <utility>
 
-#include "android_webview/browser/browser_view_renderer.h"
-#include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/render_thread_manager.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/child_frame.h"
+#include "android_webview/browser/gfx/render_thread_manager.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/location.h"
diff --git a/android_webview/browser/test/rendering_test.h b/android_webview/browser/gfx/test/rendering_test.h
similarity index 91%
rename from android_webview/browser/test/rendering_test.h
rename to android_webview/browser/gfx/test/rendering_test.h
index 31fab662..5c1e8ff 100644
--- a/android_webview/browser/test/rendering_test.h
+++ b/android_webview/browser/gfx/test/rendering_test.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ANDROID_WEBVIEW_BROWSER_TEST_RENDERING_TEST_H_
-#define ANDROID_WEBVIEW_BROWSER_TEST_RENDERING_TEST_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_GFX_TEST_RENDERING_TEST_H_
+#define ANDROID_WEBVIEW_BROWSER_GFX_TEST_RENDERING_TEST_H_
 
 #include <memory>
 
-#include "android_webview/browser/browser_view_renderer_client.h"
-#include "android_webview/browser/test/fake_window.h"
+#include "android_webview/browser/gfx/browser_view_renderer_client.h"
+#include "android_webview/browser/gfx/test/fake_window.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
@@ -109,4 +109,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_TEST_RENDERING_TEST_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_GFX_TEST_RENDERING_TEST_H_
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
index 8337d96..8a74a76 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
@@ -117,15 +117,15 @@
   }
 }
 
-void AwRenderViewHostExt::SetShouldSuppressErrorPage(bool suppress) {
+void AwRenderViewHostExt::SetWillSuppressErrorPage(bool suppress) {
   // We need to store state on the browser-side, as state might need to be
   // synchronized again later (see AwRenderViewHostExt::RenderFrameCreated)
-  if (should_suppress_error_page_ == suppress)
+  if (will_suppress_error_page_ == suppress)
     return;
-  should_suppress_error_page_ = suppress;
+  will_suppress_error_page_ = suppress;
 
-  web_contents()->SendToAllFrames(new AwViewMsg_ShouldSuppressErrorPage(
-      MSG_ROUTING_NONE, should_suppress_error_page_));
+  web_contents()->SendToAllFrames(new AwViewMsg_WillSuppressErrorPage(
+      MSG_ROUTING_NONE, will_suppress_error_page_));
 }
 
 void AwRenderViewHostExt::SetJsOnlineProperty(bool network_up) {
@@ -170,8 +170,8 @@
   // it) because for cross-origin navigations in multi-process mode, the
   // navigation will already have started then. Also, newly created subframes
   // need to inherit the state.
-  frame_host->Send(new AwViewMsg_ShouldSuppressErrorPage(
-      frame_host->GetRoutingID(), should_suppress_error_page_));
+  frame_host->Send(new AwViewMsg_WillSuppressErrorPage(
+      frame_host->GetRoutingID(), will_suppress_error_page_));
 }
 
 void AwRenderViewHostExt::DidFinishNavigation(
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.h b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
index c7e25ea..0591d58 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.h
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
@@ -75,7 +75,7 @@
   // the meta viewport tag.
   void SetInitialPageScale(double page_scale_factor);
   void SetBackgroundColor(SkColor c);
-  void SetShouldSuppressErrorPage(bool suppress);
+  void SetWillSuppressErrorPage(bool suppress);
   void SetJsOnlineProperty(bool network_up);
 
   void SmoothScroll(int target_x, int target_y, long duration_ms);
@@ -124,7 +124,7 @@
   service_manager::BinderRegistry registry_;
 
   // Some WebView users might want to show their own error pages / logic.
-  bool should_suppress_error_page_ = false;
+  bool will_suppress_error_page_ = false;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index 0aa7c605..b148fdc 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -89,8 +89,8 @@
 
 // Sent to inform renderers whether the internal error page should be shown or
 // not.
-IPC_MESSAGE_ROUTED1(AwViewMsg_ShouldSuppressErrorPage,
-                    bool /* should_suppress_error_page */)
+IPC_MESSAGE_ROUTED1(AwViewMsg_WillSuppressErrorPage,
+                    bool /* will_suppress_error_page */)
 
 //-----------------------------------------------------------------------------
 // RenderView messages
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
index b887a98..68c85a1f 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -112,7 +112,7 @@
     private int mMixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW;
     private boolean mCSSHexAlphaColorEnabled;
     private boolean mScrollTopLeftInteropEnabled;
-    private boolean mShouldSuppressErrorPage;
+    private boolean mWillSuppressErrorPage;
 
     private boolean mOffscreenPreRaster;
     private int mDisabledMenuItems = WebSettings.MENU_ITEM_NONE;
@@ -1257,31 +1257,31 @@
     }
 
     @CalledByNative
-    private boolean getShouldSuppressErrorPageLocked() {
+    private boolean getWillSuppressErrorPageLocked() {
         assert Thread.holdsLock(mAwSettingsLock);
-        return mShouldSuppressErrorPage;
+        return mWillSuppressErrorPage;
     }
 
-    public boolean getShouldSuppressErrorPage() {
+    public boolean getWillSuppressErrorPage() {
         synchronized (mAwSettingsLock) {
-            return getShouldSuppressErrorPageLocked();
+            return getWillSuppressErrorPageLocked();
         }
     }
 
-    public void setShouldSuppressErrorPage(boolean suppressed) {
+    public void setWillSuppressErrorPage(boolean suppressed) {
         synchronized (mAwSettingsLock) {
-            if (mShouldSuppressErrorPage == suppressed) return;
+            if (mWillSuppressErrorPage == suppressed) return;
 
-            mShouldSuppressErrorPage = suppressed;
-            updateShouldSuppressErrorStateLocked();
+            mWillSuppressErrorPage = suppressed;
+            updateWillSuppressErrorStateLocked();
         }
     }
 
-    private void updateShouldSuppressErrorStateLocked() {
+    private void updateWillSuppressErrorStateLocked() {
         mEventHandler.runOnUiThreadBlockingAndLocked(() -> {
             assert Thread.holdsLock(mAwSettingsLock);
             assert mNativeAwSettings != 0;
-            nativeUpdateShouldSuppressErrorStateLocked(mNativeAwSettings);
+            nativeUpdateWillSuppressErrorStateLocked(mNativeAwSettings);
         });
     }
 
@@ -1851,5 +1851,5 @@
 
     private native void nativeUpdateOffscreenPreRasterLocked(long nativeAwSettings);
 
-    private native void nativeUpdateShouldSuppressErrorStateLocked(long nativeAwSettings);
+    private native void nativeUpdateWillSuppressErrorStateLocked(long nativeAwSettings);
 }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
index cfa7690e..b8112ac 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -343,10 +343,26 @@
     @Feature({"AndroidWebView", "Downloads"})
     @SmallTest
     public void testDownload() throws Throwable {
+        downloadAndCheck(null);
+    }
+
+    @Test
+    @Feature({"AndroidWebView", "Downloads"})
+    @SmallTest
+    public void testDownloadWithCustomUserAgent() throws Throwable {
+        downloadAndCheck("Custom User Agent");
+    }
+
+    private void downloadAndCheck(String customUserAgent) throws Throwable {
         AwTestContainerView testView =
                 mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
         AwContents awContents = testView.getAwContents();
 
+        if (customUserAgent != null) {
+            AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
+            awSettings.setUserAgentString(customUserAgent);
+        }
+
         final String data = "download data";
         final String contentDisposition = "attachment;filename=\"download.txt\"";
         final String mimeType = "text/plain";
@@ -370,6 +386,13 @@
             Assert.assertEquals(contentDisposition, downloadStartHelper.getContentDisposition());
             Assert.assertEquals(mimeType, downloadStartHelper.getMimeType());
             Assert.assertEquals(data.length(), downloadStartHelper.getContentLength());
+            Assert.assertFalse(downloadStartHelper.getUserAgent().isEmpty());
+            if (customUserAgent != null) {
+                Assert.assertEquals(customUserAgent, downloadStartHelper.getUserAgent());
+            } else {
+                Assert.assertEquals(
+                        downloadStartHelper.getUserAgent(), AwSettings.getDefaultUserAgent());
+            }
         } finally {
             webServer.shutdown();
         }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index 69b24ddb4..623ceda 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -1464,13 +1464,13 @@
         }
     }
 
-    class AwSettingsShouldSuppressErrorPageTestHelper extends AwSettingsTestHelper<Boolean> {
+    class AwSettingsWillSuppressErrorPageTestHelper extends AwSettingsTestHelper<Boolean> {
         private static final String BAD_SCHEME_URL = "htt://nonsense";
         private static final String PREV_TITLE = "cuencpobgjhfdmdovhmfdkjf";
         private static final int MAX_TIME_LOADING_ERROR_PAGE = 1000;
         private final AwContents mAwContents;
 
-        AwSettingsShouldSuppressErrorPageTestHelper(AwTestContainerView containerView,
+        AwSettingsWillSuppressErrorPageTestHelper(AwTestContainerView containerView,
                 TestAwContentsClient contentViewClient) throws Throwable {
             super(containerView, contentViewClient, true);
             mAwContents = containerView.getAwContents();
@@ -1488,12 +1488,12 @@
 
         @Override
         protected Boolean getCurrentValue() {
-            return mAwSettings.getShouldSuppressErrorPage();
+            return mAwSettings.getWillSuppressErrorPage();
         }
 
         @Override
         protected void setCurrentValue(Boolean value) {
-            mAwSettings.setShouldSuppressErrorPage(value);
+            mAwSettings.setWillSuppressErrorPage(value);
         }
 
         @Override
@@ -1516,7 +1516,7 @@
 
             // Verify the state in settings reflect what we expect
             AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
-            Assert.assertEquals(value, settings.getShouldSuppressErrorPage());
+            Assert.assertEquals(value, settings.getWillSuppressErrorPage());
 
             // Verify the error page is shown / suppressed
             if (value == DISABLED) {
@@ -1725,11 +1725,11 @@
     @Test
     @MediumTest
     @Feature({"AndroidWebView", "Preferences"})
-    public void testShouldSuppressErrorPage() throws Throwable {
+    public void testWillSuppressErrorPage() throws Throwable {
         ViewPair views = createViews();
-        runPerViewSettingsTest(new AwSettingsShouldSuppressErrorPageTestHelper(
+        runPerViewSettingsTest(new AwSettingsWillSuppressErrorPageTestHelper(
                                        views.getContainer0(), views.getClient0()),
-                new AwSettingsShouldSuppressErrorPageTestHelper(
+                new AwSettingsWillSuppressErrorPageTestHelper(
                         views.getContainer1(), views.getClient1()));
     }
 
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc
index 0366ab9e..b36b36b 100644
--- a/android_webview/lib/aw_main_delegate.cc
+++ b/android_webview/lib/aw_main_delegate.cc
@@ -8,9 +8,9 @@
 
 #include "android_webview/browser/aw_content_browser_client.h"
 #include "android_webview/browser/aw_media_url_interceptor.h"
-#include "android_webview/browser/browser_view_renderer.h"
 #include "android_webview/browser/command_line_helper.h"
-#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
 #include "android_webview/browser/tracing/aw_trace_event_args_whitelist.h"
 #include "android_webview/common/aw_descriptors.h"
 #include "android_webview/common/aw_paths.h"
diff --git a/android_webview/lib/webview_tests.cc b/android_webview/lib/webview_tests.cc
index 53f2fe0..6f5ff39 100644
--- a/android_webview/lib/webview_tests.cc
+++ b/android_webview/lib/webview_tests.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/browser/gfx/deferred_gpu_command_service.h"
 #include "base/command_line.h"
 #include "base/test/test_suite.h"
 #include "content/public/common/content_switches.h"
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index 90349c2..f2f8b120 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -201,7 +201,7 @@
   if (render_frame_ext == nullptr)
     return false;
 
-  return render_frame_ext->GetShouldSuppressErrorPage();
+  return render_frame_ext->GetWillSuppressErrorPage();
 }
 
 void AwContentRendererClient::PrepareErrorPage(
diff --git a/android_webview/renderer/aw_render_frame_ext.cc b/android_webview/renderer/aw_render_frame_ext.cc
index 76117f3..4e907f48 100644
--- a/android_webview/renderer/aw_render_frame_ext.cc
+++ b/android_webview/renderer/aw_render_frame_ext.cc
@@ -230,8 +230,8 @@
                         OnResetScrollAndScaleState)
     IPC_MESSAGE_HANDLER(AwViewMsg_SetInitialPageScale, OnSetInitialPageScale)
     IPC_MESSAGE_HANDLER(AwViewMsg_SetBackgroundColor, OnSetBackgroundColor)
-    IPC_MESSAGE_HANDLER(AwViewMsg_ShouldSuppressErrorPage,
-                        OnSetShouldSuppressErrorPage)
+    IPC_MESSAGE_HANDLER(AwViewMsg_WillSuppressErrorPage,
+                        OnSetWillSuppressErrorPage)
     IPC_MESSAGE_HANDLER(AwViewMsg_SmoothScroll, OnSmoothScroll)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
@@ -347,12 +347,12 @@
   webview->SmoothScroll(target_x, target_y, static_cast<long>(duration_ms));
 }
 
-void AwRenderFrameExt::OnSetShouldSuppressErrorPage(bool suppress) {
-  this->should_suppress_error_page_ = suppress;
+void AwRenderFrameExt::OnSetWillSuppressErrorPage(bool suppress) {
+  this->will_suppress_error_page_ = suppress;
 }
 
-bool AwRenderFrameExt::GetShouldSuppressErrorPage() {
-  return this->should_suppress_error_page_;
+bool AwRenderFrameExt::GetWillSuppressErrorPage() {
+  return this->will_suppress_error_page_;
 }
 
 blink::WebView* AwRenderFrameExt::GetWebView() {
diff --git a/android_webview/renderer/aw_render_frame_ext.h b/android_webview/renderer/aw_render_frame_ext.h
index 93a946a..8a9fff3e 100644
--- a/android_webview/renderer/aw_render_frame_ext.h
+++ b/android_webview/renderer/aw_render_frame_ext.h
@@ -31,7 +31,7 @@
 
   static AwRenderFrameExt* FromRenderFrame(content::RenderFrame* render_frame);
 
-  bool GetShouldSuppressErrorPage();
+  bool GetWillSuppressErrorPage();
 
  private:
   ~AwRenderFrameExt() override;
@@ -61,7 +61,7 @@
 
   void OnSmoothScroll(int target_x, int target_y, int duration_ms);
 
-  void OnSetShouldSuppressErrorPage(bool suppress);
+  void OnSetWillSuppressErrorPage(bool suppress);
 
   blink::WebView* GetWebView();
   blink::WebFrameWidget* GetWebFrameWidget();
@@ -71,7 +71,7 @@
   blink::AssociatedInterfaceRegistry registry_;
 
   // Some WebView users might want to show their own error pages / logic
-  bool should_suppress_error_page_ = false;
+  bool will_suppress_error_page_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(AwRenderFrameExt);
 };
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
index b198e33c5..338fc326 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
@@ -21,6 +21,6 @@
     void setDisabledActionModeMenuItems(int menuItems);
     int getDisabledActionModeMenuItems();
 
-    void setShouldSuppressErrorPage(boolean suppressed);
-    boolean getShouldSuppressErrorPage();
+    void setWillSuppressErrorPage(boolean suppressed);
+    boolean getWillSuppressErrorPage();
 }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
index c2faf74..fbf0625 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -132,8 +132,8 @@
     // ProxyController.clearProxyOverride
     public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE:3";
 
-    // WebSettingsCompat.setShouldSuppressErrorPage
-    // WebSettingsCompat.getShouldSuppressErrorPage
+    // WebSettingsCompat.setWillSuppressErrorPage
+    // WebSettingsCompat.getWillSuppressErrorPage
     public static final String SUPPRESS_ERROR_PAGE = "SUPPRESS_ERROR_PAGE";
 
     // WebViewCompat.getWebViewRenderer
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java
index dfad8568..f1dba8e 100644
--- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java
@@ -48,12 +48,12 @@
     }
 
     @Override
-    public boolean getShouldSuppressErrorPage() {
-        return mAwSettings.getShouldSuppressErrorPage();
+    public boolean getWillSuppressErrorPage() {
+        return mAwSettings.getWillSuppressErrorPage();
     }
 
     @Override
-    public void setShouldSuppressErrorPage(boolean suppressed) {
-        mAwSettings.setShouldSuppressErrorPage(suppressed);
+    public void setWillSuppressErrorPage(boolean suppressed) {
+        mAwSettings.setWillSuppressErrorPage(suppressed);
     }
 }
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn
index 578383d..f3a6645f 100644
--- a/android_webview/test/BUILD.gn
+++ b/android_webview/test/BUILD.gn
@@ -337,8 +337,12 @@
     "../browser/aw_media_url_interceptor_unittest.cc",
     "../browser/aw_permission_manager_unittest.cc",
     "../browser/aw_static_cookie_policy_unittest.cc",
-    "../browser/browser_view_renderer_unittest.cc",
     "../browser/command_line_helper_unittest.cc",
+    "../browser/gfx/browser_view_renderer_unittest.cc",
+    "../browser/gfx/test/fake_window.cc",
+    "../browser/gfx/test/fake_window.h",
+    "../browser/gfx/test/rendering_test.cc",
+    "../browser/gfx/test/rendering_test.h",
     "../browser/input_stream_unittest.cc",
     "../browser/net/android_stream_reader_url_request_job_unittest.cc",
     "../browser/net/aw_cookie_store_wrapper_unittest.cc",
@@ -350,10 +354,6 @@
     "../browser/renderer_host/auto_login_parser_unittest.cc",
     "../browser/safe_browsing/aw_safe_browsing_whitelist_manager_unittest.cc",
     "../browser/state_serializer_unittest.cc",
-    "../browser/test/fake_window.cc",
-    "../browser/test/fake_window.h",
-    "../browser/test/rendering_test.cc",
-    "../browser/test/rendering_test.h",
     "../lib/webview_tests.cc",
   ]
 }
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index cd61c9cb..a182e8c 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -15,6 +15,7 @@
 #include "ash/app_list/views/apps_container_view.h"
 #include "ash/app_list/views/contents_view.h"
 #include "ash/app_list/views/search_box_view.h"
+#include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/public/cpp/shell_window_ids.h"
@@ -157,6 +158,14 @@
       if (event.type() != ui::ET_MOUSE_MOVED)
         return false;
     }
+
+    if (window->GetProperty(ash::assistant::ui::kOnlyAllowMouseClickEvents)) {
+      if (event.type() != ui::ET_MOUSE_PRESSED &&
+          event.type() != ui::ET_MOUSE_RELEASED) {
+        return false;
+      }
+    }
+
     return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(window, event);
   }
 
diff --git a/ash/app_list/views/search_result_tile_item_view.cc b/ash/app_list/views/search_result_tile_item_view.cc
index 0880836c..eb052044 100644
--- a/ash/app_list/views/search_result_tile_item_view.cc
+++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -57,6 +57,13 @@
 // Icon selected color, Google Grey 900 8%.
 constexpr int kIconSelectedColor = SkColorSetA(gfx::kGoogleGrey900, 0x14);
 
+// Offset for centering star rating when there is no price.
+constexpr int kSearchRatingCenteringOffset =
+    ((kSearchTileWidth -
+      (kSearchRatingSize + kSearchRatingStarHorizontalSpacing +
+       kSearchRatingStarSize)) /
+     2);
+
 constexpr SkColor kSearchTitleColor = gfx::kGoogleGrey900;
 constexpr SkColor kSearchAppRatingColor = gfx::kGoogleGrey700;
 constexpr SkColor kSearchAppPriceColor = gfx::kGoogleGreen600;
@@ -526,9 +533,16 @@
     rect.set_height(title_->GetPreferredSize().height());
     title_->SetBoundsRect(rect);
 
+    // If there is no price set, we center the rating.
+    const bool center_rating =
+        rating_ && rating_star_ && price_ && price_->text().empty();
+    const int rating_horizontal_offset =
+        center_rating ? kSearchRatingCenteringOffset : 0;
+
     if (rating_) {
       gfx::Rect rating_rect(rect);
-      rating_rect.Inset(0, title_->GetPreferredSize().height(), 0, 0);
+      rating_rect.Inset(rating_horizontal_offset,
+                        title_->GetPreferredSize().height(), 0, 0);
       rating_rect.set_size(rating_->GetPreferredSize());
       rating_rect.set_width(kSearchRatingSize);
       rating_->SetBoundsRect(rating_rect);
@@ -536,11 +550,11 @@
 
     if (rating_star_) {
       gfx::Rect rating_star_rect(rect);
-      rating_star_rect.Inset(
-          kSearchRatingSize + kSearchRatingStarHorizontalSpacing,
-          title_->GetPreferredSize().height() +
-              kSearchRatingStarVerticalSpacing,
-          0, 0);
+      rating_star_rect.Inset(rating_horizontal_offset + kSearchRatingSize +
+                                 kSearchRatingStarHorizontalSpacing,
+                             title_->GetPreferredSize().height() +
+                                 kSearchRatingStarVerticalSpacing,
+                             0, 0);
       rating_star_rect.set_size(rating_star_->GetPreferredSize());
       rating_star_->SetBoundsRect(rating_star_rect);
     }
diff --git a/ash/assistant/ui/BUILD.gn b/ash/assistant/ui/BUILD.gn
index bb46a713..fbc43e2 100644
--- a/ash/assistant/ui/BUILD.gn
+++ b/ash/assistant/ui/BUILD.gn
@@ -7,7 +7,11 @@
 
 assert(is_chromeos)
 
-source_set("constants") {
+component("constants") {
+  output_name = "assistant_ui_constants"
+
+  defines = [ "IS_ASSISTANT_UI_CONSTANTS_IMPL" ]
+
   sources = [
     "assistant_ui_constants.cc",
     "assistant_ui_constants.h",
@@ -16,6 +20,8 @@
   deps = [
     "//base",
     "//skia",
+    "//ui/aura",
+    "//ui/base",
     "//ui/gfx",
   ]
 }
diff --git a/ash/assistant/ui/assistant_container_view.cc b/ash/assistant/ui/assistant_container_view.cc
index 2626d5c..7c77f1c4 100644
--- a/ash/assistant/ui/assistant_container_view.cc
+++ b/ash/assistant/ui/assistant_container_view.cc
@@ -37,9 +37,6 @@
 // Appearance.
 constexpr SkColor kBackgroundColor = SK_ColorWHITE;
 
-// Window properties.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kOnlyAllowMouseClickEvents, false)
-
 // AssistantContainerClientView ------------------------------------------------
 
 // AssistantContainerClientView is the client view for AssistantContainerView
@@ -130,7 +127,7 @@
   // aura::WindowTargeter:
   bool SubtreeShouldBeExploredForEvent(aura::Window* window,
                                        const ui::LocatedEvent& event) override {
-    if (window->GetProperty(kOnlyAllowMouseClickEvents)) {
+    if (window->GetProperty(assistant::ui::kOnlyAllowMouseClickEvents)) {
       if (event.type() != ui::ET_MOUSE_PRESSED &&
           event.type() != ui::ET_MOUSE_RELEASED) {
         return false;
@@ -273,11 +270,6 @@
   delegate_->RemoveUiModelObserver(this);
 }
 
-// static
-void AssistantContainerView::OnlyAllowMouseClickEvents(aura::Window* window) {
-  window->SetProperty(kOnlyAllowMouseClickEvents, true);
-}
-
 const char* AssistantContainerView::GetClassName() const {
   return "AssistantContainerView";
 }
diff --git a/ash/assistant/ui/assistant_container_view.h b/ash/assistant/ui/assistant_container_view.h
index dc00d04..477d94a 100644
--- a/ash/assistant/ui/assistant_container_view.h
+++ b/ash/assistant/ui/assistant_container_view.h
@@ -13,10 +13,6 @@
 #include "base/macros.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 
-namespace aura {
-class Window;
-}  // namespace aura
-
 namespace ash {
 
 class AssistantContainerViewAnimator;
@@ -32,11 +28,6 @@
   explicit AssistantContainerView(AssistantViewDelegate* delegate);
   ~AssistantContainerView() override;
 
-  // Instructs the event targeter for the Assistant window to only allow mouse
-  // click events to reach the specified |window|. All other events will not
-  // be explored by |window|'s subtree for handling.
-  static void OnlyAllowMouseClickEvents(aura::Window* window);
-
   // views::BubbleDialogDelegateView:
   const char* GetClassName() const override;
   void AddedToWidget() override;
diff --git a/ash/assistant/ui/assistant_ui_constants.cc b/ash/assistant/ui/assistant_ui_constants.cc
index fe5c020..a81a830d 100644
--- a/ash/assistant/ui/assistant_ui_constants.cc
+++ b/ash/assistant/ui/assistant_ui_constants.cc
@@ -5,12 +5,15 @@
 #include "ash/assistant/ui/assistant_ui_constants.h"
 
 #include "base/no_destructor.h"
+#include "ui/base/class_property.h"
 #include "ui/gfx/font_list.h"
 
 namespace ash {
 namespace assistant {
 namespace ui {
 
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kOnlyAllowMouseClickEvents, false)
+
 const gfx::FontList& GetDefaultFontList() {
   static const base::NoDestructor<gfx::FontList> font_list("Google Sans, 12px");
   return *font_list;
@@ -18,4 +21,4 @@
 
 }  // namespace ui
 }  // namespace assistant
-}  // namespace ash
\ No newline at end of file
+}  // namespace ash
diff --git a/ash/assistant/ui/assistant_ui_constants.h b/ash/assistant/ui/assistant_ui_constants.h
index 79b589a6..58c51383 100644
--- a/ash/assistant/ui/assistant_ui_constants.h
+++ b/ash/assistant/ui/assistant_ui_constants.h
@@ -5,7 +5,9 @@
 #ifndef ASH_ASSISTANT_UI_ASSISTANT_UI_CONSTANTS_H_
 #define ASH_ASSISTANT_UI_ASSISTANT_UI_CONSTANTS_H_
 
+#include "base/component_export.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/window.h"
 #include "ui/gfx/color_palette.h"
 
 namespace gfx {
@@ -32,7 +34,14 @@
 namespace assistant {
 namespace ui {
 
+// Window property to instruct the event targeter for the Assistant window to
+// only allow mouse click events to reach the specified |window|. All other
+// events will not be explored by |window|'s subtree for handling.
+COMPONENT_EXPORT(ASSISTANT_UI_CONSTANTS)
+extern const aura::WindowProperty<bool>* const kOnlyAllowMouseClickEvents;
+
 // Returns the default font list for Assistant UI.
+COMPONENT_EXPORT(ASSISTANT_UI_CONSTANTS)
 const gfx::FontList& GetDefaultFontList();
 
 }  // namespace ui
diff --git a/ash/assistant/ui/main_stage/assistant_card_element_view.cc b/ash/assistant/ui/main_stage/assistant_card_element_view.cc
index e261394..e45cae445 100644
--- a/ash/assistant/ui/main_stage/assistant_card_element_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_card_element_view.cc
@@ -8,7 +8,9 @@
 
 #include "ash/assistant/model/assistant_ui_element.h"
 #include "ash/assistant/ui/assistant_container_view.h"
+#include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/assistant/ui/assistant_view_delegate.h"
+#include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/events/event.h"
 #include "ui/events/event_sink.h"
@@ -80,7 +82,7 @@
   // vertically. As such, we need to prevent the Assistant card window from
   // receiving events it doesn't need. It needs mouse click events for
   // handling links.
-  AssistantContainerView::OnlyAllowMouseClickEvents(window);
+  window->SetProperty(ash::assistant::ui::kOnlyAllowMouseClickEvents, true);
 }
 
 void AssistantCardElementView::ChildPreferredSizeChanged(views::View* child) {
diff --git a/ash/display/cros_display_config.cc b/ash/display/cros_display_config.cc
index f801f90d..54d47ea18 100644
--- a/ash/display/cros_display_config.cc
+++ b/ash/display/cros_display_config.cc
@@ -229,6 +229,7 @@
   result->device_scale_factor = display_mode.device_scale_factor();
   result->refresh_rate = display_mode.refresh_rate();
   result->is_native = display_mode.native();
+  result->is_interlaced = display_mode.is_interlaced();
   return result;
 }
 
@@ -416,8 +417,8 @@
     return mojom::DisplayConfigResult::kInvalidDisplayIdError;
 
   display::ManagedDisplayMode new_mode(
-      display_mode.size_in_native_pixels, current_mode.refresh_rate(),
-      current_mode.is_interlaced(), display_mode.is_native,
+      display_mode.size_in_native_pixels, display_mode.refresh_rate,
+      display_mode.is_interlaced, display_mode.is_native,
       display_mode.device_scale_factor);
 
   if (!new_mode.IsEquivalent(current_mode)) {
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 28ec8e8..38e384f 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -3264,7 +3264,7 @@
   // display zoom enabled.
   display_manager()->RegisterDisplayProperty(id, display::Display::ROTATE_0,
                                              -1000, nullptr, gfx::Size(), 1.f,
-                                             zoom_factor);
+                                             zoom_factor, 60.f, false);
 
   const display::ManagedDisplayInfo& info =
       display_manager()->GetDisplayInfo(id);
@@ -3274,8 +3274,9 @@
 
 TEST_F(DisplayManagerTest, CheckInitializationOfRotationProperty) {
   int64_t id = display_manager()->GetDisplayAt(0).id();
-  display_manager()->RegisterDisplayProperty(
-      id, display::Display::ROTATE_90, 1.0f, nullptr, gfx::Size(), 1.0f, 1.0f);
+  display_manager()->RegisterDisplayProperty(id, display::Display::ROTATE_90,
+                                             1.0f, nullptr, gfx::Size(), 1.0f,
+                                             1.0f, 60.f, false);
 
   const display::ManagedDisplayInfo& info =
       display_manager()->GetDisplayInfo(id);
@@ -3383,8 +3384,7 @@
   display::Screen* screen = display::Screen::GetScreen();
   DCHECK(screen);
   Shell* shell = Shell::Get();
-  display::DisplayChangeObserver observer(shell->display_configurator(),
-                                          display_manager());
+  display::DisplayChangeObserver observer(shell->display_manager());
   display::DisplayConfigurator::DisplayStateList outputs;
   std::unique_ptr<display::DisplaySnapshot> internal_snapshot =
       display::FakeDisplaySnapshot::Builder()
@@ -3430,9 +3430,7 @@
           .SetFirstDisplayAsInternalDisplay();
   display::Screen* screen = display::Screen::GetScreen();
   DCHECK(screen);
-  Shell* shell = Shell::Get();
-  display::DisplayChangeObserver observer(shell->display_configurator(),
-                                          display_manager());
+  display::DisplayChangeObserver observer(display_manager());
   display::DisplayConfigurator::DisplayStateList outputs;
   std::unique_ptr<display::DisplaySnapshot> internal_snapshot =
       display::FakeDisplaySnapshot::Builder()
@@ -3480,9 +3478,7 @@
   constexpr int64_t id2 = 2;
   display::Screen* screen = display::Screen::GetScreen();
   DCHECK(screen);
-  Shell* shell = Shell::Get();
-  display::DisplayChangeObserver observer(shell->display_configurator(),
-                                          display_manager());
+  display::DisplayChangeObserver observer(display_manager());
   display::DisplayConfigurator::DisplayStateList outputs;
   std::unique_ptr<display::DisplaySnapshot> snapshot1 =
       display::FakeDisplaySnapshot::Builder()
diff --git a/ash/display/display_prefs.cc b/ash/display/display_prefs.cc
index 9ad51b93..9f7d61f 100644
--- a/ash/display/display_prefs.cc
+++ b/ash/display/display_prefs.cc
@@ -22,6 +22,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/display_layout_store.h"
 #include "ui/display/manager/display_manager.h"
@@ -278,6 +279,16 @@
     if (dict_value->GetInteger("device-scale-factor", &dsf_value))
       device_scale_factor = static_cast<float>(dsf_value) / 1000.0f;
 
+    // Default refresh rate is 60 Hz, until
+    // DisplayManager::OnNativeDisplaysChanged() updates us with the actual
+    // display info.
+    double refresh_rate = 60.0;
+    bool is_interlaced = false;
+    if (display::features::IsListAllDisplayModesEnabled()) {
+      dict_value->GetDouble("refresh-rate", &refresh_rate);
+      dict_value->GetBoolean("interlaced", &is_interlaced);
+    }
+
     gfx::Insets insets;
     if (ValueToInsets(*dict_value, &insets))
       insets_to_set = &insets;
@@ -287,7 +298,7 @@
 
     GetDisplayManager()->RegisterDisplayProperty(
         id, rotation, ui_scale, insets_to_set, resolution_in_pixels,
-        device_scale_factor, display_zoom);
+        device_scale_factor, display_zoom, refresh_rate, is_interlaced);
   }
 }
 
@@ -567,6 +578,11 @@
       property_value->SetInteger(
           "device-scale-factor",
           static_cast<int>(mode.device_scale_factor() * 1000));
+
+      if (display::features::IsListAllDisplayModesEnabled()) {
+        property_value->SetBoolean("interlaced", mode.is_interlaced());
+        property_value->SetDouble("refresh-rate", mode.refresh_rate());
+      }
     }
     if (!info.overscan_insets_in_dip().IsEmpty())
       InsetsToValue(info.overscan_insets_in_dip(), property_value.get());
diff --git a/ash/display/display_prefs_unittest.cc b/ash/display/display_prefs_unittest.cc
index 3c9eded..ba09ee0b 100644
--- a/ash/display/display_prefs_unittest.cc
+++ b/ash/display/display_prefs_unittest.cc
@@ -574,7 +574,7 @@
   // Set new display's selected resolution.
   display_manager()->RegisterDisplayProperty(
       id2 + 1, display::Display::ROTATE_0, 1.0f, nullptr, gfx::Size(500, 400),
-      1.0f, 1.0f);
+      1.0f, 1.0f, 60.f, false);
 
   UpdateDisplay("200x200*2, 600x500#600x500|500x400");
 
@@ -597,7 +597,7 @@
   // Set yet another new display's selected resolution.
   display_manager()->RegisterDisplayProperty(
       id2 + 1, display::Display::ROTATE_0, 1.0f, nullptr, gfx::Size(500, 400),
-      1.0f, 1.0f);
+      1.0f, 1.0f, 60.f, false);
   // Disconnect 2nd display first to generate new id for external display.
   UpdateDisplay("200x200*2");
   UpdateDisplay("200x200*2, 500x400#600x500|500x400%60.0f");
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index eb2a2f9..1a17ba6 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -772,10 +772,6 @@
   Shell::Get()->UpdateCursorCompositingEnabled();
 }
 
-display::DisplayConfigurator* WindowTreeHostManager::display_configurator() {
-  return Shell::Get()->display_configurator();
-}
-
 ui::EventDispatchDetails WindowTreeHostManager::DispatchKeyEventPostIME(
     ui::KeyEvent* event,
     DispatchKeyEventPostIMECallback callback) {
diff --git a/ash/display/window_tree_host_manager.h b/ash/display/window_tree_host_manager.h
index 0d282c1..0bd021f 100644
--- a/ash/display/window_tree_host_manager.h
+++ b/ash/display/window_tree_host_manager.h
@@ -171,7 +171,6 @@
   void SetPrimaryDisplayId(int64_t id) override;
   void PreDisplayConfigurationChange(bool clear_focus) override;
   void PostDisplayConfigurationChange() override;
-  display::DisplayConfigurator* display_configurator() override;
 
   // ui::internal::InputMethodDelegate overrides:
   ui::EventDispatchDetails DispatchKeyEventPostIME(
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc
index c0231c5..75330823 100644
--- a/ash/public/cpp/app_list/app_list_features.cc
+++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -38,7 +38,9 @@
 
 bool IsAnswerCardEnabled() {
   // Not using local static variable to allow tests to change this value.
-  return base::FeatureList::IsEnabled(kEnableAnswerCard);
+  // Do not show answer card if the embedded Assistant UI is enabled.
+  return base::FeatureList::IsEnabled(kEnableAnswerCard) &&
+         !IsEmbeddedAssistantUIEnabled();
 }
 
 bool IsAppShortcutSearchEnabled() {
diff --git a/ash/public/interfaces/cros_display_config.mojom b/ash/public/interfaces/cros_display_config.mojom
index de14b58..7039c8b7 100644
--- a/ash/public/interfaces/cros_display_config.mojom
+++ b/ash/public/interfaces/cros_display_config.mojom
@@ -143,6 +143,8 @@
   double refresh_rate;
   // True if the mode is the display's native mode.
   bool is_native;
+  // True if the mode is interlaced.
+  bool is_interlaced;
 };
 
 // Defines the properties of an individual display, returned by
diff --git a/ash/shelf/shelf_window_targeter.cc b/ash/shelf/shelf_window_targeter.cc
index c0cdebb..6fc951ff 100644
--- a/ash/shelf/shelf_window_targeter.cc
+++ b/ash/shelf/shelf_window_targeter.cc
@@ -52,8 +52,8 @@
     gfx::Rect* hit_test_rect_touch) const {
   // We only want to special case a very specific situation where we are not
   // currently in an active session and change only the behavior of the login
-  // shelf.
-  if (target->id() == kShellWindowId_ShelfContainer &&
+  // shelf. On secondary displays, the login shelf will not be visible.
+  if (target->id() == kShellWindowId_ShelfContainer && shelf_->IsVisible() &&
       Shell::Get()->session_controller()->GetSessionState() !=
           session_manager::SessionState::ACTIVE) {
     // When this is the case, let events pass through the "empty" part of
diff --git a/ash/shell.cc b/ash/shell.cc
index 411cbca..7dbcf32 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -423,6 +423,10 @@
   PowerPrefs::RegisterUserProfilePrefs(registry, for_test);
 }
 
+display::DisplayConfigurator* Shell::display_configurator() {
+  return display_manager_->configurator();
+}
+
 void Shell::InitWaylandServer(std::unique_ptr<exo::FileHelper> file_helper) {
   wayland_server_controller_ = WaylandServerController::CreateIfNecessary(
       std::move(file_helper), aura_env_);
@@ -651,9 +655,6 @@
       system_tray_notifier_(std::make_unique<SystemTrayNotifier>()),
       vpn_list_(std::make_unique<VpnList>()),
       window_cycle_controller_(std::make_unique<WindowCycleController>()),
-      display_configurator_(std::make_unique<display::DisplayConfigurator>()),
-      display_output_protection_(std::make_unique<DisplayOutputProtection>(
-          display_configurator_.get())),
       native_cursor_manager_(nullptr),
       weak_factory_(this) {
   // Ash doesn't properly remove pre-target-handlers.
@@ -667,6 +668,8 @@
   login_screen_controller_ =
       std::make_unique<LoginScreenController>(system_tray_notifier_.get());
   display_manager_.reset(ScreenAsh::CreateDisplayManager());
+  display_output_protection_ = std::make_unique<DisplayOutputProtection>(
+      display_manager_->configurator());
   window_tree_host_manager_ = std::make_unique<WindowTreeHostManager>();
   user_metrics_recorder_ = std::make_unique<UserMetricsRecorder>();
   ash_keyboard_controller_ =
@@ -898,9 +901,11 @@
   projecting_observer_.reset();
 
   if (display_change_observer_)
-    display_configurator_->RemoveObserver(display_change_observer_.get());
+    display_manager_->configurator()->RemoveObserver(
+        display_change_observer_.get());
   if (display_error_observer_)
-    display_configurator_->RemoveObserver(display_error_observer_.get());
+    display_manager_->configurator()->RemoveObserver(
+        display_error_observer_.get());
   display_change_observer_.reset();
   display_shutdown_observer_.reset();
 
@@ -1017,6 +1022,8 @@
   cursor_manager_ =
       std::make_unique<CursorManager>(base::WrapUnique(native_cursor_manager_));
 
+  InitializeDisplayManager();
+
   // In CLASSIC mode, |initial_display_prefs| contains the synchronously
   // loaded display pref values. Otherwise |initial_display_prefs| is null and
   // the pref values will be loaded once |local_state_| is available. (Any store
@@ -1024,8 +1031,6 @@
   display_prefs_ =
       std::make_unique<DisplayPrefs>(std::move(initial_display_prefs));
 
-  InitializeDisplayManager();
-
   // This will initialize aura::Env which requires |display_manager_| to
   // be initialized first.
   if (context_factory)
@@ -1128,7 +1133,7 @@
       backlights_forced_off_setter_.get());
   // Pass the initial display state to PowerButtonController.
   power_button_controller_->OnDisplayModeChanged(
-      display_configurator_->cached_displays());
+      display_configurator()->cached_displays());
 
   drag_drop_controller_ = std::make_unique<DragDropController>();
 
@@ -1284,11 +1289,11 @@
 void Shell::InitializeDisplayManager() {
   bool display_initialized = display_manager_->InitFromCommandLine();
 
+  display_manager_->InitConfigurator(
+      ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate());
   display_configuration_controller_ =
       std::make_unique<DisplayConfigurationController>(
           display_manager_.get(), window_tree_host_manager_.get());
-  display_configurator_->Init(
-      ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(), false);
   display_configuration_observer_ =
       std::make_unique<DisplayConfigurationObserver>();
 
@@ -1298,32 +1303,26 @@
       std::make_unique<PersistentWindowController>();
 
   projecting_observer_ =
-      std::make_unique<ProjectingObserver>(display_configurator_.get());
+      std::make_unique<ProjectingObserver>(display_manager_->configurator());
 
   if (!display_initialized) {
     if (chromeos::IsRunningAsSystemCompositor()) {
       display_change_observer_ =
           std::make_unique<display::DisplayChangeObserver>(
-              display_configurator_.get(), display_manager_.get());
+              display_manager_.get());
 
+      display_error_observer_ = std::make_unique<DisplayErrorObserver>();
       display_shutdown_observer_ = std::make_unique<DisplayShutdownObserver>(
-          display_configurator_.get());
+          display_manager_->configurator());
 
-      // Register |display_change_observer_| first so that the rest of
-      // observer gets invoked after the root windows are configured.
-      display_configurator_->AddObserver(display_change_observer_.get());
-      display_error_observer_.reset(new DisplayErrorObserver());
-      display_configurator_->AddObserver(display_error_observer_.get());
-      display_configurator_->set_state_controller(
-          display_change_observer_.get());
-      display_configurator_->set_mirroring_controller(display_manager_.get());
-      display_configurator_->ForceInitialConfigure();
+      display_manager_->ForceInitialConfigureWithObservers(
+          display_change_observer_.get(), display_error_observer_.get());
       display_initialized = true;
     }
   }
 
   display_color_manager_ = std::make_unique<DisplayColorManager>(
-      display_configurator_.get(), display::Screen::GetScreen());
+      display_manager_->configurator(), display::Screen::GetScreen());
 
   if (!display_initialized)
     display_manager_->InitDefaultDisplay();
diff --git a/ash/shell.h b/ash/shell.h
index 5995f35a..99a00ca 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -382,10 +382,8 @@
     return display_configuration_controller_.get();
   }
 
-  // TODO(oshima): Move these objects to WindowTreeHostManager.
-  display::DisplayConfigurator* display_configurator() {
-    return display_configurator_.get();
-  }
+  display::DisplayConfigurator* display_configurator();
+
   DisplayColorManager* display_color_manager() {
     return display_color_manager_.get();
   }
@@ -824,7 +822,6 @@
   std::unique_ptr<TrayBluetoothHelper> tray_bluetooth_helper_;
   std::unique_ptr<AshKeyboardController> ash_keyboard_controller_;
   // Controls video output device state.
-  std::unique_ptr<display::DisplayConfigurator> display_configurator_;
   std::unique_ptr<DisplayOutputProtection> display_output_protection_;
   std::unique_ptr<DisplayColorManager> display_color_manager_;
   std::unique_ptr<DisplayErrorObserver> display_error_observer_;
diff --git a/ash/system/message_center/unified_message_center_view_unittest.cc b/ash/system/message_center/unified_message_center_view_unittest.cc
index a164797..b9c30c1c 100644
--- a/ash/system/message_center/unified_message_center_view_unittest.cc
+++ b/ash/system/message_center/unified_message_center_view_unittest.cc
@@ -395,9 +395,12 @@
   message_center_view()->OnMessageCenterScrolled();
 
   EXPECT_TRUE(GetStackingCounter()->visible());
-  // The offset change matches with the scroll amount.
-  EXPECT_EQ(previous_bounds - gfx::Vector2d(0, scroll_amount),
-            GetMessageViewVisibleBounds(2));
+  // The offset change matches with the scroll amount plus the stacking bar
+  // height.
+  EXPECT_EQ(
+      previous_bounds -
+          gfx::Vector2d(0, scroll_amount + kStackingNotificationCounterHeight),
+      GetMessageViewVisibleBounds(2));
 
   GetScroller()->ScrollToPosition(GetScrollBar(), scroll_amount - 1);
   message_center_view()->OnMessageCenterScrolled();
diff --git a/ash/system/night_light/night_light_controller_unittest.cc b/ash/system/night_light/night_light_controller_unittest.cc
index e3feb4f..91939b6 100644
--- a/ash/system/night_light/night_light_controller_unittest.cc
+++ b/ash/system/night_light/night_light_controller_unittest.cc
@@ -870,23 +870,19 @@
   static constexpr int64_t kId1 = 123;
   static constexpr int64_t kId2 = 456;
 
-  display::DisplayConfigurator* display_configurator() {
-    return Shell::Get()->display_configurator();
-  }
-
   // NightLightTest:
   void SetUp() override {
     NightLightTest::SetUp();
 
     native_display_delegate_ =
         new display::test::TestNativeDisplayDelegate(logger_.get());
-    display_configurator()->SetDelegateForTesting(
+    display_manager()->configurator()->SetDelegateForTesting(
         std::unique_ptr<display::NativeDisplayDelegate>(
             native_display_delegate_));
-    display_change_observer_ = std::make_unique<display::DisplayChangeObserver>(
-        display_configurator(), display_manager());
+    display_change_observer_ =
+        std::make_unique<display::DisplayChangeObserver>(display_manager());
     test_api_ = std::make_unique<display::DisplayConfigurator::TestApi>(
-        display_configurator());
+        display_manager()->configurator());
   }
 
   void TearDown() override {
@@ -938,7 +934,7 @@
   // display snapshots.
   void UpdateDisplays(const std::vector<display::DisplaySnapshot*>& outputs) {
     native_display_delegate_->set_outputs(outputs);
-    display_configurator()->OnConfigurationChanged();
+    display_manager()->configurator()->OnConfigurationChanged();
     EXPECT_TRUE(test_api_->TriggerConfigureTimeout());
     display_change_observer_->GetStateForDisplayIds(outputs);
     display_change_observer_->OnDisplayModeChanged(outputs);
diff --git a/ash/system/status_area_widget_unittest.cc b/ash/system/status_area_widget_unittest.cc
index e9b16ae3..ff8e98b 100644
--- a/ash/system/status_area_widget_unittest.cc
+++ b/ash/system/status_area_widget_unittest.cc
@@ -126,7 +126,8 @@
 
 // Tests that tab traversal through status area widget in non-active session
 // could properly send FocusOut event.
-TEST_F(StatusAreaWidgetFocusTest, FocusOutObserverUnified) {
+// TODO(crbug.com/934939): Failing on trybot.
+TEST_F(StatusAreaWidgetFocusTest, DISABLED_FocusOutObserverUnified) {
   // Set session state to LOCKED.
   SessionController* session = Shell::Get()->session_controller();
   ASSERT_TRUE(session->IsActiveUserSessionStarted());
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 852d7123..31f7a6c 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -874,11 +874,12 @@
       break;
   }
 
-  // If there is a window snapped to one side but no window snapped to the other
-  // side, then overview should be started (to be seen on the side with no
-  // snapped window).
+  // Ensure that overview mode is active if and only if there is a window
+  // snapped to one side but no window snapped to the other side.
   if (state_ == LEFT_SNAPPED || state_ == RIGHT_SNAPPED)
     StartOverview();
+  else
+    EndOverview();
 }
 
 void SplitViewController::StartObserving(aura::Window* window) {
diff --git a/ash/wm/wm_toplevel_window_event_handler.cc b/ash/wm/wm_toplevel_window_event_handler.cc
index 34b179b..755e117 100644
--- a/ash/wm/wm_toplevel_window_event_handler.cc
+++ b/ash/wm/wm_toplevel_window_event_handler.cc
@@ -20,6 +20,7 @@
 #include "ui/aura/window_delegate.h"
 #include "ui/aura/window_observer.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"
@@ -49,9 +50,31 @@
     return nullptr;
 
   aura::Window* toplevel = widget->GetNativeWindow();
-  if (!toplevel->GetProperty(
-          aura::client::kGestureDragFromClientAreaTopMovesWindow)) {
-    return nullptr;
+  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 (event->details().scroll_y_hint() < 0)
diff --git a/base/profiler/native_stack_sampler_mac.cc b/base/profiler/native_stack_sampler_mac.cc
index 4b5c4a0..162fc2d 100644
--- a/base/profiler/native_stack_sampler_mac.cc
+++ b/base/profiler/native_stack_sampler_mac.cc
@@ -409,11 +409,12 @@
     return HasValidRbp(unwind_cursor, new_stack_top);
   };
 
-  WalkStack(thread_state,
-            [&frames](uintptr_t frame_ip, ModuleCache::Module module) {
-              frames.emplace_back(frame_ip, std::move(module));
-            },
-            continue_predicate);
+  WalkStack(
+      thread_state,
+      [&frames](uintptr_t frame_ip, const ModuleCache::Module* module) {
+        frames.emplace_back(frame_ip, module);
+      },
+      continue_predicate);
 
   return frames;
 }
@@ -444,8 +445,8 @@
     // libunwind adds the expected stack size, it will look for the return
     // address in the wrong place. This check should ensure that we bail before
     // trying to deref a bad IP obtained this way in the previous frame.
-    const ModuleCache::Module& module = module_cache_->GetModuleForAddress(rip);
-    if (!module.is_valid)
+    const ModuleCache::Module* module = module_cache_->GetModuleForAddress(rip);
+    if (!module->is_valid)
       return false;
 
     callback(static_cast<uintptr_t>(rip), module);
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc
index 99b2fef9..ebf449c6 100644
--- a/base/profiler/native_stack_sampler_win.cc
+++ b/base/profiler/native_stack_sampler_win.cc
@@ -427,24 +427,22 @@
 
   win::ScopedHandle thread_handle_;
 
+  ModuleCache* module_cache_;
+
   NativeStackSamplerTestDelegate* const test_delegate_;
 
   // The stack base address corresponding to |thread_handle_|.
   const void* const thread_stack_base_address_;
 
-  // The module objects, indexed by the module handle.
-  std::map<HMODULE, ModuleCache::Module> module_cache_;
-
   DISALLOW_COPY_AND_ASSIGN(NativeStackSamplerWin);
 };
 
 NativeStackSamplerWin::NativeStackSamplerWin(
     win::ScopedHandle thread_handle,
-    // Ignored for now, until we can switch the internal module cache to use
-    // this one.
     ModuleCache* module_cache,
     NativeStackSamplerTestDelegate* test_delegate)
     : thread_handle_(thread_handle.Take()),
+      module_cache_(module_cache),
       test_delegate_(test_delegate),
       thread_stack_base_address_(
           GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase) {}
@@ -452,7 +450,6 @@
 NativeStackSamplerWin::~NativeStackSamplerWin() {}
 
 void NativeStackSamplerWin::ProfileRecordingStarting() {
-  module_cache_.clear();
 }
 
 std::vector<Frame> NativeStackSamplerWin::RecordStackFrames(
@@ -489,26 +486,8 @@
   frames.reserve(stack.size());
 
   for (const auto& frame : stack) {
-    auto frame_ip = reinterpret_cast<uintptr_t>(frame.instruction_pointer);
-
-    HMODULE module_handle = frame.module.Get();
-    if (!module_handle) {
-      frames.emplace_back(frame_ip, ModuleCache::Module());
-      continue;
-    }
-
-    auto loc = module_cache_.find(module_handle);
-    if (loc != module_cache_.end()) {
-      frames.emplace_back(frame_ip, loc->second);
-      continue;
-    }
-
-    ModuleCache::Module module =
-        ModuleCache::CreateModuleForHandle(module_handle);
-    if (module.is_valid)
-      module_cache_.insert(std::make_pair(module_handle, module));
-
-    frames.emplace_back(frame_ip, std::move(module));
+    frames.emplace_back(reinterpret_cast<uintptr_t>(frame.instruction_pointer),
+                        module_cache_->GetModuleForHandle(frame.module.Get()));
   }
 
   return frames;
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index e86df0d..c077557 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -50,8 +50,8 @@
 // StackSamplingProfiler::Frame -------------------------------------
 
 StackSamplingProfiler::Frame::Frame(uintptr_t instruction_pointer,
-                                    ModuleCache::Module module)
-    : instruction_pointer(instruction_pointer), module(std::move(module)) {}
+                                    const ModuleCache::Module* module)
+    : instruction_pointer(instruction_pointer), module(module) {}
 
 StackSamplingProfiler::Frame::~Frame() = default;
 
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h
index 9205b47..5973137 100644
--- a/base/profiler/stack_sampling_profiler.h
+++ b/base/profiler/stack_sampling_profiler.h
@@ -58,14 +58,14 @@
   // This struct is only used for sampling data transfer from NativeStackSampler
   // to ProfileBuilder.
   struct BASE_EXPORT Frame {
-    Frame(uintptr_t instruction_pointer, ModuleCache::Module module);
+    Frame(uintptr_t instruction_pointer, const ModuleCache::Module* module);
     ~Frame();
 
     // The sampled instruction pointer within the function.
     uintptr_t instruction_pointer;
 
     // The module information.
-    ModuleCache::Module module;
+    const ModuleCache::Module* module;
   };
 
   // Represents parameters that configure the sampling.
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc
index 1c1e6c9..3c57921 100644
--- a/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -318,7 +318,8 @@
 // TestProfileBuilder collects frames produced by the profiler.
 class TestProfileBuilder : public StackSamplingProfiler::ProfileBuilder {
  public:
-  TestProfileBuilder(const ProfileCompletedCallback& callback);
+  TestProfileBuilder(ModuleCache* module_cache,
+                     const ProfileCompletedCallback& callback);
 
   ~TestProfileBuilder() override;
 
@@ -330,7 +331,7 @@
                           TimeDelta sampling_period) override;
 
  private:
-  ModuleCache module_cache_;
+  ModuleCache* module_cache_;
 
   // The sets of frames recorded.
   std::vector<Frames> frame_sets_;
@@ -344,13 +345,14 @@
   DISALLOW_COPY_AND_ASSIGN(TestProfileBuilder);
 };
 
-TestProfileBuilder::TestProfileBuilder(const ProfileCompletedCallback& callback)
-    : callback_(callback) {}
+TestProfileBuilder::TestProfileBuilder(ModuleCache* module_cache,
+                                       const ProfileCompletedCallback& callback)
+    : module_cache_(module_cache), callback_(callback) {}
 
 TestProfileBuilder::~TestProfileBuilder() = default;
 
 ModuleCache* TestProfileBuilder::GetModuleCache() {
-  return &module_cache_;
+  return module_cache_;
 }
 
 void TestProfileBuilder::RecordMetadata() {
@@ -440,12 +442,14 @@
 struct TestProfilerInfo {
   TestProfilerInfo(PlatformThreadId thread_id,
                    const SamplingParams& params,
+                   ModuleCache* module_cache,
                    NativeStackSamplerTestDelegate* delegate = nullptr)
       : completed(WaitableEvent::ResetPolicy::MANUAL,
                   WaitableEvent::InitialState::NOT_SIGNALED),
         profiler(thread_id,
                  params,
                  std::make_unique<TestProfileBuilder>(
+                     module_cache,
                      BindLambdaForTesting([this](Profile result_profile) {
                        profile = std::move(result_profile);
                        completed.Signal();
@@ -465,13 +469,14 @@
 // Creates multiple profilers based on a vector of parameters.
 std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers(
     PlatformThreadId target_thread_id,
-    const std::vector<SamplingParams>& params) {
+    const std::vector<SamplingParams>& params,
+    ModuleCache* module_cache) {
   DCHECK(!params.empty());
 
   std::vector<std::unique_ptr<TestProfilerInfo>> profilers;
   for (const auto& i : params) {
     profilers.push_back(
-        std::make_unique<TestProfilerInfo>(target_thread_id, i));
+        std::make_unique<TestProfilerInfo>(target_thread_id, i, module_cache));
   }
 
   return profilers;
@@ -480,11 +485,11 @@
 // Captures frames as specified by |params| on the TargetThread, and returns
 // them. Waits up to |profiler_wait_time| for the profiler to complete.
 FrameSets CaptureFrameSets(const SamplingParams& params,
-                           TimeDelta profiler_wait_time) {
+                           TimeDelta profiler_wait_time,
+                           ModuleCache* module_cache) {
   FrameSets frame_sets;
-  WithTargetThread([&params, &frame_sets,
-                    profiler_wait_time](PlatformThreadId target_thread_id) {
-    TestProfilerInfo info(target_thread_id, params);
+  WithTargetThread([&](PlatformThreadId target_thread_id) {
+    TestProfilerInfo info(target_thread_id, params, module_cache);
     info.profiler.Start();
     info.completed.TimedWait(profiler_wait_time);
     info.profiler.Stop();
@@ -557,7 +562,7 @@
   for (const auto& frame : frames) {
     output += StringPrintf(
         "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer),
-        frame.module.filename.AsUTF8Unsafe().c_str());
+        frame.module->filename.AsUTF8Unsafe().c_str());
   }
   return output;
 }
@@ -572,7 +577,7 @@
 // before walking it. If |wait_until_unloaded| is true, ensures that the
 // asynchronous library loading has completed before walking the stack. If
 // false, the unloading may still be occurring during the stack walk.
-void TestLibraryUnload(bool wait_until_unloaded) {
+void TestLibraryUnload(bool wait_until_unloaded, ModuleCache* module_cache) {
   // Test delegate that supports intervening between the copying of the stack
   // and the walking of the stack.
   class StackCopiedSignaler : public NativeStackSamplerTestDelegate {
@@ -622,11 +627,13 @@
                                     wait_until_unloaded);
   StackSamplingProfiler profiler(
       target_thread.id(), params,
-      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
-          [&profile, &sampling_thread_completed](Profile result_profile) {
-            profile = std::move(result_profile);
-            sampling_thread_completed.Signal();
-          })),
+      std::make_unique<TestProfileBuilder>(
+          module_cache,
+          BindLambdaForTesting(
+              [&profile, &sampling_thread_completed](Profile result_profile) {
+                profile = std::move(result_profile);
+                sampling_thread_completed.Signal();
+              })),
       &test_delegate);
 
   profiler.Start();
@@ -731,6 +738,12 @@
     // idle-shutdown behavior.
     StackSamplingProfiler::TestPeer::Reset();
   }
+
+ protected:
+  ModuleCache* module_cache() { return &module_cache_; }
+
+ private:
+  ModuleCache module_cache_;
 };
 
 }  // namespace
@@ -748,7 +761,8 @@
   params.sampling_interval = TimeDelta::FromMilliseconds(0);
   params.samples_per_profile = 1;
 
-  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  FrameSets frame_sets =
+      CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
 
   // Check that the size of the frame sets are correct.
   ASSERT_EQ(1u, frame_sets.size());
@@ -756,7 +770,7 @@
 
   // Check that all the modules are valid.
   for (const auto& frame : frames)
-    EXPECT_TRUE(frame.module.is_valid);
+    EXPECT_TRUE(frame.module->is_valid);
 
   // Check that the stack contains a frame for
   // TargetThread::SignalAndWaitUntilSignaled().
@@ -785,14 +799,16 @@
 
   Profile profile;
   WithTargetThread(
-      [&params, &profile](PlatformThreadId target_thread_id) {
+      [&](PlatformThreadId target_thread_id) {
         WaitableEvent sampling_thread_completed(
             WaitableEvent::ResetPolicy::MANUAL,
             WaitableEvent::InitialState::NOT_SIGNALED);
         StackSamplingProfiler profiler(
             target_thread_id, params,
-            std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
-                [&profile, &sampling_thread_completed](Profile result_profile) {
+            std::make_unique<TestProfileBuilder>(
+                module_cache(),
+                BindLambdaForTesting([&profile, &sampling_thread_completed](
+                                         Profile result_profile) {
                   profile = std::move(result_profile);
                   sampling_thread_completed.Signal();
                 })));
@@ -834,7 +850,7 @@
 
 // Checks that a profiler can stop/destruct without ever having started.
 PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params;
     params.sampling_interval = TimeDelta::FromMilliseconds(0);
     params.samples_per_profile = 1;
@@ -845,11 +861,13 @@
 
     StackSamplingProfiler profiler(
         target_thread_id, params,
-        std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
-            [&profile, &sampling_completed](Profile result_profile) {
-              profile = std::move(result_profile);
-              sampling_completed.Signal();
-            })));
+        std::make_unique<TestProfileBuilder>(
+            module_cache(),
+            BindLambdaForTesting(
+                [&profile, &sampling_completed](Profile result_profile) {
+                  profile = std::move(result_profile);
+                  sampling_completed.Signal();
+                })));
 
     profiler.Stop();  // Constructed but never started.
     EXPECT_FALSE(sampling_completed.IsSignaled());
@@ -879,7 +897,7 @@
     size_t count_ = 0;
   };
 
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params[2];
 
     // Providing an initial delay makes it more likely that both will be
@@ -896,9 +914,9 @@
 
     SampleRecordedCounter samples_recorded[size(params)];
 
-    TestProfilerInfo profiler_info0(target_thread_id, params[0],
+    TestProfilerInfo profiler_info0(target_thread_id, params[0], module_cache(),
                                     &samples_recorded[0]);
-    TestProfilerInfo profiler_info1(target_thread_id, params[1],
+    TestProfilerInfo profiler_info1(target_thread_id, params[1], module_cache(),
                                     &samples_recorded[1]);
 
     profiler_info0.profiler.Start();
@@ -938,7 +956,7 @@
   params.initial_delay = TimeDelta::FromSeconds(60);
 
   FrameSets frame_sets =
-      CaptureFrameSets(params, TimeDelta::FromMilliseconds(0));
+      CaptureFrameSets(params, TimeDelta::FromMilliseconds(0), module_cache());
 
   EXPECT_TRUE(frame_sets.empty());
 }
@@ -961,14 +979,15 @@
     WaitableEvent sample_recorded_;
   };
 
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params;
 
     params.sampling_interval = AVeryLongTimeDelta();
     params.samples_per_profile = 2;
 
     SampleRecordedEvent samples_recorded;
-    TestProfilerInfo profiler_info(target_thread_id, params, &samples_recorded);
+    TestProfilerInfo profiler_info(target_thread_id, params, module_cache(),
+                                   &samples_recorded);
 
     profiler_info.profiler.Start();
 
@@ -989,9 +1008,10 @@
   params.sampling_interval = TimeDelta::FromMilliseconds(10);
 
   Profile profile;
-  WithTargetThread([&params, &profile](PlatformThreadId target_thread_id) {
+  WithTargetThread([&, this](PlatformThreadId target_thread_id) {
     std::unique_ptr<StackSamplingProfiler> profiler;
     auto profile_builder = std::make_unique<TestProfileBuilder>(
+        module_cache(),
         BindLambdaForTesting([&profile](Profile result_profile) {
           profile = std::move(result_profile);
         }));
@@ -1012,16 +1032,17 @@
   params.sampling_interval = TimeDelta::FromMilliseconds(0);
   params.samples_per_profile = 1;
 
-  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  FrameSets frame_sets =
+      CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
   ASSERT_EQ(1u, frame_sets.size());
 
-  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
   ASSERT_EQ(1u, frame_sets.size());
 }
 
 // Checks that a sampler can be started while another is running.
 PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     std::vector<SamplingParams> params(2);
 
     params[0].initial_delay = AVeryLongTimeDelta();
@@ -1031,7 +1052,7 @@
     params[1].samples_per_profile = 1;
 
     std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
-        CreateProfilers(target_thread_id, params);
+        CreateProfilers(target_thread_id, params, module_cache());
 
     profiler_infos[0]->profiler.Start();
     profiler_infos[1]->profiler.Start();
@@ -1044,12 +1065,12 @@
 // correctly. Also checks that RecordMetadata() is invoked each time a sample
 // is recorded.
 PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params;
     params.sampling_interval = TimeDelta::FromMilliseconds(1);
     params.samples_per_profile = 3;
 
-    TestProfilerInfo profiler_info(target_thread_id, params);
+    TestProfilerInfo profiler_info(target_thread_id, params, module_cache());
 
     profiler_info.profiler.Start();
     profiler_info.completed.Wait();
@@ -1074,7 +1095,8 @@
   params.sampling_interval = TimeDelta::FromMilliseconds(0);
   params.samples_per_profile = 1;
 
-  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  FrameSets frame_sets =
+      CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
   ASSERT_EQ(1u, frame_sets.size());
 
   // Capture thread should still be running at this point.
@@ -1099,7 +1121,8 @@
   params.sampling_interval = TimeDelta::FromMilliseconds(0);
   params.samples_per_profile = 1;
 
-  FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  FrameSets frame_sets =
+      CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
   ASSERT_EQ(1u, frame_sets.size());
 
   // Capture thread should still be running at this point.
@@ -1110,7 +1133,7 @@
   StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false);
 
   // Ensure another capture will start the sampling thread and run.
-  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+  frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta(), module_cache());
   ASSERT_EQ(1u, frame_sets.size());
   EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
 }
@@ -1118,13 +1141,13 @@
 // Checks that it's safe to stop a task after it's completed and the sampling
 // thread has shut-down for being idle.
 PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params;
 
     params.sampling_interval = TimeDelta::FromMilliseconds(1);
     params.samples_per_profile = 1;
 
-    TestProfilerInfo profiler_info(target_thread_id, params);
+    TestProfilerInfo profiler_info(target_thread_id, params, module_cache());
 
     profiler_info.profiler.Start();
     profiler_info.completed.Wait();
@@ -1145,7 +1168,7 @@
 // started.
 PROFILER_TEST_F(StackSamplingProfilerTest,
                 ProfileBeforeAndAfterSamplingThreadRunning) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     std::vector<SamplingParams> params(2);
 
     params[0].initial_delay = AVeryLongTimeDelta();
@@ -1157,7 +1180,7 @@
     params[1].samples_per_profile = 1;
 
     std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
-        CreateProfilers(target_thread_id, params);
+        CreateProfilers(target_thread_id, params, module_cache());
 
     // First profiler is started when there has never been a sampling thread.
     EXPECT_FALSE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
@@ -1175,13 +1198,13 @@
 // Checks that an idle-shutdown task will abort if a new profiler starts
 // between when it was posted and when it runs.
 PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     SamplingParams params;
 
     params.sampling_interval = TimeDelta::FromMilliseconds(1);
     params.samples_per_profile = 1;
 
-    TestProfilerInfo profiler_info(target_thread_id, params);
+    TestProfilerInfo profiler_info(target_thread_id, params, module_cache());
 
     profiler_info.profiler.Start();
     profiler_info.completed.Wait();
@@ -1200,7 +1223,7 @@
     EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
 
     // Ensure that it's still possible to run another sampler.
-    TestProfilerInfo another_info(target_thread_id, params);
+    TestProfilerInfo another_info(target_thread_id, params, module_cache());
     another_info.profiler.Start();
     another_info.completed.Wait();
     EXPECT_EQ(1u, another_info.profile.frame_sets.size());
@@ -1209,7 +1232,7 @@
 
 // Checks that synchronized multiple sampling requests execute in parallel.
 PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     std::vector<SamplingParams> params(2);
 
     // Providing an initial delay makes it more likely that both will be
@@ -1226,7 +1249,7 @@
     params[1].samples_per_profile = 8;
 
     std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
-        CreateProfilers(target_thread_id, params);
+        CreateProfilers(target_thread_id, params, module_cache());
 
     profiler_infos[0]->profiler.Start();
     profiler_infos[1]->profiler.Start();
@@ -1246,7 +1269,7 @@
 
 // Checks that several mixed sampling requests execute in parallel.
 PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     std::vector<SamplingParams> params(3);
 
     params[0].initial_delay = TimeDelta::FromMilliseconds(8);
@@ -1262,7 +1285,7 @@
     params[2].samples_per_profile = 10;
 
     std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
-        CreateProfilers(target_thread_id, params);
+        CreateProfilers(target_thread_id, params, module_cache());
 
     for (auto& i : profiler_infos)
       i->profiler.Start();
@@ -1296,13 +1319,14 @@
   {
     ScopedNativeLibrary other_library(LoadOtherLibrary());
     WithTargetThread(
-        [&params, &profile](PlatformThreadId target_thread_id) {
+        [&, this](PlatformThreadId target_thread_id) {
           WaitableEvent sampling_thread_completed(
               WaitableEvent::ResetPolicy::MANUAL,
               WaitableEvent::InitialState::NOT_SIGNALED);
           StackSamplingProfiler profiler(
               target_thread_id, params,
               std::make_unique<TestProfileBuilder>(
+                  module_cache(),
                   BindLambdaForTesting([&profile, &sampling_thread_completed](
                                            Profile result_profile) {
                     profile = std::move(result_profile);
@@ -1363,7 +1387,7 @@
 #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary
 #endif
 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
-  TestLibraryUnload(false);
+  TestLibraryUnload(false, module_cache());
 }
 
 // Checks that a stack that runs through a library that has been unloaded
@@ -1375,7 +1399,7 @@
 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
 #endif
 PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
-  TestLibraryUnload(true);
+  TestLibraryUnload(true, module_cache());
 }
 
 // Checks that different threads can be sampled in parallel.
@@ -1411,22 +1435,26 @@
       WaitableEvent::InitialState::NOT_SIGNALED);
   StackSamplingProfiler profiler1(
       target_thread1.id(), params1,
-      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
-          [&profile1, &sampling_thread_completed1](Profile result_profile) {
-            profile1 = std::move(result_profile);
-            sampling_thread_completed1.Signal();
-          })));
+      std::make_unique<TestProfileBuilder>(
+          module_cache(),
+          BindLambdaForTesting(
+              [&profile1, &sampling_thread_completed1](Profile result_profile) {
+                profile1 = std::move(result_profile);
+                sampling_thread_completed1.Signal();
+              })));
 
   WaitableEvent sampling_thread_completed2(
       WaitableEvent::ResetPolicy::MANUAL,
       WaitableEvent::InitialState::NOT_SIGNALED);
   StackSamplingProfiler profiler2(
       target_thread2.id(), params2,
-      std::make_unique<TestProfileBuilder>(BindLambdaForTesting(
-          [&profile2, &sampling_thread_completed2](Profile result_profile) {
-            profile2 = std::move(result_profile);
-            sampling_thread_completed2.Signal();
-          })));
+      std::make_unique<TestProfileBuilder>(
+          module_cache(),
+          BindLambdaForTesting(
+              [&profile2, &sampling_thread_completed2](Profile result_profile) {
+                profile2 = std::move(result_profile);
+                sampling_thread_completed2.Signal();
+              })));
 
   // Finally the real work.
   profiler1.Start();
@@ -1447,7 +1475,8 @@
  public:
   ProfilerThread(const std::string& name,
                  PlatformThreadId thread_id,
-                 const SamplingParams& params)
+                 const SamplingParams& params,
+                 ModuleCache* module_cache)
       : SimpleThread(name, Options()),
         run_(WaitableEvent::ResetPolicy::MANUAL,
              WaitableEvent::InitialState::NOT_SIGNALED),
@@ -1456,6 +1485,7 @@
         profiler_(thread_id,
                   params,
                   std::make_unique<TestProfileBuilder>(
+                      module_cache,
                       BindLambdaForTesting([this](Profile result_profile) {
                         profile_ = std::move(result_profile);
                         completed_.Signal();
@@ -1482,7 +1512,7 @@
 
 // Checks that different threads can run samplers in parallel.
 PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) {
-  WithTargetThread([](PlatformThreadId target_thread_id) {
+  WithTargetThread([this](PlatformThreadId target_thread_id) {
     // Providing an initial delay makes it more likely that both will be
     // scheduled before either starts to run. Once started, samples will
     // run ordered by their scheduled, interleaved times regardless of
@@ -1496,8 +1526,10 @@
     params2.samples_per_profile = 8;
 
     // Start the profiler threads and give them a moment to get going.
-    ProfilerThread profiler_thread1("profiler1", target_thread_id, params1);
-    ProfilerThread profiler_thread2("profiler2", target_thread_id, params2);
+    ProfilerThread profiler_thread1("profiler1", target_thread_id, params1,
+                                    module_cache());
+    ProfilerThread profiler_thread2("profiler2", target_thread_id, params2,
+                                    module_cache());
     profiler_thread1.Start();
     profiler_thread2.Start();
     PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
diff --git a/base/sampling_heap_profiler/module_cache.cc b/base/sampling_heap_profiler/module_cache.cc
index 3871d517..d1e03c1 100644
--- a/base/sampling_heap_profiler/module_cache.cc
+++ b/base/sampling_heap_profiler/module_cache.cc
@@ -4,6 +4,8 @@
 
 #include "base/sampling_heap_profiler/module_cache.h"
 
+#include <utility>
+
 #include "base/no_destructor.h"
 
 namespace base {
@@ -30,29 +32,29 @@
 ModuleCache::ModuleCache() = default;
 ModuleCache::~ModuleCache() = default;
 
-const ModuleCache::Module& ModuleCache::GetModuleForAddress(uintptr_t address) {
+const ModuleCache::Module* ModuleCache::GetModuleForAddress(uintptr_t address) {
   static NoDestructor<Module> invalid_module;
   auto it = modules_cache_map_.upper_bound(address);
   if (it != modules_cache_map_.begin()) {
     DCHECK(!modules_cache_map_.empty());
     --it;
-    Module& module = it->second;
-    if (address < module.base_address + module.size)
+    const Module* module = it->second.get();
+    if (address < module->base_address + module->size)
       return module;
   }
 
-  auto module = CreateModuleForAddress(address);
-  if (!module.is_valid)
-    return *invalid_module;
-  return modules_cache_map_.emplace(module.base_address, std::move(module))
-      .first->second;
+  std::unique_ptr<Module> module = CreateModuleForAddress(address);
+  if (!module->is_valid)
+    return invalid_module.get();
+  return modules_cache_map_.emplace(module->base_address, std::move(module))
+      .first->second.get();
 }
 
 std::vector<const ModuleCache::Module*> ModuleCache::GetModules() const {
   std::vector<const Module*> result;
   result.reserve(modules_cache_map_.size());
   for (const auto& it : modules_cache_map_)
-    result.push_back(&it.second);
+    result.push_back(it.second.get());
   return result;
 }
 
diff --git a/base/sampling_heap_profiler/module_cache.h b/base/sampling_heap_profiler/module_cache.h
index fee09ff..b7d6d94 100644
--- a/base/sampling_heap_profiler/module_cache.h
+++ b/base/sampling_heap_profiler/module_cache.h
@@ -6,6 +6,7 @@
 #define BASE_SAMPLING_HEAP_PROFILER_MODULE_CACHE_H_
 
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -35,6 +36,9 @@
            size_t size);
     ~Module();
 
+    Module(const Module&) = delete;
+    Module& operator=(const Module&) = delete;
+
     // Points to the base address of the module.
     uintptr_t base_address;
 
@@ -60,7 +64,10 @@
   ModuleCache();
   ~ModuleCache();
 
-  const Module& GetModuleForAddress(uintptr_t address);
+  // Gets the module containing |address| or an invalid module if |address| is
+  // not within a module. The returned module remains owned by and has the same
+  // lifetime as the ModuleCache object.
+  const Module* GetModuleForAddress(uintptr_t address);
   std::vector<const Module*> GetModules() const;
 
  private:
@@ -69,7 +76,7 @@
 
   // Creates a Module object for the specified memory address. If the address
   // does not belong to a module returns an invalid module.
-  static Module CreateModuleForAddress(uintptr_t address);
+  static std::unique_ptr<Module> CreateModuleForAddress(uintptr_t address);
   friend class NativeStackSamplerMac;
 
 #if defined(OS_MACOSX)
@@ -80,11 +87,16 @@
 #endif
 
 #if defined(OS_WIN)
-  static Module CreateModuleForHandle(HMODULE module_handle);
+  const Module* GetModuleForHandle(HMODULE module_handle);
+  static std::unique_ptr<Module> CreateModuleForHandle(HMODULE module_handle);
   friend class NativeStackSamplerWin;
+
+  // The module objects, indexed by the module handle.
+  // TODO(wittman): Merge this state into modules_cache_map_ and remove
+  std::map<HMODULE, std::unique_ptr<Module>> win_module_cache_;
 #endif
 
-  std::map<uintptr_t, Module> modules_cache_map_;
+  std::map<uintptr_t, std::unique_ptr<Module>> modules_cache_map_;
 };
 
 }  // namespace base
diff --git a/base/sampling_heap_profiler/module_cache_mac.cc b/base/sampling_heap_profiler/module_cache_mac.cc
index de145458..96b24ab 100644
--- a/base/sampling_heap_profiler/module_cache_mac.cc
+++ b/base/sampling_heap_profiler/module_cache_mac.cc
@@ -64,13 +64,15 @@
 }  // namespace
 
 // static
-ModuleCache::Module ModuleCache::CreateModuleForAddress(uintptr_t address) {
+std::unique_ptr<ModuleCache::Module> ModuleCache::CreateModuleForAddress(
+    uintptr_t address) {
   Dl_info inf;
   if (!dladdr(reinterpret_cast<const void*>(address), &inf))
-    return Module();
+    return std::make_unique<Module>();
   auto base_module_address = reinterpret_cast<uintptr_t>(inf.dli_fbase);
-  return Module(base_module_address, GetUniqueId(inf.dli_fbase),
-                FilePath(inf.dli_fname), GetModuleTextSize(inf.dli_fbase));
+  return std::make_unique<Module>(
+      base_module_address, GetUniqueId(inf.dli_fbase), FilePath(inf.dli_fname),
+      GetModuleTextSize(inf.dli_fbase));
 }
 
 size_t ModuleCache::GetModuleTextSize(const void* module_addr) {
diff --git a/base/sampling_heap_profiler/module_cache_posix.cc b/base/sampling_heap_profiler/module_cache_posix.cc
index 16d6019..a82c27e 100644
--- a/base/sampling_heap_profiler/module_cache_posix.cc
+++ b/base/sampling_heap_profiler/module_cache_posix.cc
@@ -7,9 +7,10 @@
 namespace base {
 
 // static
-ModuleCache::Module ModuleCache::CreateModuleForAddress(uintptr_t address) {
+std::unique_ptr<ModuleCache::Module> ModuleCache::CreateModuleForAddress(
+    uintptr_t address) {
   // TODO(alph): Implement it.
-  return Module();
+  return std::make_unique<Module>();
 }
 
 }  // namespace base
diff --git a/base/sampling_heap_profiler/module_cache_unittest.cc b/base/sampling_heap_profiler/module_cache_unittest.cc
index 1ffe0d6..a9e3a62 100644
--- a/base/sampling_heap_profiler/module_cache_unittest.cc
+++ b/base/sampling_heap_profiler/module_cache_unittest.cc
@@ -28,28 +28,28 @@
   uintptr_t ptr1 = reinterpret_cast<uintptr_t>(&AFunctionForTest);
   uintptr_t ptr2 = ptr1 + 1;
   ModuleCache cache;
-  const ModuleCache::Module& module1 = cache.GetModuleForAddress(ptr1);
-  const ModuleCache::Module& module2 = cache.GetModuleForAddress(ptr2);
-  EXPECT_EQ(&module1, &module2);
-  EXPECT_TRUE(module1.is_valid);
-  EXPECT_GT(module1.size, 0u);
-  EXPECT_LE(module1.base_address, ptr1);
-  EXPECT_GT(module1.base_address + module1.size, ptr2);
+  const ModuleCache::Module* module1 = cache.GetModuleForAddress(ptr1);
+  const ModuleCache::Module* module2 = cache.GetModuleForAddress(ptr2);
+  EXPECT_EQ(module1, module2);
+  EXPECT_TRUE(module1->is_valid);
+  EXPECT_GT(module1->size, 0u);
+  EXPECT_LE(module1->base_address, ptr1);
+  EXPECT_GT(module1->base_address + module1->size, ptr2);
 }
 
 TEST_F(ModuleCacheTest, MAYBE_ModulesList) {
   ModuleCache cache;
   uintptr_t ptr = reinterpret_cast<uintptr_t>(&AFunctionForTest);
-  const ModuleCache::Module& module = cache.GetModuleForAddress(ptr);
-  EXPECT_TRUE(module.is_valid);
+  const ModuleCache::Module* module = cache.GetModuleForAddress(ptr);
+  EXPECT_TRUE(module->is_valid);
   EXPECT_EQ(1u, cache.GetModules().size());
-  EXPECT_EQ(&module, cache.GetModules().front());
+  EXPECT_EQ(module, cache.GetModules().front());
 }
 
 TEST_F(ModuleCacheTest, InvalidModule) {
   ModuleCache cache;
-  const ModuleCache::Module& invalid_module = cache.GetModuleForAddress(1);
-  EXPECT_FALSE(invalid_module.is_valid);
+  const ModuleCache::Module* invalid_module = cache.GetModuleForAddress(1);
+  EXPECT_FALSE(invalid_module->is_valid);
 }
 
 }  // namespace
diff --git a/base/sampling_heap_profiler/module_cache_win.cc b/base/sampling_heap_profiler/module_cache_win.cc
index 95061e7d..ca79f17b 100644
--- a/base/sampling_heap_profiler/module_cache_win.cc
+++ b/base/sampling_heap_profiler/module_cache_win.cc
@@ -7,6 +7,7 @@
 #include <objbase.h>
 #include <psapi.h>
 
+#include "base/no_destructor.h"
 #include "base/process/process_handle.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -66,35 +67,59 @@
 }  // namespace
 
 // static
-ModuleCache::Module ModuleCache::CreateModuleForAddress(uintptr_t address) {
+std::unique_ptr<ModuleCache::Module> ModuleCache::CreateModuleForAddress(
+    uintptr_t address) {
   HMODULE module_handle = nullptr;
   if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                            reinterpret_cast<LPCTSTR>(address),
                            &module_handle)) {
     DCHECK_EQ(ERROR_MOD_NOT_FOUND, static_cast<int>(::GetLastError()));
-    return Module();
+    return std::make_unique<Module>();
   }
-  Module module = CreateModuleForHandle(module_handle);
+  std::unique_ptr<Module> module = CreateModuleForHandle(module_handle);
   ::CloseHandle(module_handle);
   return module;
 }
 
+const ModuleCache::Module* ModuleCache::GetModuleForHandle(
+    HMODULE module_handle) {
+  static NoDestructor<ModuleCache::Module> invalid_module;
+
+  if (!module_handle)
+    return invalid_module.get();
+
+  auto loc = win_module_cache_.find(module_handle);
+  if (loc != win_module_cache_.end())
+    return loc->second.get();
+
+  std::unique_ptr<ModuleCache::Module> module =
+      ModuleCache::CreateModuleForHandle(module_handle);
+  if (module->is_valid) {
+    const auto result = win_module_cache_.insert(
+        std::make_pair(module_handle, std::move(module)));
+    return result.first->second.get();
+  }
+  return invalid_module.get();
+}
+
 // static
-ModuleCache::Module ModuleCache::CreateModuleForHandle(HMODULE module_handle) {
+std::unique_ptr<ModuleCache::Module> ModuleCache::CreateModuleForHandle(
+    HMODULE module_handle) {
   FilePath pdb_name;
   std::string build_id;
   GetDebugInfoForModule(module_handle, &build_id, &pdb_name);
   if (build_id.empty())
-    return Module();
+    return std::make_unique<Module>();
 
   MODULEINFO module_info;
   if (!::GetModuleInformation(GetCurrentProcessHandle(), module_handle,
                               &module_info, sizeof(module_info))) {
-    return Module();
+    return std::make_unique<Module>();
   }
 
-  return Module(reinterpret_cast<uintptr_t>(module_info.lpBaseOfDll), build_id,
-                pdb_name, module_info.SizeOfImage);
+  return std::make_unique<Module>(
+      reinterpret_cast<uintptr_t>(module_info.lpBaseOfDll), build_id, pdb_name,
+      module_info.SizeOfImage);
 }
 
 }  // namespace base
diff --git a/base/test/launcher/test_results_tracker.cc b/base/test/launcher/test_results_tracker.cc
index 95024f8a..438bdb78 100644
--- a/base/test/launcher/test_results_tracker.cc
+++ b/base/test/launcher/test_results_tracker.cc
@@ -234,7 +234,7 @@
 }
 
 void TestResultsTracker::AddTestPlaceholder(const std::string& test_name) {
-  test_placeholders_.push_back(test_name);
+  test_placeholders_.insert(test_name);
 }
 
 void TestResultsTracker::AddTestResult(const TestResult& result) {
diff --git a/base/test/launcher/test_results_tracker.h b/base/test/launcher/test_results_tracker.h
index 341b128..61f29cd 100644
--- a/base/test/launcher/test_results_tracker.h
+++ b/base/test/launcher/test_results_tracker.h
@@ -141,7 +141,7 @@
   std::map<std::string, CodeLocation> test_locations_;
 
   // Name of tests that will run and produce results.
-  std::vector<std::string> test_placeholders_;
+  std::set<std::string> test_placeholders_;
 
   // Set of all disabled tests in the current executable.
   std::set<std::string> disabled_tests_;
diff --git a/base/threading/scoped_blocking_call.cc b/base/threading/scoped_blocking_call.cc
index 71cbfb2..8034c6c 100644
--- a/base/threading/scoped_blocking_call.cc
+++ b/base/threading/scoped_blocking_call.cc
@@ -66,6 +66,10 @@
 }  // namespace internal
 
 ScopedBlockingCall::ScopedBlockingCall(BlockingType blocking_type)
+    : ScopedBlockingCall(FROM_HERE, blocking_type) {}
+
+ScopedBlockingCall::ScopedBlockingCall(const Location& from_here,
+                                       BlockingType blocking_type)
     : UncheckedScopedBlockingCall(blocking_type) {
 #if DCHECK_IS_ON()
   DCHECK(!tls_construction_in_progress.Get().Get());
@@ -73,9 +77,9 @@
 #endif
 
   internal::AssertBlockingAllowed();
-  TRACE_EVENT_BEGIN1("base", "ScopedBlockingCall", "blocking_type",
-                     static_cast<int>(blocking_type));
-
+  TRACE_EVENT_BEGIN2("base", "ScopedBlockingCall", "file_name",
+                     from_here.file_name(), "function_name",
+                     from_here.function_name());
 #if DCHECK_IS_ON()
   tls_construction_in_progress.Get().Set(false);
 #endif
@@ -89,6 +93,11 @@
 
 ScopedBlockingCallWithBaseSyncPrimitives::
     ScopedBlockingCallWithBaseSyncPrimitives(BlockingType blocking_type)
+    : ScopedBlockingCallWithBaseSyncPrimitives(FROM_HERE, blocking_type) {}
+
+ScopedBlockingCallWithBaseSyncPrimitives::
+    ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
+                                             BlockingType blocking_type)
     : UncheckedScopedBlockingCall(blocking_type) {
 #if DCHECK_IS_ON()
   DCHECK(!tls_construction_in_progress.Get().Get());
@@ -96,8 +105,9 @@
 #endif
 
   internal::AssertBaseSyncPrimitivesAllowed();
-  TRACE_EVENT_BEGIN1("base", "ScopedBlockingCallWithBaseSyncPrimitives",
-                     "blocking_type", static_cast<int>(blocking_type));
+  TRACE_EVENT_BEGIN2("base", "ScopedBlockingCallWithBaseSyncPrimitives",
+                     "file_name", from_here.file_name(), "function_name",
+                     from_here.function_name());
 
 #if DCHECK_IS_ON()
   tls_construction_in_progress.Get().Set(false);
diff --git a/base/threading/scoped_blocking_call.h b/base/threading/scoped_blocking_call.h
index b8c08fc..022a773f 100644
--- a/base/threading/scoped_blocking_call.h
+++ b/base/threading/scoped_blocking_call.h
@@ -6,6 +6,7 @@
 #define BASE_THREADING_SCOPED_BLOCKING_CALL_H
 
 #include "base/base_export.h"
+#include "base/location.h"
 #include "base/logging.h"
 
 namespace base {
@@ -34,7 +35,7 @@
 // ScopedBlockingCallWithBaseSyncPrimitives without assertions.
 class BASE_EXPORT UncheckedScopedBlockingCall {
  public:
-  UncheckedScopedBlockingCall(BlockingType blocking_type);
+  explicit UncheckedScopedBlockingCall(BlockingType blocking_type);
   ~UncheckedScopedBlockingCall();
 
  private:
@@ -109,7 +110,8 @@
 class BASE_EXPORT ScopedBlockingCall
     : public internal::UncheckedScopedBlockingCall {
  public:
-  ScopedBlockingCall(BlockingType blocking_type);
+  explicit ScopedBlockingCall(BlockingType blocking_type);
+  ScopedBlockingCall(const Location& from_here, BlockingType blocking_type);
   ~ScopedBlockingCall();
 };
 
@@ -123,7 +125,9 @@
 class BASE_EXPORT ScopedBlockingCallWithBaseSyncPrimitives
     : public UncheckedScopedBlockingCall {
  public:
-  ScopedBlockingCallWithBaseSyncPrimitives(BlockingType blocking_type);
+  explicit ScopedBlockingCallWithBaseSyncPrimitives(BlockingType blocking_type);
+  ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
+                                           BlockingType blocking_type);
   ~ScopedBlockingCallWithBaseSyncPrimitives();
 };
 
diff --git a/base/trace_event/trace_config.h b/base/trace_event/trace_config.h
index 30f647f..343ec85 100644
--- a/base/trace_event/trace_config.h
+++ b/base/trace_event/trace_config.h
@@ -105,6 +105,9 @@
     void ToDict(DictionaryValue*) const;
 
     bool IsEnabled(base::ProcessId) const;
+    const std::unordered_set<base::ProcessId>& included_process_ids() const {
+      return included_process_ids_;
+    }
 
     bool operator==(const ProcessFilterConfig& other) const {
       return included_process_ids_ == other.included_process_ids_;
diff --git a/build/config/fuchsia/package.gni b/build/config/fuchsia/package.gni
index dc36498..9df27e9 100644
--- a/build/config/fuchsia/package.gni
+++ b/build/config/fuchsia/package.gni
@@ -38,6 +38,7 @@
   _pkg_out_dir = "${target_gen_dir}/${pkg.package_name}"
   _runtime_deps_file = "$_pkg_out_dir/${pkg.package_name}.runtime_deps"
   _archive_manifest = "$_pkg_out_dir/${pkg.package_name}.archive_manifest"
+  _build_ids_file = "$_pkg_out_dir/ids.txt"
   _component_manifest = "$_pkg_out_dir/${pkg.package_name}.cmx"
   _key_file = "$_pkg_out_dir/signing-key"
   _meta_far_file = "$_pkg_out_dir/meta.far"
@@ -61,7 +62,7 @@
                              "testonly",
                            ])
 
-    script = "//build/config/fuchsia/build_manifest.py"
+    script = "//build/config/fuchsia/prepare_package_inputs.py"
 
     inputs = [
       _runtime_deps_file,
@@ -70,6 +71,7 @@
 
     outputs = [
       _archive_manifest,
+      _build_ids_file,
       _component_manifest,
     ]
 
@@ -98,8 +100,10 @@
       rebase_path(_runtime_deps_file, root_build_dir),
       "--depfile-path",
       rebase_path(_depfile, root_build_dir),
-      "--output-path",
+      "--manifest-path",
       rebase_path(_archive_manifest, root_build_dir),
+      "--build-ids-file",
+      rebase_path(_build_ids_file, root_build_dir),
     ]
 
     if (defined(pkg.excluded_files)) {
@@ -215,6 +219,7 @@
     data = [
       _final_far_file,
       _package_info_path,
+      _build_ids_file,
     ]
 
     sources = [
diff --git a/build/config/fuchsia/build_manifest.py b/build/config/fuchsia/prepare_package_inputs.py
similarity index 72%
rename from build/config/fuchsia/build_manifest.py
rename to build/config/fuchsia/prepare_package_inputs.py
index ee13568..4198aee 100644
--- a/build/config/fuchsia/build_manifest.py
+++ b/build/config/fuchsia/prepare_package_inputs.py
@@ -66,8 +66,48 @@
   return file_tag == '\x7fELF'
 
 
+def _WriteBuildIdsTxt(binary_paths, ids_txt_path):
+  """Writes an index text file that maps build IDs to the paths of unstripped
+  binaries."""
+
+  READELF_FILE_PREFIX = 'File: '
+  READELF_BUILD_ID_PREFIX = 'Build ID: '
+
+  # List of binaries whose build IDs are awaiting processing by readelf.
+  # Entries are removed as readelf's output is parsed.
+  unprocessed_binary_paths = {os.path.basename(p): p for p in binary_paths}
+
+  with open(ids_txt_path, 'w') as ids_file:
+    readelf_stdout = subprocess.check_output(
+        ['readelf', '-n'] + map(_GetStrippedPath, binary_paths))
+
+    if len(binary_paths) == 1:
+      # Readelf won't report a binary's path if only one was provided to the
+      # tool.
+      binary_shortname = binary_paths[0]
+    else:
+      binary_shortname = None
+
+    for line in readelf_stdout.split('\n'):
+      line = line.strip()
+
+      if line.startswith(READELF_FILE_PREFIX):
+        binary_shortname = os.path.basename(line[len(READELF_FILE_PREFIX):])
+        assert binary_shortname in unprocessed_binary_paths
+
+      elif line.startswith(READELF_BUILD_ID_PREFIX):
+        build_id = line[len(READELF_BUILD_ID_PREFIX):]
+        ids_file.write(build_id + ' ' +
+                       unprocessed_binary_paths[binary_shortname])
+        del unprocessed_binary_paths[binary_shortname]
+
+  # Did readelf forget anything? Make sure that all binaries are accounted for.
+  assert not unprocessed_binary_paths
+
+
 def BuildManifest(args):
-  with open(args.output_path, 'w') as manifest, \
+  binaries = []
+  with open(args.manifest_path, 'w') as manifest, \
        open(args.depfile_path, 'w') as depfile:
     # Process the runtime deps file for file paths, recursively walking
     # directories as needed.
@@ -94,6 +134,7 @@
     excluded_files_set = set(args.exclude_file)
     for current_file in expanded_files:
       if _IsBinary(current_file):
+        binaries.append(current_file)
         current_file = _GetStrippedPath(current_file)
 
       in_package_path = MakePackagePath(current_file,
@@ -116,14 +157,14 @@
       raise Exception('Could not locate executable inside runtime_deps.')
 
     # Write meta/package manifest file.
-    with open(os.path.join(os.path.dirname(args.output_path), 'package'), 'w') \
-        as package_json:
+    with open(os.path.join(os.path.dirname(args.manifest_path), 'package'),
+              'w') as package_json:
       json.dump({'version': '0', 'name': args.app_name}, package_json)
       manifest.write('meta/package=%s\n' %
                    os.path.relpath(package_json.name, args.out_dir))
 
     # Write component manifest file.
-    cmx_file_path = os.path.join(os.path.dirname(args.output_path),
+    cmx_file_path = os.path.join(os.path.dirname(args.manifest_path),
                                  args.app_name + '.cmx')
     with open(cmx_file_path, 'w') as component_manifest_file:
       component_manifest = {
@@ -137,11 +178,15 @@
                       os.path.relpath(cmx_file_path, args.out_dir)))
 
     depfile.write(
-        "%s: %s" % (os.path.relpath(args.output_path, args.out_dir),
+        "%s: %s" % (os.path.relpath(args.manifest_path, args.out_dir),
                     " ".join([os.path.relpath(f, args.out_dir)
                               for f in expanded_files])))
+
+    _WriteBuildIdsTxt(binaries, args.build_ids_file)
+
   return 0
 
+
 def main():
   parser = argparse.ArgumentParser()
   parser.add_argument('--root-dir', required=True, help='Build root directory')
@@ -157,7 +202,10 @@
       help='Path to write GN deps file.')
   parser.add_argument('--exclude-file', action='append', default=[],
       help='Package-relative file path to exclude from the package.')
-  parser.add_argument('--output-path', required=True, help='Output file path.')
+  parser.add_argument('--manifest-path', required=True,
+                      help='Manifest output path.')
+  parser.add_argument('--build-ids-file', required=True,
+                      help='Debug symbol index path.')
 
   args = parser.parse_args()
 
diff --git a/build/config/fuchsia/rules.gni b/build/config/fuchsia/rules.gni
index 5087edd..9b62040 100644
--- a/build/config/fuchsia/rules.gni
+++ b/build/config/fuchsia/rules.gni
@@ -86,6 +86,7 @@
         _manifest_path,
         "//build/fuchsia/",
         "//build/util/lib/",
+        "//third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer",
         "${qemu_root}/",
         "${fuchsia_sdk}/",
       ]
@@ -129,8 +130,6 @@
         rebase_path(_package_path, root_build_dir),
         "--package-name",
         _pkg_shortname,
-        "--package-manifest",
-        rebase_path(_manifest_path, root_build_dir),
       ]
 
       if (defined(install_only) && install_only) {
diff --git a/build/fuchsia/common_args.py b/build/fuchsia/common_args.py
index 486718896..ee90cc67c 100644
--- a/build/fuchsia/common_args.py
+++ b/build/fuchsia/common_args.py
@@ -21,9 +21,6 @@
   common_args.add_argument('--package-name', required=True,
                            help='Name of the package to execute, defined in ' +
                                 'package metadata.')
-  common_args.add_argument('--package-manifest',
-                           type=os.path.realpath, required=True,
-                           help='Path to the Fuchsia package manifest file.')
   common_args.add_argument('--package-dep', action='append', default=[],
                            help='Path to an additional package to install.')
   common_args.add_argument('--install-only', action='store_true', default=False,
diff --git a/build/fuchsia/create_runner_script.py b/build/fuchsia/create_runner_script.py
index 16da5e94..d922be3 100755
--- a/build/fuchsia/create_runner_script.py
+++ b/build/fuchsia/create_runner_script.py
@@ -56,7 +56,6 @@
   group.add_argument('--output-directory')
   group.add_argument('--package')
   group.add_argument('--package-dep', action='append', default=[])
-  group.add_argument('--package-manifest')
   args, runner_args = parser.parse_known_args(args)
 
   def RelativizePathToScript(path):
@@ -75,8 +74,6 @@
   for next_package_dep in args.package_dep:
     runner_path_args.append(
         ('--package-dep', RelativizePathToScript(next_package_dep)))
-  runner_path_args.append(
-      ('--package-manifest', RelativizePathToScript(args.package_manifest)))
 
   with open(args.script_output_path, 'w') as script:
     script.write(SCRIPT_TEMPLATE.format(
diff --git a/build/fuchsia/run_package.py b/build/fuchsia/run_package.py
index fa7ccbd..0d12e65 100644
--- a/build/fuchsia/run_package.py
+++ b/build/fuchsia/run_package.py
@@ -21,7 +21,7 @@
 import threading
 import uuid
 
-from symbolizer import FilterStream
+from symbolizer import SymbolizerFilter
 
 FAR = os.path.join(common.SDK_ROOT, 'tools', 'far')
 PM = os.path.join(common.SDK_ROOT, 'tools', 'pm')
@@ -43,27 +43,72 @@
                                 stdout=subprocess.PIPE)
 
 
-def _ReadMergedLines(streams):
-  """Creates a generator which merges the buffered line output from |streams|.
-  The generator is terminated when the primary (first in sequence) stream
-  signals EOF. Absolute output ordering is not guaranteed."""
+class MergedInputStream(object):
+  """Merges a number of input streams into a UNIX pipe on a dedicated thread.
+  Terminates when the file descriptor of the primary stream (the first in
+  the sequence) is closed."""
 
-  assert len(streams) > 0
-  streams_by_fd = {}
-  primary_fd = streams[0].fileno()
-  for s in streams:
-    streams_by_fd[s.fileno()] = s
+  def __init__(self, streams):
+    assert len(streams) > 0
+    self._streams = streams
+    self._read_pipe, write_pipe = os.pipe()
+    self._output_stream = os.fdopen(write_pipe, 'w')
+    self._thread = threading.Thread(target=self._Run)
 
-  while primary_fd != None:
-    rlist, _, _ = select.select(streams_by_fd, [], [], 0.1)
-    for fileno in rlist:
-      line = streams_by_fd[fileno].readline()
-      if line:
-        yield line
-      elif fileno == primary_fd:
-        primary_fd = None
-      else:
+  def Start(self):
+    """Returns a file descriptor to the merged output stream."""
+
+    self._thread.start();
+    return self._read_pipe
+
+  def _Run(self):
+    streams_by_fd = {}
+    primary_fd = self._streams[0].fileno()
+    for s in self._streams:
+      streams_by_fd[s.fileno()] = s
+
+    # Set when the primary FD is closed. Input from other FDs will continue to
+    # be processed until select() runs dry.
+    flush = False
+
+    # The lifetime of the MergedInputStream is bound to the lifetime of
+    # |primary_fd|.
+    while primary_fd:
+      # When not flushing: block until data is read or an exception occurs.
+      rlist, _, xlist = select.select(streams_by_fd, [], streams_by_fd)
+
+      if len(rlist) == 0 and flush:
+        break
+
+      for fileno in xlist:
         del streams_by_fd[fileno]
+        if fileno == primary_fd:
+          primary_fd = None
+
+      for fileno in rlist:
+        line = streams_by_fd[fileno].readline()
+        if line:
+          self._output_stream.write(line + '\n')
+        else:
+          del streams_by_fd[fileno]
+          if fileno == primary_fd:
+            primary_fd = None
+
+    # Flush the streams by executing nonblocking reads from the input file
+    # descriptors until no more data is available,  or all the streams are
+    # closed.
+    while streams_by_fd:
+      rlist, _, _ = select.select(streams_by_fd, [], [], 0)
+
+      if not rlist:
+        break
+
+      for fileno in rlist:
+        line = streams_by_fd[fileno].readline()
+        if line:
+          self._output_stream.write(line + '\n')
+        else:
+          del streams_by_fd[fileno]
 
 
 def _GetComponentUri(package_name):
@@ -161,7 +206,6 @@
   def FromCommonArgs(args):
     run_package_args = RunPackageArgs()
     run_package_args.install_only = args.install_only
-    run_package_args.symbolizer_config = args.package_manifest
     run_package_args.system_logging = args.include_system_logs
     run_package_args.target_staging_path = args.target_staging_path
     return run_package_args
@@ -184,8 +228,8 @@
       stderr=subprocess.STDOUT)
 
 
-def RunPackage(output_dir, target, package_path, package_name, package_deps,
-               package_args, args):
+def RunPackage(output_dir, target, package_path, package_name,
+               package_deps, package_args, args):
   """Copies the Fuchsia package at |package_path| to the target,
   executes it with |package_args|, and symbolizes its output.
 
@@ -260,19 +304,16 @@
                                      stderr=subprocess.STDOUT)
 
     if system_logger:
-      task_output = _ReadMergedLines([process.stdout, system_logger.stdout])
+      output_fd = MergedInputStream([process.stdout,
+                                       system_logger.stdout]).Start()
     else:
-      task_output = process.stdout
+      output_fd = process.stdout.fileno()
 
-    if args.symbolizer_config:
-      # Decorate the process output stream with the symbolizer.
-      output = FilterStream(task_output, package_name, args.symbolizer_config,
-                            output_dir)
-    else:
-      logging.warn('Symbolization is DISABLED.')
-      output = process.stdout
+    # Run the log data through the symbolizer process.
+    build_ids_path = os.path.join(os.path.dirname(package_path), 'ids.txt')
+    output_stream = SymbolizerFilter(output_fd, build_ids_path)
 
-    for next_line in output:
+    for next_line in output_stream:
       print next_line.rstrip()
 
     process.wait()
diff --git a/build/fuchsia/symbolizer.py b/build/fuchsia/symbolizer.py
index 67c487d..5a7c1b63 100644
--- a/build/fuchsia/symbolizer.py
+++ b/build/fuchsia/symbolizer.py
@@ -4,227 +4,34 @@
 
 import logging
 import os
-import re
 import subprocess
 
-# Matches the coarse syntax of a backtrace entry.
-_BACKTRACE_PREFIX_RE = re.compile(r'(\[[0-9.]+\] )?bt#(?P<frame_id>\d+): ')
-
-# Matches the specific fields of a backtrace entry.
-# Back-trace line matcher/parser assumes that 'pc' is always present, and
-# expects that 'sp' and ('binary','pc_offset') may also be provided.
-_BACKTRACE_ENTRY_RE = re.compile(
-    r'pc 0(?:x[0-9a-f]+)?' +
-    r'(?: sp 0x[0-9a-f]+)?' +
-    r'(?: \((?P<binary>\S+),(?P<pc_offset>0x[0-9a-f]+)\))?$')
+from common import SDK_ROOT
 
 
-def _GetUnstrippedPath(path):
-  """If there is a binary located at |path|, returns a path to its unstripped
-  source.
+def SymbolizerFilter(input_fd, build_ids_file):
+  """Symbolizes an output stream from a process.
 
-  Returns None if |path| isn't a binary or doesn't exist in the lib.unstripped
-  or exe.unstripped directories."""
+  input_fd: A file descriptor of the stream to be symbolized.
+  build_ids_file: Path to the ids.txt file which maps build IDs to
+                  unstripped binaries on the filesystem.
+  Returns a generator that yields symbolized process output."""
 
-  if path.endswith('.so'):
-    maybe_unstripped_path = os.path.normpath(
-        os.path.join(path, os.path.pardir, 'lib.unstripped',
-                     os.path.basename(path)))
-  else:
-    maybe_unstripped_path = os.path.normpath(
-        os.path.join(path, os.path.pardir, 'exe.unstripped',
-                     os.path.basename(path)))
+  llvm_symbolizer_path = os.path.join(SDK_ROOT, os.pardir, os.pardir,
+                                      'llvm-build', 'Release+Asserts', 'bin',
+                                      'llvm-symbolizer')
+  symbolizer = os.path.join(SDK_ROOT, 'tools', 'symbolize')
+  symbolizer_cmd = [symbolizer, '-ids', build_ids_file,
+                    '-ids-rel', '-llvm-symbolizer', llvm_symbolizer_path]
 
-  if not os.path.exists(maybe_unstripped_path):
-    return None
+  logging.info('Running "%s".' % ' '.join(symbolizer_cmd))
+  symbolizer_proc = subprocess.Popen(
+      symbolizer_cmd,
+      stdout=subprocess.PIPE,
+      stdin=input_fd,
+      close_fds=True)
 
-  with open(maybe_unstripped_path, 'rb') as f:
-    file_tag = f.read(4)
-  if file_tag != '\x7fELF':
-    logging.warn('Expected an ELF binary: ' + maybe_unstripped_path)
-    return None
+  for line in symbolizer_proc.stdout:
+    yield line
 
-  return maybe_unstripped_path
-
-
-def FilterStream(stream, package_name, manifest_path, output_dir):
-  """Looks for backtrace lines from an iterable |stream| and symbolizes them.
-  Yields a stream of strings with symbolized entries replaced."""
-
-  return _SymbolizerFilter(package_name,
-                           manifest_path,
-                           output_dir).SymbolizeStream(stream)
-
-
-class _SymbolizerFilter(object):
-  """Adds backtrace symbolization capabilities to a process output stream."""
-
-  def __init__(self, package_name, manifest_path, output_dir):
-    self._symbols_mapping = {}
-    self._output_dir = output_dir
-    self._package_name = package_name
-
-    # Compute remote/local path mappings using the manifest data.
-    for next_line in open(manifest_path):
-      target, source = next_line.strip().split('=')
-      stripped_binary_path = _GetUnstrippedPath(os.path.join(output_dir,
-                                                             source))
-      if not stripped_binary_path:
-        continue
-
-      self._symbols_mapping[os.path.basename(target)] = stripped_binary_path
-      self._symbols_mapping[target] = stripped_binary_path
-      if target == 'bin/app':
-        self._symbols_mapping[package_name] = stripped_binary_path
-      logging.debug('Symbols: %s -> %s' % (source, target))
-
-  def _SymbolizeEntries(self, entries):
-    """Symbolizes the parsed backtrace |entries| by calling addr2line.
-
-    Returns a set of (frame_id, result) pairs."""
-
-    filename_re = re.compile(r'at ([-._a-zA-Z0-9/+]+):(\d+)')
-
-    # Use addr2line to symbolize all the |pc_offset|s in |entries| in one go.
-    # Entries with no |debug_binary| are also processed here, so that we get
-    # consistent output in that case, with the cannot-symbolize case.
-    addr2line_output = None
-    if entries[0].has_key('debug_binary'):
-      addr2line_args = (['addr2line', '-Cipf', '-p',
-                        '--exe=' + entries[0]['debug_binary']] +
-                        map(lambda entry: entry['pc_offset'], entries))
-      addr2line_output = subprocess.check_output(addr2line_args).splitlines()
-      assert addr2line_output
-
-    results = {}
-    for entry in entries:
-      raw, frame_id = entry['raw'], entry['frame_id']
-      prefix = '#%s: ' % frame_id
-
-      if not addr2line_output:
-        # Either there was no addr2line output, or too little of it.
-        filtered_line = raw
-      else:
-        output_line = addr2line_output.pop(0)
-
-        # Relativize path to the current working (output) directory if we see
-        # a filename.
-        def RelativizePath(m):
-          relpath = os.path.relpath(os.path.normpath(m.group(1)))
-          return 'at ' + relpath + ':' + m.group(2)
-        filtered_line = filename_re.sub(RelativizePath, output_line)
-
-        if '??' in filtered_line.split():
-          # If symbolization fails just output the raw backtrace.
-          filtered_line = raw
-        else:
-          # Release builds may inline things, resulting in "(inlined by)" lines.
-          inlined_by_prefix = " (inlined by)"
-          while (addr2line_output and
-                 addr2line_output[0].startswith(inlined_by_prefix)):
-            inlined_by_line = \
-                '\n' + (' ' * len(prefix)) + addr2line_output.pop(0)
-            filtered_line += filename_re.sub(RelativizePath, inlined_by_line)
-
-      results[entry['frame_id']] = prefix + filtered_line
-
-    return results
-
-  def _LookupDebugBinary(self, entry):
-    """Looks up the binary listed in |entry| in the |_symbols_mapping|.
-    Returns the corresponding host-side binary's filename, or None."""
-
-    binary = entry['binary']
-    if not binary:
-      return None
-
-    app_prefix = 'app:'
-    if binary.startswith(app_prefix):
-      binary = binary[len(app_prefix):]
-
-    # We change directory into /system/ before running the target executable, so
-    # all paths are relative to "/system/", and will typically start with "./".
-    # Some crashes still uses the full filesystem path, so cope with that, too.
-    pkg_prefix = '/pkg/'
-    cwd_prefix = './'
-    if binary.startswith(cwd_prefix):
-      binary = binary[len(cwd_prefix):]
-    elif binary.startswith(pkg_prefix):
-      binary = binary[len(pkg_prefix):]
-    # Allow other paths to pass-through; sometimes neither prefix is present.
-
-    if binary in self._symbols_mapping:
-      return self._symbols_mapping[binary]
-
-    # |binary| may be truncated by the crashlogger, so if there is a unique
-    # match for the truncated name in |symbols_mapping|, use that instead.
-    matches = filter(lambda x: x.startswith(binary),
-                               self._symbols_mapping.keys())
-    if len(matches) == 1:
-      return self._symbols_mapping[matches[0]]
-
-    return None
-
-  def _SymbolizeBacktrace(self, backtrace):
-    """Group |backtrace| entries according to the associated binary, and locate
-    the path to the debug symbols for that binary, if any."""
-
-    batches = {}
-
-    for entry in backtrace:
-      debug_binary = self._LookupDebugBinary(entry)
-      if debug_binary:
-        entry['debug_binary'] = debug_binary
-      batches.setdefault(debug_binary, []).append(entry)
-
-    # Run _SymbolizeEntries on each batch and collate the results.
-    symbolized = {}
-    for batch in batches.itervalues():
-      symbolized.update(self._SymbolizeEntries(batch))
-
-    # Map each entry to its symbolized form, by frame-id, and return the list.
-    return map(lambda entry: symbolized[entry['frame_id']], backtrace)
-
-  def SymbolizeStream(self, stream):
-    """Creates a symbolized logging stream object using the output from
-    |stream|."""
-
-    # A buffer of backtrace entries awaiting symbolization, stored as dicts:
-    # raw: The original back-trace line that followed the prefix.
-    # frame_id: backtrace frame number (starting at 0).
-    # binary: path to executable code corresponding to the current frame.
-    # pc_offset: memory offset within the executable.
-    backtrace_entries = []
-
-    # Read from the stream until we hit EOF.
-    for line in stream:
-      line = line.rstrip()
-
-      # Look for the back-trace prefix, otherwise just emit the line.
-      matched = _BACKTRACE_PREFIX_RE.match(line)
-      if not matched:
-        yield line
-        continue
-      backtrace_line = line[matched.end():]
-
-      # If this was the end of a back-trace then symbolize and emit it.
-      frame_id = matched.group('frame_id')
-      if backtrace_line == 'end':
-        if backtrace_entries:
-          for processed in self._SymbolizeBacktrace(backtrace_entries):
-            yield processed
-        backtrace_entries = []
-        continue
-
-      # Parse the program-counter offset, etc into |backtrace_entries|.
-      matched = _BACKTRACE_ENTRY_RE.match(backtrace_line)
-      if matched:
-        # |binary| and |pc_offset| will be None if not present.
-        backtrace_entries.append(
-            {'raw': backtrace_line, 'frame_id': frame_id,
-             'binary': matched.group('binary'),
-             'pc_offset': matched.group('pc_offset')})
-      else:
-        backtrace_entries.append(
-            {'raw': backtrace_line, 'frame_id': frame_id,
-             'binary': None, 'pc_offset': None})
+  symbolizer_proc.wait()
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
index 286c328..812eda7 100644
--- a/cc/mojo_embedder/async_layer_tree_frame_sink.cc
+++ b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -245,12 +245,22 @@
     last_submitted_device_scale_factor_ = frame.device_scale_factor();
     last_submitted_size_in_pixels_ = frame.size_in_pixels();
 
+    // These traces are split into two due to the incoming flow using
+    // TRACE_ID_LOCAL, and the outgoing flow using TRACE_ID_GLOBAL. This is
+    // needed to ensure the incoming flow is not messed up. The outgoing flow is
+    // going to a different process.
+    TRACE_EVENT_WITH_FLOW2(
+        TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+        "LocalSurfaceId.Submission.Flow",
+        TRACE_ID_LOCAL(local_surface_id_.submission_trace_id()),
+        TRACE_EVENT_FLAG_FLOW_IN, "step", "SubmitCompositorFrame", "surface_id",
+        local_surface_id_.ToString());
     TRACE_EVENT_WITH_FLOW2(
         TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
         "LocalSurfaceId.Submission.Flow",
         TRACE_ID_GLOBAL(local_surface_id_.submission_trace_id()),
-        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
-        "SubmitCompositorFrame", "surface_id", local_surface_id_.ToString());
+        TRACE_EVENT_FLAG_FLOW_OUT, "step", "SubmitCompositorFrame",
+        "surface_id", local_surface_id_.ToString());
   }
 
   // The trace_id is negated in order to keep the Graphics.Pipeline and
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc
index 96c632a..e08e392 100644
--- a/cc/paint/paint_op_reader.cc
+++ b/cc/paint/paint_op_reader.cc
@@ -1016,7 +1016,7 @@
     sk_sp<PaintFilter>* filter,
     const base::Optional<PaintFilter::CropRect>& crop_rect) {
   size_t input_count = 0;
-  ReadSimple(&input_count);
+  ReadSize(&input_count);
 
   // The minimum size for a serialized filter is 4 bytes (a zero uint32_t to
   // indicate a null filter). Make sure the |input_count| doesn't exceed the
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc
index 8c2f1f8..bd40b6f 100644
--- a/cc/paint/paint_op_writer.cc
+++ b/cc/paint/paint_op_writer.cc
@@ -676,7 +676,7 @@
 }
 
 void PaintOpWriter::Write(const MergePaintFilter& filter) {
-  WriteSimple(filter.input_count());
+  WriteSize(filter.input_count());
   for (size_t i = 0; i < filter.input_count(); ++i)
     Write(filter.input_at(i));
 }
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index c0ec353..aae24d7 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -34,8 +34,10 @@
 #include "cc/trees/proxy_main.h"
 #include "cc/trees/single_thread_proxy.h"
 #include "components/ukm/test_ukm_recorder.h"
+#include "components/viz/service/display/skia_output_surface.h"
 #include "components/viz/test/begin_frame_args_test.h"
 #include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/fake_skia_output_surface.h"
 #include "components/viz/test/test_context_provider.h"
 #include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -594,6 +596,11 @@
       : hooks_(hooks) {}
 
   // viz::TestLayerTreeFrameSinkClient implementation.
+  std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
+      override {
+    return hooks_->CreateDisplaySkiaOutputSurfaceOnThread();
+  }
+
   std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
       scoped_refptr<viz::ContextProvider> compositor_context_provider)
       override {
@@ -1113,6 +1120,11 @@
       begin_frame_source_);
 }
 
+std::unique_ptr<viz::SkiaOutputSurface>
+LayerTreeTest::CreateDisplaySkiaOutputSurfaceOnThread() {
+  return viz::FakeSkiaOutputSurface::Create3d();
+}
+
 std::unique_ptr<viz::OutputSurface>
 LayerTreeTest::CreateDisplayOutputSurfaceOnThread(
     scoped_refptr<viz::ContextProvider> compositor_context_provider) {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index a7251166..a439eff 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -158,6 +158,8 @@
       double refresh_rate,
       scoped_refptr<viz::ContextProvider> compositor_context_provider,
       scoped_refptr<viz::RasterContextProvider> worker_context_provider);
+  std::unique_ptr<viz::SkiaOutputSurface>
+  CreateDisplaySkiaOutputSurfaceOnThread() override;
   // Override this and call the base class to change what viz::ContextProvider
   // will be used, such as to prevent sharing the context with the
   // LayerTreeFrameSink. Or override it and create your own OutputSurface to
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h
index e1f7323..73f32ba 100644
--- a/cc/test/test_hooks.h
+++ b/cc/test/test_hooks.h
@@ -17,6 +17,7 @@
 namespace viz {
 class CompositorFrame;
 class OutputSurface;
+class SkiaOutputSurface;
 }
 
 namespace cc {
@@ -133,6 +134,8 @@
   // OutputSurface indirections to the LayerTreeTest, that can be further
   // overridden.
   virtual void RequestNewLayerTreeFrameSink() = 0;
+  virtual std::unique_ptr<viz::SkiaOutputSurface>
+  CreateDisplaySkiaOutputSurfaceOnThread() = 0;
   virtual std::unique_ptr<viz::OutputSurface>
   CreateDisplayOutputSurfaceOnThread(
       scoped_refptr<viz::ContextProvider> compositor_context_provider) = 0;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index cb3c29d..3b69a28 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -1342,11 +1342,22 @@
   DCHECK_EQ(local_surface_id_from_parent.is_valid(),
             local_surface_id_allocation_from_parent.IsValid());
 
+  // These traces are split into two due to the usage of TRACE_ID_GLOBAL for the
+  // incoming flow (it comes from a different process), and TRACE_ID_LOCAL for
+  // the outgoing flow. The outgoing flow uses local to ensure that it doesn't
+  // flow into the wrong trace in different process.
   TRACE_EVENT_WITH_FLOW2(
       TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
       "LocalSurfaceId.Submission.Flow",
       TRACE_ID_GLOBAL(local_surface_id_from_parent.submission_trace_id()),
-      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
+      TRACE_EVENT_FLAG_FLOW_IN, "step", "SetLocalSurfaceAllocationIdFromParent",
+      "local_surface_id_allocation",
+      local_surface_id_allocation_from_parent.ToString());
+  TRACE_EVENT_WITH_FLOW2(
+      TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+      "LocalSurfaceId.Submission.Flow",
+      TRACE_ID_LOCAL(local_surface_id_from_parent.submission_trace_id()),
+      TRACE_EVENT_FLAG_FLOW_OUT, "step",
       "SetLocalSurfaceAllocationIdFromParent", "local_surface_id_allocation",
       local_surface_id_allocation_from_parent.ToString());
   // Always update the cached state of the viz::LocalSurfaceId to reflect the
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 50e845a..229c385 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -78,6 +78,7 @@
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/gl_renderer.h"
+#include "components/viz/service/display/skia_output_surface.h"
 #include "components/viz/test/begin_frame_args_test.h"
 #include "components/viz/test/fake_output_surface.h"
 #include "components/viz/test/test_layer_tree_frame_sink.h"
@@ -10106,6 +10107,12 @@
       scoped_refptr<viz::ContextProvider> display_context_provider)
       : display_context_provider_(std::move(display_context_provider)) {}
 
+  std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
+      override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+
   std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
       scoped_refptr<viz::ContextProvider> compositor_context_provider)
       override {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
index ea485d6..7d8d1f2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -43,6 +43,8 @@
     /**
      * The orientation of the device.
      */
+    @IntDef({Orientation.UNSET, Orientation.PORTRAIT, Orientation.LANDSCAPE})
+    @Retention(RetentionPolicy.SOURCE)
     public @interface Orientation {
         int UNSET = 0;
         int PORTRAIT = 1;
@@ -84,7 +86,7 @@
     private Context mContext;
 
     /** The current {@link Orientation} of the layout. */
-    private int mCurrentOrientation;
+    private @Orientation int mCurrentOrientation;
 
     // Tabs
     protected TabModelSelector mTabModelSelector;
@@ -308,7 +310,7 @@
      */
     public final void sizeChanged(RectF visibleViewportPx, RectF screenViewportPx,
             float topBrowserControlsHeightPx, float bottomBrowserControlsHeightPx,
-            int orientation) {
+            @Orientation int orientation) {
         // 1. Pull out this Layout's width and height properties based on the viewport.
         float width = screenViewportPx.width() / mDpToPx;
         float height = screenViewportPx.height() / mDpToPx;
@@ -347,7 +349,7 @@
      * @param height      The new height in dp.
      * @param orientation The new orientation.
      */
-    protected void notifySizeChanged(float width, float height, int orientation) { }
+    protected void notifySizeChanged(float width, float height, @Orientation int orientation) {}
 
     /**
      * Notify the a title has changed.
@@ -529,7 +531,7 @@
      * @return The orientation of the screen (portrait or landscape). Values are defined by
      *         {@link Orientation}.
      */
-    public int getOrientation() {
+    public @Orientation int getOrientation() {
         return mCurrentOrientation;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
index f507480e..314b1353 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -904,7 +904,7 @@
         if (tab != null) mTabCache.put(tabId, tab);
     }
 
-    private int getOrientation() {
+    private @Orientation int getOrientation() {
         return mHost.getWidth() > mHost.getHeight() ? Orientation.LANDSCAPE : Orientation.PORTRAIT;
     }
 
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 8c645fa..1124238 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
@@ -186,7 +186,7 @@
 
     private float mWidth;
     private float mHeight;
-    private int mOrientation;
+    private @Orientation int mOrientation;
 
     // Pre-allocated temporary arrays that store id of visible tabs.
     // They can be used to call populatePriorityVisibilityList.
@@ -892,7 +892,7 @@
     }
 
     @Override
-    public void notifySizeChanged(float width, float height, int orientation) {
+    public void notifySizeChanged(float width, float height, @Orientation int orientation) {
         mWidth = width;
         mHeight = height;
         mOrientation = orientation;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java
index 018350e..51ddc2c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/OverlappingStack.java
@@ -624,7 +624,7 @@
     }
 
     @Override
-    protected void updateCurrentMode(int orientation) {
+    protected void updateCurrentMode(@Orientation int orientation) {
         setWarpState(true, false);
         super.updateCurrentMode(orientation);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
index 8ff22aed..205ca3e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -213,7 +213,7 @@
     private int mReferenceOrderIndex = -1;
 
     // Orientation Variables
-    protected int mCurrentMode = Orientation.PORTRAIT;
+    protected @Orientation int mCurrentMode = Orientation.PORTRAIT;
 
     // Animation Variables
     protected @OverviewAnimationType int mOverviewAnimationType = OverviewAnimationType.NONE;
@@ -1165,7 +1165,7 @@
      * @param height      The new height of the layout.
      * @param orientation The new orientation of the layout.
      */
-    public void notifySizeChanged(float width, float height, int orientation) {
+    public void notifySizeChanged(float width, float height, @Orientation int orientation) {
         updateCurrentMode(orientation);
 
         // Changing the orientation can change which side of the tab we want to show the close
@@ -1941,7 +1941,7 @@
         return 1.f - Math.abs(t);
     }
 
-    protected void updateCurrentMode(int orientation) {
+    protected void updateCurrentMode(@Orientation int orientation) {
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID)) {
             mCurrentMode = Orientation.LANDSCAPE;
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
index 3133034..36f389db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
@@ -131,7 +131,8 @@
      */
     public static StackAnimation createAnimationFactory(Stack stack, float width, float height,
             float topBrowserControlsHeight, float borderFramePaddingTop,
-            float borderFramePaddingTopOpaque, float borderFramePaddingLeft, int orientation) {
+            float borderFramePaddingTopOpaque, float borderFramePaddingLeft,
+            @Orientation int orientation) {
         StackAnimation factory = null;
         switch (orientation) {
             case Orientation.LANDSCAPE:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackTab.java
index 1631104..cc166db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackTab.java
@@ -362,7 +362,7 @@
      * @param orientation The orientation to choose to get the size.
      * @return            The size of the content along the provided orientation.
      */
-    public float getSizeInScrollDirection(int orientation) {
+    public float getSizeInScrollDirection(@Orientation int orientation) {
         if (orientation == Orientation.PORTRAIT) {
             return mLayoutTab.getScaledContentHeight();
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
index f195e6d..ea09737 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -302,7 +302,7 @@
 
         if (requiresFirstRunToBeCompleted(intent)
                 && FirstRunFlowSequencer.launch(this, intent, false /* requiresBroadcast */,
-                        false /* preferLightweightFre */)) {
+                        shouldPreferLightweightFre(intent))) {
             abortLaunch(LaunchIntentDispatcher.Action.FINISH_ACTIVITY_REMOVE_TASK);
             return;
         }
@@ -401,6 +401,14 @@
     }
 
     /**
+     * Whether to use the Lightweight First Run Experience instead of the
+     * non-Lightweight First Run Experience.
+     */
+    protected boolean shouldPreferLightweightFre(Intent intent) {
+        return false;
+    }
+
+    /**
      * Whether or not the Activity was started up via a valid Intent.
      */
     protected boolean isStartedUpCorrectly(Intent intent) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java
index 1745839..269ca08 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/ContextMenuManager.java
@@ -186,7 +186,12 @@
             {
                 put(ContextMenuItemId.OPEN_IN_NEW_WINDOW,
                         R.string.contextmenu_open_in_other_window);
-                put(ContextMenuItemId.OPEN_IN_NEW_TAB, R.string.contextmenu_open_in_new_tab);
+                put(ContextMenuItemId.OPEN_IN_NEW_TAB,
+                        ChromeFeatureList.isInitialized()
+                                        && ChromeFeatureList.isEnabled(
+                                                ChromeFeatureList.TAB_GROUP_ANDROID)
+                                ? R.string.contextmenu_open_in_new_tab_group
+                                : R.string.contextmenu_open_in_new_tab);
                 put(ContextMenuItemId.OPEN_IN_INCOGNITO_TAB,
                         ChromeFeatureList.isInitialized()
                                         && ChromeFeatureList.isEnabled(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index 4427fc8e..9941f189 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -145,9 +145,9 @@
         mAutocomplete = new AutocompleteController(this);
         mHandler = new Handler();
         mBasicSuggestionProcessor = new BasicSuggestionProcessor(mContext, this, textProvider);
+        mAnswerSuggestionProcessor = new AnswerSuggestionProcessor(mContext, this, textProvider);
         mEditUrlProcessor = new EditUrlSuggestionProcessor(
                 delegate, (suggestion) -> onSelection(suggestion, 0));
-        mAnswerSuggestionProcessor = new AnswerSuggestionProcessor(mContext, this);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
index dd14ba3..14e9783 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -12,6 +12,8 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
+import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider;
 import org.chromium.chrome.browser.omnibox.suggestions.AnswersImageFetcher;
 import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteCoordinator.SuggestionProcessor;
 import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
@@ -37,22 +39,27 @@
     private final Context mContext;
     private final SuggestionHost mSuggestionHost;
     private final AnswersImageFetcher mImageFetcher;
+    private final UrlBarEditingTextStateProvider mUrlBarEditingTextProvider;
     private boolean mEnableNewAnswerLayout;
 
     /**
      * @param context An Android context.
      * @param suggestionHost A handle to the object using the suggestions.
      */
-    public AnswerSuggestionProcessor(Context context, SuggestionHost suggestionHost) {
+    public AnswerSuggestionProcessor(Context context, SuggestionHost suggestionHost,
+            UrlBarEditingTextStateProvider editingTextProvider) {
         mContext = context;
         mSuggestionHost = suggestionHost;
         mPendingAnswerRequestUrls = new HashMap<>();
         mImageFetcher = new AnswersImageFetcher();
+        mUrlBarEditingTextProvider = editingTextProvider;
     }
 
     @Override
     public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) {
-        return suggestion.hasAnswer();
+        // Calculation answers are specific in a way that these are basic suggestions, but processed
+        // as answers, when new answer layout is enabled.
+        return suggestion.hasAnswer() || suggestion.getType() == OmniboxSuggestionType.CALCULATOR;
     }
 
     @Override
@@ -81,9 +88,9 @@
                 mSuggestionHost.createSuggestionViewDelegate(suggestion, position);
 
         if (mEnableNewAnswerLayout) {
-            setStateForNewSuggestion(model, suggestion.getAnswer(), delegate);
+            setStateForNewSuggestion(model, suggestion, delegate);
         } else {
-            setStateForClassicSuggestion(model, suggestion.getAnswer(), delegate);
+            setStateForClassicSuggestion(model, suggestion, delegate);
         }
     }
 
@@ -98,6 +105,7 @@
         // Attempting to fetch answer data before we have a profile to request it for.
         if (mSuggestionHost.getCurrentProfile() == null) return;
 
+        // Note: we also handle calculations here, which do not have answer defined.
         if (!suggestion.hasAnswer()) return;
         final String url = suggestion.getAnswer().getSecondLine().getImage();
         if (url == null) return;
@@ -140,33 +148,34 @@
      * Sets both lines of the Omnibox suggestion in a basic Suggestion result.
      */
     private void setStateForClassicSuggestion(
-            PropertyModel model, SuggestionAnswer answer, SuggestionViewDelegate delegate) {
-        SuggestionAnswer.ImageLine firstLine = answer.getFirstLine();
-        SuggestionAnswer.ImageLine secondLine = answer.getSecondLine();
+            PropertyModel model, OmniboxSuggestion suggestion, SuggestionViewDelegate delegate) {
+        AnswerText[] details = AnswerTextClassic.from(mContext, suggestion);
+
+        SuggestionAnswer answer = suggestion.getAnswer();
+        if (answer != null) {
+            model.set(SuggestionViewProperties.HAS_ANSWER_IMAGE, answer.getSecondLine().hasImage());
+        }
 
         model.set(SuggestionViewProperties.IS_ANSWER, true);
-
-        AnswerText[] details = AnswerTextClassic.from(mContext, answer);
-
         model.set(SuggestionViewProperties.DELEGATE, delegate);
 
         model.set(SuggestionViewProperties.TEXT_LINE_1_SIZING,
                 Pair.create(TypedValue.COMPLEX_UNIT_SP, details[0].mHeightSp));
-        model.set(SuggestionViewProperties.TEXT_LINE_2_SIZING,
-                Pair.create(TypedValue.COMPLEX_UNIT_SP, details[1].mHeightSp));
-
         model.set(SuggestionViewProperties.TEXT_LINE_1_TEXT,
                 new SuggestionTextContainer(details[0].mText));
-        model.set(SuggestionViewProperties.TEXT_LINE_2_TEXT,
-                new SuggestionTextContainer(details[1].mText));
-
         model.set(SuggestionViewProperties.TEXT_LINE_1_MAX_LINES, details[0].mMaxLines);
-        model.set(SuggestionViewProperties.TEXT_LINE_2_MAX_LINES, details[1].mMaxLines);
-
         model.set(SuggestionViewProperties.TEXT_LINE_1_TEXT_DIRECTION, View.TEXT_DIRECTION_INHERIT);
-        model.set(SuggestionViewProperties.TEXT_LINE_2_TEXT_DIRECTION, View.TEXT_DIRECTION_INHERIT);
 
-        model.set(SuggestionViewProperties.HAS_ANSWER_IMAGE, secondLine.hasImage());
+        if (details[1] != null) {
+            model.set(SuggestionViewProperties.TEXT_LINE_2_SIZING,
+                    Pair.create(TypedValue.COMPLEX_UNIT_SP, details[1].mHeightSp));
+            model.set(SuggestionViewProperties.TEXT_LINE_2_TEXT,
+                    new SuggestionTextContainer(details[1].mText));
+            model.set(SuggestionViewProperties.TEXT_LINE_2_MAX_LINES, details[1].mMaxLines);
+            model.set(SuggestionViewProperties.TEXT_LINE_2_TEXT_DIRECTION,
+                    View.TEXT_DIRECTION_INHERIT);
+        }
+
         model.set(SuggestionViewProperties.SUGGESTION_ICON_TYPE, SuggestionIcon.MAGNIFIER);
 
         model.set(SuggestionViewProperties.REFINABLE, true);
@@ -176,11 +185,10 @@
      * Sets both lines of the Omnibox suggestion based on an Answers in Suggest result.
      */
     private void setStateForNewSuggestion(
-            PropertyModel model, SuggestionAnswer answer, SuggestionViewDelegate delegate) {
-        SuggestionAnswer.ImageLine firstLine = answer.getFirstLine();
-        SuggestionAnswer.ImageLine secondLine = answer.getSecondLine();
-
-        AnswerText[] details = AnswerTextNewLayout.from(mContext, answer);
+            PropertyModel model, OmniboxSuggestion suggestion, SuggestionViewDelegate delegate) {
+        SuggestionAnswer answer = suggestion.getAnswer();
+        AnswerText[] details = AnswerTextNewLayout.from(
+                mContext, suggestion, mUrlBarEditingTextProvider.getTextWithAutocomplete());
 
         model.set(AnswerSuggestionViewProperties.DELEGATE, delegate);
 
@@ -196,33 +204,38 @@
         @AnswerIcon
         int icon = AnswerIcon.UNDEFINED;
 
-        switch (answer.getType()) {
-            case AnswerType.DICTIONARY:
-                icon = AnswerIcon.DICTIONARY;
-                break;
-            case AnswerType.FINANCE:
-                icon = AnswerIcon.FINANCE;
-                break;
-            case AnswerType.KNOWLEDGE_GRAPH:
-                icon = AnswerIcon.KNOWLEDGE;
-                break;
-            case AnswerType.SUNRISE:
-                icon = AnswerIcon.SUNRISE;
-                break;
-            case AnswerType.TRANSLATION:
-                icon = AnswerIcon.TRANSLATION;
-                break;
-            case AnswerType.WEATHER:
-                icon = AnswerIcon.WEATHER;
-                break;
-            case AnswerType.WHEN_IS:
-                icon = AnswerIcon.EVENT;
-                break;
-            case AnswerType.CURRENCY:
-                icon = AnswerIcon.CURRENCY;
-                break;
-            case AnswerType.SPORTS:
-                icon = AnswerIcon.SPORTS;
+        if (answer != null) {
+            switch (answer.getType()) {
+                case AnswerType.DICTIONARY:
+                    icon = AnswerIcon.DICTIONARY;
+                    break;
+                case AnswerType.FINANCE:
+                    icon = AnswerIcon.FINANCE;
+                    break;
+                case AnswerType.KNOWLEDGE_GRAPH:
+                    icon = AnswerIcon.KNOWLEDGE;
+                    break;
+                case AnswerType.SUNRISE:
+                    icon = AnswerIcon.SUNRISE;
+                    break;
+                case AnswerType.TRANSLATION:
+                    icon = AnswerIcon.TRANSLATION;
+                    break;
+                case AnswerType.WEATHER:
+                    icon = AnswerIcon.WEATHER;
+                    break;
+                case AnswerType.WHEN_IS:
+                    icon = AnswerIcon.EVENT;
+                    break;
+                case AnswerType.CURRENCY:
+                    icon = AnswerIcon.CURRENCY;
+                    break;
+                case AnswerType.SPORTS:
+                    icon = AnswerIcon.SPORTS;
+            }
+        } else {
+            assert suggestion.getType() == OmniboxSuggestionType.CALCULATOR;
+            icon = AnswerIcon.CALCULATOR;
         }
 
         model.set(AnswerSuggestionViewProperties.ANSWER_ICON_TYPE, icon);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerText.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerText.java
index b14b0e0a..34831aa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerText.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerText.java
@@ -49,6 +49,8 @@
     AnswerText(Context context) {
         mContext = context;
         mDensity = context.getResources().getDisplayMetrics().density;
+        mText = new SpannableStringBuilder();
+        mMaxLines = 1;
     }
 
     /**
@@ -58,16 +60,14 @@
      * @param delegate Callback converting AnswerTextType to an array of TextAppearanceSpan objects.
      */
     protected void build(SuggestionAnswer.ImageLine line) {
-        mText = new SpannableStringBuilder();
-        mMaxLines = 1;
-
         // This method also computes height of the entire text span.
         // Ensure we're not rebuilding or appending once AnswerText has been constructed.
         assert mHeightSp == 0;
 
         List<SuggestionAnswer.TextField> textFields = line.getTextFields();
         for (int i = 0; i < textFields.size(); i++) {
-            appendAndStyleText(textFields.get(i));
+            appendAndStyleText(
+                    textFields.get(i).getText(), getAppearanceForText(textFields.get(i).getType()));
             if (textFields.get(i).hasNumLines()) {
                 mMaxLines = Math.max(mMaxLines, Math.min(3, textFields.get(i).getNumLines()));
             }
@@ -75,22 +75,24 @@
 
         if (line.hasAdditionalText()) {
             mText.append("  ");
-            appendAndStyleText(line.getAdditionalText());
+            appendAndStyleText(line.getAdditionalText().getText(),
+                    getAppearanceForText(line.getAdditionalText().getType()));
         }
         if (line.hasStatusText()) {
             mText.append("  ");
-            appendAndStyleText(line.getStatusText());
+            appendAndStyleText(line.getStatusText().getText(),
+                    getAppearanceForText(line.getStatusText().getType()));
         }
     }
 
     /**
      * Append the styled text in textField to the supplied builder.
      *
-     * @param textField The text field (with text and type) to append.
+     * @param text Text to be appended.
+     * @param styles Styles to be applied to appended text.
      */
     @SuppressWarnings("deprecation") // Update usage of Html.fromHtml when API min is 24
-    private void appendAndStyleText(SuggestionAnswer.TextField textField) {
-        MetricAffectingSpan[] styles = getAppearanceForText(textField.getType());
+    protected void appendAndStyleText(String text, MetricAffectingSpan[] styles) {
         // Determine the maximum height of the TextAppearanceSpans that are applied for this field.
         for (MetricAffectingSpan style : styles) {
             if (!(style instanceof TextAppearanceSpan)) continue;
@@ -100,7 +102,7 @@
         }
 
         // Unescape HTML entities (e.g. "&quot;", "&gt;").
-        String text = Html.fromHtml(textField.getText()).toString();
+        text = Html.fromHtml(text).toString();
 
         // Append as HTML (answer responses contain simple markup).
         int start = mText.length();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextClassic.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextClassic.java
index d0b55e7..075ede0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextClassic.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextClassic.java
@@ -13,6 +13,8 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
+import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
 import org.chromium.components.omnibox.AnswerTextType;
 import org.chromium.components.omnibox.SuggestionAnswer;
 
@@ -27,14 +29,22 @@
      * content.
      *
      * @param context Current context.
-     * @param answer Specifies answer to be converted.
+     * @param suggestion Suggestion to be converted.
      * @return array of AnswerText elements to use to construct suggestion item.
      */
-    static AnswerText[] from(Context context, SuggestionAnswer answer) {
+    static AnswerText[] from(Context context, OmniboxSuggestion suggestion) {
         AnswerText[] result = new AnswerText[2];
-
-        result[0] = new AnswerTextClassic(context, answer.getFirstLine());
-        result[1] = new AnswerTextClassic(context, answer.getSecondLine());
+        SuggestionAnswer answer = suggestion.getAnswer();
+        if (answer == null) {
+            // As an exception, we handle calculation suggestions, too, considering them an Answer,
+            // even if these are not one.
+            assert suggestion.getType() == OmniboxSuggestionType.CALCULATOR;
+            result[0] = new AnswerTextClassic(context, suggestion.getDisplayText());
+            result[1] = null;
+        } else {
+            result[0] = new AnswerTextClassic(context, answer.getFirstLine());
+            result[1] = new AnswerTextClassic(context, answer.getSecondLine());
+        }
 
         // Trim number of presented query lines.
         result[0].mMaxLines = 1;
@@ -43,7 +53,7 @@
     }
 
     /**
-     * Create new instance of AnswerTextClassic.
+     * Create new instance of AnswerTextClassic for answer suggestions.
      *
      * @param context Current context.
      * @param line Suggestion line that will be converted to Answer Text.
@@ -54,6 +64,17 @@
     }
 
     /**
+     * Create new instance of AnswerTextClassic for non-answer suggestions.
+     *
+     * @param context Current context.
+     * @param text Suggestion text.
+     */
+    AnswerTextClassic(Context context, String text) {
+        super(context);
+        appendAndStyleText(text, getAppearanceForText(AnswerTextType.SUGGESTION));
+    }
+
+    /**
      * Return the TextAppearanceSpan array specifying text decorations for a given field type.
      *
      * @param type The answer type as specified at http://goto.google.com/ais_api.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextNewLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextNewLayout.java
index ed587d1..5693c6ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextNewLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerTextNewLayout.java
@@ -11,6 +11,8 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
+import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
 import org.chromium.components.omnibox.AnswerTextType;
 import org.chromium.components.omnibox.AnswerType;
 import org.chromium.components.omnibox.SuggestionAnswer;
@@ -27,17 +29,24 @@
      * content.
      *
      * @param context Current context.
-     * @param answer Specifies answer to be converted.
+     * @param suggestion Suggestion to be converted.
+     * @param query Query that triggered the suggestion.
      * @return array of AnswerText elements to use to construct suggestion item.
      */
-    static AnswerText[] from(Context context, SuggestionAnswer answer) {
+    static AnswerText[] from(Context context, OmniboxSuggestion suggestion, String query) {
         AnswerText[] result = new AnswerText[2];
 
-        if (answer.getType() == AnswerType.DICTIONARY) {
+        SuggestionAnswer answer = suggestion.getAnswer();
+        if (answer == null) {
+            // As an exception, we handle calculation suggestions, too, considering them an Answer,
+            // even if these are not one.
+            assert suggestion.getType() == OmniboxSuggestionType.CALCULATOR;
+            result[0] = new AnswerTextNewLayout(context, suggestion.getFillIntoEdit(), true);
+            result[1] = new AnswerTextNewLayout(context, query, false);
+        } else if (answer.getType() == AnswerType.DICTIONARY) {
             result[0] = new AnswerTextNewLayout(context, answer.getFirstLine(), true);
             result[1] = new AnswerTextNewLayout(context, answer.getSecondLine(), false);
             result[0].mMaxLines = 1;
-
         } else {
             result[0] = new AnswerTextNewLayout(context, answer.getSecondLine(), true);
             result[1] = new AnswerTextNewLayout(context, answer.getFirstLine(), false);
@@ -48,11 +57,11 @@
     }
 
     /**
-     * Create new instance of AnswerTextNewLayout.
+     * Create new instance of AnswerTextNewLayout for answer suggestions.
      *
      * @param context Current context.
      * @param line Suggestion line that will be converted to Answer Text.
-     * @param isAnswerLine True, whether this instance holds answer.
+     * @param isAnswerLine True, if this instance holds answer.
      */
     AnswerTextNewLayout(Context context, SuggestionAnswer.ImageLine line, boolean isAnswerLine) {
         super(context);
@@ -61,6 +70,18 @@
     }
 
     /**
+     * Create new instance of AnswerTextNewLayout for non-answer suggestions.
+     * @param context Current context.
+     * @param text Suggestion text.
+     * @param isAnswerLine True, if this instance holds answer.
+     */
+    AnswerTextNewLayout(Context context, String text, boolean isAnswerLine) {
+        super(context);
+        mIsAnswer = isAnswerLine;
+        appendAndStyleText(text, getAppearanceForText(AnswerTextType.SUGGESTION));
+    }
+
+    /**
      * Return the TextAppearanceSpan array specifying text decorations for a given field type.
      *
      * @param type The answer type as specified at http://goto.google.com/ais_api.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java
new file mode 100644
index 0000000..ac8ad538
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java
@@ -0,0 +1,53 @@
+// 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.tasks.tab_groups;
+
+import android.content.res.Resources;
+import android.support.annotation.StringRes;
+import android.view.View;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.widget.textbubble.TextBubble;
+import org.chromium.components.feature_engagement.FeatureConstants;
+import org.chromium.components.feature_engagement.Tracker;
+import org.chromium.ui.widget.ViewRectProvider;
+
+/**
+ * Helper class to handle tab groups related utilities.
+ */
+public class TabGroupUtils {
+    public static void maybeShowIPH(@FeatureConstants String featureName, View view) {
+        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GROUP_ANDROID)) return;
+
+        Resources res = view.getContext().getResources();
+        @StringRes
+        int textId;
+        if (featureName.equals(FeatureConstants.TAB_GROUPS_QUICKLY_COMPARE_PAGES_FEATURE)) {
+            textId = R.string.iph_tab_groups_quickly_compare_pages_text;
+        } else if (featureName.equals(FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE)) {
+            textId = R.string.iph_tab_groups_tap_to_see_another_tab_text;
+        } else if (featureName.equals(FeatureConstants.TAB_GROUPS_YOUR_TABS_ARE_TOGETHER_FEATURE)) {
+            textId = R.string.iph_tab_groups_your_tabs_together_text;
+        } else {
+            assert false;
+            return;
+        }
+
+        final Tracker tracker = TrackerFactory.getTrackerForProfile(
+                Profile.getLastUsedProfile().getOriginalProfile());
+        if (!tracker.shouldTriggerHelpUI(featureName)) return;
+
+        ViewRectProvider rectProvider = new ViewRectProvider(view);
+
+        TextBubble textBubble =
+                new TextBubble(view.getContext(), view, textId, textId, true, rectProvider);
+        textBubble.setDismissOnTouchInteraction(true);
+        textBubble.addOnDismissListener(() -> tracker.dismissed(featureName));
+        textBubble.show();
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
index 7b2dd62..58df2811 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
@@ -35,7 +35,7 @@
             BottomSheetController bottomSheetController, TabModelSelector tabModelSelector,
             TabContentManager tabContentManager, ActivityLifecycleDispatcher lifecycleDispatcher) {
         mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
-                tabModelSelector, tabContentManager, bottomSheetController.getBottomSheet());
+                tabModelSelector, tabContentManager, bottomSheetController.getBottomSheet(), false);
 
         mMediator = new BottomTabGridMediator(bottomSheetController, this::resetWithTabModel);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
index ab1fa9bd..0b7afff 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
@@ -40,7 +40,7 @@
         PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS);
 
         mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
-                tabModelSelector, tabContentManager, compositorViewHolder);
+                tabModelSelector, tabContentManager, compositorViewHolder, true);
 
         mContainerViewChangeProcessor = PropertyModelChangeProcessor.create(containerViewModel,
                 mTabGridCoordinator.getContainerView(), TabGridContainerViewBinder::bind);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
index 5d0a5d41..7ea8e85c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.LinearLayoutManager;
 import android.view.LayoutInflater;
@@ -43,7 +44,8 @@
     private final TabListRecyclerView mRecyclerView;
 
     TabListCoordinator(@TabListMode int mode, Context context, TabModelSelector tabModelSelector,
-            TabContentManager tabContentManager, ViewGroup parentView) {
+            TabContentManager tabContentManager, @NonNull ViewGroup parentView,
+            boolean attachToParent) {
         TabListModel tabListModel = new TabListModel();
 
         RecyclerViewAdapter adapter;
@@ -64,7 +66,7 @@
                     "Attempting to create a tab list UI with invalid mode");
         }
 
-        if (parentView != null) {
+        if (!attachToParent) {
             mRecyclerView = (TabListRecyclerView) LayoutInflater.from(context).inflate(
                     R.layout.tab_list_recycler_view_layout, parentView, false);
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
index d1acafc..f774f88 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
@@ -105,7 +105,6 @@
         mActivityTabTabObserver = new ActivityTabTabObserver(activityTabProvider) {
             @Override
             public void onObservingDifferentTab(Tab tab) {
-                if (tab == null) return;
                 updateButtonEnabledState();
             }
 
@@ -126,6 +125,10 @@
 
     private boolean isActiveTabNTP() {
         if (mActivityTabProvider == null) return false;
-        return NewTabPage.isNTPUrl(mActivityTabProvider.getActivityTab().getUrl());
+
+        final Tab tab = mActivityTabProvider.getActivityTab();
+        if (tab == null) return false;
+
+        return NewTabPage.isNTPUrl(tab.getUrl());
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java
index b03c9af..96f1824 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java
@@ -14,6 +14,8 @@
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.metrics.WebApkSplashscreenMetrics;
 import org.chromium.chrome.browser.metrics.WebApkUma;
+import org.chromium.chrome.browser.util.IntentUtils;
+import org.chromium.webapk.lib.common.WebApkConstants;
 
 /**
  * An Activity is designed for WebAPKs (native Android apps) and displays a webapp in a nearly
@@ -50,6 +52,18 @@
     }
 
     @Override
+    public boolean shouldPreferLightweightFre(Intent intent) {
+        // We cannot use getWebApkPackageName() because {@link WebappActivity#preInflationStartup()}
+        // may not have been called yet.
+        String webApkPackageName =
+                IntentUtils.safeGetStringExtra(intent, WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME);
+
+        // Use the lightweight FRE for unbound WebAPKs.
+        return webApkPackageName != null
+                && !webApkPackageName.startsWith(WebApkConstants.WEBAPK_PACKAGE_PREFIX);
+    }
+
+    @Override
     public String getWebApkPackageName() {
         return getWebappInfo().webApkPackageName();
     }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 77c1530..0f6068c4 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2065,6 +2065,9 @@
       <message name="IDS_CONTEXTMENU_OPEN_IN_NEW_TAB" desc="Context sensitive menu item to open the selected link in a new tab. [CHAR-LIMIT=30]">
         Open in new tab
       </message>
+      <message name="IDS_CONTEXTMENU_OPEN_IN_NEW_TAB_GROUP" desc="Context sensitive menu item to open the selected link in a new tab in a new group. [CHAR-LIMIT=30]">
+        Open in new tab in group
+      </message>
       <message name="IDS_CONTEXTMENU_OPEN_IN_INCOGNITO_TAB" desc="Context sensitive menu item to open the selected link in a new incognito tab. [CHAR-LIMIT=30]">
         Open in incognito tab
       </message>
@@ -3857,6 +3860,15 @@
       <message name="IDS_IPH_PREVIEWS_OMNIBOX_UI_ACCESSIBILITY_TEXT" desc="The in-product-help text informing the user that the displayed page was modified to make it load faster or use less data. Prompts the user to tap the message and load the original, unaltered, page if they would like. The 'Lite page provided by Google.' sentence should match TC ID 373879247902731825">
         Lite page provided by Google. Tap the load original button to load the original page.
       </message>
+      <message name="IDS_IPH_TAB_GROUPS_QUICKLY_COMPARE_PAGES_TEXT" desc="In-product help for prompting the user on pages with links to long press and open links in different tabs.">
+        Quickly compare pages by making a group. To start, touch &amp; hold a link.
+      </message>
+      <message name="IDS_IPH_TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_TEXT" desc="In-product help for when the tab strip containing the tabs in a tab group are shown.">
+        Tap to see another tab
+      </message>
+      <message name="IDS_IPH_TAB_GROUPS_YOUR_TABS_TOGETHER_TEXT" desc="In-product help for when a tab switcher card with multiple thumbnails are shown.">
+        Your tabs are grouped together here
+      </message>
       <message name="IDS_IPH_TRANSLATE_MENU_BUTTON_TEXT" desc="The in-product-help message after a successful navigation prompting user to translate current page.">
         Translate this page to any language
       </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 339bfa2..dbbeaeb5 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1621,6 +1621,7 @@
   "java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java",
   "java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java",
   "java/src/org/chromium/chrome/browser/tasks/TasksUma.java",
+  "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridMediator.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridSheetContent.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java
index 5bd741ea7f..f1ead97 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java
@@ -17,10 +17,12 @@
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
 import org.chromium.content_public.browser.test.util.Criteria;
 import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.ui.test.util.UiRestriction;
 
 import java.io.File;
 
@@ -97,6 +99,7 @@
     @LargeTest
     @Feature({"Download"})
     @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
+    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
     /**
      * Verify metadata and thumbnail can be retrieved correctly from h264 video file.
      * @throws InterruptedException
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
index f871e33..471829b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
@@ -10,6 +10,7 @@
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE;
 
 import android.graphics.PointF;
+import android.graphics.RectF;
 import android.os.SystemClock;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
@@ -528,4 +529,68 @@
     private String generateRenderTestIdentifier(String name, boolean incognito) {
         return name + (incognito ? "_incognito" : "") + "_browser_ui";
     }
+
+    /**
+     * Tests that highlighting suggestions looks correct and that clicking just outside of the
+     * suggestion doesn't trigger its onclick. Regression test for https://crbug.com/799593.
+     */
+    @Test
+    @MediumTest
+    @Feature({"Browser", "RenderTest"})
+    public void testSuggestionHovering()
+            throws InterruptedException, TimeoutException, IOException {
+        // Input some text to get suggestions.
+        NativeUiUtils.enableMockedKeyboard();
+        NativeUiUtils.clickElementAndWaitForUiQuiescence(UserFriendlyElementName.URL, new PointF());
+        NativeUiUtils.performActionAndWaitForVisibilityStatus(
+                UserFriendlyElementName.SUGGESTION_BOX, true /* visible */,
+                () -> { NativeUiUtils.inputString("chrome://"); });
+
+        // We need to crop the image before comparing to avoid the blinking cursor in the omnibox.
+        // So, crop roughly around the suggestion box. This tends to chop off the bottom half of
+        // the bottom suggestion on larger devices, but that's preferable to accidentally getting
+        // the omnibox in the image, and should still be sufficient to catch the intended issues
+        // (hover states, clicks actually registering).
+        final RectF cropBounds = new RectF(0.1f, 0.4f, 0.6f, 0.625f);
+
+        // There should be three suggestions, so hover the top then the middle one to ensure that
+        // the hover effect properly moves between the two.
+        NativeUiUtils.hoverElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.0f, 0.3f));
+        NativeUiUtils.waitForUiQuiescence();
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_hovering_top", cropBounds, mRenderTestRule);
+        NativeUiUtils.hoverElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF());
+        NativeUiUtils.waitForUiQuiescence();
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_hovering_middle", cropBounds, mRenderTestRule);
+
+        // Ensure that the hover effect disappears when slightly to the right of the suggestion and
+        // that clicking doesn't do anything.
+        NativeUiUtils.clickElementAndWaitForUiQuiescence(
+                UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.51f, 0.0f));
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_clicking_right", cropBounds, mRenderTestRule);
+        // Again on the left side.
+        NativeUiUtils.hoverElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF());
+        NativeUiUtils.clickElementAndWaitForUiQuiescence(
+                UserFriendlyElementName.SUGGESTION_BOX, new PointF(-0.51f, 0.0f));
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_clicking_left", cropBounds, mRenderTestRule);
+        // Again above the top suggestion.
+        NativeUiUtils.hoverElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.0f, 0.3f));
+        NativeUiUtils.clickElementAndWaitForUiQuiescence(
+                UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.0f, 0.51f));
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_clicking_top", cropBounds, mRenderTestRule);
+        // Again below the bottom suggestion.
+        NativeUiUtils.hoverElement(UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.0f, -0.3f));
+        // For some reason, we have to aim slightly more offset than in other directions in order
+        // to not actually hit the suggestion (probably due to the way we calculate where to click
+        // not taking into account where the controller is, so hit testing can produce a slightly
+        // different result).
+        NativeUiUtils.clickElementAndWaitForUiQuiescence(
+                UserFriendlyElementName.SUGGESTION_BOX, new PointF(0.0f, -0.55f));
+        RenderTestUtils.dumpAndCompareWithCrop(NativeUiUtils.FRAME_BUFFER_SUFFIX_BROWSER_UI,
+                "suggestion_clicking_bottom", cropBounds, mRenderTestRule);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
index a10bb33b..7a229ed 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java
@@ -6,6 +6,7 @@
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.RectF;
 
 import org.junit.Assert;
 
@@ -34,9 +35,18 @@
      */
     public static void dumpAndCompare(String suffix, String id, RenderTestRule rule)
             throws IOException, InterruptedException {
+        dumpAndCompareWithCrop(suffix, id, null /* bounds */, rule);
+    }
+
+    /**
+     * Helper function for running the general dumpAndCompare when only one image needs to be
+     * compared and it needs to be cropped before comparing.
+     */
+    public static void dumpAndCompareWithCrop(String suffix, String id, RectF bounds,
+            RenderTestRule rule) throws IOException, InterruptedException {
         HashMap<String, String> suffixToId = new HashMap<String, String>();
         suffixToId.put(suffix, id);
-        dumpAndCompare(suffixToId, rule);
+        dumpAndCompare(suffixToId, bounds, rule);
     }
 
     /**
@@ -45,10 +55,12 @@
      *
      * @param suffixToIds a map from framebuffer suffixes from NativeUiUtils to RenderTest image
      *        IDs.
+     * @param bounds a RectF defining the bounds [0, 1] with the origin in the top left corner to
+     *        crop the image to before comparing. Pass null to not crop.
      * @param rule the RenderTestRule to use for comparing images.
      */
-    public static void dumpAndCompare(HashMap<String, String> suffixToIds, RenderTestRule rule)
-            throws IOException, InterruptedException {
+    public static void dumpAndCompare(HashMap<String, String> suffixToIds, RectF bounds,
+            RenderTestRule rule) throws IOException, InterruptedException {
         File dumpDirectory = new File(UrlUtils.getIsolatedTestFilePath(IMAGE_DUMP_DIR));
         if (!dumpDirectory.exists() && !dumpDirectory.isDirectory()) {
             Assert.assertTrue("Failed to make framebuffer dump directory", dumpDirectory.mkdirs());
@@ -66,6 +78,27 @@
             options.inPreferredConfig = Bitmap.Config.ARGB_8888;
             Bitmap bitmap = BitmapFactory.decodeFile(filepath, options);
 
+            // Crop the image if necessary
+            if (bounds != null) {
+                Assert.assertTrue(
+                        "Given left bound is not in [0, 1)", bounds.left >= 0 && bounds.left < 1);
+                Assert.assertTrue("Given right bound is not in (0, 1]",
+                        bounds.right > 0 && bounds.right <= 1);
+                Assert.assertTrue(
+                        "Given horizontal bounds are not valid", bounds.left < bounds.right);
+                Assert.assertTrue(
+                        "Given top bound is not in [0, 1)", bounds.top >= 0 && bounds.top < 1);
+                Assert.assertTrue("Given bottom bound is not in (0, 1]",
+                        bounds.bottom > 0 && bounds.bottom <= 1);
+                Assert.assertTrue(
+                        "Given vertical bounds are not valid", bounds.top < bounds.bottom);
+
+                bitmap = Bitmap.createBitmap(bitmap, (int) (bounds.left * bitmap.getWidth()),
+                        (int) (bounds.top * bitmap.getHeight()),
+                        (int) (bounds.width() * bitmap.getWidth()),
+                        (int) (bounds.height() * bitmap.getHeight()));
+            }
+
             // The browser UI dump contains both eyes rendered, which is unnecessary for comparing
             // since any difference in one should show up in the other. So, take the left half of
             // the image to get the left eye, which reduces the amount of space the image takes up.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java
index ca98287..e1317c0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java
@@ -25,13 +25,18 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 import org.robolectric.shadows.ShadowApplication;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+import org.chromium.chrome.browser.init.BrowserParts;
+import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.searchwidget.SearchActivity;
+import org.chromium.chrome.browser.webapps.WebApkActivity;
 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
 import org.chromium.webapk.lib.client.WebApkValidator;
 import org.chromium.webapk.lib.common.WebApkConstants;
@@ -40,8 +45,19 @@
 
 /** JUnit tests for first run triggering code. */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
+@Config(manifest = Config.NONE,
+        shadows = {FirstRunIntegrationUnitTest.MockChromeBrowserInitializer.class})
 public final class FirstRunIntegrationUnitTest {
+    /** Do nothing version of {@link ChromeBrowserInitializer}. */
+    @Implements(ChromeBrowserInitializer.class)
+    public static class MockChromeBrowserInitializer {
+        @Implementation
+        public void __constructor__() {}
+
+        @Implementation
+        public void handlePreNativeStartup(final BrowserParts parts) {}
+    }
+
     @Rule
     public MockitoRule mMockitoRule = MockitoJUnit.rule();
 
@@ -61,6 +77,11 @@
         WebApkValidator.disableValidationForTesting();
     }
 
+    /** Checks that the intent component targets the passed-in class. */
+    private boolean checkIntentComponentClass(Intent intent, Class componentClass) {
+        return checkIntentComponentClassOneOf(intent, new Class[] {componentClass});
+    }
+
     /** Checks that the intent component is one of the provided classes. */
     private boolean checkIntentComponentClassOneOf(Intent intent, Class[] componentClassOptions) {
         if (intent == null || intent.getComponent() == null) return false;
@@ -178,8 +199,7 @@
         Robolectric.buildActivity(WebappLauncherActivity.class, intent).create();
 
         Intent launchedIntent = mShadowApplication.getNextStartedActivity();
-        while (checkIntentComponentClassOneOf(
-                launchedIntent, new Class[] {WebappLauncherActivity.class})) {
+        while (checkIntentComponentClass(launchedIntent, WebappLauncherActivity.class)) {
             buildActivityWithClassNameFromIntent(launchedIntent);
             launchedIntent = mShadowApplication.getNextStartedActivity();
         }
@@ -191,4 +211,35 @@
         Assert.assertEquals(webApkPackageName,
                 Shadows.shadowOf(freCompleteLaunchIntent).getSavedIntent().getPackage());
     }
+
+    /**
+     * Test that if a WebAPK only requires the lightweight FRE and a user has gone through the
+     * lightweight FRE that the WebAPK launches and no FRE is shown to the user.
+     */
+    @Test
+    public void testUserAcceptedLightweightFreLaunch() {
+        FirstRunStatus.setLightweightFirstRunFlowComplete(true);
+
+        String webApkPackageName = "unbound.webapk";
+        String startUrl = "https://pwa.rocks/";
+
+        Bundle bundle = new Bundle();
+        bundle.putString(WebApkMetaDataKeys.START_URL, startUrl);
+        WebApkTestHelper.registerWebApkWithMetaData(
+                webApkPackageName, bundle, null /* shareTargetMetaData */);
+        WebApkTestHelper.addIntentFilterForUrl(webApkPackageName, startUrl);
+
+        Intent intent = new Intent();
+        intent.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, webApkPackageName);
+        intent.putExtra(ShortcutHelper.EXTRA_URL, startUrl);
+
+        Robolectric.buildActivity(WebappLauncherActivity.class, intent).create();
+
+        Intent launchedIntent = mShadowApplication.getNextStartedActivity();
+        Assert.assertTrue(checkIntentComponentClass(launchedIntent, WebApkActivity.class));
+        buildActivityWithClassNameFromIntent(launchedIntent);
+
+        // No FRE should have been launched.
+        Assert.assertNull(mShadowApplication.getNextStartedActivity());
+    }
 }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index b201111..cc19f43 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -3133,16 +3133,21 @@
     Access your Assistant with Voice Match
   </message>
   <message name="IDS_ASSISTANT_VOICE_MATCH_MESSAGE" desc="Message for Assistant voice match screen.">
-    Your Assistant uses these recordings to create your voice model, which is stored in your device. Delete or retrain the model in Assistant settings. View or delete voice commands in your Google activity controls.
+    Voice Match lets you access your Assistant directly by using your voice.
+    <ph name="BR">&lt;br&gt;</ph>
+    <ph name="BEGIN_BOLD">&lt;b&gt;</ph>Keep in mind:<ph name="END_BOLD">&lt;/b&gt;</ph> A similar voice or recording might be able to access your Assistant, too. You can remove Voice Match permission later by turning it off in Assistant Settings.
+  </message>
+  <message name="IDS_ASSISTANT_VOICE_MATCH_NO_DSP_MESSAGE" desc="Message without DSP support for Assistant voice match screen.">
+    To save battery, “Ok Google” is on only when your device is connected to a power source. To make changes, go to Settings.
   </message>
   <message name="IDS_ASSISTANT_VOICE_MATCH_RECORDING" desc="Title for recording in assistant voice match screen.">
-    Teach the Assistant to recognize your voice
+    Teach your Assistant to recognize your voice
   </message>
   <message name="IDS_ASSISTANT_VOICE_MATCH_COMPLETED" desc="Title for completed assistant voice match screen.">
     Ok Google is all set
   </message>
   <message name="IDS_ASSISTANT_VOICE_MATCH_FOOTER" desc="Footer message for Assistant voice match screen.">
-    Your Assistant uses these recordings and your spoken requests to create and update your voice model, which is only stored on devices where you've turned on Voice Match. View or delete voice activity in your Google activity controls.
+    Your Assistant uses these recordings and your spoken requests to create and update your voice model, which is only stored on devices where you've turned on Voice Match. View or retrain voice activity in Assistant Settings.
   </message>
   <message name="IDS_ASSISTANT_VOICE_MATCH_INSTRUCTION0" desc="Instruction message for assistant voice match recording.">
     Say "Ok Google"
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 76d1fc6..945a1b6 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -4225,6 +4225,9 @@
     <message name="IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM" desc="In Device Settings > Displays, the text entry for a single item in the external display resolution drop down menu.">
       <ph name="WIDTH">$1<ex>1600</ex></ph> x <ph name="HEIGHT">$2<ex>1200</ex></ph> (<ph name="REFRESH_RATE">$3<ex>60</ex></ph> Hertz)
     </message>
+    <message name="IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM" desc="In Device Settings > Displays, the text entry for a single item in the external display resolution drop down menu, when the display mode is interlaced (which means the display's odd and even lines are scanned alternately in two interwoven rasterized lines).">
+      <ph name="WIDTH">$1<ex>1600</ex></ph> x <ph name="HEIGHT">$2<ex>1200</ex></ph> (<ph name="REFRESH_RATE">$3<ex>60</ex></ph> Hertz) - interlaced
+    </message>
     <message name="IDS_SETTINGS_DISPLAY_ZOOM_TITLE" desc="In Device Settings > Displays, the title for the section for changing the display's zoom.">
       Display Size
     </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e47c714..04265cab 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -135,6 +135,7 @@
 #include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/compositor/compositor_switches.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/events/blink/blink_features.h"
 #include "ui/events/event_switches.h"
@@ -1503,6 +1504,9 @@
      flag_descriptions::kVideoPlayerChromecastSupportDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(
          chromeos::switches::kEnableVideoPlayerChromecastSupport)},
+    {"list-all-display-modes", flag_descriptions::kListAllDisplayModesName,
+     flag_descriptions::kListAllDisplayModesDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(display::features::kListAllDisplayModes)},
     {"instant-tethering", flag_descriptions::kTetherName,
      flag_descriptions::kTetherDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kInstantTethering)},
@@ -1542,7 +1546,7 @@
 #if defined(OS_WIN)
     {"enable-hdr", flag_descriptions::kEnableHDRName,
      flag_descriptions::kEnableHDRDescription, kOsWin,
-     FEATURE_VALUE_TYPE(features::kHighDynamicRange)},
+     FEATURE_VALUE_TYPE(display::features::kHighDynamicRange)},
 #endif  // OS_WIN
 #if defined(OS_CHROMEOS)
     {
@@ -2902,7 +2906,7 @@
 #if defined(OS_CHROMEOS)
     {"use-monitor-color-space", flag_descriptions::kUseMonitorColorSpaceName,
      flag_descriptions::kUseMonitorColorSpaceDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(features::kUseMonitorColorSpace)},
+     FEATURE_VALUE_TYPE(display::features::kUseMonitorColorSpace)},
 
     {"quick-unlock-pin-signin", flag_descriptions::kQuickUnlockPinSignin,
      flag_descriptions::kQuickUnlockPinSigninDescription, kOsCrOS,
@@ -3811,6 +3815,10 @@
      flag_descriptions::kEnableZeroStateSuggestionsName,
      flag_descriptions::kEnableZeroStateSuggestionsDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(app_list_features::kEnableZeroStateSuggestions)},
+    {"enable-zero-state-app-reinstall-suggestions",
+     flag_descriptions::kEnableAppReinstallZeroStateName,
+     flag_descriptions::kEnableAppReinstallZeroStateDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(app_list_features::kEnableAppReinstallZeroState)},
 #endif  // OS_CHROMEOS
 
     {"enable-bloated-renderer-detection",
diff --git a/chrome/browser/android/download/download_controller.cc b/chrome/browser/android/download/download_controller.cc
index 7e5006d..5795d22 100644
--- a/chrome/browser/android/download/download_controller.cc
+++ b/chrome/browser/android/download/download_controller.cc
@@ -382,7 +382,8 @@
   download_item->RemoveObserver(this);
   download_item->AddObserver(this);
 
-  download::AutoResumptionHandler::Get()->OnDownloadStarted(download_item);
+  if (download::AutoResumptionHandler::Get())
+    download::AutoResumptionHandler::Get()->OnDownloadStarted(download_item);
 
   OnDownloadUpdated(download_item);
 }
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.cc b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
index c8c4d2fb..9b8b454 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
@@ -37,16 +37,21 @@
     const char* pref_name;
     base::RepeatingCallback<void(BrowserSwitcherPrefs*)> callback;
   } hooks[] = {
-      {prefs::kAlternativeBrowserPath,
-       base::BindRepeating(
-           &BrowserSwitcherPrefs::AlternativeBrowserPathChanged)},
-      {prefs::kAlternativeBrowserParameters,
-       base::BindRepeating(
-           &BrowserSwitcherPrefs::AlternativeBrowserParametersChanged)},
-      {prefs::kUrlList,
-       base::BindRepeating(&BrowserSwitcherPrefs::UrlListChanged)},
-      {prefs::kUrlGreylist,
-       base::BindRepeating(&BrowserSwitcherPrefs::GreylistChanged)},
+    {prefs::kAlternativeBrowserPath,
+     base::BindRepeating(&BrowserSwitcherPrefs::AlternativeBrowserPathChanged)},
+    {prefs::kAlternativeBrowserParameters,
+     base::BindRepeating(
+         &BrowserSwitcherPrefs::AlternativeBrowserParametersChanged)},
+    {prefs::kUrlList,
+     base::BindRepeating(&BrowserSwitcherPrefs::UrlListChanged)},
+    {prefs::kUrlGreylist,
+     base::BindRepeating(&BrowserSwitcherPrefs::GreylistChanged)},
+#if defined(OS_WIN)
+    {prefs::kChromePath,
+     base::BindRepeating(&BrowserSwitcherPrefs::ChromePathChanged)},
+    {prefs::kChromeParameters,
+     base::BindRepeating(&BrowserSwitcherPrefs::ChromeParametersChanged)},
+#endif
   };
 
   // Listen for pref changes, and run all the hooks once to initialize state.
@@ -69,6 +74,8 @@
     prefs::kExternalSitelistUrl,
 #if defined(OS_WIN)
     prefs::kUseIeSitelist,
+    prefs::kChromePath,
+    prefs::kChromeParameters,
 #endif
   };
   for (const char* pref_name : all_prefs) {
@@ -101,6 +108,8 @@
   registry->RegisterStringPref(prefs::kExternalSitelistUrl, "");
 #if defined(OS_WIN)
   registry->RegisterBooleanPref(prefs::kUseIeSitelist, false);
+  registry->RegisterStringPref(prefs::kChromePath, "");
+  registry->RegisterListPref(prefs::kChromeParameters);
 #endif
 }
 
@@ -142,6 +151,15 @@
     return false;
   return prefs_->GetBoolean(prefs::kUseIeSitelist);
 }
+
+const std::string& BrowserSwitcherPrefs::GetChromePath() const {
+  return chrome_path_;
+}
+
+const std::vector<std::string>& BrowserSwitcherPrefs::GetChromeParameters()
+    const {
+  return chrome_params_;
+}
 #endif
 
 void BrowserSwitcherPrefs::OnPolicyUpdated(const policy::PolicyNamespace& ns,
@@ -230,6 +248,25 @@
   UMA_HISTOGRAM_BOOLEAN("BrowserSwitcher.UrlListWildcard", has_wildcard);
 }
 
+#if defined(OS_WIN)
+void BrowserSwitcherPrefs::ChromePathChanged() {
+  chrome_path_.clear();
+  if (prefs_->IsManagedPreference(prefs::kChromePath))
+    chrome_path_ = prefs_->GetString(prefs::kChromePath);
+}
+
+void BrowserSwitcherPrefs::ChromeParametersChanged() {
+  chrome_params_.clear();
+  if (!prefs_->IsManagedPreference(prefs::kChromeParameters))
+    return;
+  const base::ListValue* params = prefs_->GetList(prefs::kChromeParameters);
+  for (const auto& param : *params) {
+    std::string param_string = param.GetString();
+    chrome_params_.push_back(param_string);
+  }
+}
+#endif
+
 namespace prefs {
 
 // Path to the executable of the alternative browser, or one of "${chrome}",
@@ -257,6 +294,12 @@
 #if defined(OS_WIN)
 // If set to true, use the IE Enterprise Mode Sitelist policy.
 const char kUseIeSitelist[] = "browser_switcher.use_ie_sitelist";
+
+// Path to the Chrome executable for the alternative browser.
+const char kChromePath[] = "browser_switcher.chrome_path";
+
+// Arguments the alternative browser should pass to Chrome when launching it.
+const char kChromeParameters[] = "browser_switcher.chrome_parameters";
 #endif
 
 // Disable browser_switcher unless this is set to true.
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.h b/chrome/browser/browser_switcher/browser_switcher_prefs.h
index 90382ecb..0705e26 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs.h
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs.h
@@ -85,6 +85,14 @@
   // Returns true if Chrome should download and apply the XML sitelist from
   // IEEM's SiteList policy. If the pref is not managed, returns false.
   bool UseIeSitelist() const;
+
+  // Returns the path to the Chrome executable to launch when switching from IE,
+  // before substitutions.
+  const std::string& GetChromePath() const;
+
+  // Returns the arguments to pass to Chrome when switching from IE, before
+  // substitutions.
+  const std::vector<std::string>& GetChromeParameters() const;
 #endif
 
   // policy::PolicyService::Observer
@@ -109,6 +117,10 @@
   void AlternativeBrowserParametersChanged();
   void UrlListChanged();
   void GreylistChanged();
+#if defined(OS_WIN)
+  void ChromePathChanged();
+  void ChromeParametersChanged();
+#endif
 
   policy::PolicyService* const policy_service_;
   PrefService* const prefs_;
@@ -128,6 +140,10 @@
   // PrefChangeRegistrar hooks.
   std::string alt_browser_path_;
   std::vector<std::string> alt_browser_params_;
+#if defined(OS_WIN)
+  std::string chrome_path_;
+  std::vector<std::string> chrome_params_;
+#endif
 
   RuleSet rules_;
 
@@ -154,6 +170,8 @@
 
 #if defined(OS_WIN)
 extern const char kUseIeSitelist[];
+extern const char kChromePath[];
+extern const char kChromeParameters[];
 #endif
 
 }  // namespace prefs
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
index 8dd8e19..585a93d 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/run_loop.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
 #include "chrome/browser/browser_switcher/ieem_sitelist_parser.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
@@ -91,6 +92,12 @@
                                   std::make_unique<base::Value>("notepad.exe"));
   prefs_backend()->SetManagedPref(prefs::kAlternativeBrowserParameters,
                                   StringArrayToValue({"a", "b", "c"}));
+#if defined(OS_WIN)
+  prefs_backend()->SetManagedPref(prefs::kChromePath,
+                                  std::make_unique<base::Value>("cmd.exe"));
+  prefs_backend()->SetManagedPref(prefs::kChromeParameters,
+                                  StringArrayToValue({"d", "e", "f"}));
+#endif
   prefs_backend()->SetManagedPref(prefs::kUrlList,
                                   StringArrayToValue({"example.com"}));
   prefs_backend()->SetManagedPref(prefs::kUrlGreylist,
@@ -105,6 +112,15 @@
   EXPECT_EQ("b", prefs()->GetAlternativeBrowserParameters()[1]);
   EXPECT_EQ("c", prefs()->GetAlternativeBrowserParameters()[2]);
 
+#if defined(OS_WIN)
+  EXPECT_EQ("cmd.exe", prefs()->GetChromePath());
+
+  EXPECT_EQ(3u, prefs()->GetChromeParameters().size());
+  EXPECT_EQ("d", prefs()->GetChromeParameters()[0]);
+  EXPECT_EQ("e", prefs()->GetChromeParameters()[1]);
+  EXPECT_EQ("f", prefs()->GetChromeParameters()[2]);
+#endif
+
   EXPECT_EQ(1u, prefs()->GetRules().sitelist.size());
   EXPECT_EQ("example.com", prefs()->GetRules().sitelist[0]);
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.cc b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
index b49f418..9f60842 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_win.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
@@ -53,11 +53,8 @@
   buffer << base::JoinString(prefs.GetAlternativeBrowserParameters(), " ")
          << std::endl;
 
-  // TODO(nicolaso): Use GetChromePath() and GetChromeParameters once the
-  // policies are implemented. For now, those are just ${chrome} with no
-  // arguments, to ensure the BHO works correctly.
-  buffer << "${chrome}" << std::endl;
-  buffer << base::JoinString(std::vector<std::string>(), " ") << std::endl;
+  buffer << prefs.GetChromePath() << std::endl;
+  buffer << base::JoinString(prefs.GetChromeParameters(), " ") << std::endl;
 
   const auto& rules = prefs.GetRules();
   buffer << rules.sitelist.size() << std::endl;
diff --git a/chrome/browser/browser_switcher/ieem_sitelist_parser.cc b/chrome/browser/browser_switcher/ieem_sitelist_parser.cc
index 7615f1a..71bed5e 100644
--- a/chrome/browser/browser_switcher/ieem_sitelist_parser.cc
+++ b/chrome/browser/browser_switcher/ieem_sitelist_parser.cc
@@ -45,10 +45,10 @@
 struct Entry {
   // URL or path concerned.
   std::string text;
-  // Whether to include or exclude the URL.
+  // True if the exclude attribute is "true".
   bool exclude;
-  // List affected by this rule (sitelist or greylist).
-  std::vector<std::string>* list;
+  // True if the doNotTransition attribute is "true".
+  bool do_not_transition;
 };
 
 Entry ParseDomainOrPath(const base::Value& node, ParsedXml* result) {
@@ -63,9 +63,7 @@
 
   std::string do_not_transition_attrib =
       GetXmlElementAttribute(node, kSchema1DoNotTransitionAttribute);
-  entry.list =
-      ((do_not_transition_attrib == kSchema1TrueValue) ? &result->greylist
-                                                       : &result->sitelist);
+  entry.do_not_transition = (do_not_transition_attrib == kSchema1TrueValue);
 
   GetXmlElementText(node, &entry.text);
   base::TrimWhitespaceASCII(entry.text, base::TRIM_ALL, &entry.text);
@@ -87,17 +85,17 @@
     for (const base::Value* domain_node :
          GetChildrenWithTag(node, kSchema1DomainElement)) {
       Entry domain = ParseDomainOrPath(*domain_node, result);
-      if (!domain.text.empty()) {
-        std::string prefix = (domain.exclude ? "!" : "");
-        domain.list->push_back(prefix + domain.text);
+      if (!domain.text.empty() && !domain.exclude) {
+        std::string prefix = (domain.do_not_transition ? "!" : "");
+        result->sitelist.push_back(prefix + domain.text);
       }
       // Loop over <path> elements.
       for (const base::Value* path_node :
            GetChildrenWithTag(*domain_node, kSchema1PathElement)) {
         Entry path = ParseDomainOrPath(*path_node, result);
-        if (!path.text.empty() && !domain.text.empty()) {
-          std::string prefix = (path.exclude ? "!" : "");
-          path.list->push_back(prefix + domain.text + path.text);
+        if (!path.text.empty() && !domain.text.empty() && !path.exclude) {
+          std::string prefix = (path.do_not_transition ? "!" : "");
+          result->sitelist.push_back(prefix + domain.text + path.text);
         }
       }
     }
diff --git a/chrome/browser/browser_switcher/ieem_sitelist_parser_browsertest.cc b/chrome/browser/browser_switcher/ieem_sitelist_parser_browsertest.cc
index 3ac7c6b..e963b76 100644
--- a/chrome/browser/browser_switcher/ieem_sitelist_parser_browsertest.cc
+++ b/chrome/browser/browser_switcher/ieem_sitelist_parser_browsertest.cc
@@ -101,49 +101,41 @@
       "exclude=\"false\">/r6</path></domain><domain docMode=\"5\" "
       "exclude=\"false\">howmanydomainz.com<path docMode=\"5\">/r8</path><path "
       "docMode=\"5\" exclude=\"true\">/r9</path><path docMode=\"5\" "
-      "exclude=\"false\">/r10</path></domain><domain doNotTransition=\"true\">"
-      "notransition.com<path>/yestransition</path><path exclude=\"true\" "
-      "doNotTransition=\"true\">/guessnot</path></domain></docMode></rules>";
+      "exclude=\"false\">/r10</path></domain><domain exclude=\"true\" "
+      "doNotTransition=\"true\">maybe.com<path>/yestransition</path>"
+      "<path doNotTransition=\"true\">/guessnot</path></domain><domain>"
+      "yes.com<path doNotTransition=\"true\">/actuallyno</path></domain>"
+      "<domain doNotTransition=\"true\">no.com</domain></docMode></rules>";
   std::vector<std::string> expected_sitelist = {
       "inside.com",
       "inside.com/in_domain",
       "google.com",
-      "!good.com",
       "more.com",
       "e100.com",
       "e100.com/path1",
-      "!e100.com/pa2",
       "e100.com/path3",
-      "!e200.com",
       "e200.com/path1",
-      "!e200.com/pth2",
       "e200.com/path3",
       "e300.com",
       "e300.com/path1",
-      "!e300.com/pt2",
       "e300.com/path3",
-      "!random.com",
-      "!random.com/path1/",
       "random.com/path2",
       "moredomains.com",
       "evenmore.com",
       "evenmore.com/r1",
       "evenmore.com/r2",
-      "!domainz.com",
       "domainz.com/r2",
-      "!domainz.com/r5",
       "domainz.com/r6",
       "howmanydomainz.com",
       "howmanydomainz.com/r8",
-      "!howmanydomainz.com/r9",
       "howmanydomainz.com/r10",
-      "notransition.com/yestransition",
+      "maybe.com/yestransition",
+      "!maybe.com/guessnot",
+      "yes.com",
+      "!yes.com/actuallyno",
+      "!no.com",
   };
-  std::vector<std::string> expected_greylist = {
-      "notransition.com", "!notransition.com/guessnot",
-  };
-  TestParseXml(xml, ParsedXml(std::move(expected_sitelist),
-                              std::move(expected_greylist), base::nullopt));
+  TestParseXml(xml, ParsedXml(std::move(expected_sitelist), {}, base::nullopt));
 }
 
 IN_PROC_BROWSER_TEST_F(IeemSitelistParserTest, V2Full) {
diff --git a/chrome/browser/chrome_browser_application_mac.mm b/chrome/browser/chrome_browser_application_mac.mm
index 2c065b3..08e79d6 100644
--- a/chrome/browser/chrome_browser_application_mac.mm
+++ b/chrome/browser/chrome_browser_application_mac.mm
@@ -31,7 +31,7 @@
   // will not be a BrowserCrApplication, but will instead be an NSApplication.
   // This is undesirable and we must enforce that this doesn't happen.
   CHECK([NSApp isKindOfClass:[BrowserCrApplication class]]);
-};
+}
 
 void Terminate() {
   [NSApp terminate:nil];
diff --git a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
index 9c4dc8df..0327de0 100644
--- a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
+++ b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
@@ -96,7 +96,6 @@
     : binding_(this),
       notifier_(std::move(notifier)),
       size_(size),
-      desktop_window_(nullptr),
       client_native_pixmap_factory_(
           gfx::CreateClientNativePixmapFactoryDmabuf()),
       weak_ptr_factory_(this) {}
@@ -106,18 +105,19 @@
     const std::string& display_name,
     bool enable_notification) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  desktop_window_ = content::DesktopMediaID::GetNativeWindowById(desktop_id);
-  if (!desktop_window_) {
+  display_root_window_ =
+      content::DesktopMediaID::GetNativeWindowById(desktop_id);
+  if (!display_root_window_) {
     LOG(ERROR) << "Unable to find Aura desktop window";
     return nullptr;
   }
 
-  ui::Layer* layer = desktop_window_->layer();
+  ui::Layer* layer = display_root_window_->layer();
   if (!layer) {
     LOG(ERROR) << "Unable to find layer for the desktop window";
     return nullptr;
   }
-  auto context_provider = aura::Env::GetInstance()
+  auto context_provider = display_root_window_->env()
                               ->context_factory()
                               ->SharedMainThreadContextProvider();
   gl_helper_ = std::make_unique<viz::GLHelper>(
@@ -129,7 +129,7 @@
       gfx::Vector2d(desktop_size.width(), desktop_size.height()),
       gfx::Vector2d(size_.width(), size_.height()), false, true, false);
 
-  desktop_window_->GetHost()->compositor()->AddAnimationObserver(this);
+  display_root_window_->GetHost()->compositor()->AddAnimationObserver(this);
 
   if (enable_notification) {
     // Show the tray notification icon now.
@@ -159,7 +159,10 @@
 }
 
 ArcScreenCaptureSession::~ArcScreenCaptureSession() {
-  desktop_window_->GetHost()->compositor()->RemoveAnimationObserver(this);
+  if (!display_root_window_)
+    return;
+
+  display_root_window_->GetHost()->compositor()->RemoveAnimationObserver(this);
   ash::Shell::Get()->display_manager()->dec_screen_capture_active_counter();
   ash::Shell::Get()->UpdateCursorCompositingEnabled();
 }
@@ -352,7 +355,7 @@
     return;
   }
 
-  ui::Layer* layer = desktop_window_->layer();
+  ui::Layer* layer = display_root_window_->layer();
   if (!layer) {
     LOG(ERROR) << "Unable to find layer for the desktop window";
     return;
@@ -363,7 +366,7 @@
           base::BindOnce(&ArcScreenCaptureSession::OnDesktopCaptured,
                          weak_ptr_factory_.GetWeakPtr()));
   // Clip the requested area to the desktop area. See b/118675936.
-  request->set_area(gfx::Rect(desktop_window_->bounds().size()));
+  request->set_area(gfx::Rect(display_root_window_->bounds().size()));
   layer->RequestCopyOfOutput(std::move(request));
 }
 
diff --git a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.h b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.h
index c5f79163..236e3f5 100644
--- a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.h
+++ b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.h
@@ -93,7 +93,9 @@
   mojo::Binding<mojom::ScreenCaptureSession> binding_;
   mojom::ScreenCaptureSessionNotifierPtr notifier_;
   gfx::Size size_;
-  aura::Window* desktop_window_;
+  // aura::Window of the display being captured. This corresponds to one of
+  // Ash's root windows.
+  aura::Window* display_root_window_ = nullptr;
 
   // We have 2 separate queues for handling incoming GPU buffers from Android
   // and also textures for the desktop we have captured already. Due to the
diff --git a/chrome/browser/chromeos/assistant/assistant_util.cc b/chrome/browser/chromeos/assistant/assistant_util.cc
index 744048c..12a59b63 100644
--- a/chrome/browser/chromeos/assistant/assistant_util.cc
+++ b/chrome/browser/chromeos/assistant/assistant_util.cc
@@ -41,8 +41,18 @@
   if (user_manager::UserManager::Get()->IsLoggedInAsPublicAccount())
     return ash::mojom::AssistantAllowedState::DISALLOWED_BY_PUBLIC_SESSION;
 
-  const std::string kAllowedLocales[] = {ULOC_US, ULOC_UK, ULOC_CANADA,
-                                         ULOC_CANADA_FRENCH};
+  // String literals used in some cases in the array because their
+  // constant equivalents don't exist in:
+  // third_party/icu/source/common/unicode/uloc.h
+  const std::string kAllowedLocales[] = {ULOC_CANADA,
+                                         ULOC_CANADA_FRENCH,
+                                         ULOC_FRENCH,
+                                         ULOC_UK,
+                                         ULOC_US,
+                                         "da_DK",
+                                         "nl_NL",
+                                         "no_NO"
+                                         "sv_SE"};
 
   const PrefService* prefs = profile->GetPrefs();
   std::string pref_locale =
diff --git a/chrome/browser/chromeos/display/output_protection_controller_ash.cc b/chrome/browser/chromeos/display/output_protection_controller_ash.cc
index 83a7c62a..13648a2 100644
--- a/chrome/browser/chromeos/display/output_protection_controller_ash.cc
+++ b/chrome/browser/chromeos/display/output_protection_controller_ash.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/chromeos/display/output_protection_controller_ash.h"
+#include "ui/display/manager/display_configurator.h"
 
 #include "ash/shell.h"  // mash-ok
 
diff --git a/chrome/browser/chromeos/display/output_protection_controller_ash.h b/chrome/browser/chromeos/display/output_protection_controller_ash.h
index 5c0983c..d69c0e1 100644
--- a/chrome/browser/chromeos/display/output_protection_controller_ash.h
+++ b/chrome/browser/chromeos/display/output_protection_controller_ash.h
@@ -8,7 +8,6 @@
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "chrome/browser/chromeos/display/output_protection_delegate.h"
-#include "ui/display/manager/display_configurator.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/network_change_manager_client_browsertest.cc b/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
index a6fb47c6..0a93bbc 100644
--- a/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
+++ b/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
@@ -138,8 +138,9 @@
 
 // Tests that the NetworkChangeManagerClient reconnects to the network service
 // after it gets disconnected.
+// TODO(crbug.com/934583): Fix the flakiness.
 IN_PROC_BROWSER_TEST_F(NetworkChangeManagerClientBrowserTest,
-                       ReconnectToNetworkService) {
+                       DISABLED_ReconnectToNetworkService) {
   if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
     return;
 
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index 418fd636..0655a59 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -525,7 +525,6 @@
       base::BindRepeating(&SmbService::RequestUpdatedSharePath,
                           base::Unretained(this))));
   RestoreMounts();
-  net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
 }
 
 void SmbService::FireMountCallback(MountResponse callback,
@@ -663,22 +662,6 @@
          previous_host_discovery_time_ + kHostDiscoveryInterval;
 }
 
-void SmbService::OnNetworkChanged(
-    net::NetworkChangeNotifier::ConnectionType type) {
-  user_manager::User* user =
-      chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
-
-  if (!user) {
-    // If a network change occurs on the lockscreen, do nothing.
-    return;
-  }
-
-  // Run host discovery to refresh list of cached hosts for subsequent name
-  // resolution attempts.
-  share_finder_->DiscoverHostsInNetwork(base::DoNothing()
-                                        /* HostDiscoveryResponse */);
-}
-
 void SmbService::RecordMountCount() const {
   const std::vector<ProvidedFileSystemInfo> file_systems =
       GetProviderService()->GetProvidedFileSystemInfoList(provider_id_);
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h
index b74dd9d5..076faf0f 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.h
+++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -25,7 +25,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/dbus/smb_provider_client.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "net/base/network_change_notifier.h"
 
 namespace base {
 class FilePath;
@@ -47,7 +46,6 @@
 
 // Creates and manages an smb file system.
 class SmbService : public KeyedService,
-                   public net::NetworkChangeNotifier::NetworkChangeObserver,
                    public base::SupportsWeakPtr<SmbService> {
  public:
   using MountResponse = base::OnceCallback<void(SmbMountResult result)>;
@@ -247,11 +245,6 @@
   // false if HostDiscovery was recently run.
   bool ShouldRunHostDiscoveryAgain() const;
 
-  // NetworkChangeNotifier::NetworkChangeObserver override. Runs HostDiscovery
-  // when network detects a change.
-  void OnNetworkChanged(
-      net::NetworkChangeNotifier::ConnectionType type) override;
-
   // Records metrics on the number of SMB mounts a user has.
   void RecordMountCount() const;
 
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
index 46a8d26..5a329246 100644
--- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
@@ -134,6 +134,7 @@
   result.device_scale_factor = mode.device_scale_factor;
   result.refresh_rate = mode.refresh_rate;
   result.is_native = mode.is_native;
+  result.is_interlaced = mode.is_interlaced;
   return result;
 }
 
@@ -368,6 +369,7 @@
         api_display_mode.device_scale_factor;
     mojo_display_mode->refresh_rate = api_display_mode.refresh_rate;
     mojo_display_mode->is_native = api_display_mode.is_native;
+    mojo_display_mode->is_interlaced = api_display_mode.is_interlaced;
     config_properties->display_mode = std::move(mojo_display_mode);
   }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 91f5204..65e49bc 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2242,6 +2242,13 @@
     "expiry_milestone": 76
   },
   {
+    "name": "list-all-display-modes",
+    "owners": [ "//ui/display/OWNERS" ],
+    // This flag is used for debugging and development purposes to list all
+    // external displays' modes without any exclusions.'
+    "expiry_milestone": -1
+  },
+  {
     "name": "load-media-router-component-extension",
     // "owners": [ "your-team" ],
     "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index b9c388f..6c21514 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3310,6 +3310,10 @@
 const char kImeServiceDescription[] =
     "Enable IME service to provide the IME functionality instead of NaCl";
 
+const char kListAllDisplayModesName[] = "List all display modes";
+const char kListAllDisplayModesDescription[] =
+    "Enables listing all external displays' modes in the display settings.";
+
 const char kLockScreenNotificationName[] = "Lock screen notification";
 const char kLockScreenNotificationDescription[] =
     "Enable notifications on the lock screen.";
@@ -3520,6 +3524,12 @@
 const char kWakeOnPacketsDescription[] =
     "Enables waking the device based on the receipt of some network packets.";
 
+const char kEnableAppReinstallZeroStateName[] =
+    "Enable Zero State App Reinstall Suggestions.";
+const char kEnableAppReinstallZeroStateDescription[] =
+    "Enable Zero State App Reinstall Suggestions feature in launcher, which "
+    "will show app reinstall recommendations at end of zero state list.";
+
 #endif  // defined(OS_CHROMEOS)
 
 // Random platform combinations -----------------------------------------------
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index f4b277d..0a03528 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1981,6 +1981,9 @@
 extern const char kImeServiceName[];
 extern const char kImeServiceDescription[];
 
+extern const char kListAllDisplayModesName[];
+extern const char kListAllDisplayModesDescription[];
+
 extern const char kLockScreenNotificationName[];
 extern const char kLockScreenNotificationDescription[];
 
@@ -2105,6 +2108,9 @@
 extern const char kWakeOnPacketsName[];
 extern const char kWakeOnPacketsDescription[];
 
+extern const char kEnableAppReinstallZeroStateName[];
+extern const char kEnableAppReinstallZeroStateDescription[];
+
 #endif  // #if defined(OS_CHROMEOS)
 
 // Random platform combinations -----------------------------------------------
diff --git a/chrome/browser/google/google_brand_code_map_chromeos.cc b/chrome/browser/google/google_brand_code_map_chromeos.cc
index a5b7e0b1..68cd1ce1 100644
--- a/chrome/browser/google/google_brand_code_map_chromeos.cc
+++ b/chrome/browser/google/google_brand_code_map_chromeos.cc
@@ -21,21 +21,7 @@
   };
   static const base::NoDestructor<
       base::flat_map<std::string, BrandCodeValueEntry>>
-      kBrandCodeMap({{"NPEC", {"BMGD", "YETH", "XAWJ"}},
-                     {"VHUH", {"JYDF", "SFJY", "JMBU"}},
-                     {"FWVK", {"MUTD", "GWKK", "SQSC"}},
-                     {"HOMH", {"BXHI", "WXYD", "VRZY"}},
-                     {"BDIW", {"UDUG", "TRYQ", "PWFV"}},
-                     {"FQPJ", {"ZTQG", "ZNEO", "LYMZ"}},
-                     {"NOMD", {"GZLV", "UNZR", "FVOP"}},
-                     {"MCDN", {"BAOV", "GLVV", "XHGO"}},
-                     {"TKER", {"KOSM", "IUCL", "LIIM"}},
-                     {"PGQF", {"USPJ", "SFKO", "KNBH"}},
-                     {"GJZV", {"BUSA", "GIOS", "UYOM"}},
-                     {"FSGY", {"PJQC", "RHZW", "POVI"}},
-                     {"IHZG", {"MLLN", "EZTK", "GJEJ"}},
-                     {"PXDO", {"ZXCF", "TQWC", "HOAL"}},
-                     {"ACAC", {"CFZM", "BEUH", "GUTN"}},
+      kBrandCodeMap({{"ACAC", {"CFZM", "BEUH", "GUTN"}},
                      {"ACAG", {"KSOU", "MUHR", "YYJR"}},
                      {"ACAH", {"KEFG", "RYNH", "HHAZ"}},
                      {"ACAJ", {"KVPC", "UHAI", "CPNG"}},
@@ -47,31 +33,41 @@
                      {"ACAV", {"TTSD", "XTQQ", "TIQC"}},
                      {"ACAY", {"HKDC", "RYKK", "KSIY"}},
                      {"ACBA", {"TVZD", "HLQR", "DOWV"}},
-                     {"MNZG", {"PPTP", "OFXE", "ROJJ"}},
-                     {"CYQR", {"XGJJ", "DRMC", "RUQD"}},
+                     {"ADGK", {"PKUQ", "AEMI", "CUUL"}},
+                     {"ASCT", {"CTRF", "LBBD", "YBND"}},
                      {"ASUA", {"IEIT", "JAIV", "MURN"}},
                      {"ASUD", {"QLMM", "CRUA", "JSID"}},
                      {"ASUE", {"XLEN", "KECH", "HBGX"}},
                      {"ASUF", {"IVGE", "VNTM", "XELD"}},
                      {"ASUJ", {"HJUL", "XWWL", "WSCY"}},
                      {"ASUK", {"RGUX", "OXBQ", "LDTL"}},
+                     {"BAQN", {"YJJJ", "LDCA", "QSJF"}},
+                     {"BCOL", {"YJDV", "GSIC", "BAUL"}},
+                     {"BDIW", {"UDUG", "TRYQ", "PWFV"}},
+                     {"CYQR", {"XGJJ", "DRMC", "RUQD"}},
+                     {"CYSQ", {"NHHD", "TAVM", "FHSA"}},
                      {"DEAA", {"HXUG", "BJUN", "IYTV"}},
                      {"DEAC", {"DSMM", "IXET", "KQDV"}},
                      {"DEAF", {"TATK", "RWXF", "DQDT"}},
                      {"DEAG", {"JFEX", "CVLN", "UFWN"}},
                      {"DRYI", {"LWTQ", "OLEY", "NWUA"}},
-                     {"ZZAB", {"WVIK", "IUXK", "ZCIK"}},
-                     {"ZZAD", {"KSTH", "CBJY", "TSID"}},
-                     {"ZZAF", {"OTWH", "RRNB", "VNXA"}},
-                     {"XWJE", {"KDZI", "IYPJ", "ERIM"}},
-                     {"NBQS", {"KMJF", "MFWA", "UWRX"}},
-                     {"HPZY", {"RAWP", "CNRC", "TPIA"}},
-                     {"HPZV", {"WAFN", "PQVW", "MJVM"}},
-                     {"HPZT", {"IUCU", "WDAV", "LOLH"}},
-                     {"HPZS", {"QRFK", "SQGI", "VESI"}},
-                     {"HPZQ", {"XGER", "OLTF", "DVQA"}},
+                     {"FQPJ", {"ZTQG", "ZNEO", "LYMZ"}},
+                     {"FSFR", {"ZDAR", "BERM", "COKX"}},
+                     {"FSGY", {"PJQC", "RHZW", "POVI"}},
+                     {"FWVK", {"MUTD", "GWKK", "SQSC"}},
+                     {"GJZV", {"BUSA", "GIOS", "UYOM"}},
+                     {"HOMH", {"BXHI", "WXYD", "VRZY"}},
+                     {"HOWM", {"MJNG", "XPYN", "IRWY"}},
                      {"HPZP", {"NQDY", "QIMT", "QKAK"}},
+                     {"HPZQ", {"XGER", "OLTF", "DVQA"}},
+                     {"HPZS", {"QRFK", "SQGI", "VESI"}},
+                     {"HPZT", {"IUCU", "WDAV", "LOLH"}},
+                     {"HPZV", {"WAFN", "PQVW", "MJVM"}},
+                     {"HPZY", {"RAWP", "CNRC", "TPIA"}},
+                     {"IHZG", {"MLLN", "EZTK", "GJEJ"}},
                      {"JBPA", {"VUZL", "XYPI", "XOWE"}},
+                     {"JLRH", {"SAMJ", "GLJZ", "SKTN"}},
+                     {"LASN", {"ILWC", "BQYG", "RROZ"}},
                      {"LEAC", {"DMEA", "EXWD", "PBTU"}},
                      {"LEAE", {"QFVM", "GACH", "BMXB"}},
                      {"LEAG", {"XTLW", "WLQO", "QVKP"}},
@@ -81,20 +77,39 @@
                      {"LEAL", {"EYPX", "SOCH", "PFPW"}},
                      {"LEAO", {"MKOE", "YJSI", "QQMN"}},
                      {"LEAP", {"AEZG", "JOYE", "JHWK"}},
-                     {"ZFCZ", {"JQUA", "SEEH", "RJVV"}},
-                     {"VEUT", {"JDFA", "ALIR", "DDJM"}},
+                     {"MCDN", {"BAOV", "GLVV", "XHGO"}},
+                     {"MCOO", {"IPNW", "CRSK", "QTAX"}},
+                     {"MNZG", {"PPTP", "OFXE", "ROJJ"}},
+                     {"NBQS", {"KMJF", "MFWA", "UWRX"}},
+                     {"NOMD", {"GZLV", "UNZR", "FVOP"}},
+                     {"NPEC", {"BMGD", "YETH", "XAWJ"}},
+                     {"OFPE", {"YFOO", "UIGY", "PFGZ"}},
+                     {"PGQF", {"USPJ", "SFKO", "KNBH"}},
+                     {"PXDO", {"ZXCF", "TQWC", "HOAL"}},
+                     {"RVRM", {"MZJU", "IGXP", "DSJP"}},
                      {"SMAE", {"SUUV", "QXWL", "LYKX"}},
                      {"SMAF", {"HKPA", "NFCE", "UBOP"}},
                      {"SMAH", {"EXLB", "YYYY", "LLLA"}},
                      {"SMAI", {"PPDO", "ISMM", "BKNT"}},
                      {"SMAJ", {"PVCB", "UCIK", "XVBK"}},
                      {"SMAK", {"WOMZ", "OHAX", "JSTF"}},
-                     {"ZSKM", {"JPEZ", "FTUS", "ZFUF"}},
                      {"SMAL", {"OWLX", "YXSA", "TXJR"}},
                      {"TAAB", {"ZBMY", "NYDT", "CXYZ"}},
+                     {"TKER", {"KOSM", "IUCL", "LIIM"}},
+                     {"UGAY", {"YDHM", "HVCY", "ILHO"}},
+                     {"VEUT", {"JDFA", "ALIR", "DDJM"}},
+                     {"VHUH", {"JYDF", "SFJY", "JMBU"}},
+                     {"WBZQ", {"LAYK", "LQDM", "QBFV"}},
+                     {"XVYQ", {"UAVB", "OEMI", "VQVK"}},
+                     {"XWJE", {"KDZI", "IYPJ", "ERIM"}},
+                     {"YHYU", {"CDLM", "QDXQ", "HPTE"}},
                      {"YMMU", {"ZVIA", "CFKN", "ERLO"}},
-                     {"FSFR", {"ZDAR", "BERM", "COKX"}},
-                     {"ASCT", {"CTRF", "LBBD", "YBND"}}});
+                     {"ZDKS", {"UBRP", "AWQF", "GOVG"}},
+                     {"ZFCZ", {"JQUA", "SEEH", "RJVV"}},
+                     {"ZSKM", {"JPEZ", "FTUS", "ZFUF"}},
+                     {"ZZAB", {"WVIK", "IUXK", "ZCIK"}},
+                     {"ZZAD", {"KSTH", "CBJY", "TSID"}},
+                     {"ZZAF", {"OTWH", "RRNB", "VNXA"}}});
 
   const auto it = kBrandCodeMap->find(static_brand_code);
   if (it == kBrandCodeMap->end())
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.h b/chrome/browser/metrics/chrome_metrics_service_accessor.h
index dc53afbc..4e08bee 100644
--- a/chrome/browser/metrics/chrome_metrics_service_accessor.h
+++ b/chrome/browser/metrics/chrome_metrics_service_accessor.h
@@ -121,6 +121,8 @@
   friend class metrics::UkmConsentParamBrowserTest;
   FRIEND_TEST_ALL_PREFIXES(ChromeMetricsServiceAccessorTest,
                            MetricsReportingEnabled);
+  FRIEND_TEST_ALL_PREFIXES(ChromeMetricsServicesManagerClientTest,
+                           ForceTrialsDisablesReporting);
 
   // Returns true if metrics reporting is enabled. This does NOT necessary mean
   // that it is active as configuration may prevent it on some devices (i.e.
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
index c4a62565..e960bdb 100644
--- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/metrics/chrome_metrics_services_manager_client.h"
 
+#include <map>
+#include <string>
+
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
@@ -88,12 +91,24 @@
 
 // Only clients that were given an opt-out metrics-reporting consent flow are
 // eligible for sampling.
-bool IsClientEligibleForSampling() {
-  return metrics::GetMetricsReportingDefaultState(
-             g_browser_process->local_state()) ==
+bool IsClientEligibleForSampling(PrefService* local_state) {
+  return metrics::GetMetricsReportingDefaultState(local_state) ==
          metrics::EnableMetricsDefault::OPT_OUT;
 }
 
+// Implementation of IsClientInSample() that takes a PrefService param.
+bool IsClientInSampleImpl(PrefService* local_state) {
+  // Only some clients are eligible for sampling. Clients that aren't eligible
+  // will always be considered "in sample". In this case, we don't want the
+  // feature state queried, because we don't want the field trial that controls
+  // sampling to be reported as active.
+  if (!IsClientEligibleForSampling(local_state))
+    return true;
+
+  return base::FeatureList::IsEnabled(
+      metrics::internal::kMetricsReportingFeature);
+}
+
 #if defined(OS_CHROMEOS)
 // Callback to update the metrics reporting state when the Chrome OS metrics
 // reporting setting changes.
@@ -129,8 +144,8 @@
   }
 
   bool IsReportingEnabled() const override {
-    return IsConsentGiven() &&
-           ChromeMetricsServicesManagerClient::IsClientInSample();
+    return metrics::EnabledStateProvider::IsReportingEnabled() &&
+           IsClientInSampleImpl(local_state_);
   }
 
  private:
@@ -194,22 +209,14 @@
 
 // static
 bool ChromeMetricsServicesManagerClient::IsClientInSample() {
-  // Only some clients are eligible for sampling. Clients that aren't eligible
-  // will always be considered "in sample". In this case, we don't want the
-  // feature state queried, because we don't want the field trial that controls
-  // sampling to be reported as active.
-  if (!IsClientEligibleForSampling())
-    return true;
-
-  return base::FeatureList::IsEnabled(
-      metrics::internal::kMetricsReportingFeature);
+  return IsClientInSampleImpl(g_browser_process->local_state());
 }
 
 // static
 bool ChromeMetricsServicesManagerClient::GetSamplingRatePerMille(int* rate) {
   // The population that is NOT eligible for sampling in considered "in sample",
   // but does not have a defined sample rate.
-  if (!IsClientEligibleForSampling())
+  if (!IsClientEligibleForSampling(g_browser_process->local_state()))
     return false;
 
   std::string rate_str = variations::GetVariationParamValueByFeature(
@@ -233,6 +240,11 @@
 }
 #endif
 
+const metrics::EnabledStateProvider&
+ChromeMetricsServicesManagerClient::GetEnabledStateProviderForTesting() {
+  return *enabled_state_provider_;
+}
+
 std::unique_ptr<rappor::RapporServiceImpl>
 ChromeMetricsServicesManagerClient::CreateRapporServiceImpl() {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.h b/chrome/browser/metrics/chrome_metrics_services_manager_client.h
index 00e7fc9..e1d8f71 100644
--- a/chrome/browser/metrics/chrome_metrics_services_manager_client.h
+++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.h
@@ -64,6 +64,9 @@
   void OnCrosSettingsCreated();
 #endif
 
+  // Accessor for the EnabledStateProvider instance used by this object.
+  const metrics::EnabledStateProvider& GetEnabledStateProviderForTesting();
+
  private:
   // This is defined as a member class to get access to
   // ChromeMetricsServiceAccessor through ChromeMetricsServicesManagerClient's
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client_unittest.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client_unittest.cc
new file mode 100644
index 0000000..08b9fcb3
--- /dev/null
+++ b/chrome/browser/metrics/chrome_metrics_services_manager_client_unittest.cc
@@ -0,0 +1,69 @@
+// 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/metrics/chrome_metrics_services_manager_client.h"
+
+#include "base/base_switches.h"
+#include "base/command_line.h"
+#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
+#include "components/metrics/enabled_state_provider.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/metrics/metrics_reporting_default_state.h"
+#include "components/metrics/metrics_service_accessor.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(ChromeMetricsServicesManagerClientTest, ForceTrialsDisablesReporting) {
+  TestingPrefServiceSimple local_state;
+
+  metrics::RegisterMetricsReportingStatePrefs(local_state.registry());
+
+  // First, test with UMA reporting setting defaulting to off.
+  local_state.registry()->RegisterBooleanPref(
+      metrics::prefs::kMetricsReportingEnabled, false);
+  // Force the pref to be used, even in unofficial builds.
+  ChromeMetricsServiceAccessor::SetForceIsMetricsReportingEnabledPrefLookup(
+      true);
+
+  ChromeMetricsServicesManagerClient client(&local_state);
+  const metrics::EnabledStateProvider& provider =
+      client.GetEnabledStateProviderForTesting();
+  metrics_services_manager::MetricsServicesManagerClient* base_client = &client;
+
+  // The provider and client APIs should agree.
+  EXPECT_EQ(provider.IsConsentGiven(), base_client->IsMetricsConsentGiven());
+  EXPECT_EQ(provider.IsReportingEnabled(),
+            base_client->IsMetricsReportingEnabled());
+
+  // Both consent and reporting should be false.
+  EXPECT_FALSE(provider.IsConsentGiven());
+  EXPECT_FALSE(provider.IsReportingEnabled());
+
+  // Set the pref to true.
+  local_state.SetBoolean(metrics::prefs::kMetricsReportingEnabled, true);
+
+  // The provider and client APIs should agree.
+  EXPECT_EQ(provider.IsConsentGiven(), base_client->IsMetricsConsentGiven());
+  EXPECT_EQ(provider.IsReportingEnabled(),
+            base_client->IsMetricsReportingEnabled());
+
+  // Both consent and reporting should be true.
+  EXPECT_TRUE(provider.IsConsentGiven());
+  EXPECT_TRUE(provider.IsReportingEnabled());
+
+  // Set --force-fieldtrials= command-line flag, which should disable reporting
+  // but not consent.
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kForceFieldTrials, "Foo/Bar");
+
+  // The provider and client APIs should agree.
+  EXPECT_EQ(provider.IsConsentGiven(), base_client->IsMetricsConsentGiven());
+  EXPECT_EQ(provider.IsReportingEnabled(),
+            base_client->IsMetricsReportingEnabled());
+
+  // Consent should be true but reporting should be false.
+  EXPECT_TRUE(provider.IsConsentGiven());
+  EXPECT_FALSE(provider.IsReportingEnabled());
+}
diff --git a/chrome/browser/metrics/tab_stats_data_store.cc b/chrome/browser/metrics/tab_stats_data_store.cc
index e03182d..754dcd9 100644
--- a/chrome/browser/metrics/tab_stats_data_store.cc
+++ b/chrome/browser/metrics/tab_stats_data_store.cc
@@ -31,7 +31,11 @@
       total_tab_count_max(0U),
       max_tab_per_window(0U),
       window_count(0U),
-      window_count_max(0U) {}
+      window_count_max(0U) {
+  tab_discard_counts.fill(0U);
+  tab_reload_counts.fill(0U);
+}
+TabStatsDataStore::TabsStats::TabsStats(const TabsStats& other) = default;
 
 TabStatsDataStore::TabStatsDataStore(PrefService* pref_service)
     : pref_service_(pref_service) {
@@ -164,6 +168,20 @@
     AddTabToIntervalMap(iter.first, GetTabID(iter.first), true, interval_map);
 }
 
+void TabStatsDataStore::OnTabDiscardStateChange(
+    LifecycleUnitDiscardReason discard_reason,
+    bool is_discarding) {
+  if (is_discarding)
+    tab_stats_.tab_discard_counts[static_cast<size_t>(discard_reason)]++;
+  else
+    tab_stats_.tab_reload_counts[static_cast<size_t>(discard_reason)]++;
+}
+
+void TabStatsDataStore::ClearTabDiscardAndReloadCounts() {
+  tab_stats_.tab_discard_counts.fill(0U);
+  tab_stats_.tab_reload_counts.fill(0U);
+}
+
 base::Optional<TabStatsDataStore::TabID> TabStatsDataStore::GetTabIDForTesting(
     content::WebContents* web_contents) {
   if (!base::ContainsKey(existing_tabs_, web_contents))
diff --git a/chrome/browser/metrics/tab_stats_data_store.h b/chrome/browser/metrics/tab_stats_data_store.h
index 630dfd5..d04994c 100644
--- a/chrome/browser/metrics/tab_stats_data_store.h
+++ b/chrome/browser/metrics/tab_stats_data_store.h
@@ -12,6 +12,9 @@
 #include "base/gtest_prod_util.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit_state.mojom.h"
+
+using mojom::LifecycleUnitDiscardReason;
 
 class PrefService;
 
@@ -32,6 +35,7 @@
   struct TabsStats {
     // Constructor, initializes everything to zero.
     TabsStats();
+    TabsStats(const TabsStats& other);
 
     // The total number of tabs opened across all the windows.
     size_t total_tab_count;
@@ -49,6 +53,16 @@
 
     // The maximum total number of windows opened at the same time.
     size_t window_count_max;
+
+    // The number of tabs discarded, per discard reason.
+    std::array<size_t,
+               static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue) + 1>
+        tab_discard_counts;
+
+    // The number of tabs reloaded after a discard, per discard reason.
+    std::array<size_t,
+               static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue) + 1>
+        tab_reload_counts;
   };
 
   // Structure describing the state of a tab during an interval of time.
@@ -115,6 +129,14 @@
   // Reset |interval_map| with the list of current tabs.
   void ResetIntervalData(TabsStateDuringIntervalMap* interval_map);
 
+  // Updates counters when the discarded state of a tab changes.
+  void OnTabDiscardStateChange(LifecycleUnitDiscardReason discard_reason,
+                               bool is_discarding);
+
+  // Clears the discard and reload counters. Called after reporting the counter
+  // values.
+  void ClearTabDiscardAndReloadCounts();
+
   const TabsStats& tab_stats() const { return tab_stats_; }
 
   base::Optional<TabID> GetTabIDForTesting(content::WebContents* web_contents);
diff --git a/chrome/browser/metrics/tab_stats_tracker.cc b/chrome/browser/metrics/tab_stats_tracker.cc
index ce703f2..a7f7292 100644
--- a/chrome/browser/metrics/tab_stats_tracker.cc
+++ b/chrome/browser/metrics/tab_stats_tracker.cc
@@ -14,6 +14,9 @@
 #include "base/power_monitor/power_monitor.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit_observer.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -98,6 +101,20 @@
     TabStatsTracker::UmaStatsReportingDelegate::kWindowCountHistogramName[] =
         "Tabs.WindowCount";
 
+// Tab discard and reload histogram names in the same order as in discard reason
+// enum.
+const char* kTabDiscardCountHistogramNames[] = {
+    "Discarding.DiscardsPer10Minutes.Extension",
+    "Discarding.DiscardsPer10Minutes.Proactive",
+    "Discarding.DiscardsPer10Minutes.Urgent",
+};
+
+const char* kTabReloadCountHistogramNames[] = {
+    "Discarding.ReloadsPer10Minutes.Extension",
+    "Discarding.ReloadsPer10Minutes.Proactive",
+    "Discarding.ReloadsPer10Minutes.Urgent",
+};
+
 const TabStatsDataStore::TabsStats& TabStatsTracker::tab_stats() const {
   return tab_stats_data_store_->tab_stats();
 }
@@ -162,6 +179,14 @@
   heartbeat_timer_.Start(FROM_HERE, kTabsHeartbeatReportingInterval,
                          base::BindRepeating(&TabStatsTracker::OnHeartbeatEvent,
                                              base::Unretained(this)));
+
+  // Report discarding stats every 10 minutes.
+  tab_discard_reload_stats_timer_.Start(
+      FROM_HERE, base::TimeDelta::FromMinutes(10),
+      base::BindRepeating(&TabStatsTracker::OnTabDiscardCountReportInterval,
+                          base::Unretained(this)));
+
+  g_browser_process->GetTabManager()->AddObserver(this);
 }
 
 TabStatsTracker::~TabStatsTracker() {
@@ -303,6 +328,19 @@
       tab_stats_data_store_->tab_stats().total_tab_count);
 }
 
+// resource_coordinator::TabLifecycleObserver:
+void TabStatsTracker::OnDiscardedStateChange(
+    content::WebContents* contents,
+    mojom::LifecycleUnitDiscardReason reason,
+    bool is_discarded) {
+  // Increment the count in the data store for tabs metrics reporting.
+  tab_stats_data_store_->OnTabDiscardStateChange(reason, is_discarded);
+}
+
+void TabStatsTracker::OnAutoDiscardableStateChange(
+    content::WebContents* contents,
+    bool is_auto_discardable) {}
+
 void TabStatsTracker::OnInterval(
     base::TimeDelta interval,
     TabStatsDataStore::TabsStateDuringIntervalMap* interval_map) {
@@ -313,6 +351,20 @@
   tab_stats_data_store_->ResetIntervalData(interval_map);
 }
 
+void TabStatsTracker::OnTabDiscardCountReportInterval() {
+  for (size_t reason = 0;
+       reason < static_cast<size_t>(LifecycleUnitDiscardReason::kMaxValue);
+       reason++) {
+    base::UmaHistogramCounts100(
+        kTabDiscardCountHistogramNames[reason],
+        tab_stats_data_store_->tab_stats().tab_discard_counts[reason]);
+    base::UmaHistogramCounts100(
+        kTabReloadCountHistogramNames[reason],
+        tab_stats_data_store_->tab_stats().tab_reload_counts[reason]);
+  }
+  tab_stats_data_store_->ClearTabDiscardAndReloadCounts();
+}
+
 void TabStatsTracker::OnInitialOrInsertedTab(
     content::WebContents* web_contents) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chrome/browser/metrics/tab_stats_tracker.h b/chrome/browser/metrics/tab_stats_tracker.h
index 4b6ac337..9ac83fe7 100644
--- a/chrome/browser/metrics/tab_stats_tracker.h
+++ b/chrome/browser/metrics/tab_stats_tracker.h
@@ -20,6 +20,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/metrics/tab_stats_data_store.h"
 #include "chrome/browser/metrics/tab_stats_tracker_delegate.h"
+#include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "components/metrics/daily_event.h"
@@ -41,7 +42,8 @@
 //         std::make_unique<TabStatsTracker>(g_browser_process->local_state()));
 class TabStatsTracker : public TabStripModelObserver,
                         public BrowserListObserver,
-                        public base::PowerObserver {
+                        public base::PowerObserver,
+                        public resource_coordinator::TabLifecycleObserver {
  public:
   // Constructor. |pref_service| must outlive this object.
   explicit TabStatsTracker(PrefService* pref_service);
@@ -147,6 +149,14 @@
   // base::PowerObserver:
   void OnResume() override;
 
+  // resource_coordinator::TabLifecycleObserver:
+  void OnDiscardedStateChange(content::WebContents* contents,
+                              mojom::LifecycleUnitDiscardReason reason,
+                              bool is_discarded) override;
+
+  void OnAutoDiscardableStateChange(content::WebContents* contents,
+                                    bool is_auto_discardable) override;
+
   // Callback when an interval timer triggers.
   void OnInterval(base::TimeDelta interval,
                   TabStatsDataStore::TabsStateDuringIntervalMap* interval_map);
@@ -203,10 +213,17 @@
   // The timer used to report the heartbeat metrics at regular interval.
   base::RepeatingTimer heartbeat_timer_;
 
+  // The timer used to report tab discard and reload count histograms at regular
+  // interval.
+  base::RepeatingTimer tab_discard_reload_stats_timer_;
+
   // The observers that track how the tabs are used.
   std::map<content::WebContents*, std::unique_ptr<WebContentsUsageObserver>>
       web_contents_usage_observers_;
 
+  // Called at regular time intervals to report tab discard count histograms.
+  void OnTabDiscardCountReportInterval();
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(TabStatsTracker);
diff --git a/chrome/browser/page_load_metrics/observers/previews_lite_page_redirect_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/previews_lite_page_redirect_metrics_observer.cc
index 4921582e..fd890fcf 100644
--- a/chrome/browser/page_load_metrics/observers/previews_lite_page_redirect_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/previews_lite_page_redirect_metrics_observer.cc
@@ -36,7 +36,7 @@
 
   previews::PreviewsUserData::ServerLitePageInfo* info =
       previews_data->server_lite_page_info();
-  if (!info)
+  if (!info || info->status == previews::ServerLitePageStatus::kUnknown)
     return STOP_OBSERVING;
 
   // Past this point, we know this navigation is a preview or at least attempted
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 20b54f7..9c06e58 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -726,6 +726,9 @@
   { key::kVoiceInteractionContextEnabled,
     arc::prefs::kVoiceInteractionContextEnabled,
     base::Value::Type::BOOLEAN },
+  { key::kVoiceInteractionHotwordEnabled,
+    arc::prefs::kVoiceInteractionHotwordEnabled,
+    base::Value::Type::BOOLEAN },
 #endif  // defined(OS_CHROMEOS)
 
 // Metrics reporting is controlled by a platform specific policy for ChromeOS
@@ -987,6 +990,12 @@
   { key::kBrowserSwitcherUseIeSitelist,
     browser_switcher::prefs::kUseIeSitelist,
     base::Value::Type::BOOLEAN },
+  { key::kBrowserSwitcherChromePath,
+    browser_switcher::prefs::kChromePath,
+    base::Value::Type::STRING },
+  { key::kBrowserSwitcherChromeParameters,
+    browser_switcher::prefs::kChromeParameters,
+    base::Value::Type::LIST },
 #endif
 };
 // clang-format on
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index ef66f50..ea5eaddf 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -71,7 +71,6 @@
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
 #include "chrome/browser/io_thread.h"
-#include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
 #include "chrome/browser/media/webrtc/webrtc_event_log_manager.h"
@@ -103,8 +102,6 @@
 #include "chrome/browser/ui/search/instant_test_utils.h"
 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
-#include "chrome/browser/ui/toolbar/media_router_action_controller.h"
 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
 #include "chrome/browser/usb/usb_chooser_context.h"
 #include "chrome/browser/usb/usb_chooser_context_factory.h"
@@ -307,6 +304,7 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
+#include "chrome/browser/ui/toolbar/media_router_action_controller.h"
 #endif
 
 using content::BrowserThread;
@@ -5197,17 +5195,6 @@
                  std::make_unique<base::Value>(enable), nullptr);
     provider_.UpdateChromePolicy(policies);
   }
-
- protected:
-  bool HasMediaRouterActionAtInit() const {
-    const std::set<std::string>& component_ids =
-        ToolbarActionsModel::Get(browser()->profile())
-            ->component_actions_factory()
-            ->GetInitialComponentIds();
-
-    return base::ContainsKey(
-        component_ids, ComponentToolbarActionsFactory::kMediaRouterActionId);
-  }
 };
 
 using MediaRouterActionEnabledPolicyTest = MediaRouterActionPolicyTest<true>;
@@ -5217,14 +5204,12 @@
                        MediaRouterActionEnabled) {
   EXPECT_TRUE(
       MediaRouterActionController::IsActionShownByPolicy(browser()->profile()));
-  EXPECT_TRUE(HasMediaRouterActionAtInit());
 }
 
 IN_PROC_BROWSER_TEST_F(MediaRouterActionDisabledPolicyTest,
                        MediaRouterActionDisabled) {
   EXPECT_FALSE(
       MediaRouterActionController::IsActionShownByPolicy(browser()->profile()));
-  EXPECT_FALSE(HasMediaRouterActionAtInit());
 }
 
 class MediaRouterCastAllowAllIPsPolicyTest
diff --git a/chrome/browser/previews/previews_content_util.cc b/chrome/browser/previews/previews_content_util.cc
index b9c6d61..c32e254 100644
--- a/chrome/browser/previews/previews_content_util.cc
+++ b/chrome/browser/previews/previews_content_util.cc
@@ -171,7 +171,7 @@
   // the Lite Page mechanism should redirect to the original URL. Either way,
   // set the allowed PreviewsState.
   if (IsLitePageRedirectPreviewURL(url)) {
-    return previews_state = content::LITE_PAGE_REDIRECT_ON;
+    return content::LITE_PAGE_REDIRECT_ON;
   }
 
   // Record whether the hint cache has a matching entry for this pre-commit URL.
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc
index 06d205e..372bcfc 100644
--- a/chrome/browser/previews/previews_lite_page_browsertest.cc
+++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -765,8 +765,9 @@
 #define DISABLE_ON_WIN_MAC(x) x
 #endif
 
+// TODO(crbug.com/934955): Failing on Linux trybots.
 IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
-                       DISABLE_ON_WIN_MAC(LitePagePreviewsTriggering)) {
+                       DISABLED_LitePagePreviewsTriggering) {
   // TODO(crbug.com/874150): Use ExpectUniqueSample in these tests.
   // The histograms in these tests can only be checked by the expected bucket,
   // and not by a unique sample. This is because each navigation to a preview
@@ -1024,9 +1025,9 @@
   VerifyPreviewNotLoaded();
 }
 
-IN_PROC_BROWSER_TEST_P(
-    PreviewsLitePageServerBrowserTest,
-    DISABLE_ON_WIN_MAC(ReloadingLitePagesDisablesLitePages)) {
+// TODO(crbug.com/934955): Failing on Linux trybots.
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
+                       DISABLED_ReloadingLitePagesDisablesLitePages) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       {previews::features::kPreviewsReloadsAreSoftOptOuts}, {});
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc
index b1f8c77..e5b9afe 100644
--- a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc
+++ b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/command_line.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/optional.h"
@@ -36,6 +37,7 @@
 #include "components/content_settings/core/common/cookie_settings_base.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/previews/core/previews_experiments.h"
 #include "components/previews/core/previews_lite_page_redirect.h"
 #include "content/public/browser/browser_context.h"
@@ -320,6 +322,14 @@
   DCHECK(original_url.is_valid());
   std::string experiment_id =
       previews::params::LitePageRedirectPreviewExperiment();
+
+  // Allow the command line to override any variations-provided experiment.
+  std::string cmd_line_experiment =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          data_reduction_proxy::switches::kDataReductionProxyExperiment);
+  if (!cmd_line_experiment.empty())
+    experiment_id = cmd_line_experiment;
+
   std::string experiment_query;
   if (!experiment_id.empty()) {
     experiment_query =
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc
index ab29a66d..0413784f 100644
--- a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc
+++ b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
@@ -13,6 +14,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "chrome/browser/previews/previews_lite_page_decider.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/previews/core/previews_features.h"
 #include "content/public/browser/navigation_handle.h"
 #include "net/http/http_util.h"
@@ -24,7 +26,8 @@
     std::string previews_host;
     std::string original_url;
     std::string expected_previews_url;
-    std::string experiment;
+    std::string experiment_variation;
+    std::string experiment_cmd_line;
   };
   const TestCase kTestCases[]{
       // Use https://play.golang.org/p/HUM2HxmUTOW to compute
@@ -36,6 +39,7 @@
           "previews.host.com/p?u="
           "https%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes",
           "",
+          "",
       },
       {
           "https://previews.host.com",
@@ -52,6 +56,7 @@
           "previews.host.com/p?u=https%3A%2F%2Foriginal.host.com%3A1443"
           "%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes",
           "",
+          "",
       },
       {
           "https://previews.host.com:1443",
@@ -60,6 +65,7 @@
           "previews.host.com:1443/p?u="
           "http%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes",
           "",
+          "",
       },
       {
           "https://previews.host.com:1443",
@@ -68,6 +74,7 @@
           "previews.host.com:1443/p?u=https%3A%2F%2Foriginal.host.com%3A1443"
           "%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes",
           "",
+          "",
       },
       {
           "https://previews.host.com",
@@ -77,6 +84,7 @@
           "https%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes"
           "#fragment",
           "",
+          "",
       },
       {
           "https://previews.host.com",
@@ -84,8 +92,21 @@
           "https://shta44dh4bi7rc6fnpjnkrtytwlabygjhk53v2trlot2wddylwua."
           "previews.host.com/p?u="
           "https%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes"
-          "&x=enable_HTCPCP",
-          "enable_HTCPCP",
+          "&x=variation_experiment",
+          "variation_experiment",
+          "",
+      },
+      {
+          // Ensure that the command line experiment takes precedence over the
+          // one provided by variations.
+          "https://previews.host.com",
+          "https://original.host.com/path/path/path?query=yes",
+          "https://shta44dh4bi7rc6fnpjnkrtytwlabygjhk53v2trlot2wddylwua."
+          "previews.host.com/p?u="
+          "https%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes"
+          "&x=cmdline_experiment",
+          "variation_experiment",
+          "cmdline_experiment",
       },
       {
           "https://previews.host.com",
@@ -93,15 +114,20 @@
           "https://2ikmbopbfxagkb7uer2vgfxmbzu2vw4qq3d3ixe3h2hfhgcabvua."
           "previews.host.com/p?u=https%3A%2F%2F%5B%3A%3A1%5D%3A12345%2F",
           "",
+          "",
       },
   };
 
   for (const TestCase& test_case : kTestCases) {
+    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+        data_reduction_proxy::switches::kDataReductionProxyExperiment,
+        test_case.experiment_cmd_line);
+
     base::test::ScopedFeatureList scoped_feature_list;
     scoped_feature_list.InitAndEnableFeatureWithParameters(
         previews::features::kLitePageServerPreviews,
         {{"previews_host", test_case.previews_host},
-         {"lite_page_preview_experiment", test_case.experiment}});
+         {"lite_page_preview_experiment", test_case.experiment_variation}});
 
     EXPECT_EQ(PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(
                   GURL(test_case.original_url)),
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
index 474ef8b..5ec9898 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
@@ -11,6 +11,10 @@
   padding-bottom: 36px;
 }
 
+#no-dsp-message {
+  padding-top: 16px;
+}
+
 #footer-text {
   color: #757575;
 }
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
index 132adc7..2d9e93c5 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -16,7 +16,11 @@
           <img id="logo" src="assistant_logo.png">
           <div id="intro-container">
             <div class="title" i18n-content="assistantVoiceMatchTitle"></div>
-            <div class="content" i18n-content="assistantVoiceMatchMessage">
+            <div class="content"
+                i18n-values=".innerHTML:assistantVoiceMatchMessage">
+            </div>
+            <div class="content" id="no-dsp-message"
+                i18n-content="assistantVoiceMatchNoDspMessage">
             </div>
             <div id="voice-match-video">
               <video muted autoplay loop>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js
index b3f3e75..6294491 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.js
@@ -102,5 +102,8 @@
    */
   onShow: function() {
     this.$['agree-button'].focus();
+    if (loadTimeData.getBoolean('hotwordDspAvailable')) {
+      this.$['no-dsp-message'].hidden = true;
+    }
   },
 });
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
index a31c0238..c1101e85 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -451,7 +451,8 @@
           $restriction $description`
     },
     image: {
-      speak: `$if($name, $name, $urlFilename)
+      speak: `$if($name, $name,
+          $if($imageAnnotation, $imageAnnotation, $urlFilename))
           $value $state $role $description`,
     },
     inlineTextBox: {speak: `$name=`},
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js
index 7528b6f7..bf4f491d 100644
--- a/chrome/browser/resources/settings/device_page/display.js
+++ b/chrome/browser/resources/settings/device_page/display.js
@@ -136,6 +136,14 @@
     },
 
     /** @private */
+    listAllDisplayModes_: {
+      type: Boolean,
+      value: function() {
+        return loadTimeData.getBoolean('listAllDisplayModes');
+      }
+    },
+
+    /** @private */
     unifiedDesktopMode_: {
       type: Boolean,
       value: false,
@@ -359,12 +367,20 @@
    */
   getDisplayModeOptionList_: function(selectedDisplay) {
     const optionList = [];
+
+    const listAllModes = this.listAllDisplayModes_;
+
     for (let i = 0; i < selectedDisplay.modes.length; ++i) {
+      const mode = selectedDisplay.modes[i];
+
+      const id = listAllModes && mode.isInterlaced ?
+          'displayResolutionInterlacedMenuItem' :
+          'displayResolutionMenuItem';
+      const refreshRate = Math.round(mode.refreshRate * 100) / 100;
       const option = this.i18n(
-          'displayResolutionMenuItem',
-          selectedDisplay.modes[i].width.toString(),
-          selectedDisplay.modes[i].height.toString(),
-          Math.round(selectedDisplay.modes[i].refreshRate).toString());
+          id, mode.width.toString(), mode.height.toString(),
+          refreshRate.toString());
+
       optionList.push({
         name: option,
         value: i,
@@ -505,7 +521,11 @@
    * @private
    */
   showDisplaySelectMenu_: function(displays, selectedDisplay) {
-    return displays.length > 1 && !selectedDisplay.isPrimary;
+    if (selectedDisplay) {
+      return displays.length > 1 && !selectedDisplay.isPrimary;
+    }
+
+    return false;
   },
 
   /**
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
index e53fa505..494ebd9e 100644
--- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
+++ b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
@@ -1,10 +1,12 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/html/md_select_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
 <link rel="import" href="google_assistant_browser_proxy.html">
+<link rel="import" href="../controls/controlled_button.html">
 <link rel="import" href="../controls/settings_toggle_button.html">
 <link rel="import" href="../i18n_setup.html">
 <link rel="import" href="../prefs/prefs.html">
@@ -22,6 +24,20 @@
       select.md-select {
         min-width: 200px;
       }
+
+      /**
+       * This style is copied from the settings_dropdown_menu.
+       * We don't use the settings_dropdown_menu for the
+       * dspHotwordState drop down (see below), because the
+       * dspHotwordState manages 2 preferences. The
+       * settings_dropdown_menu is designed to manage only a
+       * single preference.
+       */
+      cr-policy-pref-indicator {
+        height: 24px;
+        order: 0;
+        width: 24px;
+      }
     </style>
     <settings-toggle-button id="googleAssistantEnable"
         class="first primary-toggle"
@@ -56,9 +72,17 @@
               $i18n{googleAssistantEnableHotwordDescription}
             </div>
           </div>
+          <template is="dom-if"
+              if="[[prefs.settings.voice_interaction.enabled.controllerBy]]"
+              restamp>
+            <cr-policy-pref-indicator
+                pref="{{prefs.settings.voice_interaction.hotword.enabled}}">
+            </cr-policy-pref-indicator>
+          </template>
           <select id="dspHotwordState" class="md-select"
               aria-labelledby="googleAssistantEnableHotword"
-              on-change="onDspHotwordStateChange_">
+              on-change="onDspHotwordStateChange_"
+              disabled="[[hotwordDisabled_]]">
             <template is="dom-repeat" items="[[hotwordDropdownList_]]">
               <option value="[[item.value]]"
                   selected="[[isDspHotwordStateMatch_(item.value)]]">
@@ -77,10 +101,11 @@
                 $i18n{googleAssistantVoiceSettingsDescription}
               </div>
             </div>
-            <paper-button id="button" class="secondary-button"
-                on-click="onRetrainVoiceModelTapped_">
-              $i18n{googleAssistantVoiceSettingsRetrainButton}
-            </paper-button>
+            <controlled-button id="button" class="secondary-button"
+                on-click="onRetrainVoiceModelTapped_"
+                label="$i18n{googleAssistantVoiceSettingsRetrainButton}"
+                pref="{{prefs.settings.voice_interaction.hotword.enabled}}">
+            </controlled-button>
           </div>
         </template>
         <settings-toggle-button id="googleAssistantNotificationEnable"
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
index 1866b23..5d7886e8 100644
--- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
+++ b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
@@ -13,6 +13,28 @@
 };
 
 /**
+ * Indicates user's activity control consent status.
+ *
+ * Note: This should be kept in sync with ash::mojom::ConsentStatus in
+ * ash/public/interfaces/voice_interaction_controller.mojom
+ * @enum {number}
+ */
+const ConsentStatus = {
+  // The status is unknown.
+  kUnknown: 0,
+
+  // The user accepted activity control access.
+  kActivityControlAccepted: 1,
+
+  // The user is not authorized to give consent.
+  kUnauthorized: 2,
+
+  // The user's consent information is not found. This is typically the case
+  // when consent from the user has never been requested.
+  kNotFound: 3,
+};
+
+/**
  * @fileoverview 'settings-google-assistant-page' is the settings page
  * containing Google Assistant settings.
  */
@@ -83,6 +105,8 @@
   observers: [
     'onPrefsChanged_(prefs.settings.voice_interaction.hotword.enabled.value)',
     'onPrefsChanged_(prefs.settings.voice_interaction.hotword.always_on.value)',
+    `onPrefsChanged_(
+      prefs.settings.voice_interaction.activity_control.consent_status.value)`,
   ],
 
   /** @private {?settings.GoogleAssistantBrowserProxy} */
@@ -153,8 +177,9 @@
     this.shouldShowVoiceMatchSettings_ =
         loadTimeData.getBoolean('voiceMatchEnabled') &&
         this.getPref('settings.voice_interaction.hotword.enabled.value') &&
-        this.getPref(
-            'settings.voice_interaction.activity_control.accepted.value');
+        (this.getPref(
+          'settings.voice_interaction.activity_control.consent_status.value') ==
+            ConsentStatus.kActivityControlAccepted);
   },
 
   /** @private */
@@ -174,5 +199,14 @@
     if (this.$$('#dspHotwordState')) {
       this.$$('#dspHotwordState').value = this.dspHotwordState_;
     }
-  }
+  },
+
+  /** @private */
+  hotwordDisabled_: function() {
+    const hotwordPref =
+        this.getPref('prefs.settings.voice_interaction.hotword.enabled');
+
+    return !!hotwordPref &&
+        hotwordPref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED;
+  },
 });
diff --git a/chrome/browser/safe_browsing/advanced_protection_status_manager.cc b/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
index 17bb8779..6be6fef 100644
--- a/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
+++ b/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
@@ -56,11 +56,11 @@
 
 void AdvancedProtectionStatusManager::MaybeRefreshOnStartUp() {
   // Retrieves advanced protection service status from primary account's info.
-  AccountInfo info = identity_manager_->GetPrimaryAccountInfo();
-  if (info.account_id.empty())
+  CoreAccountInfo core_info = identity_manager_->GetPrimaryAccountInfo();
+  if (core_info.account_id.empty())
     return;
 
-  is_under_advanced_protection_ = info.is_under_advanced_protection;
+  is_under_advanced_protection_ = core_info.is_under_advanced_protection;
 
   if (profile_->GetPrefs()->HasPrefPath(
           prefs::kAdvancedProtectionLastRefreshInUs)) {
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
index a0d4408..1435ad47 100644
--- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
+++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -152,9 +152,15 @@
   if (item->GetState() == download::DownloadItem::COMPLETE) {
     // Download completed. Send report.
     MaybeSendApkDownloadReport(item);
+    // No longer interested in this |DownloadItem| since the report has been
+    // sent so remove the observer.
+    item->RemoveObserver(this);
   } else if (item->GetState() == download::DownloadItem::CANCELLED) {
     RecordApkDownloadTelemetryOutcome(
         ApkDownloadTelemetryOutcome::NOT_SENT_DOWNLOAD_CANCELLED);
+    // No longer interested in this |DownloadItem| since the download did not
+    // complete so remove the observer.
+    item->RemoveObserver(this);
   }
 }
 
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc
index cf3b5bf..f77ead0 100644
--- a/chrome/browser/site_details_browsertest.cc
+++ b/chrome/browser/site_details_browsertest.cc
@@ -1047,8 +1047,10 @@
 
 // Verifies that the UMA counter for SiteInstances in a BrowsingInstance is
 // correct when using tabs with web pages.
+//
+// Disabled since it's flaky. https://crbug.com/934900
 IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest,
-                       VerifySiteInstanceCountInBrowsingInstance) {
+                       DISABLED_VerifySiteInstanceCountInBrowsingInstance) {
   // Page with 14 nested oopifs across 9 sites (a.com through i.com).
   GURL abcdefghi_url = embedded_test_server()->GetURL(
       "a.com",
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 14efc2ca..bdac18b 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -104,7 +104,7 @@
 
   // String to check for when parsing theme manifests or NULL if this isn't
   // supposed to be changeable by the user.
-  const char* key;
+  const char* const key;
 };
 
 // IDR_* resource names change whenever new resources are added; use persistent
@@ -215,7 +215,7 @@
 }
 
 struct StringToIntTable {
-  const char* key;
+  const char* const key;
   TP::OverwritableByUserThemeProperty id;
 };
 
@@ -608,93 +608,53 @@
 }
 
 // static
+void BrowserThemePack::BuildFromColor(SkColor color, BrowserThemePack* pack) {
+  DCHECK(!pack->is_valid());
+
+  pack->InitEmptyPack();
+
+  // Init |source_images_| only here as other code paths initialize it
+  // differently.
+  pack->InitSourceImages();
+
+  // TODO(gayane): Implement complementary color generation logic.
+  SkColor complementary_color = color;
+
+  pack->SetColor(TP::COLOR_FRAME, color);
+  pack->SetColor(TP::COLOR_TOOLBAR, complementary_color);
+  pack->SetColor(TP::COLOR_NTP_BACKGROUND, complementary_color);
+
+  pack->AdjustThemePack();
+
+  // The BrowserThemePack is now in a consistent state.
+  pack->is_valid_ = true;
+}
+
+// static
 void BrowserThemePack::BuildFromExtension(
     const extensions::Extension* extension,
-    scoped_refptr<BrowserThemePack> pack) {
+    BrowserThemePack* pack) {
   DCHECK(extension);
   DCHECK(extension->is_theme());
   DCHECK(!pack->is_valid());
 
-  pack->BuildHeader(extension);
-  pack->BuildTintsFromJSON(extensions::ThemeInfo::GetTints(extension));
-  pack->BuildColorsFromJSON(extensions::ThemeInfo::GetColors(extension));
-  pack->BuildDisplayPropertiesFromJSON(
+  pack->InitEmptyPack();
+  pack->SetHeaderId(extension);
+  pack->SetTintsFromJSON(extensions::ThemeInfo::GetTints(extension));
+  pack->SetColorsFromJSON(extensions::ThemeInfo::GetColors(extension));
+  pack->SetDisplayPropertiesFromJSON(
       extensions::ThemeInfo::GetDisplayProperties(extension));
 
   // Builds the images. (Image building is dependent on tints).
   FilePathMap file_paths;
-  pack->ParseImageNamesFromJSON(
-      extensions::ThemeInfo::GetImages(extension),
-      extension->path(),
-      &file_paths);
+  pack->ParseImageNamesFromJSON(extensions::ThemeInfo::GetImages(extension),
+                                extension->path(), &file_paths);
   pack->BuildSourceImagesArray(file_paths);
 
   if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_))
     return;
 
-  pack->CropImages(&pack->images_);
-
-  // Set toolbar related elements' colors (e.g. status bubble, info bar,
-  // download shelf, detached bookmark bar) to toolbar color.
-  pack->SetToolbarRelatedColors();
-
-  // Create toolbar image, and generate toolbar color from image where relevant.
-  // This must be done after reading colors from JSON (so they can be used for
-  // compositing the image).
-  pack->CreateToolbarImageAndColors(&pack->images_);
-
-  // Create frame images, and generate frame colors from images where relevant.
-  // This must be done after reading colors from JSON (so they can be used for
-  // compositing the image).
-  pack->CreateFrameImagesAndColors(&pack->images_);
-
-  // Generate any missing frame colors.  This must be done after generating
-  // colors from the frame images, so only colors with no matching images are
-  // generated.
-  pack->GenerateFrameColors();
-
-  // Generate background color information for window control buttons.  This
-  // must be done after frame colors are set, since they are used when
-  // determining window control button colors.
-  pack->GenerateWindowControlButtonColor(&pack->images_);
-
-  // Create the tab background images, and generate colors where relevant.  This
-  // must be done after all frame colors are set, since they are used when
-  // creating these.
-  pack->CreateTabBackgroundImagesAndColors(&pack->images_);
-
-  // Generate any missing text colors.  This must be done after generating frame
-  // and tab colors, as generated text colors will try to appropriately contrast
-  // with the frame/tab behind them.
-  pack->GenerateMissingTextColors();
-
-  // Make sure the |images_on_file_thread_| has bitmaps for supported
-  // scale factors before passing to FILE thread.
-  pack->images_on_file_thread_ = pack->images_;
-  for (auto it = pack->images_on_file_thread_.begin();
-       it != pack->images_on_file_thread_.end(); ++it) {
-    gfx::ImageSkia* image_skia =
-        const_cast<gfx::ImageSkia*>(it->second.ToImageSkia());
-    image_skia->MakeThreadSafe();
-  }
-
-  // Set ThemeImageSource on |images_| to resample the source
-  // image if a caller of BrowserThemePack::GetImageNamed() requests an
-  // ImageSkiaRep for a scale factor not specified by the theme author.
-  // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve
-  // ImageSkiaReps for all supported scale factors.
-  for (auto it = pack->images_.begin(); it != pack->images_.end(); ++it) {
-    const gfx::ImageSkia source_image_skia = it->second.AsImageSkia();
-    auto source = std::make_unique<ThemeImageSource>(source_image_skia);
-    gfx::ImageSkia image_skia(std::move(source), source_image_skia.size());
-    it->second = gfx::Image(image_skia);
-  }
-
-  // Generate raw images (for new-tab-page attribution and background) for
-  // any missing scale from an available scale image.
-  for (size_t i = 0; i < base::size(kPreloadIDs); ++i) {
-    pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]);
-  }
+  pack->AdjustThemePack();
 
   // The BrowserThemePack is now in a consistent state.
   pack->is_valid_ = true;
@@ -707,7 +667,10 @@
   // Allow IO on UI thread due to deep-seated theme design issues.
   // (see http://crbug.com/80206)
   base::ThreadRestrictions::ScopedAllowIO allow_io;
-  scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
+
+  // For now data pack can only have extension type.
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(ThemeType::EXTENSION));
   // Scale factor parameter is moot as data pack has image resources for all
   // supported scale factors.
   pack->data_pack_.reset(
@@ -778,7 +741,8 @@
   return false;
 }
 
-BrowserThemePack::BrowserThemePack() : CustomThemeSupplier(EXTENSION) {
+BrowserThemePack::BrowserThemePack(ThemeType theme_type)
+    : CustomThemeSupplier(theme_type) {
   scale_factors_ = ui::GetSupportedScaleFactors();
   // On Windows HiDPI SCALE_FACTOR_100P may not be supported by default.
   if (!base::ContainsValue(scale_factors_, ui::SCALE_FACTOR_100P))
@@ -802,11 +766,11 @@
 
   int source_count = 1;
   int* end = source_images_;
-  for (; *end != -1 ; end++)
+  for (; *end != -1; end++)
     source_count++;
-  resources[kSourceImagesID] = base::StringPiece(
-      reinterpret_cast<const char*>(source_images_),
-      source_count * sizeof(*source_images_));
+  resources[kSourceImagesID] =
+      base::StringPiece(reinterpret_cast<const char*>(source_images_),
+                        source_count * sizeof(*source_images_));
 
   // Store results of GetScaleFactorsAsString() in std::string as
   // base::StringPiece does not copy data in constructor.
@@ -951,7 +915,82 @@
 
 // private:
 
-void BrowserThemePack::BuildHeader(const Extension* extension) {
+void BrowserThemePack::AdjustThemePack() {
+  CropImages(&images_);
+
+  // Set toolbar related elements' colors (e.g. status bubble, info bar,
+  // download shelf, detached bookmark bar) to toolbar color.
+  SetToolbarRelatedColors();
+
+  // Create toolbar image, and generate toolbar color from image where relevant.
+  // This must be done after reading colors from JSON (so they can be used for
+  // compositing the image).
+  CreateToolbarImageAndColors(&images_);
+
+  // Create frame images, and generate frame colors from images where relevant.
+  // This must be done after reading colors from JSON (so they can be used for
+  // compositing the image).
+  CreateFrameImagesAndColors(&images_);
+
+  // Generate any missing frame colors.  This must be done after generating
+  // colors from the frame images, so only colors with no matching images are
+  // generated.
+  GenerateFrameColors();
+
+  // Generate background color information for window control buttons.  This
+  // must be done after frame colors are set, since they are used when
+  // determining window control button colors.
+  GenerateWindowControlButtonColor(&images_);
+
+  // Create the tab background images, and generate colors where relevant.  This
+  // must be done after all frame colors are set, since they are used when
+  // creating these.
+  CreateTabBackgroundImagesAndColors(&images_);
+
+  // Generate any missing text colors.  This must be done after generating frame
+  // and tab colors, as generated text colors will try to appropriately contrast
+  // with the frame/tab behind them.
+  GenerateMissingTextColors();
+
+  // Make sure the |images_on_file_thread_| has bitmaps for supported
+  // scale factors before passing to FILE thread.
+  images_on_file_thread_ = images_;
+  for (auto& image : images_on_file_thread_) {
+    gfx::ImageSkia* image_skia =
+        const_cast<gfx::ImageSkia*>(image.second.ToImageSkia());
+    image_skia->MakeThreadSafe();
+  }
+
+  // Set ThemeImageSource on |images_| to resample the source
+  // image if a caller of BrowserThemePack::GetImageNamed() requests an
+  // ImageSkiaRep for a scale factor not specified by the theme author.
+  // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve
+  // ImageSkiaReps for all supported scale factors.
+  for (auto& image : images_) {
+    const gfx::ImageSkia source_image_skia = image.second.AsImageSkia();
+    auto source = std::make_unique<ThemeImageSource>(source_image_skia);
+    gfx::ImageSkia image_skia(std::move(source), source_image_skia.size());
+    image.second = gfx::Image(image_skia);
+  }
+
+  // Generate raw images (for new-tab-page attribution and background) for
+  // any missing scale from an available scale image.
+  for (size_t i = 0; i < base::size(kPreloadIDs); ++i) {
+    GenerateRawImageForAllSupportedScales(kPreloadIDs[i]);
+  }
+}
+
+void BrowserThemePack::InitEmptyPack() {
+  InitHeader();
+
+  InitTints();
+
+  InitColors();
+
+  InitDisplayProperties();
+}
+
+void BrowserThemePack::InitHeader() {
   header_ = new BrowserThemePackHeader;
   header_->version = kThemePackVersion;
 
@@ -966,13 +1005,9 @@
 #error DataPack assumes little endian
 #endif
   header_->little_endian = 1;
-
-  const std::string& id = extension->id();
-  memcpy(header_->theme_id, id.c_str(), crx_file::id_util::kIdSize);
 }
 
-void BrowserThemePack::BuildTintsFromJSON(
-    const base::DictionaryValue* tints_value) {
+void BrowserThemePack::InitTints() {
   tints_ = new TintEntry[kTintTableLength];
   for (size_t i = 0; i < kTintTableLength; ++i) {
     tints_[i].id = -1;
@@ -980,6 +1015,40 @@
     tints_[i].s = -1;
     tints_[i].l = -1;
   }
+}
+
+void BrowserThemePack::InitColors() {
+  colors_ = new ColorPair[kColorsArrayLength];
+  for (size_t i = 0; i < kColorsArrayLength; ++i) {
+    colors_[i].id = -1;
+    colors_[i].color = SkColorSetRGB(0, 0, 0);
+  }
+}
+
+void BrowserThemePack::InitDisplayProperties() {
+  display_properties_ = new DisplayPropertyPair[kDisplayPropertiesSize];
+  for (size_t i = 0; i < kDisplayPropertiesSize; ++i) {
+    display_properties_[i].id = -1;
+    display_properties_[i].property = 0;
+  }
+  display_properties_[0].id = TP::NTP_LOGO_ALTERNATE;
+  display_properties_[0].property = 1;
+}
+
+void BrowserThemePack::InitSourceImages() {
+  source_images_ = new int[1];
+  source_images_[0] = -1;
+}
+
+void BrowserThemePack::SetHeaderId(const Extension* extension) {
+  DCHECK(header_);
+  const std::string& id = extension->id();
+  memcpy(header_->theme_id, id.c_str(), crx_file::id_util::kIdSize);
+}
+
+void BrowserThemePack::SetTintsFromJSON(
+    const base::DictionaryValue* tints_value) {
+  DCHECK(tints_);
 
   if (!tints_value)
     return;
@@ -1018,13 +1087,9 @@
   }
 }
 
-void BrowserThemePack::BuildColorsFromJSON(
+void BrowserThemePack::SetColorsFromJSON(
     const base::DictionaryValue* colors_value) {
-  colors_ = new ColorPair[kColorsArrayLength];
-  for (size_t i = 0; i < kColorsArrayLength; ++i) {
-    colors_[i].id = -1;
-    colors_[i].color = SkColorSetRGB(0, 0, 0);
-  }
+  DCHECK(colors_);
 
   std::map<int, SkColor> temp_colors;
   if (colors_value)
@@ -1087,13 +1152,9 @@
   }
 }
 
-void BrowserThemePack::BuildDisplayPropertiesFromJSON(
+void BrowserThemePack::SetDisplayPropertiesFromJSON(
     const base::DictionaryValue* display_properties_value) {
-  display_properties_ = new DisplayPropertyPair[kDisplayPropertiesSize];
-  for (size_t i = 0; i < kDisplayPropertiesSize; ++i) {
-    display_properties_[i].id = -1;
-    display_properties_[i].property = 0;
-  }
+  DCHECK(display_properties_);
 
   if (!display_properties_value)
     return;
diff --git a/chrome/browser/themes/browser_theme_pack.h b/chrome/browser/themes/browser_theme_pack.h
index 3131d6c..ac02240 100644
--- a/chrome/browser/themes/browser_theme_pack.h
+++ b/chrome/browser/themes/browser_theme_pack.h
@@ -58,7 +58,10 @@
   // separate thread as it takes so long. This can fail in the case where the
   // theme has invalid data, in which case |pack->is_valid()| will be false.
   static void BuildFromExtension(const extensions::Extension* extension,
-                                 scoped_refptr<BrowserThemePack> pack);
+                                 BrowserThemePack* pack);
+
+  // Builds the theme from given |color| into |pack|.
+  static void BuildFromColor(SkColor color, BrowserThemePack* pack);
 
   // Builds the theme pack from a previously performed WriteToDisk(). This
   // operation should be relatively fast, as it should be an mmap() and some
@@ -71,7 +74,7 @@
   static bool IsPersistentImageID(int id);
 
   // Default. Everything is empty.
-  BrowserThemePack();
+  explicit BrowserThemePack(ThemeType theme_type);
 
   bool is_valid() const { return is_valid_; }
 
@@ -124,24 +127,44 @@
   // Calculates the dominant color of the top |height| rows of |image|.
   SkColor ComputeImageColor(const gfx::Image& image, int height);
 
-  // Builds a header ready to write to disk.
-  void BuildHeader(const extensions::Extension* extension);
+  // Adjusts/sets theme properties.
+  void AdjustThemePack();
+
+  // Initializes necessary fields.
+  void InitEmptyPack();
+
+  // Initializes the |header_| with default values.
+  void InitHeader();
+
+  // Initializes the |tints_| with default values.
+  void InitTints();
+
+  // Initializes the |colors_| with default values.
+  void InitColors();
+
+  // Initializes the |display_properties_| with default values.
+  void InitDisplayProperties();
+
+  // Initializes the |source_images_| with default values.
+  void InitSourceImages();
+
+  // Sets the ID from |extension|.
+  void SetHeaderId(const extensions::Extension* extension);
 
   // Transforms the JSON tint values into their final versions in the |tints_|
   // array.
-  void BuildTintsFromJSON(const base::DictionaryValue* tints_value);
+  void SetTintsFromJSON(const base::DictionaryValue* tints_value);
 
   // Transforms the JSON color values into their final versions in the
   // |colors_| array and also fills in unspecified colors based on tint values.
-  void BuildColorsFromJSON(const base::DictionaryValue* color_value);
+  void SetColorsFromJSON(const base::DictionaryValue* color_value);
 
   // Implementation details of BuildColorsFromJSON().
   void ReadColorsFromJSON(const base::DictionaryValue* colors_value,
                           std::map<int, SkColor>* temp_colors);
 
   // Transforms the JSON display properties into |display_properties_|.
-  void BuildDisplayPropertiesFromJSON(
-      const base::DictionaryValue* display_value);
+  void SetDisplayPropertiesFromJSON(const base::DictionaryValue* display_value);
 
   // Parses the image names out of an extension.
   void ParseImageNamesFromJSON(const base::DictionaryValue* images_value,
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc
index add3cbe..766cf41f 100644
--- a/chrome/browser/themes/browser_theme_pack_unittest.cc
+++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -63,13 +63,13 @@
   // This function returns void in order to be able use ASSERT_...
   // The BrowserThemePack is returned in |pack|.
   static void BuildFromUnpackedExtension(const base::FilePath& extension_path,
-                                         scoped_refptr<BrowserThemePack>* pack);
+                                         BrowserThemePack* pack);
 
   // Builds the theme represented by an unpacked extension (located in
   // {DIR_TEST_DATA}/extensions/|theme_folder|).
   // The BrowserThemePack is returned in |pack|.
   static void BuildTestExtensionTheme(const base::StringPiece theme_folder,
-                                      scoped_refptr<BrowserThemePack>* pack);
+                                      BrowserThemePack* pack);
 
   static base::FilePath GetTestExtensionThemePath(
       base::StringPiece theme_folder);
@@ -113,12 +113,14 @@
 };
 
 BrowserThemePackTest::BrowserThemePackTest()
-    : theme_pack_(new BrowserThemePack()) {
+    : theme_pack_(
+          new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION)) {
   std::vector<ui::ScaleFactor> scale_factors;
   scale_factors.push_back(ui::SCALE_FACTOR_100P);
   scale_factors.push_back(ui::SCALE_FACTOR_200P);
   scoped_set_supported_scale_factors_.reset(
       new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
+  theme_pack_->InitEmptyPack();
 }
 
 // static
@@ -158,7 +160,7 @@
 }
 
 void BrowserThemePackTest::LoadColorDictionary(base::DictionaryValue* value) {
-  theme_pack_->BuildColorsFromJSON(value);
+  theme_pack_->SetColorsFromJSON(value);
   theme_pack_->GenerateFrameColors();
 }
 
@@ -169,7 +171,7 @@
 }
 
 void BrowserThemePackTest::LoadTintDictionary(base::DictionaryValue* value) {
-  theme_pack_->BuildTintsFromJSON(value);
+  theme_pack_->SetTintsFromJSON(value);
 }
 
 void BrowserThemePackTest::LoadDisplayPropertiesJSON(const std::string& json) {
@@ -181,7 +183,7 @@
 
 void BrowserThemePackTest::LoadDisplayPropertiesDictionary(
     base::DictionaryValue* value) {
-  theme_pack_->BuildDisplayPropertiesFromJSON(value);
+  theme_pack_->SetDisplayPropertiesFromJSON(value);
 }
 
 void BrowserThemePackTest::ParseImageNamesJSON(
@@ -210,7 +212,7 @@
 // static
 void BrowserThemePackTest::BuildFromUnpackedExtension(
     const base::FilePath& extension_path,
-    scoped_refptr<BrowserThemePack>* pack) {
+    BrowserThemePack* pack) {
   base::FilePath manifest_path = extension_path.AppendASCII("manifest.json");
   std::string error;
   JSONFileValueDeserializer deserializer(manifest_path);
@@ -223,15 +225,14 @@
                         *valid_value, Extension::REQUIRE_KEY, &error));
   ASSERT_TRUE(extension.get());
   ASSERT_EQ("", error);
-  *pack = new BrowserThemePack;
-  BrowserThemePack::BuildFromExtension(extension.get(), *pack);
-  ASSERT_TRUE((*pack)->is_valid());
+  BrowserThemePack::BuildFromExtension(extension.get(), pack);
+  ASSERT_TRUE(pack->is_valid());
 }
 
 // static
 void BrowserThemePackTest::BuildTestExtensionTheme(
     const base::StringPiece theme_folder,
-    scoped_refptr<BrowserThemePack>* pack) {
+    BrowserThemePack* pack) {
   base::FilePath contrast_theme_path = GetTestExtensionThemePath(theme_folder);
   BuildFromUnpackedExtension(contrast_theme_path, pack);
 }
@@ -712,8 +713,9 @@
   // Part 1: Build the pack from an extension.
   {
     base::FilePath star_gazing_path = GetStarGazingPath();
-    scoped_refptr<BrowserThemePack> pack;
-    BuildFromUnpackedExtension(star_gazing_path, &pack);
+    scoped_refptr<BrowserThemePack> pack(
+        new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+    BuildFromUnpackedExtension(star_gazing_path, pack.get());
     ASSERT_TRUE(pack->WriteToDisk(file));
     VerifyStarGazing(pack.get());
   }
@@ -736,8 +738,9 @@
   // Part 1: Build the pack from an extension.
   {
     base::FilePath hidpi_path = GetHiDpiThemePath();
-    scoped_refptr<BrowserThemePack> pack;
-    BuildFromUnpackedExtension(hidpi_path, &pack);
+    scoped_refptr<BrowserThemePack> pack(
+        new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+    BuildFromUnpackedExtension(hidpi_path, pack.get());
     ASSERT_TRUE(pack->WriteToDisk(file));
     VerifyHiDpiTheme(pack.get());
   }
@@ -755,8 +758,9 @@
 // are too similar, the importing process modifies the text color so that it
 // maintains a minimum readable contrast ratio with the background.
 TEST_F(BrowserThemePackTest, TestBackgroundTabTextMinimumContrast) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_tabcontrast", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_tabcontrast", pack.get());
 
   // Check the contrast ratio of text/tab color pairs to make sure that they
   // meet the minimum criteria for readable contrast ratio.
@@ -797,8 +801,9 @@
   // (theme_test_bgtabtext_notabcolor_singletextcolor).
   base::FilePath theme_path = GetTestExtensionThemePath(
       "theme_test_bgtabtext_notabcolor_singletextcolor");
-  scoped_refptr<BrowserThemePack> pack;
-  BuildFromUnpackedExtension(theme_path, &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildFromUnpackedExtension(theme_path, pack.get());
 
   SkColor frame_color;
   SkColor text_color;
@@ -815,17 +820,18 @@
 // COLOR_BACKGROUND_TAB_TEXT, that color is used for the other variants of
 // background tab text (inactive, incognito, and incognito+inactive).
 TEST_F(BrowserThemePackTest, TestBGTabTextColorAutoAssign) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_testinherittextcolor", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_testinherittextcolor", pack.get());
 
   // Verify that all background tab text colors match the color for background
   // tab text.
-  BrowserThemePack* pack_ptr = pack.get();
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
+  VerifyColorsMatch(pack.get(), TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO,
+  VerifyColorsMatch(pack.get(), TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
+  VerifyColorsMatch(pack.get(),
+                    TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
 }
 
@@ -833,16 +839,17 @@
 // COLOR_BACKGROUND_TAB_TEXT and COLOR_BACKGROUND_TAB_TEXT_INCOGNITO, those
 // colors are also used for their respective inactive variants.
 TEST_F(BrowserThemePackTest, TestBGTabTextColorAutoAssign_WithIncognito) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_testinherittextcolor_withincog", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_testinherittextcolor_withincog", pack.get());
 
   // Verify that background_inactive is getting its color from background, and
   // background_incognito_inactive is getting its color from
   // background_incognito.
-  BrowserThemePack* pack_ptr = pack.get();
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
+  VerifyColorsMatch(pack.get(), TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
+  VerifyColorsMatch(pack.get(),
+                    TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO);
 }
 
@@ -857,17 +864,18 @@
   // no tab background colors, and no variants of background_tab_text.
   base::FilePath theme_path = GetTestExtensionThemePath(
       "theme_test_bgtabtext_notabcolor_singletextcolor_autoassign");
-  scoped_refptr<BrowserThemePack> pack;
-  BuildFromUnpackedExtension(theme_path, &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildFromUnpackedExtension(theme_path, pack.get());
 
   // Verify that all background tab text colors match the color for background
   // tab text.
-  BrowserThemePack* pack_ptr = pack.get();
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
+  VerifyColorsMatch(pack.get(), TP::COLOR_BACKGROUND_TAB_TEXT_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO,
+  VerifyColorsMatch(pack.get(), TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
-  VerifyColorsMatch(pack_ptr, TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
+  VerifyColorsMatch(pack.get(),
+                    TP::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE,
                     TP::COLOR_BACKGROUND_TAB_TEXT);
 }
 
@@ -880,8 +888,9 @@
   // nearly zero.
   base::FilePath theme_path =
       GetTestExtensionThemePath("theme_test_bgtabtext_tintonly");
-  scoped_refptr<BrowserThemePack> pack;
-  BuildFromUnpackedExtension(theme_path, &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildFromUnpackedExtension(theme_path, pack.get());
 
   SkColor frame_color;
   SkColor text_color;
@@ -901,21 +910,22 @@
 // Ensure that, given a theme which only specifies a frame color, the calculated
 // caption button background colors appropriately match the frame color.
 TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_FrameColor) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_captionbutton_framecolor", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_captionbutton_framecolor", pack.get());
 
   // Verify that control button background colors are matching the frame colors.
-  BrowserThemePack* pack_ptr = pack.get();
-  VerifyColorsMatch(pack_ptr, TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_ACTIVE,
+  VerifyColorsMatch(pack.get(),
+                    TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_ACTIVE,
                     TP::COLOR_FRAME);
-  VerifyColorsMatch(pack_ptr,
+  VerifyColorsMatch(pack.get(),
                     TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE,
                     TP::COLOR_FRAME_INACTIVE);
-  VerifyColorsMatch(pack_ptr,
+  VerifyColorsMatch(pack.get(),
                     TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE,
                     TP::COLOR_FRAME_INCOGNITO);
   VerifyColorsMatch(
-      pack_ptr, TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE,
+      pack.get(), TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE,
       TP::COLOR_FRAME_INCOGNITO_INACTIVE);
 }
 
@@ -923,8 +933,9 @@
 // calculated caption button background colors appropriately match the button
 // background color blended with the frame color.
 TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_ButtonBGColor) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_captionbutton_buttoncolor", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_captionbutton_buttoncolor", pack.get());
 
   SkColor button_bg_color;
   const bool has_button_bg_color =
@@ -970,8 +981,9 @@
 // caption button image, the calculated caption button background color is dark
 // (to match the bg image).
 TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_ButtonBGImage) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_captionbutton_buttonimage", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_captionbutton_buttonimage", pack.get());
 
   // Verify that all of the calculated button background colors are on the
   // 'dark' end of the spectrum.
@@ -993,8 +1005,10 @@
 // Ensure that a specified 'toolbar' color is propagated to other 'bar' and
 // 'shelf' colors (before a new color is computed from the toolbar image).
 TEST_F(BrowserThemePackTest, TestToolbarColorPropagation) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors",
+                          pack.get());
 
   SkColor infobar_color;
   SkColor bookmark_bar_color;
@@ -1017,8 +1031,9 @@
 // Ensure that a specified 'toolbar' color is propagated to other 'bar' and
 // 'shelf' colors (before a new color is computed from the toolbar image).
 TEST_F(BrowserThemePackTest, TestToolbarColorPropagationNoImage) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_toolbar_color_no_image", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_toolbar_color_no_image", pack.get());
 
   SkColor infobar_color;
   SkColor bookmark_bar_color;
@@ -1043,8 +1058,10 @@
 // color).
 TEST_F(BrowserThemePackTest,
        TestToolbarColorComputedFromImageOverridesInputColor) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors",
+                          pack.get());
 
   SkColor toolbar_color;
   EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color));
@@ -1058,8 +1075,10 @@
 // color).
 TEST_F(BrowserThemePackTest,
        TestFrameColorComputedFromImageOverridesInputColor) {
-  scoped_refptr<BrowserThemePack> pack;
-  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors", &pack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+  BuildTestExtensionTheme("theme_test_toolbar_frame_images_and_colors",
+                          pack.get());
 
   SkColor frame_color;
   EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME, &frame_color));
@@ -1067,3 +1086,18 @@
   constexpr SkColor kExplicitColor = SkColorSetRGB(255, 0, 255);
   EXPECT_NE(frame_color, kExplicitColor);
 }
+
+// Test theme generation for a given color.
+TEST_F(BrowserThemePackTest, TestBuildFromColor) {
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::AUTOGENERATED));
+  SkColor color = SkColorSetRGB(100, 100, 200);
+  BrowserThemePack::BuildFromColor(color, pack.get());
+
+  SkColor frame_color;
+  EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME, &frame_color));
+  EXPECT_EQ(frame_color, color);
+
+  EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &frame_color));
+  EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_BACKGROUND, &frame_color));
+}
diff --git a/chrome/browser/themes/custom_theme_supplier.h b/chrome/browser/themes/custom_theme_supplier.h
index d6cd02e5..ff6612a 100644
--- a/chrome/browser/themes/custom_theme_supplier.h
+++ b/chrome/browser/themes/custom_theme_supplier.h
@@ -35,6 +35,7 @@
     NATIVE_X11,
     SUPERVISED_USER_THEME,
     INCREASED_CONTRAST,
+    AUTOGENERATED,
   };
 
   explicit CustomThemeSupplier(ThemeType type);
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index 857a57c..9ee0917 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -15,6 +15,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
@@ -79,6 +80,9 @@
 // unpacked on the filesystem.)
 const char kDefaultThemeGalleryID[] = "hkacjpbfdknhflllbcmjibkdeoafencn";
 
+// Theme ID to use for autogenerated themes.
+const char kAutogeneratedThemeID[] = "autogenerated";
+
 // Wait this many seconds after startup to garbage collect unused themes.
 // Removing unused themes is done after a delay because there is no
 // reason to do it at startup.
@@ -330,6 +334,20 @@
                  content::Source<Profile>(profile_));
 
   theme_syncable_service_.reset(new ThemeSyncableService(profile_, this));
+
+  // TODO(gayane): Temporary entry point for Chrome Colors. Remove once UI is
+  // there.
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch("chrome-colors-r") &&
+      command_line->HasSwitch("chrome-colors-g") &&
+      command_line->HasSwitch("chrome-colors-b")) {
+    int r, g, b;
+    base::StringToInt(command_line->GetSwitchValueASCII("chrome-colors-r"), &r);
+    base::StringToInt(command_line->GetSwitchValueASCII("chrome-colors-g"), &g);
+    base::StringToInt(command_line->GetSwitchValueASCII("chrome-colors-b"), &b);
+    BuildFromColor(SkColorSetRGB(r, g, b));
+  }
 }
 
 void ThemeService::Shutdown() {
@@ -861,9 +879,10 @@
     // Theme migration is done on the UI thread. Blocking the UI from appearing
     // until it's ready is deemed better than showing a blip of the default
     // theme.
-    scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
-    BrowserThemePack::BuildFromExtension(extension, pack);
-    OnThemeBuiltFromExtension(extension->id(), pack, true);
+    scoped_refptr<BrowserThemePack> pack(
+        new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
+    BrowserThemePack::BuildFromExtension(extension, pack.get());
+    OnThemeBuiltFromExtension(extension->id(), pack.get(), true);
     base::RecordAction(UserMetricsAction("Themes.Migrated"));
   } else {
     DLOG(ERROR) << "Theme is mysteriously gone.";
@@ -894,18 +913,28 @@
                                       bool suppress_infobar) {
   build_extension_task_tracker_.TryCancelAll();
   building_extension_id_ = extension->id();
-  scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::EXTENSION));
   auto task_runner = base::CreateTaskRunnerWithTraits(
       {base::MayBlock(), base::TaskPriority::USER_BLOCKING});
   build_extension_task_tracker_.PostTaskAndReply(
       task_runner.get(), FROM_HERE,
       base::Bind(&BrowserThemePack::BuildFromExtension,
-                 base::RetainedRef(extension), pack),
+                 base::RetainedRef(extension), base::RetainedRef(pack.get())),
       base::Bind(&ThemeService::OnThemeBuiltFromExtension,
                  weak_ptr_factory_.GetWeakPtr(), extension->id(), pack,
                  suppress_infobar));
 }
 
+void ThemeService::BuildFromColor(SkColor color) {
+  scoped_refptr<BrowserThemePack> pack(
+      new BrowserThemePack(CustomThemeSupplier::ThemeType::AUTOGENERATED));
+  BrowserThemePack::BuildFromColor(color, pack.get());
+  SwapThemeSupplier(pack);
+  if (theme_supplier_)
+    SaveThemeID(kAutogeneratedThemeID);
+}
+
 void ThemeService::OnThemeBuiltFromExtension(
     const extensions::ExtensionId& extension_id,
     scoped_refptr<BrowserThemePack> pack,
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h
index be72f7bd..93358a8 100644
--- a/chrome/browser/themes/theme_service.h
+++ b/chrome/browser/themes/theme_service.h
@@ -267,6 +267,9 @@
   void BuildFromExtension(const extensions::Extension* extension,
                           bool new_theme);
 
+  // Builds a theme from a given |color|.
+  void BuildFromColor(SkColor color);
+
   // Callback when |pack| has finished or failed building.
   void OnThemeBuiltFromExtension(const extensions::ExtensionId& extension_id,
                                  scoped_refptr<BrowserThemePack> pack,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 938eee5..91a02a3 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1054,8 +1054,6 @@
       "toolbar/component_action_delegate.h",
       "toolbar/component_toolbar_actions_factory.cc",
       "toolbar/component_toolbar_actions_factory.h",
-      "toolbar/media_router_action.cc",
-      "toolbar/media_router_action.h",
       "toolbar/media_router_action_controller.cc",
       "toolbar/media_router_action_controller.h",
       "toolbar/media_router_contextual_menu.cc",
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
index c3a91c24..b16b080 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h"
 
 #include <memory>
+#include <string>
 #include <utility>
 
 #include "ash/public/cpp/app_list/app_list_features.h"
@@ -14,6 +15,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h"
+#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service_manager.h"
 
@@ -54,10 +56,19 @@
           weak_ptr_factory_.GetWeakPtr()));
 }
 
+void ArcAppShortcutsSearchProvider::Train(const std::string& id,
+                                          RankingItemType type) {
+  if (type == RankingItemType::kArcAppShortcut && ranker_ != nullptr)
+    ranker_->Train(id);
+}
+
 void ArcAppShortcutsSearchProvider::OnGetAppShortcutGlobalQueryItems(
     std::vector<arc::mojom::AppShortcutItemPtr> shortcut_items) {
   const ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile_);
   DCHECK(arc_prefs);
+  base::flat_map<std::string, float> ranker_scores;
+  if (app_list_features::IsAppSearchResultRankerEnabled() && ranker_ != nullptr)
+    ranker_scores = ranker_->Rank();
 
   SearchProvider::Results search_results;
   for (auto& item : shortcut_items) {
@@ -68,16 +79,16 @@
     // Ignore shortcuts for apps that are not present in the launcher.
     if (!app_info || !app_info->show_in_launcher)
       continue;
-    search_results.emplace_back(std::make_unique<ArcAppShortcutSearchResult>(
-        std::move(item), profile_, list_controller_));
-
-    if (app_list_features::IsAppSearchResultRankerEnabled() &&
-        ranker_ != nullptr) {
-      // TODO(crbug.com/931149): tweak the scores of each search result item
-      // using the ranker.
-    }
+    auto result = std::make_unique<ArcAppShortcutSearchResult>(
+        std::move(item), profile_, list_controller_);
+    // TODO(crbug.com/931149): update the formula for relevance scores.
+    // This formula should be updated in the same way as query-based
+    // app search results
+    const auto find_in_ranker = ranker_scores.find(result->id());
+    if (find_in_ranker != ranker_scores.end())
+      result->set_relevance(result->relevance() + find_in_ranker->second / 10);
+    search_results.emplace_back(std::move(result));
   }
-
   SwapResults(&search_results);
 }
 
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h
index af537a6..8b3b3914 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_ARC_ARC_APP_SHORTCUTS_SEARCH_PROVIDER_H_
 #define CHROME_BROWSER_UI_APP_LIST_SEARCH_ARC_ARC_APP_SHORTCUTS_SEARCH_PROVIDER_H_
 
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -30,6 +31,7 @@
 
   // SearchProvider:
   void Start(const base::string16& query) override;
+  void Train(const std::string& id, RankingItemType type) override;
 
  private:
   void OnGetAppShortcutGlobalQueryItems(
@@ -38,8 +40,6 @@
   const int max_results_;
   Profile* const profile_;                            // Owned by ProfileInfo.
   AppListControllerDelegate* const list_controller_;  // Owned by AppListClient.
-  // TODO(crbug.com/931149): train this ranker on app shortcut clicks, and use
-  // it to tweak their relevance scores.
   AppSearchResultRanker* ranker_;
 
   base::WeakPtrFactory<ArcAppShortcutsSearchProvider> weak_ptr_factory_;
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
index da831c6..25ed7e5 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h"
+#include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -109,6 +110,31 @@
               base::UTF16ToUTF8(results[i]->title()));
     EXPECT_EQ(ash::SearchResultDisplayType::kTile, results[i]->display_type());
   }
+
+  // If ranker_ is nullptr, the program won't break
+  // TODO(crbug.com/931149): Add more tests to check ranker_ does have some
+  // effects
+  auto provider_null_ranker = std::make_unique<ArcAppShortcutsSearchProvider>(
+      kMaxResults, profile(), controller_.get(), nullptr);
+
+  EXPECT_TRUE(provider_null_ranker->results().empty());
+  arc::IconDecodeRequest::DisableSafeDecodingForTesting();
+
+  provider_null_ranker->Start(base::UTF8ToUTF16(kQuery));
+  provider_null_ranker->Train(
+      AddArcAppAndShortcut(
+          CreateAppInfo("FakeName", "FakeActivity", kFakeAppPackageName),
+          launchable),
+      RankingItemType::kArcAppShortcut);
+  const auto& results_null_ranker = provider_null_ranker->results();
+  EXPECT_EQ(kMaxResults, results_null_ranker.size());
+  // Verify search results.
+  for (size_t i = 0; i < results_null_ranker.size(); ++i) {
+    EXPECT_EQ(base::StringPrintf("ShortLabel %zu", i),
+              base::UTF16ToUTF8(results_null_ranker[i]->title()));
+    EXPECT_EQ(ash::SearchResultDisplayType::kTile,
+              results_null_ranker[i]->display_type());
+  }
 }
 
 INSTANTIATE_TEST_SUITE_P(, ArcAppShortcutsSearchProviderTest, testing::Bool());
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc
index 6f3b25b..28f50ac2 100644
--- a/chrome/browser/ui/app_list/search/mixer.cc
+++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -122,9 +122,9 @@
     for (auto& result : results) {
       RankingItemType type = RankingItemTypeFromSearchResult(*result.result);
       const auto& rank_it = ranks.find(std::to_string(static_cast<int>(type)));
-      // The ranker only contains entries trained with types
-      // |RankingItemType::kFile| and |RankingItemType::kOmnibox|. This means
-      // scores for apps and answer cards will be unchanged.
+      // The ranker only contains entries trained with types relating to files
+      // or the omnibox. This means scores for apps, app shortcuts, and answer
+      // cards will be unchanged.
       if (rank_it != ranks.end())
         // Ranker scores are guaranteed to be in [0,1]. But, enforce that the
         // result of tweaking does not put the score above 3.0, as that may
@@ -189,7 +189,12 @@
   if (!ranker_)
     return;
 
-  if (type == RankingItemType::kFile || type == RankingItemType::kOmnibox) {
+  if (type == RankingItemType::kFile ||
+      type == RankingItemType::kOmniboxGeneric ||
+      type == RankingItemType::kOmniboxBookmark ||
+      type == RankingItemType::kOmniboxDocument ||
+      type == RankingItemType::kOmniboxHistory ||
+      type == RankingItemType::kOmniboxSearch) {
     ranker_->Record(std::to_string(static_cast<int>(type)));
   }
 }
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc
index 89aee7b..42ced60 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.cc
@@ -4,23 +4,75 @@
 
 #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 
+#include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "base/macros.h"
+#include "base/metrics/field_trial_params.h"
 #include "chrome/browser/ui/app_list/chrome_app_list_item.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
+#include "components/omnibox/browser/autocomplete_match_type.h"
 
 namespace app_list {
 
 using SearchResultType = ash::SearchResultType;
 
+// Given a |ChromeSearchResult| representing an omnibox result, convert it based
+// on the subtype specified by |ChromeSearchResult::GetSubType|. Any
+// unanticipated subtypes are converted into |RankingItemType::kOmniboxGeneric|.
+RankingItemType ExpandOmniboxType(const ChromeSearchResult& result) {
+  if (result.result_type() != SearchResultType::kOmnibox) {
+    NOTREACHED();
+    return RankingItemType::kUnknown;
+  }
+
+  switch (static_cast<AutocompleteMatchType::Type>(result.GetSubType())) {
+    case AutocompleteMatchType::Type::HISTORY_URL:
+    case AutocompleteMatchType::Type::HISTORY_TITLE:
+    case AutocompleteMatchType::Type::HISTORY_BODY:
+    case AutocompleteMatchType::Type::HISTORY_KEYWORD:
+      return RankingItemType::kOmniboxHistory;
+    case AutocompleteMatchType::Type::NAVSUGGEST:
+    case AutocompleteMatchType::Type::NAVSUGGEST_PERSONALIZED:
+      return RankingItemType::kOmniboxNavSuggest;
+    case AutocompleteMatchType::Type::SEARCH_HISTORY:
+    case AutocompleteMatchType::Type::SEARCH_SUGGEST:
+    case AutocompleteMatchType::Type::SEARCH_SUGGEST_ENTITY:
+    case AutocompleteMatchType::Type::SEARCH_SUGGEST_TAIL:
+    case AutocompleteMatchType::Type::SEARCH_SUGGEST_PERSONALIZED:
+    case AutocompleteMatchType::Type::SEARCH_SUGGEST_PROFILE:
+    case AutocompleteMatchType::Type::SEARCH_OTHER_ENGINE:
+      return RankingItemType::kOmniboxSearch;
+    case AutocompleteMatchType::Type::BOOKMARK_TITLE:
+      return RankingItemType::kOmniboxBookmark;
+    case AutocompleteMatchType::Type::DOCUMENT_SUGGESTION:
+      return RankingItemType::kOmniboxDocument;
+    case AutocompleteMatchType::Type::EXTENSION_APP_DEPRECATED:
+    case AutocompleteMatchType::Type::CONTACT_DEPRECATED:
+    case AutocompleteMatchType::Type::PHYSICAL_WEB_DEPRECATED:
+    case AutocompleteMatchType::Type::PHYSICAL_WEB_OVERFLOW_DEPRECATED:
+    case AutocompleteMatchType::Type::TAB_SEARCH_DEPRECATED:
+      return RankingItemType::kOmniboxDeprecated;
+    default:
+      return RankingItemType::kOmniboxGeneric;
+  }
+}
+
 RankingItemType RankingItemTypeFromSearchResult(
     const ChromeSearchResult& result) {
+  // We don't want or expect the expand_omnibox_types parameter to change during
+  // the execution of chrome, so make it static.
+  static bool expand_omnibox_types = base::GetFieldTrialParamByFeatureAsBool(
+      app_list_features::kEnableAdaptiveResultRanker, "expand_omnibox_types",
+      false);
+
   switch (result.result_type()) {
     case SearchResultType::kInstalledApp:
     case SearchResultType::kInternalApp:
       return RankingItemType::kApp;
     case SearchResultType::kOmnibox:
-      return RankingItemType::kOmnibox;
+      if (expand_omnibox_types)
+        return ExpandOmniboxType(result);
+      return RankingItemType::kOmniboxGeneric;
     case SearchResultType::kLauncher:
       return RankingItemType::kFile;
     case SearchResultType::kUnknown:
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h
index ddf3ca8..17adb15 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h
@@ -17,8 +17,14 @@
   kIgnored,
   kFile,
   kApp,
-  kOmnibox,
-  kArcAppShortcut
+  kOmniboxGeneric,
+  kArcAppShortcut,
+  kOmniboxBookmark,
+  kOmniboxDeprecated,
+  kOmniboxDocument,
+  kOmniboxHistory,
+  kOmniboxNavSuggest,
+  kOmniboxSearch
 };
 
 // Convert a |ChromeSearchResult| into its |RankingItemType|.
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc
new file mode 100644
index 0000000..71b7045c
--- /dev/null
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc
@@ -0,0 +1,69 @@
+// 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 "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "ash/public/cpp/app_list/app_list_features.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
+#include "chrome/browser/ui/app_list/app_list_test_util.h"
+#include "chrome/browser/ui/app_list/search/omnibox_result.h"
+#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/omnibox/browser/autocomplete_match_type.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using test::TestAppListControllerDelegate;
+using testing::Eq;
+
+namespace app_list {
+
+class RankingItemUtilTest : public AppListTestBase {
+ public:
+  RankingItemUtilTest() {}
+  ~RankingItemUtilTest() override {}
+
+  // AppListTestBase overrides:
+  void SetUp() override {
+    AppListTestBase::SetUp();
+
+    app_list_controller_delegate_ =
+        std::make_unique<::test::TestAppListControllerDelegate>();
+  }
+
+  void SetAdaptiveRankerParams(
+      const std::map<std::string, std::string>& params) {
+    scoped_feature_list_.InitAndEnableFeatureWithParameters(
+        app_list_features::kEnableAdaptiveResultRanker, params);
+  }
+
+  std::unique_ptr<OmniboxResult> MakeOmniboxResult(
+      AutocompleteMatchType::Type type) {
+    AutocompleteMatch match;
+    match.type = type;
+    return std::make_unique<OmniboxResult>(profile_.get(),
+                                           app_list_controller_delegate_.get(),
+                                           nullptr, match, false);
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  std::unique_ptr<TestAppListControllerDelegate> app_list_controller_delegate_;
+};
+
+TEST_F(RankingItemUtilTest, OmniboxSubtypeReturnedWithFinchParameterOn) {
+  SetAdaptiveRankerParams({{"expand_omnibox_types", "true"}});
+  std::unique_ptr<OmniboxResult> result =
+      MakeOmniboxResult(AutocompleteMatchType::HISTORY_URL);
+  RankingItemType type = RankingItemTypeFromSearchResult(*result.get());
+  EXPECT_EQ(type, RankingItemType::kOmniboxHistory);
+}
+
+}  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
index 52b567b..9f00090 100644
--- a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
+++ b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
@@ -310,7 +310,7 @@
   CreateMixer(false);
 
   for (int i = 0; i < 20; ++i)
-    Train("omnibox2", RankingItemType::kOmnibox);
+    Train("omnibox2", RankingItemType::kOmniboxGeneric);
 
   app_provider()->set_count(4);
   app_provider()->set_small_relevance_range();
@@ -327,7 +327,7 @@
   CreateMixer(true, {{"boost_coefficient", "10.0"}});
 
   for (int i = 0; i < 20; ++i)
-    Train("omnibox2", RankingItemType::kOmnibox);
+    Train("omnibox2", RankingItemType::kOmniboxGeneric);
 
   app_provider()->set_count(4);
   app_provider()->set_small_relevance_range();
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
index 760395f..9c5fd75 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 
-#include <memory>
+#include <utility>
 
 #include "ash/public/interfaces/constants.mojom.h"
 #include "base/bind.h"
@@ -379,8 +379,13 @@
   DVLOG(1) << "OnLoadKeyboardContentsRequested: Create: " << keyboard_url;
   keyboard_contents_ = std::make_unique<ChromeKeyboardWebContents>(
       GetProfile(), keyboard_url,
+      /*load_callback=*/
       base::BindOnce(&ChromeKeyboardControllerClient::OnKeyboardContentsLoaded,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr()),
+      /*unembed_callback=*/
+      base::BindRepeating(
+          &ChromeKeyboardControllerClient::OnKeyboardUIDestroyed,
+          weak_ptr_factory_.GetWeakPtr()));
 }
 
 void ChromeKeyboardControllerClient::OnKeyboardUIDestroyed() {
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h
index e1d87fd..ed5b8704 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h
@@ -6,6 +6,8 @@
 #define CHROME_BROWSER_UI_ASH_KEYBOARD_CHROME_KEYBOARD_CONTROLLER_CLIENT_H_
 
 #include <memory>
+#include <set>
+#include <vector>
 
 #include "ash/public/interfaces/keyboard_controller.mojom.h"
 #include "base/callback_forward.h"
@@ -103,7 +105,7 @@
   // Returns whether |flag| has been set.
   bool IsEnableFlagSet(const keyboard::mojom::KeyboardEnableFlag& flag);
 
-  // Calls forwarded to ash.mojom.KeyboardController..
+  // Calls forwarded to ash.mojom.KeyboardController.
   void ReloadKeyboardIfNeeded();
   void RebuildKeyboardIfEnabled();
   void ShowKeyboard();
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_ui.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_ui.cc
index 81c45af..826a1a4 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_ui.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_ui.cc
@@ -9,6 +9,7 @@
 
 #include "ash/shell.h"
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/macros.h"
 #include "base/no_destructor.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_bounds_observer.h"
@@ -55,7 +56,8 @@
             ChromeKeyboardControllerClient::Get()->NotifyKeyboardLoaded();
             std::move(callback).Run();
           },
-          std::move(callback)));
+          std::move(callback)),
+      base::NullCallback());
 
   aura::Window* keyboard_window =
       keyboard_contents_->web_contents()->GetNativeView();
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
index bf94955..5db18cddd 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
@@ -4,7 +4,11 @@
 
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h"
 
+#include <string>
+#include <utility>
+
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/feature_list.h"
 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
@@ -133,8 +137,10 @@
 ChromeKeyboardWebContents::ChromeKeyboardWebContents(
     content::BrowserContext* context,
     const GURL& url,
-    LoadCallback load_callback)
-    : load_callback_(std::move(load_callback)) {
+    LoadCallback load_callback,
+    UnembedCallback unembed_callback)
+    : load_callback_(std::move(load_callback)),
+      unembed_callback_(std::move(unembed_callback)) {
   VLOG(1) << "ChromeKeyboardWebContents: " << url;
   DCHECK(context);
   content::WebContents::CreateParams web_contents_params(
@@ -232,6 +238,7 @@
     return;
   remote_view_provider_ = std::make_unique<views::RemoteViewProvider>(
       web_contents_->GetNativeView());
+  remote_view_provider_->SetCallbacks(base::NullCallback(), unembed_callback_);
   remote_view_provider_->GetEmbedToken(
       base::BindOnce(&ChromeKeyboardWebContents::OnGotEmbedToken,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h
index 324c567..86229f8 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h
@@ -44,12 +44,17 @@
  public:
   using LoadCallback = base::OnceCallback<void(const base::UnguessableToken&,
                                                const gfx::Size& size)>;
+  using UnembedCallback = base::RepeatingClosure;
 
-  // Immediately starts loading |url| in a WebContents. |callback| is called
-  // when the WebContents finishes loading.
+  // Immediately starts loading |url| in a WebContents. |load_callback| is
+  // called when the WebContents finishes loading. |unembed_callback| is only
+  // used when the content is embedded using Window Service and is called when
+  // it gets unembedded (e.g. the hosting window is closed). Note that
+  // |unembed_callback| might end up deleting this.
   ChromeKeyboardWebContents(content::BrowserContext* context,
                             const GURL& url,
-                            LoadCallback load_callback);
+                            LoadCallback load_callback,
+                            UnembedCallback unembed_callback);
   ~ChromeKeyboardWebContents() override;
 
   // Updates the keyboard URL if |url| does not match the existing url.
@@ -88,10 +93,13 @@
   std::unique_ptr<content::WebContents> web_contents_;
   std::unique_ptr<ChromeKeyboardBoundsObserver> window_bounds_observer_;
 
-  // Called from DidStopLoading(). If the WindowService is running, passes a
+  // Called from DidStopLoading(). If the Window Service is running, passes a
   // token for embedding the contents, otherwise passes an empty token.
   LoadCallback load_callback_;
 
+  // Called when content is unembedded from Window Service.
+  UnembedCallback unembed_callback_;
+
   base::UnguessableToken token_;
   gfx::Size contents_size_;
 
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents_unittest.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents_unittest.cc
index 19ee834d4..972ed4e 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents_unittest.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents_unittest.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.h"
 
 #include <memory>
+#include <utility>
 
+#include "base/bind_helpers.h"
 #include "base/run_loop.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -38,7 +40,7 @@
   void CreateWebContents(const GURL& url,
                          ChromeKeyboardWebContents::LoadCallback callback) {
     chrome_keyboard_web_contents_ = std::make_unique<ChromeKeyboardWebContents>(
-        profile(), url, std::move(callback));
+        profile(), url, std::move(callback), base::NullCallback());
   }
 
  protected:
diff --git a/chrome/browser/ui/cocoa/handoff_active_url_observer_bridge.mm b/chrome/browser/ui/cocoa/handoff_active_url_observer_bridge.mm
index 639ae937..0c7fd5b 100644
--- a/chrome/browser/ui/cocoa/handoff_active_url_observer_bridge.mm
+++ b/chrome/browser/ui/cocoa/handoff_active_url_observer_bridge.mm
@@ -13,7 +13,7 @@
   observer_.reset(new HandoffActiveURLObserver(this));
 }
 
-HandoffActiveURLObserverBridge::~HandoffActiveURLObserverBridge(){};
+HandoffActiveURLObserverBridge::~HandoffActiveURLObserverBridge() {}
 
 void HandoffActiveURLObserverBridge::HandoffActiveURLChanged(
     content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/cocoa/handoff_active_url_observer_delegate.h b/chrome/browser/ui/cocoa/handoff_active_url_observer_delegate.h
index d0d0fffc..1fcdbf6 100644
--- a/chrome/browser/ui/cocoa/handoff_active_url_observer_delegate.h
+++ b/chrome/browser/ui/cocoa/handoff_active_url_observer_delegate.h
@@ -21,7 +21,7 @@
   virtual void HandoffActiveURLChanged(content::WebContents* web_contents) = 0;
 
  protected:
-  virtual ~HandoffActiveURLObserverDelegate(){};
+  virtual ~HandoffActiveURLObserverDelegate() {}
 };
 
 #endif  // CHROME_BROWSER_UI_COCOA_HANDOFF_ACTIVE_URL_OBSERVER_DELEGATE_H_
diff --git a/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.cc b/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.cc
index c3c825a1..14859d40 100644
--- a/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.cc
+++ b/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/media_router/media_router_ui_base.h"
 #include "chrome/browser/ui/media_router/media_router_ui_service.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 
 using content::WebContents;
 
@@ -31,29 +30,15 @@
   media_router_ui_service_->RemoveObserver(this);
 }
 
-void MediaRouterDialogControllerImplBase::SetMediaRouterAction(
-    const base::WeakPtr<MediaRouterAction>& action) {
-  action_ = action;
-}
-
 void MediaRouterDialogControllerImplBase::CreateMediaRouterDialog() {
   if (!GetActionController())
     return;
-
-  // The |GetActionController_| must be notified after |action_| to avoid a UI
-  // bug in which the drop shadow is drawn in an incorrect position.
-  if (action_)
-    action_->OnDialogShown();
   GetActionController()->OnDialogShown();
 }
 
 void MediaRouterDialogControllerImplBase::Reset() {
-  if (IsShowingMediaRouterDialog()) {
-    if (action_)
-      action_->OnDialogHidden();
-    if (GetActionController())
-      GetActionController()->OnDialogHidden();
-  }
+  if (IsShowingMediaRouterDialog() && GetActionController())
+    GetActionController()->OnDialogHidden();
   MediaRouterDialogController::Reset();
 }
 
diff --git a/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h b/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h
index 4419037..2b4db93 100644
--- a/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h
+++ b/chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h
@@ -9,8 +9,6 @@
 #include "chrome/browser/media/router/media_router_dialog_controller.h"
 #include "chrome/browser/ui/media_router/media_router_ui_service.h"
 
-class MediaRouterAction;
-
 namespace media_router {
 
 class MediaRouterUIBase;
@@ -27,15 +25,10 @@
   static MediaRouterDialogControllerImplBase* FromWebContents(
       content::WebContents* web_contents);
 
-  // Sets the action to notify when a dialog gets shown or hidden.
-  void SetMediaRouterAction(const base::WeakPtr<MediaRouterAction>& action);
-
   // MediaRouterDialogController:
   void CreateMediaRouterDialog() override;
   void Reset() override;
 
-  MediaRouterAction* action() { return action_.get(); }
-
  protected:
   // Use MediaRouterDialogControllerImplBase::CreateForWebContents() to create
   // an instance.
@@ -53,15 +46,6 @@
   // toolbar action. It's owned by MediaRouterUIService and it may be nullptr.
   MediaRouterActionController* GetActionController();
 
-  // |action_| refers to the MediaRouterAction on the toolbar, rather than
-  // overflow menu. A MediaRouterAction is always created for the toolbar
-  // first. Any subsequent creations for the overflow menu will not be set as
-  // |action_|.
-  // The lifetime of |action_| is dependent on the creation and destruction of
-  // a browser window. The overflow menu's MediaRouterAction is only created
-  // when the overflow menu is opened and destroyed when the menu is closed.
-  base::WeakPtr<MediaRouterAction> action_;
-
   // |media_router_ui_service_| Service which provides
   // MediaRouterActionController. It outlives |this|.
   MediaRouterUIService* const media_router_ui_service_;
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
index ae3381cc..368df50 100644
--- a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
+++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
@@ -7,32 +7,18 @@
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
-#include "chrome/browser/ui/toolbar/media_router_action_controller.h"
 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
 #include "extensions/browser/extension_registry.h"
 
-// static
-const char ComponentToolbarActionsFactory::kMediaRouterActionId[] =
-    "media_router_action";
-
 ComponentToolbarActionsFactory::ComponentToolbarActionsFactory(
-    Profile* profile) {
-  if (media_router::MediaRouterEnabled(profile) &&
-      MediaRouterActionController::IsActionShownByPolicy(profile)) {
-    initial_ids_.insert(kMediaRouterActionId);
-  }
-}
+    Profile* profile) {}
 
-ComponentToolbarActionsFactory::~ComponentToolbarActionsFactory() {}
+ComponentToolbarActionsFactory::~ComponentToolbarActionsFactory() = default;
 
 std::set<std::string> ComponentToolbarActionsFactory::GetInitialComponentIds() {
-  // TODO(takumif): Instead of keeping track of |initial_ids_|, simplify by
-  // checking here whether MediaRouterAction should be visible.
   return initial_ids_;
 }
 
@@ -57,10 +43,6 @@
   // (since each will have an action in the toolbar or overflow menu), this
   // should be okay. If this changes, we should rethink this design to have,
   // e.g., RegisterChromeAction().
-  if (action_id == kMediaRouterActionId)
-    return std::unique_ptr<ToolbarActionViewController>(
-        new MediaRouterAction(browser, bar));
-
-  NOTREACHED();
+  NOTIMPLEMENTED();
   return std::unique_ptr<ToolbarActionViewController>();
 }
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
index 54f44dc..3b7079d8 100644
--- a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
+++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
@@ -18,12 +18,10 @@
 
 // The registry for all component toolbar actions. Component toolbar actions
 // are actions that live in the toolbar (like extension actions), but are for
-// components of Chrome, such as Media Router.
+// components of Chrome.
+// TODO(crbug.com/934464): Delete this class.
 class ComponentToolbarActionsFactory {
  public:
-  // Extension and component action IDs.
-  static const char kMediaRouterActionId[];
-
   explicit ComponentToolbarActionsFactory(Profile* profile);
   virtual ~ComponentToolbarActionsFactory();
 
diff --git a/chrome/browser/ui/toolbar/media_router_action.cc b/chrome/browser/ui/toolbar/media_router_action.cc
deleted file mode 100644
index 062a982..0000000
--- a/chrome/browser/ui/toolbar/media_router_action.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// 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.
-
-#include "chrome/browser/ui/toolbar/media_router_action.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/metrics/user_metrics.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "chrome/browser/media/router/media_router.h"
-#include "chrome/browser/media/router/media_router_factory.h"
-#include "chrome/browser/media/router/media_router_metrics.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h"
-#include "chrome/browser/ui/media_router/media_router_ui_service.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
-#include "chrome/browser/ui/toolbar/media_router_action_controller.h"
-#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
-#include "chrome/common/media_router/issue.h"
-#include "chrome/common/media_router/media_route.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/vector_icons/vector_icons.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/color_palette.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/paint_vector_icon.h"
-#include "ui/gfx/vector_icon_types.h"
-
-using media_router::MediaRouterDialogControllerImplBase;
-
-namespace {
-
-media_router::MediaRouter* GetMediaRouter(Browser* browser) {
-  return media_router::MediaRouterFactory::GetApiForBrowserContext(
-      browser->profile());
-}
-
-}  // namespace
-
-MediaRouterAction::MediaRouterAction(Browser* browser,
-                                     ToolbarActionsBar* toolbar_actions_bar)
-    : media_router::IssuesObserver(GetMediaRouter(browser)->GetIssueManager()),
-      media_router::MediaRoutesObserver(GetMediaRouter(browser)),
-      current_icon_(&vector_icons::kMediaRouterIdleIcon),
-      has_local_display_route_(false),
-      has_dialog_(false),
-      delegate_(nullptr),
-      browser_(browser),
-      toolbar_actions_bar_(toolbar_actions_bar),
-      tab_strip_model_observer_(this),
-      toolbar_actions_bar_observer_(this),
-      skip_close_overflow_menu_for_testing_(false),
-      weak_ptr_factory_(this) {
-  DCHECK(browser_);
-  DCHECK(toolbar_actions_bar_);
-  tab_strip_model_observer_.Add(browser_->tab_strip_model());
-  toolbar_actions_bar_observer_.Add(toolbar_actions_bar_);
-  IssuesObserver::Init();
-}
-
-MediaRouterAction::~MediaRouterAction() {
-}
-
-// static
-SkColor MediaRouterAction::GetIconColor(const gfx::VectorIcon& icon_id) {
-  if (&icon_id == &vector_icons::kMediaRouterIdleIcon)
-    return gfx::kChromeIconGrey;
-  if (&icon_id == &vector_icons::kMediaRouterActiveIcon)
-    return gfx::kGoogleBlue500;
-  if (&icon_id == &vector_icons::kMediaRouterWarningIcon)
-    return gfx::kGoogleYellow700;
-  DCHECK_EQ(&vector_icons::kMediaRouterErrorIcon, &icon_id);
-  return gfx::kGoogleRed700;
-}
-
-std::string MediaRouterAction::GetId() const {
-  return ComponentToolbarActionsFactory::kMediaRouterActionId;
-}
-
-void MediaRouterAction::SetDelegate(ToolbarActionViewDelegate* delegate) {
-  delegate_ = delegate;
-
-  // In cases such as opening a new browser window, SetDelegate() will be
-  // called before the WebContents is set. In those cases, we register with the
-  // dialog controller when ActiveTabChanged() is called.
-  if (delegate_ && delegate_->GetCurrentWebContents())
-    RegisterWithDialogController();
-}
-
-gfx::Image MediaRouterAction::GetIcon(content::WebContents* web_contents,
-                                      const gfx::Size& size) {
-  return gfx::Image(
-      gfx::CreateVectorIcon(*current_icon_, GetIconColor(*current_icon_)));
-}
-
-base::string16 MediaRouterAction::GetActionName() const {
-  return l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_TITLE);
-}
-
-base::string16 MediaRouterAction::GetAccessibleName(
-    content::WebContents* web_contents) const {
-  return GetTooltip(web_contents);
-}
-
-base::string16 MediaRouterAction::GetTooltip(
-    content::WebContents* web_contents) const {
-  return l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_ICON_TOOLTIP_TEXT);
-}
-
-bool MediaRouterAction::IsEnabled(
-    content::WebContents* web_contents) const {
-  return true;
-}
-
-bool MediaRouterAction::WantsToRun(
-    content::WebContents* web_contents) const {
-  return false;
-}
-
-bool MediaRouterAction::HasPopup(
-    content::WebContents* web_contents) const {
-  return true;
-}
-
-bool MediaRouterAction::IsShowingPopup() const {
-  auto* controller = GetMediaRouterDialogController();
-  return controller && controller->IsShowingMediaRouterDialog();
-}
-
-void MediaRouterAction::HidePopup() {
-  GetMediaRouterDialogController()->HideMediaRouterDialog();
-}
-
-gfx::NativeView MediaRouterAction::GetPopupNativeView() {
-  return nullptr;
-}
-
-ui::MenuModel* MediaRouterAction::GetContextMenu() {
-  // If there is an existing context menu, destroy it before we instantiate a
-  // new one.
-  DestroyContextMenu();
-  MediaRouterActionController* controller =
-      media_router::MediaRouterUIService::Get(browser_->profile())
-          ->action_controller();
-  if (toolbar_actions_bar_->IsActionVisibleOnMainBar(this)) {
-    contextual_menu_ =
-        MediaRouterContextualMenu::CreateForToolbar(browser_, controller);
-  } else {
-    contextual_menu_ =
-        MediaRouterContextualMenu::CreateForOverflowMenu(browser_, controller);
-  }
-  return contextual_menu_->menu_model();
-}
-
-void MediaRouterAction::OnContextMenuClosed() {
-  if (toolbar_actions_bar_->popped_out_action() == this && !IsShowingPopup())
-    toolbar_actions_bar_->UndoPopOut();
-
-  // We must destroy the context menu asynchronously to prevent it from being
-  // destroyed before the command execution.
-  // TODO(takumif): Using task sequence to order operations is fragile. Consider
-  // other ways to do so when we move the icon to the trusted area.
-  base::PostTaskWithTraits(
-      FROM_HERE, {content::BrowserThread::UI},
-      base::BindOnce(&MediaRouterAction::DestroyContextMenu,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-bool MediaRouterAction::ExecuteAction(bool by_user) {
-  base::RecordAction(base::UserMetricsAction("MediaRouter_Icon_Click"));
-
-  if (IsShowingPopup()) {
-    HidePopup();
-    return false;
-  }
-
-  GetMediaRouterDialogController()->ShowMediaRouterDialog();
-  if (!skip_close_overflow_menu_for_testing_) {
-    // TODO(karandeepb): Instead of checking the return value of
-    // CloseOverflowMenuIfOpen, just check
-    // ToolbarActionsBar::IsActionVisibleOnMainBar.
-    media_router::MediaRouterMetrics::RecordMediaRouterDialogOrigin(
-        toolbar_actions_bar_->CloseOverflowMenuIfOpen()
-            ? media_router::MediaRouterDialogOpenOrigin::OVERFLOW_MENU
-            : media_router::MediaRouterDialogOpenOrigin::TOOLBAR);
-  }
-  return true;
-}
-
-void MediaRouterAction::UpdateState() {
-  delegate_->UpdateState();
-}
-
-bool MediaRouterAction::DisabledClickOpensMenu() const {
-  return false;
-}
-
-void MediaRouterAction::OnIssue(const media_router::Issue& issue) {
-  current_issue_ = std::make_unique<media_router::IssueInfo>(issue.info());
-  MaybeUpdateIcon();
-}
-
-void MediaRouterAction::OnIssuesCleared() {
-  current_issue_.reset();
-  MaybeUpdateIcon();
-}
-
-void MediaRouterAction::OnRoutesUpdated(
-    const std::vector<media_router::MediaRoute>& routes,
-    const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) {
-  has_local_display_route_ =
-      std::find_if(routes.begin(), routes.end(),
-                   [](const media_router::MediaRoute& route) {
-                     return route.is_local() && route.for_display();
-                   }) != routes.end();
-  MaybeUpdateIcon();
-}
-
-void MediaRouterAction::OnTabStripModelChanged(
-    TabStripModel* tab_strip_model,
-    const TabStripModelChange& change,
-    const TabStripSelectionChange& selection) {
-  if (!selection.active_tab_changed() || tab_strip_model->empty())
-    return;
-
-  RegisterWithDialogController();
-  UpdateDialogState();
-}
-
-void MediaRouterAction::OnToolbarActionsBarAnimationEnded() {
-  UpdateDialogState();
-}
-
-void MediaRouterAction::OnDialogHidden() {
-  if (has_dialog_) {
-    has_dialog_ = false;
-    delegate_->OnPopupClosed();
-  }
-}
-
-void MediaRouterAction::OnDialogShown() {
-  if (!has_dialog_) {
-    has_dialog_ = true;
-    // We depress the action regardless of whether ExecuteAction() was user
-    // initiated.
-    delegate_->OnPopupShown(true);
-  }
-}
-
-void MediaRouterAction::RegisterWithDialogController() {
-  MediaRouterDialogControllerImplBase* controller =
-      GetMediaRouterDialogController();
-
-  if (!controller)
-    return;
-
-  // |controller| keeps track of |this| if |this| was created with the browser
-  // window or ephemerally by activating the Cast functionality. If |this| was
-  // created in overflow mode, it will be destroyed when the overflow menu is
-  // closed.
-  if (!toolbar_actions_bar_->in_overflow_mode())
-    controller->SetMediaRouterAction(weak_ptr_factory_.GetWeakPtr());
-}
-
-void MediaRouterAction::UpdateDialogState() {
-  // The WebContents may be null during browser test shutdown, in which case we
-  // cannot call GetMediaRouterDialogController().
-  if (!delegate_->GetCurrentWebContents())
-    return;
-
-  if (IsShowingPopup())
-    OnDialogShown();
-  else
-    OnDialogHidden();
-}
-
-MediaRouterDialogControllerImplBase*
-MediaRouterAction::GetMediaRouterDialogController() {
-  DCHECK(delegate_);
-  content::WebContents* web_contents = delegate_->GetCurrentWebContents();
-  DCHECK(web_contents);
-  return MediaRouterDialogControllerImplBase::GetOrCreateForWebContents(
-      web_contents);
-}
-
-const MediaRouterDialogControllerImplBase*
-MediaRouterAction::GetMediaRouterDialogController() const {
-  DCHECK(delegate_);
-  content::WebContents* web_contents = delegate_->GetCurrentWebContents();
-  DCHECK(web_contents);
-  return MediaRouterDialogControllerImplBase::FromWebContents(web_contents);
-}
-
-void MediaRouterAction::MaybeUpdateIcon() {
-  const gfx::VectorIcon& new_icon = GetCurrentIcon();
-
-  // Update the current state if it has changed.
-  if (&new_icon != current_icon_) {
-    current_icon_ = &new_icon;
-
-    // Tell the associated view to update its icon to reflect the change made
-    // above. If MaybeUpdateIcon() was called as a result of instantiating
-    // |this|, then |delegate_| may not be set yet.
-    if (delegate_)
-      UpdateState();
-  }
-}
-
-const gfx::VectorIcon& MediaRouterAction::GetCurrentIcon() const {
-  // Highest priority is to indicate whether there's an issue.
-  if (current_issue_) {
-    media_router::IssueInfo::Severity severity = current_issue_->severity;
-    if (severity == media_router::IssueInfo::Severity::FATAL)
-      return vector_icons::kMediaRouterErrorIcon;
-    if (severity == media_router::IssueInfo::Severity::WARNING)
-      return vector_icons::kMediaRouterWarningIcon;
-    // Fall through for Severity::NOTIFICATION.
-  }
-
-  return has_local_display_route_ ? vector_icons::kMediaRouterActiveIcon
-                                  : vector_icons::kMediaRouterIdleIcon;
-}
-
-void MediaRouterAction::DestroyContextMenu() {
-  contextual_menu_.reset();
-}
diff --git a/chrome/browser/ui/toolbar/media_router_action.h b/chrome/browser/ui/toolbar/media_router_action.h
deleted file mode 100644
index 481f5fc..0000000
--- a/chrome/browser/ui/toolbar/media_router_action.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_TOOLBAR_MEDIA_ROUTER_ACTION_H_
-#define CHROME_BROWSER_UI_TOOLBAR_MEDIA_ROUTER_ACTION_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "chrome/browser/media/router/issues_observer.h"
-#include "chrome/browser/media/router/media_routes_observer.h"
-#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
-#include "chrome/browser/ui/toolbar/media_router_contextual_menu.h"
-#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h"
-
-class Browser;
-class TabStripModel;
-
-namespace gfx {
-struct VectorIcon;
-}
-
-namespace media_router {
-class MediaRouterDialogControllerImplBase;
-}  // namespace media_router
-
-// The class for the Media Router component action that will be shown in
-// the toolbar.
-class MediaRouterAction : public ToolbarActionViewController,
-                          public media_router::IssuesObserver,
-                          public media_router::MediaRoutesObserver,
-                          public TabStripModelObserver,
-                          public ToolbarActionsBarObserver {
- public:
-  MediaRouterAction(Browser* browser, ToolbarActionsBar* toolbar_actions_bar);
-  ~MediaRouterAction() override;
-
-  static SkColor GetIconColor(const gfx::VectorIcon& icon_id);
-
-  // ToolbarActionViewController implementation.
-  std::string GetId() const override;
-  void SetDelegate(ToolbarActionViewDelegate* delegate) override;
-  gfx::Image GetIcon(content::WebContents* web_contents,
-                     const gfx::Size& size) override;
-  base::string16 GetActionName() const override;
-  base::string16 GetAccessibleName(content::WebContents* web_contents)
-      const override;
-  base::string16 GetTooltip(content::WebContents* web_contents)
-      const override;
-  bool IsEnabled(content::WebContents* web_contents) const override;
-  bool WantsToRun(content::WebContents* web_contents) const override;
-  bool HasPopup(content::WebContents* web_contents) const override;
-  bool IsShowingPopup() const override;
-  void HidePopup() override;
-  gfx::NativeView GetPopupNativeView() override;
-  ui::MenuModel* GetContextMenu() override;
-  void OnContextMenuClosed() override;
-  bool ExecuteAction(bool by_user) override;
-  void UpdateState() override;
-  bool DisabledClickOpensMenu() const override;
-
-  // media_router::IssuesObserver:
-  void OnIssue(const media_router::Issue& issue) override;
-  void OnIssuesCleared() override;
-
-  // media_router::MediaRoutesObserver:
-  void OnRoutesUpdated(const std::vector<media_router::MediaRoute>& routes,
-                       const std::vector<media_router::MediaRoute::Id>&
-                           joinable_route_ids) override;
-
-  // ToolbarStripModelObserver:
-  void OnTabStripModelChanged(
-      TabStripModel* tab_strip_model,
-      const TabStripModelChange& change,
-      const TabStripSelectionChange& selection) override;
-
-  // ToolbarActionsBarObserver:
-  void OnToolbarActionsBarAnimationEnded() override;
-
-  void OnDialogHidden();
-  void OnDialogShown();
-
-  void set_skip_close_overflow_menu_for_testing(bool val) {
-    skip_close_overflow_menu_for_testing_ = val;
-  }
-
- private:
-  // Registers |this| with the MediaRouterDialogControllerImplBase associated
-  // with |delegate_|'s current WebContents if |this| is not shown in overflow
-  // mode.
-  void RegisterWithDialogController();
-
-  // Called when a new browser window is opened or when |delegate_| is swapped
-  // out to be non-null and has a valid WebContents.
-  // This updates the pressed/unpressed state of the icon, which is different
-  // on a per-tab basis.
-  void UpdateDialogState();
-
-  // Returns a reference to the MediaRouterDialogControllerImplBase associated
-  // with |delegate_|'s current WebContents. Guaranteed to be non-null.
-  // |delegate_| and its current WebContents must not be null.
-  // Marked virtual for tests.
-  virtual media_router::MediaRouterDialogControllerImplBase*
-  GetMediaRouterDialogController();
-  virtual const media_router::MediaRouterDialogControllerImplBase*
-  GetMediaRouterDialogController() const;
-
-  // Checks if the current icon of MediaRouterAction has changed. If so,
-  // updates |current_icon_|.
-  void MaybeUpdateIcon();
-
-  const gfx::VectorIcon& GetCurrentIcon() const;
-
-  void DestroyContextMenu();
-
-  // The current icon to show. This is updated based on the current issues and
-  // routes since |this| is an IssueObserver and MediaRoutesObserver.
-  const gfx::VectorIcon* current_icon_;
-
-  // The current issue shown in the Media Router WebUI, set in OnIssue() and
-  // cleared in OnIssuesCleared().
-  std::unique_ptr<media_router::IssueInfo> current_issue_;
-
-  // Whether a local displayable active route exists.
-  bool has_local_display_route_;
-
-  // Whether the Media Router dialog is shown in the current tab.
-  // This should only be updated in OnDialogShown() and OnDialogHidden().
-  bool has_dialog_;
-
-  ToolbarActionViewDelegate* delegate_;
-
-  Browser* const browser_;
-  ToolbarActionsBar* const toolbar_actions_bar_;
-
-  std::unique_ptr<MediaRouterContextualMenu> contextual_menu_;
-
-  ScopedObserver<TabStripModel, TabStripModelObserver>
-      tab_strip_model_observer_;
-  ScopedObserver<ToolbarActionsBar, ToolbarActionsBarObserver>
-      toolbar_actions_bar_observer_;
-
-  bool skip_close_overflow_menu_for_testing_;
-
-  base::WeakPtrFactory<MediaRouterAction> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaRouterAction);
-};
-
-#endif  // CHROME_BROWSER_UI_TOOLBAR_MEDIA_ROUTER_ACTION_H_
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller.cc b/chrome/browser/ui/toolbar/media_router_action_controller.cc
index e2992af..cda871f 100644
--- a/chrome/browser/ui/toolbar/media_router_action_controller.cc
+++ b/chrome/browser/ui/toolbar/media_router_action_controller.cc
@@ -10,19 +10,14 @@
 #include "chrome/browser/media/router/media_router_factory.h"
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/toolbar/component_action_delegate.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
 #include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_task_traits.h"
 
 MediaRouterActionController::MediaRouterActionController(Profile* profile)
     : MediaRouterActionController(
           profile,
-          media_router::MediaRouterFactory::GetApiForBrowserContext(profile),
-          ToolbarActionsModel::Get(profile)) {
-  DCHECK(component_action_delegate_);
-}
+          media_router::MediaRouterFactory::GetApiForBrowserContext(profile)) {}
 
 MediaRouterActionController::~MediaRouterActionController() {
   DCHECK_EQ(dialog_count_, 0u);
@@ -138,12 +133,10 @@
 
 MediaRouterActionController::MediaRouterActionController(
     Profile* profile,
-    media_router::MediaRouter* router,
-    ComponentActionDelegate* component_action_delegate)
+    media_router::MediaRouter* router)
     : media_router::IssuesObserver(router->GetIssueManager()),
       media_router::MediaRoutesObserver(router),
       profile_(profile),
-      component_action_delegate_(component_action_delegate),
       shown_by_policy_(
           MediaRouterActionController::IsActionShownByPolicy(profile)),
       weak_factory_(this) {
@@ -157,28 +150,6 @@
 }
 
 void MediaRouterActionController::MaybeAddOrRemoveAction() {
-  if (media_router::ShouldUseViewsDialog()) {
-    MaybeAddOrRemoveTrustedAreaIcon();
-  } else {
-    MaybeAddOrRemoveComponentAction();
-  }
-}
-
-void MediaRouterActionController::MaybeAddOrRemoveComponentAction() {
-  if (ShouldEnableAction()) {
-    if (!component_action_delegate_->HasComponentAction(
-            ComponentToolbarActionsFactory::kMediaRouterActionId)) {
-      component_action_delegate_->AddComponentAction(
-          ComponentToolbarActionsFactory::kMediaRouterActionId);
-    }
-  } else if (component_action_delegate_->HasComponentAction(
-                 ComponentToolbarActionsFactory::kMediaRouterActionId)) {
-    component_action_delegate_->RemoveComponentAction(
-        ComponentToolbarActionsFactory::kMediaRouterActionId);
-  }
-}
-
-void MediaRouterActionController::MaybeAddOrRemoveTrustedAreaIcon() {
   if (ShouldEnableAction()) {
     for (Observer& observer : observers_)
       observer.ShowIcon();
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller.h b/chrome/browser/ui/toolbar/media_router_action_controller.h
index 810d262..9faad405 100644
--- a/chrome/browser/ui/toolbar/media_router_action_controller.h
+++ b/chrome/browser/ui/toolbar/media_router_action_controller.h
@@ -15,8 +15,6 @@
 #include "chrome/browser/ui/toolbar/media_router_contextual_menu.h"
 #include "components/prefs/pref_change_registrar.h"
 
-class ComponentActionDelegate;
-
 // Controller for the Cast toolbar icon that determines when to show and hide
 // icon. There should be one instance of this class per profile, and it should
 // only be used on the UI thread.
@@ -25,26 +23,27 @@
                                     public media_router::MediaRoutesObserver,
                                     public MediaRouterContextualMenu::Observer {
  public:
+  // TODO(takumif): CastToolbarIcon is the only Observer implementation.
+  // Observer should be renamed to make it clear that it is responsible for
+  // changing icon states when its methods are called.
   class Observer {
    public:
     virtual ~Observer() = default;
 
-    virtual void ShowIcon() = 0;
-    virtual void HideIcon() = 0;
+    virtual void ShowIcon() {}
+    virtual void HideIcon() {}
     // TODO(https://crbug.com/872392): Use the common code path to show and hide
     // the icon's inkdrop.
     // This is called when the icon should enter pressed state.
-    virtual void ActivateIcon() = 0;
+    virtual void ActivateIcon() {}
     // This is called when the icon should enter unpressed state.
-    virtual void DeactivateIcon() = 0;
+    virtual void DeactivateIcon() {}
   };
 
   explicit MediaRouterActionController(Profile* profile);
   // Constructor for injecting dependencies in tests.
-  MediaRouterActionController(
-      Profile* profile,
-      media_router::MediaRouter* router,
-      ComponentActionDelegate* component_action_delegate);
+  MediaRouterActionController(Profile* profile,
+                              media_router::MediaRouter* router);
   ~MediaRouterActionController() override;
 
   // Whether the media router action is shown by an administrator policy.
@@ -94,25 +93,14 @@
   FRIEND_TEST_ALL_PREFIXES(MediaRouterActionControllerUnitTest,
                            EphemeralIconForDialog);
 
-  // Adds or removes the Media Router action icon to/from
-  // |component_action_delegate_| if necessary, depending on whether or not
-  // we have issues, local routes or a dialog.
+  // Adds or removes the Cast icon to/from the toolbar if necessary,
+  // depending on whether or not we have issues, local routes or a dialog.
   virtual void MaybeAddOrRemoveAction();
 
-  // Implementation-specific helper methods for MaybeAddOrRemoveAction().
-  // TODO(takumif): Remove MaybeAddOrRemoveComponentAction() once the trusted
-  // area icon is completely rolled out.
-  void MaybeAddOrRemoveComponentAction();
-  void MaybeAddOrRemoveTrustedAreaIcon();
-
   // The profile |this| is associated with. There should be one instance of this
   // class per profile.
   Profile* const profile_;
 
-  // The delegate that is responsible for showing and hiding the icon on the
-  // toolbar. It outlives |this|.
-  ComponentActionDelegate* const component_action_delegate_;
-
   bool has_issue_ = false;
   bool has_local_display_route_ = false;
 
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
index 0d23f7cd..75134d9e 100644
--- a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
+++ b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
@@ -7,41 +7,11 @@
 
 #include "base/run_loop.h"
 #include "chrome/browser/media/router/test/mock_media_router.h"
-#include "chrome/browser/ui/toolbar/component_action_delegate.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
 #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
-#include "chrome/browser/ui/webui/media_router/media_router_web_ui_test.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
-class FakeComponentActionDelegate : public ComponentActionDelegate {
- public:
-  FakeComponentActionDelegate() {}
-  ~FakeComponentActionDelegate() override {}
-
-  void AddComponentAction(const std::string& action_id) override {
-    EXPECT_EQ(action_id, ComponentToolbarActionsFactory::kMediaRouterActionId);
-    EXPECT_FALSE(HasComponentAction(
-        ComponentToolbarActionsFactory::kMediaRouterActionId));
-    has_media_router_action_ = true;
-  }
-
-  void RemoveComponentAction(const std::string& action_id) override {
-    EXPECT_EQ(action_id, ComponentToolbarActionsFactory::kMediaRouterActionId);
-    EXPECT_TRUE(HasComponentAction(
-        ComponentToolbarActionsFactory::kMediaRouterActionId));
-    has_media_router_action_ = false;
-  }
-
-  bool HasComponentAction(const std::string& action_id) const override {
-    EXPECT_EQ(action_id, ComponentToolbarActionsFactory::kMediaRouterActionId);
-    return has_media_router_action_;
-  }
-
- private:
-  bool has_media_router_action_ = false;
-};
-
 class FakeCastToolbarIcon : public MediaRouterActionController::Observer {
  public:
   FakeCastToolbarIcon() = default;
@@ -60,7 +30,7 @@
   bool icon_shown_ = false;
 };
 
-class MediaRouterActionControllerUnitTest : public MediaRouterWebUITest {
+class MediaRouterActionControllerUnitTest : public BrowserWithTestWindowTest {
  public:
   MediaRouterActionControllerUnitTest()
       : issue_(media_router::IssueInfo(
@@ -72,15 +42,12 @@
 
   ~MediaRouterActionControllerUnitTest() override {}
 
-  // MediaRouterWebUITest:
   void SetUp() override {
-    MediaRouterWebUITest::SetUp();
+    BrowserWithTestWindowTest::SetUp();
 
     router_ = std::make_unique<media_router::MockMediaRouter>();
-    component_action_delegate_ =
-        std::make_unique<FakeComponentActionDelegate>();
-    controller_ = std::make_unique<MediaRouterActionController>(
-        profile(), router_.get(), component_action_delegate_.get());
+    controller_ =
+        std::make_unique<MediaRouterActionController>(profile(), router_.get());
     controller_->AddObserver(&icon_);
 
     SetAlwaysShowActionPref(false);
@@ -95,9 +62,8 @@
 
   void TearDown() override {
     controller_.reset();
-    component_action_delegate_.reset();
     router_.reset();
-    MediaRouterWebUITest::TearDown();
+    BrowserWithTestWindowTest::TearDown();
   }
 
   bool IsIconShown() const {
@@ -113,7 +79,6 @@
  protected:
   std::unique_ptr<MediaRouterActionController> controller_;
   std::unique_ptr<media_router::MockMediaRouter> router_;
-  std::unique_ptr<FakeComponentActionDelegate> component_action_delegate_;
   FakeCastToolbarIcon icon_;
 
   const media_router::Issue issue_;
diff --git a/chrome/browser/ui/toolbar/media_router_action_unittest.cc b/chrome/browser/ui/toolbar/media_router_action_unittest.cc
deleted file mode 100644
index 2d543a10..0000000
--- a/chrome/browser/ui/toolbar/media_router_action_unittest.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// 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.
-
-#include <vector>
-
-#include "base/macros.h"
-#include "chrome/browser/extensions/extension_action_test_util.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/extensions/browser_action_test_util.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
-#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
-#include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.h"
-#include "chrome/browser/ui/webui/media_router/media_router_web_ui_test.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/vector_icons/vector_icons.h"
-#include "content/public/browser/site_instance.h"
-#include "content/public/test/test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/color_palette.h"
-#include "ui/gfx/image/image_unittest_util.h"
-#include "ui/gfx/paint_vector_icon.h"
-
-using content::WebContents;
-using media_router::MediaRouterDialogControllerWebUIImpl;
-
-namespace {
-
-gfx::Image GetActionIcon(ToolbarActionViewController* action) {
-  return action->GetIcon(nullptr, gfx::Size());
-}
-
-}  // namespace
-
-class MockToolbarActionViewDelegate : public ToolbarActionViewDelegate {
- public:
-  MockToolbarActionViewDelegate() {}
-  ~MockToolbarActionViewDelegate() override {}
-
-  MOCK_CONST_METHOD0(GetCurrentWebContents, WebContents*());
-  MOCK_METHOD0(UpdateState, void());
-  MOCK_CONST_METHOD0(IsMenuRunning, bool());
-  MOCK_METHOD1(OnPopupShown, void(bool by_user));
-  MOCK_METHOD0(OnPopupClosed, void());
-};
-
-class TestMediaRouterAction : public MediaRouterAction {
- public:
-  TestMediaRouterAction(Browser* browser,
-                        ToolbarActionsBar* toolbar_actions_bar)
-      : MediaRouterAction(browser, toolbar_actions_bar), controller_(nullptr) {}
-  ~TestMediaRouterAction() override {}
-
-  // MediaRouterAction:
-  void OnTabStripModelChanged(
-      TabStripModel* tab_strip_model,
-      const TabStripModelChange& change,
-      const TabStripSelectionChange& selection) override {
-    // This would be null if |controller_| hasn't been set.
-    if (GetMediaRouterDialogController()) {
-      MediaRouterAction::OnTabStripModelChanged(tab_strip_model, change,
-                                                selection);
-    }
-  }
-
-  void SetMediaRouterDialogController(
-      MediaRouterDialogControllerWebUIImpl* controller) {
-    DCHECK(controller);
-    controller_ = controller;
-  }
-
- private:
-  // MediaRouterAction:
-  media_router::MediaRouterDialogControllerImplBase*
-  GetMediaRouterDialogController() override {
-    return controller_;
-  }
-  const media_router::MediaRouterDialogControllerImplBase*
-  GetMediaRouterDialogController() const override {
-    return controller_;
-  }
-
-  MediaRouterDialogControllerWebUIImpl* controller_;
-};
-
-class MediaRouterActionUnitTest : public MediaRouterWebUITest {
- public:
-  MediaRouterActionUnitTest()
-      : MediaRouterWebUITest(true),
-        toolbar_model_(nullptr),
-        fake_issue_notification_(media_router::IssueInfo(
-            "title notification",
-            media_router::IssueInfo::Action::DISMISS,
-            media_router::IssueInfo::Severity::NOTIFICATION)),
-        fake_issue_warning_(media_router::IssueInfo(
-            "title warning",
-            media_router::IssueInfo::Action::LEARN_MORE,
-            media_router::IssueInfo::Severity::WARNING)),
-        fake_issue_fatal_(
-            media_router::IssueInfo("title fatal",
-                                    media_router::IssueInfo::Action::DISMISS,
-                                    media_router::IssueInfo::Severity::FATAL)),
-        fake_source1_("fakeSource1"),
-        fake_source2_("fakeSource2"),
-        active_icon_(GetIcon(vector_icons::kMediaRouterActiveIcon)),
-        error_icon_(GetIcon(vector_icons::kMediaRouterErrorIcon)),
-        idle_icon_(GetIcon(vector_icons::kMediaRouterIdleIcon)),
-        warning_icon_(GetIcon(vector_icons::kMediaRouterWarningIcon)) {}
-
-  ~MediaRouterActionUnitTest() override {}
-
-  // MediaRouterWebUITest:
-  void SetUp() override {
-    MediaRouterWebUITest::SetUp();
-    toolbar_model_ =
-        extensions::extension_action_test_util::CreateToolbarModelForProfile(
-            profile());
-
-    // browser() will only be valid once BrowserWithTestWindowTest::SetUp()
-    // has run.
-    browser_action_test_util_ = BrowserActionTestUtil::Create(browser(), false);
-    action_.reset(
-        new TestMediaRouterAction(
-            browser(),
-            browser_action_test_util_->GetToolbarActionsBar()));
-
-    local_display_route_list_.push_back(media_router::MediaRoute(
-        "routeId1", fake_source1_, "sinkId1", "description", true, true));
-    non_local_display_route_list_.push_back(media_router::MediaRoute(
-        "routeId2", fake_source1_, "sinkId2", "description", false, true));
-    non_local_display_route_list_.push_back(media_router::MediaRoute(
-        "routeId3", fake_source2_, "sinkId3", "description", true, false));
-  }
-
-  void TearDown() override {
-    action_.reset();
-    browser_action_test_util_.reset();
-    MediaRouterWebUITest::TearDown();
-  }
-
-  gfx::Image GetIcon(const gfx::VectorIcon& icon) {
-    return gfx::Image(
-        gfx::CreateVectorIcon(icon, MediaRouterAction::GetIconColor(icon)));
-  }
-
-  TestMediaRouterAction* action() { return action_.get(); }
-  const media_router::Issue& fake_issue_notification() {
-    return fake_issue_notification_;
-  }
-  const media_router::Issue& fake_issue_warning() {
-    return fake_issue_warning_;
-  }
-  const media_router::Issue& fake_issue_fatal() { return fake_issue_fatal_; }
-  const gfx::Image active_icon() { return active_icon_; }
-  const gfx::Image error_icon() { return error_icon_; }
-  const gfx::Image idle_icon() { return idle_icon_; }
-  const gfx::Image warning_icon() { return warning_icon_; }
-  const std::vector<media_router::MediaRoute>& local_display_route_list()
-      const {
-    return local_display_route_list_;
-  }
-  const std::vector<media_router::MediaRoute>& non_local_display_route_list()
-      const {
-    return non_local_display_route_list_;
-  }
-  const std::vector<media_router::MediaRoute::Id>& empty_route_id_list() const {
-    return empty_route_id_list_;
-  }
-
- private:
-  // A BrowserActionTestUtil object constructed with the associated
-  // ToolbarActionsBar.
-  std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_;
-
-  std::unique_ptr<TestMediaRouterAction> action_;
-
-  // The associated ToolbarActionsModel (owned by the keyed service setup).
-  ToolbarActionsModel* toolbar_model_;
-
-  // Fake Issues.
-  const media_router::Issue fake_issue_notification_;
-  const media_router::Issue fake_issue_warning_;
-  const media_router::Issue fake_issue_fatal_;
-
-  // Fake Sources, used for the Routes.
-  const media_router::MediaSource fake_source1_;
-  const media_router::MediaSource fake_source2_;
-
-  // Cached images.
-  const gfx::Image active_icon_;
-  const gfx::Image error_icon_;
-  const gfx::Image idle_icon_;
-  const gfx::Image warning_icon_;
-
-  std::vector<media_router::MediaRoute> local_display_route_list_;
-  std::vector<media_router::MediaRoute> non_local_display_route_list_;
-  std::vector<media_router::MediaRoute::Id> empty_route_id_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaRouterActionUnitTest);
-};
-
-// Tests the initial state of MediaRouterAction after construction.
-TEST_F(MediaRouterActionUnitTest, Initialization) {
-  EXPECT_EQ("media_router_action", action()->GetId());
-  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_TITLE),
-      action()->GetActionName());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-}
-
-// Tests the MediaRouterAction icon based on updates to issues.
-TEST_F(MediaRouterActionUnitTest, UpdateIssues) {
-  // Initially, there are no issues.
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // Don't update |current_icon_| since the issue is only a notification.
-  action()->OnIssue(fake_issue_notification());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since the issue is a warning.
-  action()->OnIssue(fake_issue_warning());
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(warning_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since the issue is fatal.
-  action()->OnIssue(fake_issue_fatal());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(error_icon(), GetActionIcon(action())));
-
-  // Clear the issue.
-  action()->OnIssuesCleared();
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-}
-
-// Tests the MediaRouterAction state updates based on whether there are local
-// routes.
-TEST_F(MediaRouterActionUnitTest, UpdateRoutes) {
-  // Initially, there are no routes.
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since there is a local route.
-  action()->OnRoutesUpdated(local_display_route_list(), empty_route_id_list());
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(active_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since there are no local routes.
-  action()->OnRoutesUpdated(non_local_display_route_list(),
-                            empty_route_id_list());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  action()->OnRoutesUpdated(std::vector<media_router::MediaRoute>(),
-                            empty_route_id_list());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-}
-
-// Tests the MediaRouterAction icon based on updates to both issues and routes.
-TEST_F(MediaRouterActionUnitTest, UpdateIssuesAndRoutes) {
-  // Initially, there are no issues or routes.
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // There is no change in |current_icon_| since notification issues do not
-  // update the state.
-  action()->OnIssue(fake_issue_notification());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // Non-local routes also do not have an effect on |current_icon_|.
-  action()->OnRoutesUpdated(non_local_display_route_list(),
-                            empty_route_id_list());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since there is a local route.
-  action()->OnRoutesUpdated(local_display_route_list(), empty_route_id_list());
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(active_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_|, with a priority to reflect the warning issue
-  // rather than the local route.
-  action()->OnIssue(fake_issue_warning());
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(warning_icon(), GetActionIcon(action())));
-
-  // Closing a local route makes no difference to |current_icon_|.
-  action()->OnRoutesUpdated(non_local_display_route_list(),
-                            empty_route_id_list());
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(warning_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| since the issue has been updated to fatal.
-  action()->OnIssue(fake_issue_fatal());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(error_icon(), GetActionIcon(action())));
-
-  // Fatal issues still take precedent over local routes.
-  action()->OnRoutesUpdated(local_display_route_list(), empty_route_id_list());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(error_icon(), GetActionIcon(action())));
-
-  // When the fatal issue is dismissed, |current_icon_| reflects the existing
-  // local route.
-  action()->OnIssuesCleared();
-  EXPECT_TRUE(
-      gfx::test::AreImagesEqual(active_icon(), GetActionIcon(action())));
-
-  // Update |current_icon_| when the local route is closed.
-  action()->OnRoutesUpdated(non_local_display_route_list(),
-                            empty_route_id_list());
-  EXPECT_TRUE(gfx::test::AreImagesEqual(idle_icon(), GetActionIcon(action())));
-}
-
-TEST_F(MediaRouterActionUnitTest, IconPressedState) {
-  // Start with one window with one tab.
-  EXPECT_EQ(0, browser()->tab_strip_model()->count());
-  chrome::NewTab(browser());
-  EXPECT_EQ(1, browser()->tab_strip_model()->count());
-
-  WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
-  MediaRouterDialogControllerWebUIImpl::CreateForWebContents(initiator);
-  MediaRouterDialogControllerWebUIImpl* dialog_controller =
-      MediaRouterDialogControllerWebUIImpl::FromWebContents(initiator);
-  ASSERT_TRUE(dialog_controller);
-
-  // Sets the controller to use for TestMediaRouterAction.
-  action()->SetMediaRouterDialogController(dialog_controller);
-
-  // Create a ToolbarActionViewDelegate to use for MediaRouterAction.
-  std::unique_ptr<MockToolbarActionViewDelegate> mock_delegate(
-      new MockToolbarActionViewDelegate());
-
-  EXPECT_CALL(*mock_delegate, GetCurrentWebContents())
-      .WillOnce(testing::Return(initiator));
-  action()->SetDelegate(mock_delegate.get());
-
-  // Skip closing the overflow menu in tests.
-  action()->set_skip_close_overflow_menu_for_testing(true);
-
-  EXPECT_CALL(*mock_delegate, OnPopupShown(true)).Times(1);
-  action()->ExecuteAction(true);
-  EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
-
-  // Pressing the icon while the popup is shown should close the popup
-  EXPECT_CALL(*mock_delegate, OnPopupClosed()).Times(1);
-  action()->ExecuteAction(true);
-  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-
-  EXPECT_CALL(*mock_delegate, OnPopupShown(true)).Times(1);
-  dialog_controller->CreateMediaRouterDialog();
-
-  EXPECT_CALL(*mock_delegate, OnPopupClosed()).Times(1);
-  dialog_controller->HideMediaRouterDialog();
-}
diff --git a/chrome/browser/ui/toolbar/media_router_contextual_menu.cc b/chrome/browser/ui/toolbar/media_router_contextual_menu.cc
index a429c3b..46f5d650 100644
--- a/chrome/browser/ui/toolbar/media_router_contextual_menu.cc
+++ b/chrome/browser/ui/toolbar/media_router_contextual_menu.cc
@@ -21,13 +21,12 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/media_router/cloud_services_dialog.h"
 #include "chrome/browser/ui/singleton_tabs.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
 #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/vector_icons/vector_icons.h"
 #include "extensions/common/constants.h"
@@ -37,33 +36,21 @@
 #include "ui/gfx/paint_vector_icon.h"
 
 // static
-std::unique_ptr<MediaRouterContextualMenu>
-MediaRouterContextualMenu::CreateForToolbar(Browser* browser,
-                                            Observer* observer) {
+std::unique_ptr<MediaRouterContextualMenu> MediaRouterContextualMenu::Create(
+    Browser* browser,
+    Observer* observer) {
   return std::make_unique<MediaRouterContextualMenu>(
-      browser, true,
-      MediaRouterActionController::IsActionShownByPolicy(browser->profile()),
-      observer);
-}
-
-// static
-std::unique_ptr<MediaRouterContextualMenu>
-MediaRouterContextualMenu::CreateForOverflowMenu(Browser* browser,
-                                                 Observer* observer) {
-  return std::make_unique<MediaRouterContextualMenu>(
-      browser, false,
+      browser,
       MediaRouterActionController::IsActionShownByPolicy(browser->profile()),
       observer);
 }
 
 MediaRouterContextualMenu::MediaRouterContextualMenu(Browser* browser,
-                                                     bool is_action_in_toolbar,
                                                      bool shown_by_policy,
                                                      Observer* observer)
-    : observer_(observer),
-      browser_(browser),
-      menu_model_(std::make_unique<ui::SimpleMenuModel>(this)),
-      is_action_in_toolbar_(is_action_in_toolbar) {
+    : browser_(browser),
+      observer_(observer),
+      menu_model_(std::make_unique<ui::SimpleMenuModel>(this)) {
   menu_model_->AddItemWithStringId(IDC_MEDIA_ROUTER_ABOUT,
                                    IDS_MEDIA_ROUTER_ABOUT);
   menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
@@ -82,14 +69,8 @@
         IDC_MEDIA_ROUTER_ALWAYS_SHOW_TOOLBAR_ACTION,
         IDS_MEDIA_ROUTER_ALWAYS_SHOW_TOOLBAR_ACTION);
   }
-  if (media_router::ShouldUseViewsDialog()) {
-    menu_model_->AddCheckItemWithStringId(
-        IDC_MEDIA_ROUTER_TOGGLE_MEDIA_REMOTING,
-        IDS_MEDIA_ROUTER_TOGGLE_MEDIA_REMOTING);
-  } else {
-    menu_model_->AddItemWithStringId(IDC_MEDIA_ROUTER_SHOW_IN_TOOLBAR,
-                                     GetChangeVisibilityTextId());
-  }
+  menu_model_->AddCheckItemWithStringId(IDC_MEDIA_ROUTER_TOGGLE_MEDIA_REMOTING,
+                                        IDS_MEDIA_ROUTER_TOGGLE_MEDIA_REMOTING);
   if (!browser_->profile()->IsOffTheRecord()) {
     menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
     menu_model_->AddCheckItemWithStringId(
@@ -132,11 +113,6 @@
 }
 
 bool MediaRouterContextualMenu::IsCommandIdEnabled(int command_id) const {
-  // If the action is in the ephemeral state, disable the menu item for moving
-  // it between the toolbar and the overflow menu, since the preference would
-  // not persist.
-  if (command_id == IDC_MEDIA_ROUTER_SHOW_IN_TOOLBAR)
-    return GetAlwaysShowActionPref();
   return command_id != IDC_MEDIA_ROUTER_SHOWN_BY_POLICY;
 }
 
@@ -181,12 +157,6 @@
     case IDC_MEDIA_ROUTER_REPORT_ISSUE:
       ReportIssue();
       break;
-    case IDC_MEDIA_ROUTER_SHOW_IN_TOOLBAR:
-      ToolbarActionsModel::Get(browser_->profile())
-          ->SetActionVisibility(
-              ComponentToolbarActionsFactory::kMediaRouterActionId,
-              !is_action_in_toolbar_);
-      break;
     case IDC_MEDIA_ROUTER_TOGGLE_MEDIA_REMOTING:
       ToggleMediaRemoting();
       break;
@@ -236,8 +206,3 @@
       request_manager->media_route_provider_extension_id() + "/feedback.html");
   ShowSingletonTab(browser_, GURL(feedback_url));
 }
-
-int MediaRouterContextualMenu::GetChangeVisibilityTextId() {
-  return is_action_in_toolbar_ ? IDS_EXTENSIONS_HIDE_BUTTON_IN_MENU
-                               : IDS_EXTENSIONS_SHOW_BUTTON_IN_TOOLBAR;
-}
diff --git a/chrome/browser/ui/toolbar/media_router_contextual_menu.h b/chrome/browser/ui/toolbar/media_router_contextual_menu.h
index 1281be35..d4cbad3 100644
--- a/chrome/browser/ui/toolbar/media_router_contextual_menu.h
+++ b/chrome/browser/ui/toolbar/media_router_contextual_menu.h
@@ -11,7 +11,7 @@
 
 class Browser;
 
-// The class for the contextual menu for the Media Router action.
+// The class for the contextual menu for the Cast toolbar icon.
 class MediaRouterContextualMenu : public ui::SimpleMenuModel::Delegate {
  public:
   class Observer {
@@ -20,21 +20,13 @@
     virtual void OnContextMenuHidden() = 0;
   };
 
-  // Creates an instance for a Media Router Action shown in the toolbar.
+  // Creates an instance for a Cast toolbar icon shown in the toolbar.
   // |observer| must outlive the context menu.
-  static std::unique_ptr<MediaRouterContextualMenu> CreateForToolbar(
-      Browser* browser,
-      Observer* observer);
-
-  // Creates an instance for a Media Router Action shown in the overflow menu.
-  // |observer| must outlive the context menu.
-  static std::unique_ptr<MediaRouterContextualMenu> CreateForOverflowMenu(
-      Browser* browser,
-      Observer* observer);
+  static std::unique_ptr<MediaRouterContextualMenu> Create(Browser* browser,
+                                                           Observer* observer);
 
   // Constructor called by the static Create* methods above and tests.
   MediaRouterContextualMenu(Browser* browser,
-                            bool is_action_in_toolbar,
                             bool shown_by_policy,
                             Observer* observer);
   ~MediaRouterContextualMenu() override;
@@ -81,22 +73,14 @@
   // Opens feedback page loaded from the media router extension.
   void ReportIssue();
 
-  // Gets the ID corresponding to the text for the menu option to change the
-  // visibility of the action (e.g. "Hide in Chrome menu" / "Show in toolbar")
-  // depending on the location of the action.
-  int GetChangeVisibilityTextId();
+  Browser* const browser_;
 
   Observer* const observer_;
 
-  Browser* const browser_;
-
   // TODO(takumif): |menu_model_| is required by MediaRouterAction but not by
   // CastToolbarButton. Remove |menu_model_| when removing MediaRouterAction.
   std::unique_ptr<ui::SimpleMenuModel> menu_model_;
 
-  // Whether the action icon is in the toolbar, as opposed to the overflow menu.
-  const bool is_action_in_toolbar_;
-
   DISALLOW_COPY_AND_ASSIGN(MediaRouterContextualMenu);
 };
 
diff --git a/chrome/browser/ui/toolbar/media_router_contextual_menu_unittest.cc b/chrome/browser/ui/toolbar/media_router_contextual_menu_unittest.cc
index ae1992d..6d309c1652 100644
--- a/chrome/browser/ui/toolbar/media_router_contextual_menu_unittest.cc
+++ b/chrome/browser/ui/toolbar/media_router_contextual_menu_unittest.cc
@@ -15,8 +15,6 @@
 #include "chrome/browser/ui/extensions/browser_action_test_util.h"
 #include "chrome/browser/ui/media_router/media_router_ui_service.h"
 #include "chrome/browser/ui/media_router/media_router_ui_service_factory.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
 #include "chrome/browser/ui/toolbar/media_router_contextual_menu.h"
 #include "chrome/browser/ui/toolbar/mock_media_router_action_controller.h"
@@ -31,9 +29,8 @@
 
 namespace {
 
-// These constants are used to inject the state of the Media Router action
+// These constants are used to inject the state of the Cast toolbar icon
 // that would be inferred in the production code.
-constexpr bool kInToolbar = true;
 constexpr bool kShownByPolicy = true;
 constexpr bool kShownByUser = false;
 
@@ -73,15 +70,9 @@
     identity_test_env_adaptor_ =
         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile());
 
-    toolbar_actions_model_ =
-        extensions::extension_action_test_util::CreateToolbarModelForProfile(
-            profile());
-
     browser_action_test_util_ = BrowserActionTestUtil::Create(browser(), false);
-    action_ = std::make_unique<MediaRouterAction>(
-        browser(), browser_action_test_util_->GetToolbarActionsBar());
 
-    // Pin the Media Router action to the toolbar.
+    // Pin the Cast icon to the toolbar.
     MediaRouterActionController::SetAlwaysShowActionPref(profile(), true);
 
     media_router::MediaRouterUIServiceFactory::GetInstance()->SetTestingFactory(
@@ -93,7 +84,6 @@
     // |identity_test_env_adaptor_| must be destroyed before the TestingProfile,
     // which occurs in BrowserWithTestWindowTest::TearDown().
     identity_test_env_adaptor_.reset();
-    action_.reset();
     browser_action_test_util_.reset();
     BrowserWithTestWindowTest::TearDown();
   }
@@ -118,7 +108,6 @@
   }
 
   std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_;
-  std::unique_ptr<MediaRouterAction> action_;
   std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
       identity_test_env_adaptor_;
 
@@ -136,14 +125,14 @@
   // Learn more
   // Help
   // Always show icon (checkbox)
-  // Hide in Chrome menu / Show in toolbar
+  // Optimize fullscreen videos (checkbox)
   // -----
   // Enable cloud services (checkbox)
   // Report an issue
   int expected_number_items = 9;
 
-  ui::SimpleMenuModel* model =
-      static_cast<ui::SimpleMenuModel*>(action_->GetContextMenu());
+  MediaRouterContextualMenu menu(browser(), kShownByUser, &observer_);
+  ui::SimpleMenuModel* model = menu.menu_model();
   // Verify the number of menu items, including separators.
   EXPECT_EQ(model->GetItemCount(), expected_number_items);
 
@@ -172,21 +161,19 @@
 // "Report an issue" should be present for normal profiles but not for
 // incognito.
 TEST_F(MediaRouterContextualMenuUnitTest, EnableAndDisableReportIssue) {
-  ui::SimpleMenuModel* model =
-      static_cast<ui::SimpleMenuModel*>(action_->GetContextMenu());
-  EXPECT_NE(-1, model->GetIndexOfCommandId(IDC_MEDIA_ROUTER_REPORT_ISSUE));
+  MediaRouterContextualMenu menu(browser(), kShownByPolicy, &observer_);
+  EXPECT_NE(-1, menu.menu_model()->GetIndexOfCommandId(
+                    IDC_MEDIA_ROUTER_REPORT_ISSUE));
 
   std::unique_ptr<BrowserWindow> window(CreateBrowserWindow());
   std::unique_ptr<Browser> incognito_browser(
       CreateBrowser(profile()->GetOffTheRecordProfile(), Browser::TYPE_TABBED,
                     false, window.get()));
 
-  action_ = std::make_unique<MediaRouterAction>(
-      incognito_browser.get(),
-      browser_action_test_util_->GetToolbarActionsBar());
-  model = static_cast<ui::SimpleMenuModel*>(action_->GetContextMenu());
-  EXPECT_EQ(-1, model->GetIndexOfCommandId(IDC_MEDIA_ROUTER_REPORT_ISSUE));
-  action_.reset();
+  MediaRouterContextualMenu incognito_menu(incognito_browser.get(),
+                                           kShownByPolicy, &observer_);
+  EXPECT_EQ(-1, incognito_menu.menu_model()->GetIndexOfCommandId(
+                    IDC_MEDIA_ROUTER_REPORT_ISSUE));
 }
 
 // Tests whether the cloud services item is correctly toggled. This menu item
@@ -194,10 +181,9 @@
 // TODO(takumif): Add a test case that checks that the cloud services dialog is
 // shown when the services are enabled for the first time.
 TEST_F(MediaRouterContextualMenuUnitTest, ToggleCloudServicesItem) {
-  // The Media Router Action has a getter for the model, but not the delegate.
+  // The Cast toolbar icon has a getter for the model, but not the delegate.
   // Create the MediaRouterContextualMenu ui::SimpleMenuModel::Delegate here.
-  MediaRouterContextualMenu menu(browser(), kInToolbar, kShownByPolicy,
-                                 &observer_);
+  MediaRouterContextualMenu menu(browser(), kShownByPolicy, &observer_);
 
   // Set up an authenticated account such that the cloud services menu item is
   // surfaced. Whether or not it is surfaced is tested in the "Basic" test.
@@ -222,8 +208,7 @@
 }
 
 TEST_F(MediaRouterContextualMenuUnitTest, ToggleMediaRemotingItem) {
-  MediaRouterContextualMenu menu(browser(), kInToolbar, kShownByPolicy,
-                                 &observer_);
+  MediaRouterContextualMenu menu(browser(), kShownByPolicy, &observer_);
 
   PrefService* pref_service = browser()->profile()->GetPrefs();
   pref_service->SetBoolean(prefs::kMediaRouterMediaRemotingEnabled, false);
@@ -241,8 +226,7 @@
 }
 
 TEST_F(MediaRouterContextualMenuUnitTest, ToggleAlwaysShowIconItem) {
-  MediaRouterContextualMenu menu(browser(), kInToolbar, kShownByUser,
-                                 &observer_);
+  MediaRouterContextualMenu menu(browser(), kShownByUser, &observer_);
 
   // Whether the option is checked should reflect the pref.
   MediaRouterActionController::SetAlwaysShowActionPref(profile(), true);
@@ -263,8 +247,7 @@
 
 TEST_F(MediaRouterContextualMenuUnitTest, ActionShownByPolicy) {
   // Create a contextual menu for an icon shown by administrator policy.
-  MediaRouterContextualMenu menu(browser(), kInToolbar, kShownByPolicy,
-                                 &observer_);
+  MediaRouterContextualMenu menu(browser(), kShownByPolicy, &observer_);
 
   // The item "Added by your administrator" should be shown disabled.
   EXPECT_TRUE(menu.IsCommandIdVisible(IDC_MEDIA_ROUTER_SHOWN_BY_POLICY));
@@ -278,7 +261,7 @@
 TEST_F(MediaRouterContextualMenuUnitTest, NotifyActionController) {
   EXPECT_CALL(observer_, OnContextMenuShown());
   auto menu = std::make_unique<MediaRouterContextualMenu>(
-      browser(), kInToolbar, kShownByUser, &observer_);
+      browser(), kShownByUser, &observer_);
   menu->OnMenuWillShow(menu->menu_model());
 
   EXPECT_CALL(observer_, OnContextMenuHidden());
diff --git a/chrome/browser/ui/toolbar/mock_media_router_action_controller.cc b/chrome/browser/ui/toolbar/mock_media_router_action_controller.cc
index 309dead7..b5f8c3b1 100644
--- a/chrome/browser/ui/toolbar/mock_media_router_action_controller.cc
+++ b/chrome/browser/ui/toolbar/mock_media_router_action_controller.cc
@@ -10,6 +10,6 @@
     Profile* profile)
     : MediaRouterActionController(
           profile,
-          media_router::MediaRouterFactory::GetApiForBrowserContext(profile),
-          nullptr) {}
-MockMediaRouterActionController::~MockMediaRouterActionController() {}
+          media_router::MediaRouterFactory::GetApiForBrowserContext(profile)) {}
+
+MockMediaRouterActionController::~MockMediaRouterActionController() = default;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index 86b7ef64..c6e7a797d 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
@@ -34,7 +35,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chrome/test/base/view_event_test_base.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/common/bookmark_pref_names.h"
 #include "components/bookmarks/test/bookmark_test_helpers.h"
@@ -608,14 +608,16 @@
 
 VIEW_TEST(BookmarkBarViewTest3, Submenus)
 
-// Observer that posts task upon the context menu creation.
-// This is necessary for Linux as the context menu has to check
-// the clipboard, which invokes the event loop.
+// Observer that posts a task upon the context menu creation.
+// This is necessary for Linux as the context menu has to check the clipboard,
+// which invokes the event loop.
+// Because |task| is a OnceClosure, callers should use a separate observer
+// instance for each successive context menu creation they wish to observe.
 class BookmarkContextMenuNotificationObserver
     : public content::NotificationObserver {
  public:
-  explicit BookmarkContextMenuNotificationObserver(const base::Closure& task)
-      : task_(task) {
+  explicit BookmarkContextMenuNotificationObserver(base::OnceClosure task)
+      : task_(std::move(task)) {
     registrar_.Add(this,
                    chrome::NOTIFICATION_BOOKMARK_CONTEXT_MENU_SHOWN,
                    content::NotificationService::AllSources());
@@ -624,15 +626,13 @@
   void Observe(int type,
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task_);
+    DCHECK(!task_.is_null());
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task_));
   }
 
-  // Sets the task that is posted when the context menu is shown.
-  void set_task(const base::Closure& task) { task_ = task; }
-
  private:
   content::NotificationRegistrar registrar_;
-  base::Closure task_;
+  base::OnceClosure task_;
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenuNotificationObserver);
 };
@@ -668,8 +668,9 @@
     ASSERT_TRUE(child_menu != NULL);
 
     // Right click on the first child to get its context menu.
-    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        child_menu, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1246,8 +1247,9 @@
     ASSERT_TRUE(child_menu != NULL);
 
     // Right click on the first child to get its context menu.
-    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        child_menu, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1342,8 +1344,8 @@
         std::make_unique<DialogWaiter>(GetWidget()->GetNativeWindow()->env());
     ui_test_utils::MoveMouseToCenterAndPress(
         child_menu, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
-        base::Bind(&BookmarkBarViewTest12::Step4, base::Unretained(this),
-                   base::Passed(&dialog_waiter)));
+        base::BindOnce(&BookmarkBarViewTest12::Step4, base::Unretained(this),
+                       std::move(dialog_waiter)));
   }
 
   void Step4(std::unique_ptr<DialogWaiter> waiter) {
@@ -1408,8 +1410,9 @@
     ASSERT_TRUE(child_menu != NULL);
 
     // Right click on the first child to get its context menu.
-    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        child_menu, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1475,8 +1478,9 @@
     // Move the mouse to the first folder on the bookmark bar and press the
     // right mouse button.
     views::LabelButton* button = GetBookmarkButton(0);
-    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        button, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step2 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1533,8 +1537,9 @@
     deleted_menu_id_ = child_menu->GetCommand();
 
     // Right click on the second child to get its context menu.
-    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        child_menu, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1618,8 +1623,8 @@
 class BookmarkBarViewTest17 : public BookmarkBarViewEventTestBase {
  public:
   BookmarkBarViewTest17()
-      : observer_(CreateEventTask(this, &BookmarkBarViewTest17::Step3)) {
-  }
+      : observer_(std::make_unique<BookmarkContextMenuNotificationObserver>(
+            CreateEventTask(this, &BookmarkBarViewTest17::Step3))) {}
 
  protected:
   void DoTestOnMessageLoop() override {
@@ -1641,8 +1646,9 @@
     // Right click on the second item to show its context menu.
     views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(2);
     ASSERT_TRUE(child_menu != NULL);
-    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        child_menu, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
@@ -1668,7 +1674,8 @@
     gfx::Rect clickable_rect =
         gfx::SubtractRects(child_menu_rect, context_rect);
     ASSERT_FALSE(clickable_rect.IsEmpty());
-    observer_.set_task(CreateEventTask(this, &BookmarkBarViewTest17::Step4));
+    observer_ = std::make_unique<BookmarkContextMenuNotificationObserver>(
+        CreateEventTask(this, &BookmarkBarViewTest17::Step4));
     MoveMouseAndPress(clickable_rect.CenterPoint(), ui_controls::RIGHT,
         ui_controls::DOWN | ui_controls::UP, base::Closure());
     // Step4 will be invoked by BookmarkContextMenuNotificationObserver.
@@ -1689,7 +1696,7 @@
     Done();
   }
 
-  BookmarkContextMenuNotificationObserver observer_;
+  std::unique_ptr<BookmarkContextMenuNotificationObserver> observer_;
 };
 
 // Flaky. See http://crbug.com/820435.
@@ -1961,8 +1968,9 @@
     EXPECT_EQ(views::MenuItemView::kEmptyMenuItemViewID, view->id());
 
     // Right click on the first child to get its context menu.
-    ui_test_utils::MoveMouseToCenterAndPress(view, ui_controls::RIGHT,
-        ui_controls::DOWN | ui_controls::UP, base::Closure());
+    ui_test_utils::MoveMouseToCenterAndPress(
+        view, ui_controls::RIGHT, ui_controls::DOWN | ui_controls::UP,
+        base::OnceClosure());
     // Step3 will be invoked by BookmarkContextMenuNotificationObserver.
   }
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index 3553e43..3663d7a0 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -152,7 +152,8 @@
                          ->hosted_app_button_container_for_testing());
 }
 
-// Tests the frame color for a bookmark app when a theme is applied.
+// Checks that the title bar for hosted app windows is hidden when in fullscreen
+// for tab mode.
 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewBrowserTest,
                        FullscreenForTabTitlebarHeight) {
   InstallAndLaunchBookmarkApp();
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc
index 7cfc948..76b02e8 100644
--- a/chrome/browser/ui/views/media_router/cast_toolbar_button.cc
+++ b/chrome/browser/ui/views/media_router/cast_toolbar_button.cc
@@ -33,7 +33,7 @@
   }
 
   std::unique_ptr<MediaRouterContextualMenu> context_menu =
-      MediaRouterContextualMenu::CreateForToolbar(
+      MediaRouterContextualMenu::Create(
           browser,
           MediaRouterUIService::Get(browser->profile())->action_controller());
   return std::make_unique<CastToolbarButton>(
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
index 938ea8b..bf3c4ec 100644
--- a/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
+++ b/chrome/browser/ui/views/media_router/cast_toolbar_button_unittest.cc
@@ -87,7 +87,7 @@
     MediaRouter* media_router =
         MediaRouterFactory::GetApiForBrowserContext(profile_.get());
     auto context_menu = std::make_unique<MediaRouterContextualMenu>(
-        browser_.get(), true, false, &context_menu_observer_);
+        browser_.get(), false, &context_menu_observer_);
     button_ = std::make_unique<CastToolbarButton>(browser_.get(), media_router,
                                                   std::move(context_menu));
 
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
index 1c7fa31..05e9f6d 100644
--- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
+++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
@@ -9,7 +9,6 @@
 #include "build/build_config.h"
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/media_router/cast_dialog_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
diff --git a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
index bc4519a8..24aa218 100644
--- a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
+++ b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
@@ -18,10 +18,7 @@
 #include "chrome/browser/ui/media_router/media_router_dialog_controller_impl_base.h"
 #include "chrome/browser/ui/media_router/media_router_ui_service.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
-#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/media_router/app_menu_test_api.h"
 #include "chrome/browser/ui/views/media_router/cast_toolbar_button.h"
@@ -52,9 +49,6 @@
   ~MediaRouterUIBrowserTest() override {}
 
   void SetUpOnMainThread() override {
-    toolbar_actions_bar_ =
-        BrowserActionTestUtil::Create(browser(), true)->GetToolbarActionsBar();
-
     action_controller_ =
         MediaRouterUIService::Get(browser()->profile())->action_controller();
 
@@ -62,38 +56,13 @@
                           "description", true, true)};
   }
 
-  void OpenMediaRouterDialogAndWaitForNewWebContents() {
-    content::TestNavigationObserver nav_observer(NULL);
-    nav_observer.StartWatchingNewWebContents();
-
-    // When the Media Router Action executes, it opens a dialog with web
-    // contents to chrome://media-router.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&MediaRouterUIBrowserTest::PressToolbarIcon,
-                                  base::Unretained(this)));
-
-    std::unique_ptr<test::AppMenuTestApi> test_api =
-        test::AppMenuTestApi::Create(browser());
-    test_api->ShowMenu();
-
-    nav_observer.Wait();
-    EXPECT_FALSE(test_api->IsMenuShowing());
-    ASSERT_EQ(chrome::kChromeUIMediaRouterURL,
-        nav_observer.last_navigation_url().spec());
-    nav_observer.StopWatchingNewWebContents();
-  }
-
   // Returns the dialog controller for the active WebContents.
   MediaRouterDialogControllerImplBase* GetDialogController() {
     return MediaRouterDialogControllerImplBase::GetOrCreateForWebContents(
         browser()->tab_strip_model()->GetActiveWebContents());
   }
 
-  MediaRouterAction* GetMediaRouterAction() {
-    return GetDialogController()->action();
-  }
-
-  CastToolbarButton* GetTrustedAreaIcon() {
+  CastToolbarButton* GetCastIcon() {
     return BrowserView::GetBrowserViewForBrowser(browser())
         ->toolbar()
         ->cast_button();
@@ -101,27 +70,18 @@
 
   ui::SimpleMenuModel* GetIconContextMenu() {
     return static_cast<ui::SimpleMenuModel*>(
-        ShouldUseViewsDialog() ? GetTrustedAreaIcon()->menu_model_for_test()
-                               : GetMediaRouterAction()->GetContextMenu());
+        GetCastIcon()->menu_model_for_test());
   }
 
   void PressToolbarIcon() {
-    if (ShouldUseViewsDialog()) {
-      GetTrustedAreaIcon()->OnMousePressed(ui::MouseEvent(
-          ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0),
-          ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0));
-    } else {
-      GetMediaRouterAction()->ExecuteAction(true);
-    }
+    GetCastIcon()->OnMousePressed(
+        ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0),
+                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0));
   }
 
   bool ToolbarIconExists() {
     base::RunLoop().RunUntilIdle();
-    if (ShouldUseViewsDialog())
-      return GetTrustedAreaIcon()->visible();
-    return ToolbarActionsModel::Get(browser()->profile())
-        ->HasComponentAction(
-            ComponentToolbarActionsFactory::kMediaRouterActionId);
+    return GetCastIcon()->visible();
   }
 
   void SetAlwaysShowActionPref(bool always_show) {
@@ -130,123 +90,6 @@
   }
 
  protected:
-  // Test* methods contain tests that are run with both WebUI and Views
-  // implementations of the dialog.
-  void TestOpenDialogFromContextMenu() {
-    // Start with one tab showing about:blank.
-    ASSERT_EQ(1, browser()->tab_strip_model()->count());
-
-    content::WebContents* web_contents =
-        browser()->tab_strip_model()->GetActiveWebContents();
-    MediaRouterDialogController* dialog_controller = GetDialogController();
-    content::ContextMenuParams params;
-    params.page_url =
-        web_contents->GetController().GetLastCommittedEntry()->GetURL();
-    TestRenderViewContextMenu menu(web_contents->GetMainFrame(), params);
-    menu.Init();
-
-    ASSERT_TRUE(menu.IsItemPresent(IDC_ROUTE_MEDIA));
-    ASSERT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-    menu.ExecuteCommand(IDC_ROUTE_MEDIA, 0);
-    EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
-
-    // Executing the command again should be a no-op, and there should only be
-    // one dialog opened per tab.
-    menu.ExecuteCommand(IDC_ROUTE_MEDIA, 0);
-    EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
-    dialog_controller->HideMediaRouterDialog();
-    EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-  }
-
-  void TestOpenDialogFromAppMenu() {
-    // Start with one tab showing about:blank.
-    ASSERT_EQ(1, browser()->tab_strip_model()->count());
-
-    std::unique_ptr<test::AppMenuTestApi> app_menu_test_api =
-        test::AppMenuTestApi::Create(browser());
-    app_menu_test_api->ShowMenu();
-
-    MediaRouterDialogController* dialog_controller = GetDialogController();
-    ASSERT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-    app_menu_test_api->ExecuteCommand(IDC_ROUTE_MEDIA);
-    EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
-
-    // Executing the command again should be a no-op, and there should only be
-    // one dialog opened per tab.
-    app_menu_test_api->ExecuteCommand(IDC_ROUTE_MEDIA);
-    EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
-    dialog_controller->HideMediaRouterDialog();
-    EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-  }
-
-  void TestEphemeralToolbarIconForDialog() {
-    MediaRouterDialogController* dialog_controller = GetDialogController();
-
-    EXPECT_FALSE(ToolbarIconExists());
-    dialog_controller->ShowMediaRouterDialog();
-    EXPECT_TRUE(ToolbarIconExists());
-    dialog_controller->HideMediaRouterDialog();
-    EXPECT_FALSE(ToolbarIconExists());
-
-    dialog_controller->ShowMediaRouterDialog();
-    EXPECT_TRUE(ToolbarIconExists());
-    // Clicking on the toolbar icon should hide both the dialog and the icon.
-    PressToolbarIcon();
-    EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
-    EXPECT_FALSE(ToolbarIconExists());
-
-    dialog_controller->ShowMediaRouterDialog();
-    SetAlwaysShowActionPref(true);
-    // When the pref is set to true, hiding the dialog shouldn't hide the icon.
-    dialog_controller->HideMediaRouterDialog();
-    EXPECT_TRUE(ToolbarIconExists());
-    dialog_controller->ShowMediaRouterDialog();
-    // While the dialog is showing, setting the pref to false shouldn't hide the
-    // icon.
-    SetAlwaysShowActionPref(false);
-    EXPECT_TRUE(ToolbarIconExists());
-    dialog_controller->HideMediaRouterDialog();
-    EXPECT_FALSE(ToolbarIconExists());
-  }
-
-  void TestEphemeralToolbarIconForRoutesAndIssues() {
-    action_controller_->OnIssue(issue_);
-    EXPECT_TRUE(ToolbarIconExists());
-    action_controller_->OnIssuesCleared();
-    EXPECT_FALSE(ToolbarIconExists());
-
-    action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
-    EXPECT_TRUE(ToolbarIconExists());
-    action_controller_->OnRoutesUpdated(std::vector<MediaRoute>(),
-                                        std::vector<MediaRoute::Id>());
-    EXPECT_FALSE(ToolbarIconExists());
-
-    SetAlwaysShowActionPref(true);
-    EXPECT_TRUE(ToolbarIconExists());
-    SetAlwaysShowActionPref(false);
-    EXPECT_FALSE(ToolbarIconExists());
-  }
-
-  void TestEphemeralToolbarIconWithMultipleWindows() {
-    action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
-    EXPECT_TRUE(ToolbarIconExists());
-
-    // Opening and closing a window shouldn't affect the state of the ephemeral
-    // icon. Creating and removing the icon with multiple windows open should
-    // also work.
-    Browser* browser2 = CreateBrowser(browser()->profile());
-    EXPECT_TRUE(ToolbarIconExists());
-    action_controller_->OnRoutesUpdated(std::vector<MediaRoute>(),
-                                        std::vector<MediaRoute::Id>());
-    EXPECT_FALSE(ToolbarIconExists());
-    action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
-    EXPECT_TRUE(ToolbarIconExists());
-    browser2->window()->Close();
-    EXPECT_TRUE(ToolbarIconExists());
-  }
-
-  ToolbarActionsBar* toolbar_actions_bar_ = nullptr;
-
   Issue issue_;
 
   // A vector of MediaRoutes that includes a local route.
@@ -255,39 +98,133 @@
   MediaRouterActionController* action_controller_ = nullptr;
 };
 
-// Runs dialog-related tests with the WebUI Cast dialog.
-class MediaRouterWebUIBrowserTest : public MediaRouterUIBrowserTest {
- protected:
-  void SetUp() override {
-    feature_list_.InitAndDisableFeature(features::kViewsCastDialog);
-    MediaRouterUIBrowserTest::SetUp();
-  }
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest, OpenDialogFromContextMenu) {
+  // Start with one tab showing about:blank.
+  ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
-  base::test::ScopedFeatureList feature_list_;
-};
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  MediaRouterDialogController* dialog_controller = GetDialogController();
+  content::ContextMenuParams params;
+  params.page_url =
+      web_contents->GetController().GetLastCommittedEntry()->GetURL();
+  TestRenderViewContextMenu menu(web_contents->GetMainFrame(), params);
+  menu.Init();
 
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest, OpenDialogFromContextMenu) {
-  TestOpenDialogFromContextMenu();
+  ASSERT_TRUE(menu.IsItemPresent(IDC_ROUTE_MEDIA));
+  ASSERT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
+  menu.ExecuteCommand(IDC_ROUTE_MEDIA, 0);
+  EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
+
+  dialog_controller->HideMediaRouterDialog();
+  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
 }
 
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest, OpenDialogFromAppMenu) {
-  TestOpenDialogFromAppMenu();
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest, OpenDialogFromAppMenu) {
+  // Start with one tab showing about:blank.
+  ASSERT_EQ(1, browser()->tab_strip_model()->count());
+
+  std::unique_ptr<test::AppMenuTestApi> app_menu_test_api =
+      test::AppMenuTestApi::Create(browser());
+  app_menu_test_api->ShowMenu();
+
+  MediaRouterDialogController* dialog_controller = GetDialogController();
+  ASSERT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
+  app_menu_test_api->ExecuteCommand(IDC_ROUTE_MEDIA);
+  EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
+
+  dialog_controller->HideMediaRouterDialog();
+  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
 }
 
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest,
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest,
                        EphemeralToolbarIconForDialog) {
-  TestEphemeralToolbarIconForDialog();
+  MediaRouterDialogController* dialog_controller = GetDialogController();
+
+  EXPECT_FALSE(ToolbarIconExists());
+  dialog_controller->ShowMediaRouterDialog();
+  EXPECT_TRUE(ToolbarIconExists());
+  dialog_controller->HideMediaRouterDialog();
+  EXPECT_FALSE(ToolbarIconExists());
+
+  dialog_controller->ShowMediaRouterDialog();
+  EXPECT_TRUE(ToolbarIconExists());
+  // Clicking on the toolbar icon should hide both the dialog and the icon.
+  PressToolbarIcon();
+  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
+  EXPECT_FALSE(ToolbarIconExists());
+
+  dialog_controller->ShowMediaRouterDialog();
+  SetAlwaysShowActionPref(true);
+  // When the pref is set to true, hiding the dialog shouldn't hide the icon.
+  dialog_controller->HideMediaRouterDialog();
+  EXPECT_TRUE(ToolbarIconExists());
+  dialog_controller->ShowMediaRouterDialog();
+  // While the dialog is showing, setting the pref to false shouldn't hide the
+  // icon.
+  SetAlwaysShowActionPref(false);
+  EXPECT_TRUE(ToolbarIconExists());
+  dialog_controller->HideMediaRouterDialog();
+  EXPECT_FALSE(ToolbarIconExists());
 }
 
-#if defined(OS_MACOSX)
-// TODO(paksting): Flakily times out on Mac.  https://crbug.com/918742
-#define MAYBE_OpenDialogWithMediaRouterAction \
-  DISABLED_OpenDialogWithMediaRouterAction
-#else
-#define MAYBE_OpenDialogWithMediaRouterAction OpenDialogWithMediaRouterAction
-#endif
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest,
-                       MAYBE_OpenDialogWithMediaRouterAction) {
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest, PinAndUnpinToolbarIcon) {
+  GetDialogController()->ShowMediaRouterDialog();
+  EXPECT_TRUE(ToolbarIconExists());
+  // Pin the icon via its context menu.
+  ui::SimpleMenuModel* context_menu = GetIconContextMenu();
+  const int command_index = context_menu->GetIndexOfCommandId(
+      IDC_MEDIA_ROUTER_ALWAYS_SHOW_TOOLBAR_ACTION);
+  context_menu->ActivatedAt(command_index);
+  GetDialogController()->HideMediaRouterDialog();
+  EXPECT_TRUE(ToolbarIconExists());
+
+  // Unpin the icon via its context menu.
+  GetIconContextMenu()->ActivatedAt(command_index);
+  EXPECT_FALSE(ToolbarIconExists());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest,
+                       EphemeralToolbarIconForRoutesAndIssues) {
+  action_controller_->OnIssue(issue_);
+  EXPECT_TRUE(ToolbarIconExists());
+  action_controller_->OnIssuesCleared();
+  EXPECT_FALSE(ToolbarIconExists());
+
+  action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
+  EXPECT_TRUE(ToolbarIconExists());
+  action_controller_->OnRoutesUpdated(std::vector<MediaRoute>(),
+                                      std::vector<MediaRoute::Id>());
+  EXPECT_FALSE(ToolbarIconExists());
+
+  SetAlwaysShowActionPref(true);
+  EXPECT_TRUE(ToolbarIconExists());
+  SetAlwaysShowActionPref(false);
+  EXPECT_FALSE(ToolbarIconExists());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest,
+                       EphemeralToolbarIconWithMultipleWindows) {
+  action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
+  EXPECT_TRUE(ToolbarIconExists());
+
+  // Opening and closing a window shouldn't affect the state of the ephemeral
+  // icon. Creating and removing the icon with multiple windows open should
+  // also work.
+  Browser* browser2 = CreateBrowser(browser()->profile());
+  EXPECT_TRUE(ToolbarIconExists());
+  action_controller_->OnRoutesUpdated(std::vector<MediaRoute>(),
+                                      std::vector<MediaRoute::Id>());
+  EXPECT_FALSE(ToolbarIconExists());
+  action_controller_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
+  EXPECT_TRUE(ToolbarIconExists());
+  browser2->window()->Close();
+  EXPECT_TRUE(ToolbarIconExists());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaRouterUIBrowserTest,
+                       OpenDialogWithMediaRouterAction) {
+  MediaRouterDialogController* dialog_controller = GetDialogController();
   // We start off at about:blank page.
   // Make sure there is 1 tab and media router is enabled.
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
@@ -295,7 +232,8 @@
   SetAlwaysShowActionPref(true);
   EXPECT_TRUE(ToolbarIconExists());
 
-  OpenMediaRouterDialogAndWaitForNewWebContents();
+  PressToolbarIcon();
+  EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
 
   // Reload the browser and wait.
   content::TestNavigationObserver reload_observer(
@@ -303,162 +241,17 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   reload_observer.Wait();
 
-  // The reload should have removed the previously created dialog.
-  // We expect a new dialog WebContents to be created by calling this.
-  OpenMediaRouterDialogAndWaitForNewWebContents();
+  // The reload should have closed the dialog.
+  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
+  PressToolbarIcon();
+  EXPECT_TRUE(dialog_controller->IsShowingMediaRouterDialog());
 
   // Navigate away.
   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
 
-  // The navigation should have removed the previously created dialog.
-  // We expect a new dialog WebContents to be created by calling this.
-  OpenMediaRouterDialogAndWaitForNewWebContents();
-
+  // The navigation should have closed the dialog.
+  EXPECT_FALSE(dialog_controller->IsShowingMediaRouterDialog());
   SetAlwaysShowActionPref(false);
 }
 
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest, OpenDialogsInMultipleTabs) {
-  // Start with two tabs.
-  chrome::NewTab(browser());
-  ASSERT_EQ(2, browser()->tab_strip_model()->count());
-  MediaRouterDialogController* dialog_controller1 =
-      MediaRouterDialogController::GetOrCreateForWebContents(
-          browser()->tab_strip_model()->GetWebContentsAt(0));
-  MediaRouterDialogController* dialog_controller2 =
-      MediaRouterDialogController::GetOrCreateForWebContents(
-          browser()->tab_strip_model()->GetWebContentsAt(1));
-
-  // Show the media router action on the toolbar.
-  SetAlwaysShowActionPref(true);
-
-  // Open a dialog in the first tab using the toolbar action.
-  browser()->tab_strip_model()->ActivateTabAt(0, true);
-  EXPECT_FALSE(dialog_controller1->IsShowingMediaRouterDialog());
-  PressToolbarIcon();
-  EXPECT_TRUE(dialog_controller1->IsShowingMediaRouterDialog());
-
-  // Move to the second tab, which shouldn't have a dialog at first. Open and
-  // close a dialog in that tab.
-  browser()->tab_strip_model()->ActivateTabAt(1, true);
-  EXPECT_FALSE(dialog_controller2->IsShowingMediaRouterDialog());
-  PressToolbarIcon();
-  EXPECT_TRUE(dialog_controller2->IsShowingMediaRouterDialog());
-  PressToolbarIcon();
-  EXPECT_FALSE(dialog_controller2->IsShowingMediaRouterDialog());
-
-  // Move back to the first tab, whose dialog should still be open. Hide the
-  // dialog.
-  browser()->tab_strip_model()->ActivateTabAt(0, true);
-  EXPECT_TRUE(dialog_controller1->IsShowingMediaRouterDialog());
-  PressToolbarIcon();
-  EXPECT_FALSE(dialog_controller1->IsShowingMediaRouterDialog());
-
-  // Reset the preference showing the toolbar action.
-  SetAlwaysShowActionPref(false);
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest,
-                       EphemeralToolbarIconForRoutesAndIssues) {
-  TestEphemeralToolbarIconForRoutesAndIssues();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest,
-                       EphemeralToolbarIconWithMultipleWindows) {
-  TestEphemeralToolbarIconWithMultipleWindows();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest, UpdateActionLocation) {
-  SetAlwaysShowActionPref(true);
-
-  // Get the index for "Hide in Chrome menu" / "Show in toolbar" menu item.
-  const int command_index = GetIconContextMenu()->GetIndexOfCommandId(
-      IDC_MEDIA_ROUTER_SHOW_IN_TOOLBAR);
-  GetMediaRouterAction()->OnContextMenuClosed();
-
-  // Start out with the action visible on the main bar.
-  EXPECT_TRUE(
-      toolbar_actions_bar_->IsActionVisibleOnMainBar(GetMediaRouterAction()));
-  GetIconContextMenu()->ActivatedAt(command_index);
-  GetMediaRouterAction()->OnContextMenuClosed();
-
-  // The action should get hidden in the overflow menu.
-  EXPECT_FALSE(
-      toolbar_actions_bar_->IsActionVisibleOnMainBar(GetMediaRouterAction()));
-  GetIconContextMenu()->ActivatedAt(command_index);
-  GetMediaRouterAction()->OnContextMenuClosed();
-
-  // The action should be back on the main bar.
-  EXPECT_TRUE(
-      toolbar_actions_bar_->IsActionVisibleOnMainBar(GetMediaRouterAction()));
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterWebUIBrowserTest, PinAndUnpinToolbarIcon) {
-  GetDialogController()->ShowMediaRouterDialog();
-  EXPECT_TRUE(ToolbarIconExists());
-  // Pin the icon via its context menu.
-  ui::SimpleMenuModel* context_menu = GetIconContextMenu();
-  const int command_index = context_menu->GetIndexOfCommandId(
-      IDC_MEDIA_ROUTER_ALWAYS_SHOW_TOOLBAR_ACTION);
-  context_menu->ActivatedAt(command_index);
-  GetMediaRouterAction()->OnContextMenuClosed();
-  GetDialogController()->HideMediaRouterDialog();
-  EXPECT_TRUE(ToolbarIconExists());
-
-  // Unpin the icon via its context menu.
-  CHECK(GetIconContextMenu());
-  GetIconContextMenu()->ActivatedAt(command_index);
-  EXPECT_FALSE(ToolbarIconExists());
-}
-
-// Runs dialog-related tests with the Views Cast dialog.
-class MediaRouterViewsUIBrowserTest : public MediaRouterUIBrowserTest {
- protected:
-  void SetUp() override {
-    feature_list_.InitAndEnableFeature(features::kViewsCastDialog);
-    MediaRouterUIBrowserTest::SetUp();
-  }
-
-  base::test::ScopedFeatureList feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest,
-                       OpenDialogFromContextMenu) {
-  TestOpenDialogFromContextMenu();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest, OpenDialogFromAppMenu) {
-  TestOpenDialogFromAppMenu();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest,
-                       EphemeralToolbarIconForDialog) {
-  TestEphemeralToolbarIconForDialog();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest, PinAndUnpinToolbarIcon) {
-  GetDialogController()->ShowMediaRouterDialog();
-  EXPECT_TRUE(ToolbarIconExists());
-  // Pin the icon via its context menu.
-  ui::SimpleMenuModel* context_menu = GetIconContextMenu();
-  const int command_index = context_menu->GetIndexOfCommandId(
-      IDC_MEDIA_ROUTER_ALWAYS_SHOW_TOOLBAR_ACTION);
-  context_menu->ActivatedAt(command_index);
-  GetDialogController()->HideMediaRouterDialog();
-  EXPECT_TRUE(ToolbarIconExists());
-
-  // Unpin the icon via its context menu.
-  GetIconContextMenu()->ActivatedAt(command_index);
-  EXPECT_FALSE(ToolbarIconExists());
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest,
-                       EphemeralToolbarIconForRoutesAndIssues) {
-  TestEphemeralToolbarIconForRoutesAndIssues();
-}
-
-IN_PROC_BROWSER_TEST_F(MediaRouterViewsUIBrowserTest,
-                       EphemeralToolbarIconWithMultipleWindows) {
-  TestEphemeralToolbarIconWithMultipleWindows();
-}
-
 }  // namespace media_router
diff --git a/chrome/browser/ui/views/menu_model_adapter_test.cc b/chrome/browser/ui/views/menu_model_adapter_test.cc
index 1414a3b..5fafbf9 100644
--- a/chrome/browser/ui/views/menu_model_adapter_test.cc
+++ b/chrome/browser/ui/views/menu_model_adapter_test.cc
@@ -10,9 +10,9 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chrome/test/base/view_event_test_base.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/test/ui_controls.h"
 #include "ui/views/controls/button/menu_button.h"
@@ -256,12 +256,10 @@
 
  private:
   // Generate a mouse click on the specified view and post a new task.
-  virtual void Click(views::View* view, const base::Closure& next) {
+  virtual void Click(views::View* view, base::OnceClosure next) {
     ui_test_utils::MoveMouseToCenterAndPress(
-        view,
-        ui_controls::LEFT,
-        ui_controls::DOWN | ui_controls::UP,
-        next);
+        view, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
+        std::move(next));
   }
 
   views::MenuButton* button_;
diff --git a/chrome/browser/ui/views/menu_test_base.cc b/chrome/browser/ui/views/menu_test_base.cc
index 1b5a7bf..5c892519 100644
--- a/chrome/browser/ui/views/menu_test_base.cc
+++ b/chrome/browser/ui/views/menu_test_base.cc
@@ -24,12 +24,10 @@
 MenuTestBase::~MenuTestBase() {
 }
 
-void MenuTestBase::Click(views::View* view, const base::Closure& next) {
-  ui_test_utils::MoveMouseToCenterAndPress(
-      view,
-      ui_controls::LEFT,
-      ui_controls::DOWN | ui_controls::UP,
-      next);
+void MenuTestBase::Click(views::View* view, base::OnceClosure next) {
+  ui_test_utils::MoveMouseToCenterAndPress(view, ui_controls::LEFT,
+                                           ui_controls::DOWN | ui_controls::UP,
+                                           std::move(next));
   views::test::WaitForMenuClosureAnimation();
 }
 
diff --git a/chrome/browser/ui/views/menu_test_base.h b/chrome/browser/ui/views/menu_test_base.h
index 45b6c13..61ed14cd 100644
--- a/chrome/browser/ui/views/menu_test_base.h
+++ b/chrome/browser/ui/views/menu_test_base.h
@@ -9,7 +9,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "chrome/test/base/view_event_test_base.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/views/controls/button/menu_button_listener.h"
 #include "ui/views/controls/menu/menu_delegate.h"
@@ -42,7 +42,7 @@
   ~MenuTestBase() override;
 
   // Generate a mouse click and run |next| once the event has been processed.
-  virtual void Click(views::View* view, const base::Closure& next);
+  virtual void Click(views::View* view, base::OnceClosure next);
 
   // Generate a keypress and run |next| once the event has been processed.
   void KeyPress(ui::KeyboardCode keycode, base::OnceClosure next);
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 961247d..e747e6c3 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -333,6 +333,7 @@
 void OverlayWindowViews::SetUpViews() {
   GetRootView()->SetPaintToLayer(ui::LAYER_TEXTURED);
   GetRootView()->layer()->set_name("RootView");
+  GetRootView()->layer()->SetMasksToBounds(true);
 
   // views::View that is displayed when video is hidden. ----------------------
   // Adding an extra pixel to width/height makes sure controls background cover
diff --git a/chrome/browser/ui/views/test/DEPS b/chrome/browser/ui/views/test/DEPS
new file mode 100644
index 0000000..f55cf00
--- /dev/null
+++ b/chrome/browser/ui/views/test/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+mojo/core/embedder",
+]
\ No newline at end of file
diff --git a/chrome/browser/ui/views/test/OWNERS b/chrome/browser/ui/views/test/OWNERS
new file mode 100644
index 0000000..fd22d01
--- /dev/null
+++ b/chrome/browser/ui/views/test/OWNERS
@@ -0,0 +1,2 @@
+pkasting@chromium.org
+sky@chromium.org
\ No newline at end of file
diff --git a/chrome/test/base/view_event_test_base.cc b/chrome/browser/ui/views/test/view_event_test_base.cc
similarity index 92%
rename from chrome/test/base/view_event_test_base.cc
rename to chrome/browser/ui/views/test/view_event_test_base.cc
index c819a63a..ece13f10 100644
--- a/chrome/test/base/view_event_test_base.cc
+++ b/chrome/browser/ui/views/test/view_event_test_base.cc
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/test/base/view_event_test_base.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/ui/views/test/view_event_test_platform_part.h"
 #include "chrome/test/base/chrome_unit_test_suite.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/view_event_test_platform_part.h"
 #include "mojo/core/embedder/embedder.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/ime/input_method_initializer.h"
@@ -59,9 +59,7 @@
 
 }  // namespace
 
-ViewEventTestBase::ViewEventTestBase()
-  : window_(NULL),
-    content_view_(NULL) {
+ViewEventTestBase::ViewEventTestBase() : window_(NULL), content_view_(NULL) {
   // The TestingBrowserProcess must be created in the constructor because there
   // are tests that require it before SetUp() is called.
   TestingBrowserProcess::CreateInstance();
@@ -112,7 +110,7 @@
 void ViewEventTestBase::TearDown() {
   if (window_) {
     window_->Close();
-    content::RunAllPendingInMessageLoop();
+    base::RunLoop().RunUntilIdle();
     window_ = NULL;
   }
 
@@ -160,7 +158,7 @@
       ui_test_utils::ShowAndFocusNativeWindow(window_->GetNativeWindow()));
 
   // Flush any pending events to make sure we start with a clean slate.
-  content::RunAllPendingInMessageLoop();
+  base::RunLoop().RunUntilIdle();
 
   // Schedule a task that starts the test. Need to do this as we're going to
   // run the message loop.
@@ -168,7 +166,7 @@
       FROM_HERE, base::BindOnce(&ViewEventTestBase::DoTestOnMessageLoop,
                                 base::Unretained(this)));
 
-  content::RunThisRunLoop(&run_loop_);
+  run_loop_.Run();
 }
 
 void ViewEventTestBase::ScheduleMouseMoveInBackground(int x, int y) {
@@ -185,10 +183,10 @@
   dnd_thread_.reset();
 }
 
-void ViewEventTestBase::RunTestMethod(const base::Closure& task) {
+void ViewEventTestBase::RunTestMethod(base::OnceClosure task) {
   StopBackgroundThread();
 
-  task.Run();
+  std::move(task).Run();
   if (HasFatalFailure())
     Done();
 }
diff --git a/chrome/test/base/view_event_test_base.h b/chrome/browser/ui/views/test/view_event_test_base.h
similarity index 89%
rename from chrome/test/base/view_event_test_base.h
rename to chrome/browser/ui/views/test/view_event_test_base.h
index 566c1c6..04a9564 100644
--- a/chrome/test/base/view_event_test_base.h
+++ b/chrome/browser/ui/views/test/view_event_test_base.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_
-#define CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_
+#define CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_
 
 // We only want to use ViewEventTestBase in test targets which properly
 // isolate each test case by running each test in a separate process.
@@ -73,8 +73,7 @@
 //   // Then schedule another mouse move to finish it.
 //   ScheduleMouseMoveInBackground(loc.x, loc.y);
 
-class ViewEventTestBase : public views::WidgetDelegate,
-                          public testing::Test {
+class ViewEventTestBase : public views::WidgetDelegate, public testing::Test {
  public:
   ViewEventTestBase();
 
@@ -118,9 +117,10 @@
   // method is called in such a way that if there are any test failures
   // Done is invoked.
   template <class T, class Method>
-  base::Closure CreateEventTask(T* target, Method method) {
-    return base::Bind(&ViewEventTestBase::RunTestMethod, base::Unretained(this),
-                      base::Bind(method, base::Unretained(target)));
+  base::OnceClosure CreateEventTask(T* target, Method method) {
+    return base::BindOnce(&ViewEventTestBase::RunTestMethod,
+                          base::Unretained(this),
+                          base::BindOnce(method, base::Unretained(target)));
   }
 
   // Spawns a new thread posts a MouseMove in the background.
@@ -134,7 +134,7 @@
 
   // Callback from CreateEventTask. Stops the background thread, runs the
   // supplied task and if there are failures invokes Done.
-  void RunTestMethod(const base::Closure& task);
+  void RunTestMethod(base::OnceClosure task);
 
   // The content of the Window.
   views::View* content_view_;
@@ -160,10 +160,8 @@
 // Convenience macro for defining a ViewEventTestBase. See class description
 // of ViewEventTestBase for details.
 #define VIEW_TEST(test_class, name) \
-  TEST_F(test_class, name) {\
-    StartMessageLoopAndRunTest();\
-  }
+  TEST_F(test_class, name) { StartMessageLoopAndRunTest(); }
 
 #endif  // defined(HAS_OUT_OF_PROC_TEST_RUNNER)
 
-#endif  // CHROME_TEST_BASE_VIEW_EVENT_TEST_BASE_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_
diff --git a/chrome/test/base/view_event_test_platform_part.h b/chrome/browser/ui/views/test/view_event_test_platform_part.h
similarity index 83%
rename from chrome/test/base/view_event_test_platform_part.h
rename to chrome/browser/ui/views/test/view_event_test_platform_part.h
index f4eb2740..261fc5d 100644
--- a/chrome/test/base/view_event_test_platform_part.h
+++ b/chrome/browser/ui/views/test/view_event_test_platform_part.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_TEST_BASE_VIEW_EVENT_TEST_PLATFORM_PART_H_
-#define CHROME_TEST_BASE_VIEW_EVENT_TEST_PLATFORM_PART_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_PLATFORM_PART_H_
+#define CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_PLATFORM_PART_H_
 
 #include "base/macros.h"
 #include "ui/gfx/native_widget_types.h"
@@ -11,7 +11,7 @@
 namespace ui {
 class ContextFactory;
 class ContextFactoryPrivate;
-}
+}  // namespace ui
 
 // A helper class owned by tests that performs platform specific initialization.
 // ViewEventTestPlatformPart behaves a bit like views::ViewsTestHelper, but on
@@ -38,4 +38,4 @@
   DISALLOW_COPY_AND_ASSIGN(ViewEventTestPlatformPart);
 };
 
-#endif  // CHROME_TEST_BASE_VIEW_EVENT_TEST_PLATFORM_PART_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_PLATFORM_PART_H_
diff --git a/chrome/test/base/view_event_test_platform_part_chromeos.cc b/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc
similarity index 97%
rename from chrome/test/base/view_event_test_platform_part_chromeos.cc
rename to chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc
index 3794a523..0a6f9588 100644
--- a/chrome/test/base/view_event_test_platform_part_chromeos.cc
+++ b/chrome/browser/ui/views/test/view_event_test_platform_part_chromeos.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/test/base/view_event_test_platform_part.h"
+#include "chrome/browser/ui/views/test/view_event_test_platform_part.h"
 
 #include <memory>
 #include <utility>
diff --git a/chrome/test/base/view_event_test_platform_part_default.cc b/chrome/browser/ui/views/test/view_event_test_platform_part_default.cc
similarity index 94%
rename from chrome/test/base/view_event_test_platform_part_default.cc
rename to chrome/browser/ui/views/test/view_event_test_platform_part_default.cc
index 5c8f3829..cfc2686 100644
--- a/chrome/test/base/view_event_test_platform_part_default.cc
+++ b/chrome/browser/ui/views/test/view_event_test_platform_part_default.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ui/views/test/view_event_test_platform_part.h"
+
 #include <memory>
 
 #include "base/macros.h"
-#include "chrome/test/base/view_event_test_platform_part.h"
+#include "build/build_config.h"
 #include "ui/aura/env.h"
 #include "ui/display/screen.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_button_interactive_uitest.cc
index eadc584..14c1054a 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button_interactive_uitest.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button_interactive_uitest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/views/toolbar/toolbar_button.h"
 
-#include "chrome/test/base/view_event_test_base.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/views/controls/menu/menu_runner.h"
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index a6bb8a9..cd2fd53 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -226,10 +226,8 @@
   browser_actions_ =
       new BrowserActionsContainer(browser_, main_container, this);
 
-  if (media_router::MediaRouterEnabled(browser_->profile()) &&
-      media_router::ShouldUseViewsDialog()) {
+  if (media_router::MediaRouterEnabled(browser_->profile()))
     cast_ = media_router::CastToolbarButton::Create(browser_).release();
-  }
 
   bool show_avatar_toolbar_button = true;
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/touch_events_interactive_uitest_win.cc b/chrome/browser/ui/views/touch_events_interactive_uitest_win.cc
index d316999..dc0495da 100644
--- a/chrome/browser/ui/views/touch_events_interactive_uitest_win.cc
+++ b/chrome/browser/ui/views/touch_events_interactive_uitest_win.cc
@@ -4,8 +4,8 @@
 
 #include "base/run_loop.h"
 #include "base/win/windows_version.h"
+#include "chrome/browser/ui/views/test/view_event_test_base.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/view_event_test_base.h"
 #include "ui/aura/env.h"
 #include "ui/aura/test/env_test_helper.h"
 #include "ui/aura/window.h"
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
index c06cf2b..6078353 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
@@ -73,6 +73,7 @@
   source->SetJsonPath("strings.js");
   source->AddResourcePath("assistant_optin.js", IDR_ASSISTANT_OPTIN_JS);
   source->AddResourcePath("assistant_logo.png", IDR_ASSISTANT_LOGO_PNG);
+  source->AddBoolean("hotwordDspAvailable", chromeos::IsHotwordDspAvailable());
   source->SetDefaultResource(IDR_ASSISTANT_OPTIN_HTML);
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
 
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
index 964538da..784140eb 100644
--- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -71,6 +71,8 @@
                IDS_VOICE_INTERACTION_VALUE_PROP_RETRY_BUTTON);
   builder->Add("assistantVoiceMatchTitle", IDS_ASSISTANT_VOICE_MATCH_TITLE);
   builder->Add("assistantVoiceMatchMessage", IDS_ASSISTANT_VOICE_MATCH_MESSAGE);
+  builder->Add("assistantVoiceMatchNoDspMessage",
+               IDS_ASSISTANT_VOICE_MATCH_NO_DSP_MESSAGE);
   builder->Add("assistantVoiceMatchRecording",
                IDS_ASSISTANT_VOICE_MATCH_RECORDING);
   builder->Add("assistantVoiceMatchCompleted",
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.cc
index d1e53bd6..82fb685f 100644
--- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_webui_impl.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
 #include "chrome/browser/ui/webui/media_router/media_router_ui.h"
 #include "chrome/common/url_constants.h"
@@ -98,7 +97,6 @@
   bool ShouldShowDialogTitle() const override { return false; }
 
  private:
-  base::WeakPtr<MediaRouterAction> action_;
   base::WeakPtr<MediaRouterDialogControllerWebUIImpl> controller_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaRouterDialogDelegate);
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index be6b6620..90f2b6e7 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -78,6 +78,7 @@
 #include "components/user_manager/user_manager.h"
 #include "ui/chromeos/devicetype_utils.h"
 #include "ui/chromeos/events/keyboard_layout_util.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/touch_device_manager.h"
 #else
@@ -811,6 +812,8 @@
        IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
       {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
       {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
+      {"displayResolutionInterlacedMenuItem",
+       IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
       {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
       {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
       {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
@@ -845,6 +848,9 @@
   html_source->AddBoolean("unifiedDesktopAvailable",
                           cmd.HasSwitch(::switches::kEnableUnifiedDesktop));
 
+  html_source->AddBoolean("listAllDisplayModes",
+                          display::features::IsListAllDisplayModesEnabled());
+
   html_source->AddBoolean(
       "enableTouchCalibrationSetting",
       cmd.HasSwitch(chromeos::switches::kEnableTouchCalibrationSetting));
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl
index e6de8390..91818708 100644
--- a/chrome/common/extensions/api/automation.idl
+++ b/chrome/common/extensions/api/automation.idl
@@ -548,6 +548,11 @@
     // The source of the name.
     NameFromType? nameFrom;
 
+    // The image annotation for image nodes, which may be a human-readable
+    // string that is the contextualized annotation or a status string related
+    // to annotations.
+    DOMString? imageAnnotation;
+
     // The value for this node: for example the <code>value</code> attribute of
     // an <code>&lt;input&gt; element.
     DOMString? value;
diff --git a/chrome/common/heap_profiler_controller.cc b/chrome/common/heap_profiler_controller.cc
index 120c4dc..e1943de 100644
--- a/chrome/common/heap_profiler_controller.cc
+++ b/chrome/common/heap_profiler_controller.cc
@@ -130,7 +130,7 @@
     frames.reserve(sample.stack.size());
     for (const void* frame : sample.stack) {
       uintptr_t address = reinterpret_cast<uintptr_t>(frame);
-      const base::ModuleCache::Module& module =
+      const base::ModuleCache::Module* module =
           module_cache.GetModuleForAddress(address);
       frames.emplace_back(address, module);
     }
diff --git a/chrome/common/net/x509_certificate_model_nss.cc b/chrome/common/net/x509_certificate_model_nss.cc
index 6e2e786..5932c3a 100644
--- a/chrome/common/net/x509_certificate_model_nss.cc
+++ b/chrome/common/net/x509_certificate_model_nss.cc
@@ -127,10 +127,6 @@
   return GetNickname(cert_handle);
 }
 
-string GetTokenName(CERTCertificate* cert_handle) {
-  return psm::GetCertTokenName(cert_handle);
-}
-
 string GetVersion(CERTCertificate* cert_handle) {
   // If the version field is omitted from the certificate, the default
   // value is v1(0).
diff --git a/chrome/common/net/x509_certificate_model_nss.h b/chrome/common/net/x509_certificate_model_nss.h
index e0c9b1e..c3a5c24 100644
--- a/chrome/common/net/x509_certificate_model_nss.h
+++ b/chrome/common/net/x509_certificate_model_nss.h
@@ -25,8 +25,6 @@
 
 std::string GetCertNameOrNickname(CERTCertificate* cert_handle);
 
-std::string GetTokenName(CERTCertificate* cert_handle);
-
 std::string GetVersion(CERTCertificate* cert_handle);
 
 net::CertType GetType(CERTCertificate* cert_handle);
diff --git a/chrome/common/trace_event_args_whitelist.cc b/chrome/common/trace_event_args_whitelist.cc
index 034beee..c2771b1 100644
--- a/chrome/common/trace_event_args_whitelist.cc
+++ b/chrome/common/trace_event_args_whitelist.cc
@@ -18,7 +18,8 @@
   const char* const* arg_name_filter;
 };
 
-const char* const kBaseAllowedArgs[] = {"blocking_type", nullptr};
+const char* const kScopedBlockingCallAllowedArgs[] = {"file_name",
+                                                      "function_name", nullptr};
 const char* const kGPUAllowedArgs[] = {nullptr};
 const char* const kInputLatencyAllowedArgs[] = {"data", nullptr};
 const char* const kMemoryDumpAllowedArgs[] = {"dumps", nullptr};
@@ -35,7 +36,7 @@
     {"__metadata", "chrome_library_module", nullptr},
     {"__metadata", "stackFrames", nullptr},
     {"__metadata", "typeNames", nullptr},
-    {"base", "*", kBaseAllowedArgs},
+    {"base", "ScopedBlockingCall*", kScopedBlockingCallAllowedArgs},
     {"browser", "KeyedServiceFactory::GetServiceForContext", nullptr},
     {"GPU", "*", kGPUAllowedArgs},
     {"ipc", "GpuChannelHost::Send", nullptr},
diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn
index 8d19c74..ec62933 100644
--- a/chrome/installer/mini_installer/BUILD.gn
+++ b/chrome/installer/mini_installer/BUILD.gn
@@ -278,6 +278,9 @@
     #      dependency on //buildtools/third_party/libc++ in builds that set
     #      use_custom_libcxx=true.
     #
+    # The net result is similar to linking with /NODEFAULTLIB, but more precise
+    # as it just excludes the CRT.
+    #
     # But in asan builds we need to link against the asan runtime library, which
     # in turn depends on the standard library and relies on it to run
     # initializers.
diff --git a/chrome/installer/mini_installer/mini_installer.cc b/chrome/installer/mini_installer/mini_installer.cc
index 1f39abbe..6d86e74 100644
--- a/chrome/installer/mini_installer/mini_installer.cc
+++ b/chrome/installer/mini_installer/mini_installer.cc
@@ -14,7 +14,8 @@
 //   BasicRuntimeChecks="0"
 //   BufferSecurityCheck="false" compiler: /GS-
 //   EntryPointSymbol="MainEntryPoint" linker: /ENTRY
-//   IgnoreAllDefaultLibraries="true" linker: /NODEFAULTLIB
+//       /ENTRY also stops the CRT from being pulled in and does this more
+//       precisely than /NODEFAULTLIB
 //   OptimizeForWindows98="1" linker: /OPT:NOWIN98
 //   linker: /SAFESEH:NO
 
diff --git a/chrome/installer/mini_installer/mini_installer_exe_main.cc b/chrome/installer/mini_installer/mini_installer_exe_main.cc
index 2967b5b..2ec2ab2 100644
--- a/chrome/installer/mini_installer/mini_installer_exe_main.cc
+++ b/chrome/installer/mini_installer/mini_installer_exe_main.cc
@@ -28,8 +28,9 @@
 }
 #endif
 
-// We don't link with the CRT so we have to implement CRT functions that the
-// compiler generates calls to.
+// We don't link with the CRT (this is enforced through use of the /ENTRY linker
+// flag) so we have to implement CRT functions that the compiler generates calls
+// to.
 
 // VC Express editions don't come with the memset CRT obj file and linking to
 // the obj files between versions becomes a bit problematic. Therefore,
diff --git a/chrome/installer/setup/archive_patch_helper.cc b/chrome/installer/setup/archive_patch_helper.cc
index dc9bc19..0fa7dae 100644
--- a/chrome/installer/setup/archive_patch_helper.cc
+++ b/chrome/installer/setup/archive_patch_helper.cc
@@ -52,7 +52,7 @@
   int32_t ntstatus = 0;
   DWORD lzma_result = UnPackArchive(compressed_archive_, working_directory_,
                                     &output_file, &unpack_status, &ntstatus);
-  RecordUnPackMetrics(unpack_status, ntstatus, consumer_);
+  RecordUnPackMetrics(unpack_status, ntstatus, lzma_result, consumer_);
   if (lzma_result != ERROR_SUCCESS)
     return false;
 
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 2a56c613a..a1bdb669 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -1130,7 +1130,7 @@
   int32_t ntstatus = 0;
   DWORD lzma_result = UnPackArchive(uncompressed_archive, unpack_path, NULL,
                                     &unpack_status, &ntstatus);
-  RecordUnPackMetrics(unpack_status, ntstatus,
+  RecordUnPackMetrics(unpack_status, ntstatus, lzma_result,
                       UnPackConsumer::UNCOMPRESSED_CHROME_ARCHIVE);
   if (lzma_result) {
     installer_state.WriteInstallerResult(
diff --git a/chrome/installer/setup/setup_util.cc b/chrome/installer/setup/setup_util.cc
index ff4ce635..66a72db 100644
--- a/chrome/installer/setup/setup_util.cc
+++ b/chrome/installer/setup/setup_util.cc
@@ -30,6 +30,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/stl_util.h"
@@ -243,8 +244,9 @@
 
 }  // namespace
 
-const char kUnPackStatusMetricsName[] = "Setup.Install.LzmaUnPackStatus";
 const char kUnPackNTSTATUSMetricsName[] = "Setup.Install.LzmaUnPackNTSTATUS";
+const char kUnPackResultMetricsName[] = "Setup.Install.LzmaUnPackResult";
+const char kUnPackStatusMetricsName[] = "Setup.Install.LzmaUnPackStatus";
 
 int CourgettePatchFiles(const base::FilePath& src,
                         const base::FilePath& patch,
@@ -662,6 +664,7 @@
 
 void RecordUnPackMetrics(UnPackStatus unpack_status,
                          int32_t status,
+                         DWORD lzma_result,
                          UnPackConsumer consumer) {
   std::string consumer_name = "";
 
@@ -680,16 +683,15 @@
       break;
   }
 
-  base::LinearHistogram::FactoryGet(
-      std::string(kUnPackStatusMetricsName) + "_" + consumer_name, 1,
-      UNPACK_STATUS_COUNT, UNPACK_STATUS_COUNT + 1,
-      base::HistogramBase::kUmaTargetedHistogramFlag)
-      ->Add(unpack_status);
+  base::UmaHistogramExactLinear(
+      std::string(std::string(kUnPackStatusMetricsName) + "_" + consumer_name),
+      unpack_status, UNPACK_STATUS_COUNT);
 
-  base::SparseHistogram::FactoryGet(
-      std::string(kUnPackNTSTATUSMetricsName) + "_" + consumer_name,
-      base::HistogramBase::kUmaTargetedHistogramFlag)
-      ->Add(status);
+  base::UmaHistogramSparse(
+      std::string(kUnPackResultMetricsName) + "_" + consumer_name, lzma_result);
+
+  base::UmaHistogramSparse(
+      std::string(kUnPackNTSTATUSMetricsName) + "_" + consumer_name, status);
 }
 
 void RegisterEventLogProvider(const base::FilePath& install_directory,
diff --git a/chrome/installer/setup/setup_util.h b/chrome/installer/setup/setup_util.h
index 6c21bb0..bfb53eb 100644
--- a/chrome/installer/setup/setup_util.h
+++ b/chrome/installer/setup/setup_util.h
@@ -33,8 +33,9 @@
 class InstallerState;
 class MasterPreferences;
 
-extern const char kUnPackStatusMetricsName[];
 extern const char kUnPackNTSTATUSMetricsName[];
+extern const char kUnPackResultMetricsName[];
+extern const char kUnPackStatusMetricsName[];
 
 // The name of consumers of UnPackArchive which is used to publish metrics.
 enum UnPackConsumer {
@@ -123,6 +124,7 @@
 // Records UMA metrics for unpack result.
 void RecordUnPackMetrics(UnPackStatus unpack_status,
                          int32_t status,
+                         DWORD lzma_result,
                          UnPackConsumer consumer);
 
 // Register Chrome's EventLog message provider dll.
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc
index d561987..5553663 100644
--- a/chrome/installer/setup/setup_util_unittest.cc
+++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -256,21 +256,27 @@
   base::HistogramTester histogram_tester;
   std::string unpack_status_metrics_name =
       std::string(installer::kUnPackStatusMetricsName) + "_SetupExePatch";
+  std::string unpack_result_metrics_name =
+      std::string(installer::kUnPackResultMetricsName) + "_SetupExePatch";
   std::string ntstatus_metrics_name =
       std::string(installer::kUnPackNTSTATUSMetricsName) + "_SetupExePatch";
   histogram_tester.ExpectTotalCount(unpack_status_metrics_name, 0);
 
-  RecordUnPackMetrics(UnPackStatus::UNPACK_NO_ERROR, 0,
+  RecordUnPackMetrics(UnPackStatus::UNPACK_NO_ERROR, 0, ERROR_SUCCESS,
                       installer::UnPackConsumer::SETUP_EXE_PATCH);
   histogram_tester.ExpectTotalCount(unpack_status_metrics_name, 1);
   histogram_tester.ExpectBucketCount(unpack_status_metrics_name, 0, 1);
+  histogram_tester.ExpectTotalCount(unpack_result_metrics_name, 1);
+  histogram_tester.ExpectBucketCount(unpack_result_metrics_name, 0, 1);
   histogram_tester.ExpectTotalCount(ntstatus_metrics_name, 1);
   histogram_tester.ExpectBucketCount(ntstatus_metrics_name, 0, 1);
 
-  RecordUnPackMetrics(UnPackStatus::UNPACK_CLOSE_FILE_ERROR, 1,
+  RecordUnPackMetrics(UnPackStatus::UNPACK_CLOSE_FILE_ERROR, 1, 2,
                       installer::UnPackConsumer::SETUP_EXE_PATCH);
   histogram_tester.ExpectTotalCount(unpack_status_metrics_name, 2);
   histogram_tester.ExpectBucketCount(unpack_status_metrics_name, 10, 1);
+  histogram_tester.ExpectTotalCount(unpack_result_metrics_name, 2);
+  histogram_tester.ExpectBucketCount(unpack_result_metrics_name, 2, 1);
   histogram_tester.ExpectTotalCount(ntstatus_metrics_name, 2);
   histogram_tester.ExpectBucketCount(ntstatus_metrics_name, 1, 1);
 }
diff --git a/chrome/installer/test/BUILD.gn b/chrome/installer/test/BUILD.gn
index 4b0d73c..17840437 100644
--- a/chrome/installer/test/BUILD.gn
+++ b/chrome/installer/test/BUILD.gn
@@ -6,7 +6,10 @@
 import("//testing/test.gni")
 assert(is_win)
 
-if (current_toolchain == host_toolchain) {
+# Don't target the tool to non-win host for cross build because the tool depends
+# on Win32 API.
+# TODO(thakis): Enable this in cross builds, https://crbug.com/799827
+if (current_toolchain == host_toolchain || host_os != "win") {
   executable("alternate_version_generator") {
     testonly = true
     sources = [
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
index f763660..e885df2 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -20,6 +20,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "chrome/common/extensions/chrome_extension_messages.h"
+#include "content/app/strings/grit/content_strings.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
@@ -38,6 +39,7 @@
 #include "ui/accessibility/ax_event.h"
 #include "ui/accessibility/ax_node.h"
 #include "ui/accessibility/ax_role_properties.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
 namespace extensions {
@@ -923,6 +925,35 @@
                                            v8::NewStringType::kNormal)
                        .ToLocalChecked());
       });
+  RouteNodeIDFunction(
+      "GetImageAnnotation",
+      [this](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
+             AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) {
+        std::string status_string;
+        auto status = node->data().GetImageAnnotationStatus();
+        switch (status) {
+          case ax::mojom::ImageAnnotationStatus::kNone:
+          case ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation:
+            break;
+
+          case ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation:
+          case ax::mojom::ImageAnnotationStatus::kAnnotationPending:
+          case ax::mojom::ImageAnnotationStatus::kAnnotationEmpty:
+          case ax::mojom::ImageAnnotationStatus::kAnnotationAdult:
+          case ax::mojom::ImageAnnotationStatus::kAnnotationProcessFailed:
+            status_string = GetLocalizedStringForImageAnnotationStatus(status);
+            break;
+          case ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded:
+            status_string = node->GetStringAttribute(
+                ax::mojom::StringAttribute::kImageAnnotation);
+            break;
+        }
+        if (status_string.empty())
+          return;
+        result.Set(v8::String::NewFromUtf8(isolate, status_string.c_str(),
+                                           v8::NewStringType::kNormal)
+                       .ToLocalChecked());
+      });
   RouteNodeIDFunction("GetSubscript", [](v8::Isolate* isolate,
                                          v8::ReturnValue<v8::Value> result,
                                          AutomationAXTreeWrapper* tree_wrapper,
@@ -1863,4 +1894,35 @@
                                            &args, nullptr, context());
 }
 
+std::string
+AutomationInternalCustomBindings::GetLocalizedStringForImageAnnotationStatus(
+    ax::mojom::ImageAnnotationStatus status) const {
+  int message_id = 0;
+  switch (status) {
+    case ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation:
+      message_id = IDS_AX_IMAGE_ELIGIBLE_FOR_ANNOTATION;
+      break;
+    case ax::mojom::ImageAnnotationStatus::kAnnotationPending:
+      message_id = IDS_AX_IMAGE_ANNOTATION_PENDING;
+      break;
+    case ax::mojom::ImageAnnotationStatus::kAnnotationEmpty:
+      message_id = IDS_AX_IMAGE_ANNOTATION_EMPTY;
+      break;
+    case ax::mojom::ImageAnnotationStatus::kAnnotationAdult:
+      message_id = IDS_AX_IMAGE_ANNOTATION_ADULT;
+      break;
+    case ax::mojom::ImageAnnotationStatus::kAnnotationProcessFailed:
+      message_id = IDS_AX_IMAGE_ANNOTATION_PROCESS_FAILED;
+      break;
+    case ax::mojom::ImageAnnotationStatus::kNone:
+    case ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation:
+    case ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded:
+      return std::string();
+  }
+
+  DCHECK(message_id);
+
+  return l10n_util::GetStringUTF8(message_id);
+}
+
 }  // namespace extensions
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.h b/chrome/renderer/extensions/automation_internal_custom_bindings.h
index a6298c3..b5c1aed 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.h
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.h
@@ -6,6 +6,7 @@
 #define CHROME_RENDERER_EXTENSIONS_AUTOMATION_INTERNAL_CUSTOM_BINDINGS_H_
 
 #include <map>
+#include <string>
 #include <vector>
 
 #include "base/compiler_specific.h"
@@ -200,6 +201,9 @@
 
   void SendChildTreeIDEvent(ui::AXTreeID child_tree_id);
 
+  std::string GetLocalizedStringForImageAnnotationStatus(
+      ax::mojom::ImageAnnotationStatus status) const;
+
   std::map<ui::AXTreeID, std::unique_ptr<AutomationAXTreeWrapper>>
       tree_id_to_tree_wrapper_map_;
   std::map<ui::AXTree*, AutomationAXTreeWrapper*> axtree_to_tree_wrapper_map_;
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js
index 9190320..7756eb4 100644
--- a/chrome/renderer/resources/extensions/automation/automation_node.js
+++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -293,6 +293,14 @@
 /**
  * @param {string} axTreeID The id of the accessibility tree.
  * @param {number} nodeID The id of a node.
+ * @return {?string} The image annotation status, which may
+ *     include the annotation itself if completed successfully.
+ */
+var GetImageAnnotation = natives.GetImageAnnotation;
+
+/**
+ * @param {string} axTreeID The id of the accessibility tree.
+ * @param {number} nodeID The id of a node.
  * @return {boolean}
  */
 var GetBold = natives.GetBold;
@@ -555,6 +563,10 @@
     return GetNameFrom(this.treeID, this.id);
   },
 
+  get imageAnnotation() {
+    return GetImageAnnotation(this.treeID, this.id);
+  },
+
   get bold() {
     return GetBold(this.treeID, this.id);
   },
@@ -1555,6 +1567,7 @@
         'restriction',
         'state',
         'location',
+        'imageAnnotationStatus',
         'indexInParent',
         'lineStartOffsets',
         'root',
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index e34d19b..81aed64 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2669,6 +2669,7 @@
     "../browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc",
     "../browser/metrics/chrome_metrics_service_accessor_unittest.cc",
     "../browser/metrics/chrome_metrics_service_client_unittest.cc",
+    "../browser/metrics/chrome_metrics_services_manager_client_unittest.cc",
     "../browser/metrics/oom/out_of_memory_reporter_unittest.cc",
     "../browser/metrics/process_memory_metrics_emitter_unittest.cc",
     "../browser/metrics/subprocess_metrics_provider_unittest.cc",
@@ -3566,7 +3567,6 @@
       "../browser/ui/media_router/query_result_manager_unittest.cc",
       "../browser/ui/passwords/manage_passwords_ui_controller_unittest.cc",
       "../browser/ui/toolbar/media_router_action_controller_unittest.cc",
-      "../browser/ui/toolbar/media_router_action_unittest.cc",
       "../browser/ui/toolbar/media_router_contextual_menu_unittest.cc",
       "../browser/ui/toolbar/mock_media_router_action_controller.cc",
       "../browser/ui/toolbar/mock_media_router_action_controller.h",
@@ -4657,6 +4657,7 @@
       "../browser/ui/app_list/search/search_result_ranker/app_launch_predictor_unittest.cc",
       "../browser/ui/app_list/search/search_result_ranker/app_search_result_ranker_unittest.cc",
       "../browser/ui/app_list/search/search_result_ranker/frecency_store_unittest.cc",
+      "../browser/ui/app_list/search/search_result_ranker/ranking_item_util_unittest.cc",
       "../browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc",
       "../browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc",
       "../browser/ui/app_list/search/settings_shortcut/settings_shortcut_provider_unittest.cc",
@@ -4972,9 +4973,6 @@
       "base/interactive_ui_tests_main.cc",
       "base/save_desktop_snapshot_win.cc",
       "base/save_desktop_snapshot_win.h",
-      "base/view_event_test_platform_part.h",
-      "base/view_event_test_platform_part_chromeos.cc",
-      "base/view_event_test_platform_part_default.cc",
       "ppapi/ppapi_interactive_browsertest.cc",
     ]
 
@@ -5117,13 +5115,16 @@
         "../browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc",
         "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc",
         "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h",
+        "../browser/ui/views/test/view_event_test_base.cc",
+        "../browser/ui/views/test/view_event_test_base.h",
+        "../browser/ui/views/test/view_event_test_platform_part.h",
+        "../browser/ui/views/test/view_event_test_platform_part_chromeos.cc",
+        "../browser/ui/views/test/view_event_test_platform_part_default.cc",
         "../browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc",
         "../browser/ui/views/toolbar/toolbar_button_interactive_uitest.cc",
         "../browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc",
         "../browser/ui/views/translate/translate_bubble_test_utils_views.cc",
         "base/interactive_test_utils_views.cc",
-        "base/view_event_test_base.cc",
-        "base/view_event_test_base.h",
       ]
       deps += [
         "//ui/views",
@@ -5164,7 +5165,7 @@
         "../browser/ui/signin_view_controller_interactive_uitest.cc",
 
         # Use only the _chromeos version on Ash / Chrome OS.
-        "base/view_event_test_platform_part_default.cc",
+        "../browser/ui/views/test/view_event_test_platform_part_default.cc",
       ]
     } else {  # ! is_chromeos
       # Non-ChromeOS notifications tests.
diff --git a/chrome/test/base/interactive_test_utils.h b/chrome/test/base/interactive_test_utils.h
index eb0fdfd..924aa98 100644
--- a/chrome/test/base/interactive_test_utils.h
+++ b/chrome/test/base/interactive_test_utils.h
@@ -190,7 +190,7 @@
     views::View* view,
     ui_controls::MouseButton button,
     int button_state,
-    const base::RepeatingClosure& task,
+    base::OnceClosure task,
     int accelerator_state = ui_controls::kNoAccelerator);
 
 // Returns the center of |view| in screen coordinates.
diff --git a/chrome/test/base/interactive_test_utils_common_views.cc b/chrome/test/base/interactive_test_utils_common_views.cc
index 9c3f6fd..ea12da64 100644
--- a/chrome/test/base/interactive_test_utils_common_views.cc
+++ b/chrome/test/base/interactive_test_utils_common_views.cc
@@ -17,7 +17,7 @@
 void MoveMouseToCenterAndPress(views::View* view,
                                ui_controls::MouseButton button,
                                int button_state,
-                               const base::RepeatingClosure& closure,
+                               base::OnceClosure closure,
                                int accelerator_state) {
   DCHECK(view);
   DCHECK(view->GetWidget());
@@ -34,8 +34,8 @@
   gfx::Point view_center = GetCenterInScreenCoordinates(view);
   ui_controls::SendMouseMoveNotifyWhenDone(
       view_center.x(), view_center.y(),
-      base::BindOnce(&internal::ClickTask, button, button_state, closure,
-                     accelerator_state));
+      base::BindOnce(&internal::ClickTask, button, button_state,
+                     std::move(closure), accelerator_state));
 }
 
 gfx::Point GetCenterInScreenCoordinates(const views::View* view) {
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index f1cc86a..b78107b 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3494,6 +3494,12 @@
     ]
   },
 
+  "VoiceInteractionHotwordEnabled": {
+    "os": ["chromeos"],
+    "test_policy": { "VoiceInteractionHotwordEnabled": true },
+    "pref_mappings": [{ "pref": "settings.voice_interaction.hotword.enabled" }]
+  },
+
   "----- Chrome OS device policies ---------------------------------------": {},
 
   "DevicePolicyRefreshRate": {
@@ -4391,6 +4397,23 @@
     ]
   },
 
+  "BrowserSwitcherChromePath": {
+    "os": ["win"],
+    "test_policy": { "BrowserSwitcherChromePath": "chrome.exe" },
+    "pref_mappings": [
+      { "pref": "browser_switcher.chrome_path" }
+    ]
+  },
+
+  "BrowserSwitcherChromeParameters": {
+    "os": ["win"],
+    "test_policy": { "BrowserSwitcherChromeParameters": ["--force-dark-mode"] },
+    "pref_mappings": [
+      { "pref": "browser_switcher.chrome_parameters" }
+    ]
+  },
+
+
   "BrowserSwitcherUrlList": {
     "os": ["win", "linux", "mac"],
     "test_policy": {
diff --git a/chrome/test/media_router/media_router_integration_browsertest.h b/chrome/test/media_router/media_router_integration_browsertest.h
index 58ff9efd..4478f74 100644
--- a/chrome/test/media_router/media_router_integration_browsertest.h
+++ b/chrome/test/media_router/media_router_integration_browsertest.h
@@ -12,7 +12,6 @@
 #include "base/files/file_path.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/media_router/media_cast_mode.h"
-#include "chrome/browser/ui/toolbar/media_router_action.h"
 #include "chrome/test/media_router/media_router_base_browsertest.h"
 #include "chrome/test/media_router/media_router_ui_for_test.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp
index 5895f31e..022b862 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp
@@ -64,12 +64,4 @@
   return rv;
 }
 
-std::string GetCertTokenName(CERTCertificate* cert) {
-  std::string token;
-  if (cert->slot) {
-    token = PK11_GetTokenName(cert->slot);
-  }
-  return token;
-}
-
 }  // namespace mozilla_security_manager
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h
index b4366019..8ac10e6 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h
@@ -50,9 +50,6 @@
 // Based on nsNSSCertificate::GetWindowTitle.
 std::string GetCertTitle(CERTCertificate* cert);
 
-// Based on nsNSSCertificate::GetTokenName.
-std::string GetCertTokenName(CERTCertificate* cert);
-
 }  // namespace mozilla_security_manager
 
 #endif  // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTIFICATE_H_
diff --git a/chromecast/base/thread_health_checker_unittest.cc b/chromecast/base/thread_health_checker_unittest.cc
index c0d770ab..b2f8438 100644
--- a/chromecast/base/thread_health_checker_unittest.cc
+++ b/chromecast/base/thread_health_checker_unittest.cc
@@ -25,7 +25,7 @@
         event_(base::WaitableEvent::ResetPolicy::MANUAL,
                base::WaitableEvent::InitialState::NOT_SIGNALED) {}
 
-  ~ThreadHealthCheckerTest() override{};
+  ~ThreadHealthCheckerTest() override {}
 
   scoped_refptr<base::TestMockTimeTaskRunner> patient_;
   scoped_refptr<base::TestMockTimeTaskRunner> doctor_;
diff --git a/chromecast/browser/cast_content_window.h b/chromecast/browser/cast_content_window.h
index 712f3a2..5bfd5628 100644
--- a/chromecast/browser/cast_content_window.h
+++ b/chromecast/browser/cast_content_window.h
@@ -103,12 +103,12 @@
 
     // Called while a system UI gesture is in progress.
     virtual void GestureProgress(GestureType gesture_type,
-                                 const gfx::Point& touch_location){};
+                                 const gfx::Point& touch_location) {}
 
     // Called when an in-progress system UI gesture is cancelled (for example
     // when the finger is lifted before the completion of the gesture.)
     virtual void CancelGesture(GestureType gesture_type,
-                               const gfx::Point& touch_location){};
+                               const gfx::Point& touch_location) {}
 
     // Consume and handle a completed UI gesture. Returns whether the gesture
     // was handled or not.
diff --git a/chromecast/browser/cast_content_window_aura.cc b/chromecast/browser/cast_content_window_aura.cc
index d0eeff3..1868421 100644
--- a/chromecast/browser/cast_content_window_aura.cc
+++ b/chromecast/browser/cast_content_window_aura.cc
@@ -151,7 +151,7 @@
 }
 
 void CastContentWindowAura::RequestVisibility(
-    VisibilityPriority visibility_priority){};
+    VisibilityPriority visibility_priority) {}
 
 void CastContentWindowAura::SetActivityContext(base::Value activity_context) {}
 
@@ -165,7 +165,7 @@
   }
 }
 
-void CastContentWindowAura::RequestMoveOut(){};
+void CastContentWindowAura::RequestMoveOut() {}
 
 void CastContentWindowAura::OnWindowVisibilityChanged(aura::Window* window,
                                                       bool visible) {
diff --git a/chromecast/browser/cast_network_delegate_unittest.cc b/chromecast/browser/cast_network_delegate_unittest.cc
index d5c81df..140ca45 100644
--- a/chromecast/browser/cast_network_delegate_unittest.cc
+++ b/chromecast/browser/cast_network_delegate_unittest.cc
@@ -70,7 +70,7 @@
     cast_network_delegate_ = std::make_unique<CastNetworkDelegate>(
         std::move(cast_network_request_interceptor_));
   }
-  ~CastNetworkDelegateTest() override{};
+  ~CastNetworkDelegateTest() override {}
 
  protected:
   base::test::ScopedTaskEnvironment task_env_;
diff --git a/chromecast/browser/extensions/api/automation_internal/automation_event_router_interface.h b/chromecast/browser/extensions/api/automation_internal/automation_event_router_interface.h
index fc89547..5a008dc 100644
--- a/chromecast/browser/extensions/api/automation_internal/automation_event_router_interface.h
+++ b/chromecast/browser/extensions/api/automation_internal/automation_event_router_interface.h
@@ -50,8 +50,8 @@
       bool result,
       content::BrowserContext* active_profile) = 0;
 
-  AutomationEventRouterInterface(){};
-  virtual ~AutomationEventRouterInterface(){};
+  AutomationEventRouterInterface() {}
+  virtual ~AutomationEventRouterInterface() {}
 
   DISALLOW_COPY_AND_ASSIGN(AutomationEventRouterInterface);
 };
diff --git a/chromecast/browser/extensions/api/notifications/notifications_api.h b/chromecast/browser/extensions/api/notifications/notifications_api.h
index e59a572..63a59ca0 100644
--- a/chromecast/browser/extensions/api/notifications/notifications_api.h
+++ b/chromecast/browser/extensions/api/notifications/notifications_api.h
@@ -19,12 +19,12 @@
   void Destruct() const override;
 
  protected:
-  ~NotificationsApiFunction() override {};
+  ~NotificationsApiFunction() override {}
 };
 
 class NotificationsCreateFunction : public NotificationsApiFunction {
  protected:
-  ~NotificationsCreateFunction() override {};
+  ~NotificationsCreateFunction() override {}
 
   ResponseAction Run() override;
 
@@ -34,7 +34,7 @@
 
 class NotificationsUpdateFunction : public NotificationsApiFunction {
  protected:
-  ~NotificationsUpdateFunction() override {};
+  ~NotificationsUpdateFunction() override {}
 
   ResponseAction Run() override;
 
@@ -44,7 +44,7 @@
 
 class NotificationsClearFunction : public NotificationsApiFunction {
  protected:
-  ~NotificationsClearFunction() override {};
+  ~NotificationsClearFunction() override {}
 
   ResponseAction Run() override;
 
@@ -54,7 +54,7 @@
 
 class NotificationsGetAllFunction : public NotificationsApiFunction {
  protected:
-  ~NotificationsGetAllFunction() override {};
+  ~NotificationsGetAllFunction() override {}
 
   ResponseAction Run() override;
 
@@ -65,7 +65,7 @@
 class NotificationsGetPermissionLevelFunction
     : public NotificationsApiFunction {
  protected:
-  ~NotificationsGetPermissionLevelFunction() override {};
+  ~NotificationsGetPermissionLevelFunction() override {}
 
   ResponseAction Run() override;
 
diff --git a/chromecast/browser/extensions/api/tabs/tabs_constants.h b/chromecast/browser/extensions/api/tabs/tabs_constants.h
index 468fb93..57130c9 100644
--- a/chromecast/browser/extensions/api/tabs/tabs_constants.h
+++ b/chromecast/browser/extensions/api/tabs/tabs_constants.h
@@ -106,7 +106,7 @@
 extern const char kCannotDetermineLanguageOfUnloadedTab[];
 extern const char kMissingLockWindowFullscreenPrivatePermission[];
 
-};  // namespace tabs_constants
-};  // namespace extensions
+}  // namespace tabs_constants
+}  // namespace extensions
 
 #endif  // CHROMECAST_BROWSER_EXTENSIONS_API_TABS_TABS_CONSTANTS_H_
diff --git a/chromecast/browser/extensions/api/tts/tts_extension_api.cc b/chromecast/browser/extensions/api/tts/tts_extension_api.cc
index 20e83df..64ff390 100644
--- a/chromecast/browser/extensions/api/tts/tts_extension_api.cc
+++ b/chromecast/browser/extensions/api/tts/tts_extension_api.cc
@@ -28,7 +28,7 @@
 
 namespace events {
 const char kOnEvent[] = "tts.onEvent";
-};  // namespace events
+}  // namespace events
 
 const char* TtsEventTypeToString(TtsEventType event_type) {
   switch (event_type) {
diff --git a/chromecast/browser/test/cast_browser_test.cc b/chromecast/browser/test/cast_browser_test.cc
index 164bda1..72c4101 100644
--- a/chromecast/browser/test/cast_browser_test.cc
+++ b/chromecast/browser/test/cast_browser_test.cc
@@ -96,11 +96,11 @@
 
 bool CastBrowserTest::CanHandleGesture(GestureType gesture_type) {
   return false;
-};
+}
 
 bool CastBrowserTest::ConsumeGesture(GestureType gesture_type) {
   return false;
-};
+}
 
 std::string CastBrowserTest::GetId() {
   return "";
diff --git a/chromecast/graphics/accessibility/accessibility_layer.h b/chromecast/graphics/accessibility/accessibility_layer.h
index c8348d4..98ba5ae 100644
--- a/chromecast/graphics/accessibility/accessibility_layer.h
+++ b/chromecast/graphics/accessibility/accessibility_layer.h
@@ -35,7 +35,7 @@
   virtual void OnAnimationStep(base::TimeTicks timestamp) = 0;
 
  protected:
-  virtual ~AccessibilityLayerDelegate(){};
+  virtual ~AccessibilityLayerDelegate() {}
 };
 
 // AccessibilityLayer manages a global always-on-top layer used to
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
index ecf8194..89ce23e2 100644
--- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
+++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -358,7 +358,7 @@
       base::BindOnce(&PipelineHelper::Start,
                      base::Unretained(pipeline_helper_.get()), eos_cb));
   base::RunLoop().Run();
-};
+}
 
 // Test all three types of pipeline: audio-only, video-only, audio-video.
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 2b31d0f..5e09fb6 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -285,6 +285,7 @@
     tast_disabled_tests = [
       # Disabled due to misleading USE flags on full boards. crbug.com/916367
       "arc.Boot",
+      "arc.BuildProperties",
       "security.NetworkListenersARC",
       "video.WebRTCPeerConnCameraVP8",  # crbug.com/923061
     ]
diff --git a/components/arc/common/usb_host.mojom b/components/arc/common/usb_host.mojom
index 0b2863f5..466864e3 100644
--- a/components/arc/common/usb_host.mojom
+++ b/components/arc/common/usb_host.mojom
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Next MinVersion: 3
+// Next MinVersion: 4
 module arc.mojom;
 
 // re-use device.mojom.UsbDeviceInfo
 import "device/usb/public/mojom/device.mojom";
 
-// Next method ID: 3
+// Next method ID: 4
 interface UsbHostHost {
   // Tries to open the USB device node for the device named 'guid' for caller
   // 'pkg_name' and returns an open file descriptor to this node. 'pkg_name'
@@ -16,8 +16,20 @@
   // call will fail. Note the 'pkg_name' is informational purposes only, there
   // is no effective way that host can restrict access to only a specific
   // package at the security boundary formed by this Mojo interface.
-  OpenDevice@0(string guid,
-               [MinVersion=1] string? pkg_name) => (handle usb_fd);
+  // Deprecated.
+  OpenDeviceDeprecated@0(string guid,
+                         [MinVersion=1] string? pkg_name) => (handle usb_fd);
+
+  // Tries to open the USB device node for the device named 'guid' for caller
+  // 'pkg_name' and returns an open file descriptor to this node. 'pkg_name'
+  // needs to have previously called RequestPermission for this 'guid' else this
+  // call will fail. Note the 'pkg_name' is informational purposes only, there
+  // is no effective way that host can restrict access to only a specific
+  // package at the security boundary formed by this Mojo interface.
+  // When app tries to open a device without requesting permission, or
+  // permission_broker rejects the open request, empty handle will be returned.
+  [MinVersion=3] OpenDevice@3(string guid, string? pkg_name) =>
+      (handle? usb_fd);
 
   // Returns the USB device descriptors for the device named 'guid'.
   GetDeviceInfo@1(string guid) => (string device_name,
diff --git a/components/arc/power/arc_power_bridge.cc b/components/arc/power/arc_power_bridge.cc
index e8bfa00..268d86f 100644
--- a/components/arc/power/arc_power_bridge.cc
+++ b/components/arc/power/arc_power_bridge.cc
@@ -23,6 +23,7 @@
 #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 "ui/display/manager/display_configurator.h"
 
 namespace arc {
 namespace {
diff --git a/components/arc/usb/usb_host_bridge.cc b/components/arc/usb/usb_host_bridge.cc
index 5e2c24b..6c78aff 100644
--- a/components/arc/usb/usb_host_bridge.cc
+++ b/components/arc/usb/usb_host_bridge.cc
@@ -166,6 +166,14 @@
                    base::Bind(&OnDeviceOpenError, repeating_callback));
 }
 
+void ArcUsbHostBridge::OpenDeviceDeprecated(
+    const std::string& guid,
+    const base::Optional<std::string>& package,
+    OpenDeviceCallback callback) {
+  LOG(ERROR) << "ArcUsbHostBridge::OpenDeviceDeprecated is deprecated";
+  OpenDevice(guid, package, std::move(callback));
+}
+
 void ArcUsbHostBridge::GetDeviceInfo(const std::string& guid,
                                      GetDeviceInfoCallback callback) {
   if (!usb_service_) {
diff --git a/components/arc/usb/usb_host_bridge.h b/components/arc/usb/usb_host_bridge.h
index 35e87b8..04719ee 100644
--- a/components/arc/usb/usb_host_bridge.h
+++ b/components/arc/usb/usb_host_bridge.h
@@ -53,6 +53,9 @@
                          const std::string& package,
                          bool interactive,
                          RequestPermissionCallback callback) override;
+  void OpenDeviceDeprecated(const std::string& guid,
+                            const base::Optional<std::string>& package,
+                            OpenDeviceCallback callback) override;
   void OpenDevice(const std::string& guid,
                   const base::Optional<std::string>& package,
                   OpenDeviceCallback callback) override;
diff --git a/components/autofill/core/browser/autofill_profile_sync_util.cc b/components/autofill/core/browser/autofill_profile_sync_util.cc
index f54c161..8f6b3ca 100644
--- a/components/autofill/core/browser/autofill_profile_sync_util.cc
+++ b/components/autofill/core/browser/autofill_profile_sync_util.cc
@@ -5,10 +5,14 @@
 #include "components/autofill/core/browser/autofill_profile_sync_util.h"
 
 #include "base/guid.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_profile.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_comparator.h"
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/proto/autofill_sync.pb.h"
@@ -235,4 +239,28 @@
   return specifics.guid();
 }
 
+bool IsLocalProfileEqualToServerProfile(
+    const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+    const AutofillProfile& local_profile,
+    const std::string& app_locale) {
+  AutofillProfileComparator comparator(app_locale);
+  for (const auto& server_profile : server_profiles) {
+    // The same logic as when deciding whether to convert into a new profile in
+    // PersonalDataManager::MergeServerAddressesIntoProfiles.
+    if (comparator.AreMergeable(*server_profile, local_profile) &&
+        (!local_profile.IsVerified() || !server_profile->IsVerified())) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void ReportAutofillProfileAddOrUpdateOrigin(
+    AutofillProfileSyncChangeOrigin origin) {
+  UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.AddOrUpdateOrigin", origin);
+}
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin) {
+  UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.DeleteOrigin", origin);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_profile_sync_util.h b/components/autofill/core/browser/autofill_profile_sync_util.h
index a435952..87d677a7 100644
--- a/components/autofill/core/browser/autofill_profile_sync_util.h
+++ b/components/autofill/core/browser/autofill_profile_sync_util.h
@@ -7,6 +7,8 @@
 
 #include <memory>
 #include <string>
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include <vector>
 
 namespace syncer {
 struct EntityData;
@@ -40,6 +42,24 @@
 std::string GetStorageKeyFromAutofillProfileSpecifics(
     const sync_pb::AutofillProfileSpecifics& specifics);
 
+// TODO(crbug.com/904390): Remove when the investigation is over.
+bool IsLocalProfileEqualToServerProfile(
+    const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+    const AutofillProfile& local_profile,
+    const std::string& app_locale);
+
+// TODO(crbug.com/904390): Remove when the investigation is over.
+enum class AutofillProfileSyncChangeOrigin {
+  kTrulyLocal = 0,
+  kConvertedLocal = 1,
+  kIncrementalRemote = 2,
+  kInitial = 3,
+  kMaxValue = kInitial,
+};
+void ReportAutofillProfileAddOrUpdateOrigin(
+    AutofillProfileSyncChangeOrigin origin);
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_SYNC_UTIL_H_
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 4ee20ea6..7acd59b 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -49,6 +49,20 @@
 // Address to this variable used as the user data key.
 static int kAutofillProfileSyncBridgeUserDataKey = 0;
 
+// TODO(crbug.com/904390): Remove when the investigation is over.
+base::Optional<AutofillProfile> FindLocalProfileByStorageKey(
+    const std::string& storage_key,
+    AutofillTable* table) {
+  std::vector<std::unique_ptr<AutofillProfile>> local_profiles;
+  table->GetAutofillProfiles(&local_profiles);
+  for (const auto& local_profile : local_profiles) {
+    if (storage_key == GetStorageKeyFromAutofillProfile(*local_profile)) {
+      return *local_profile;
+    }
+  }
+  return base::nullopt;
+}
+
 }  // namespace
 
 // static
@@ -124,8 +138,9 @@
 
   RETURN_IF_ERROR(
       initial_sync_tracker.MergeSimilarEntriesForInitialSync(app_locale_));
-  RETURN_IF_ERROR(
-      FlushSyncTracker(std::move(metadata_change_list), &initial_sync_tracker));
+  RETURN_IF_ERROR(FlushSyncTracker(std::move(metadata_change_list),
+                                   &initial_sync_tracker,
+                                   AutofillProfileSyncChangeOrigin::kInitial));
 
   web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL_PROFILE);
   return base::nullopt;
@@ -156,7 +171,8 @@
     }
   }
 
-  return FlushSyncTracker(std::move(metadata_change_list), &tracker);
+  return FlushSyncTracker(std::move(metadata_change_list), &tracker,
+                          AutofillProfileSyncChangeOrigin::kIncrementalRemote);
 }
 
 void AutofillProfileSyncBridge::GetData(StorageKeyList storage_keys,
@@ -215,6 +231,22 @@
       std::make_unique<syncer::SyncMetadataStoreChangeList>(
           GetAutofillTable(), syncer::AUTOFILL_PROFILE);
 
+  // TODO(crbug.com/904390): Remove when the investigation is over.
+  base::Optional<AutofillProfile> local_profile;
+  if (change.type() == AutofillProfileChange::REMOVE) {
+    local_profile =
+        FindLocalProfileByStorageKey(change.key(), GetAutofillTable());
+  } else {
+    local_profile = *change.data_model();
+  }
+  std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+  GetAutofillTable()->GetServerProfiles(&server_profiles);
+  bool is_converted_from_server = false;
+  if (local_profile != base::nullopt) {
+    is_converted_from_server = IsLocalProfileEqualToServerProfile(
+        server_profiles, *local_profile, app_locale_);
+  }
+
   switch (change.type()) {
     case AutofillProfileChange::ADD:
     case AutofillProfileChange::UPDATE:
@@ -222,6 +254,12 @@
           change.key(),
           CreateEntityDataFromAutofillProfile(*change.data_model()),
           metadata_change_list.get());
+
+      // TODO(crbug.com/904390): Remove when the investigation is over.
+      ReportAutofillProfileAddOrUpdateOrigin(
+          is_converted_from_server
+              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     case AutofillProfileChange::REMOVE:
       // Removals have no data_model() so this change can still be for a
@@ -231,6 +269,15 @@
       // TODO(jkrcal): implement a hash map of known storage_keys and use it
       // here.
       change_processor()->Delete(change.key(), metadata_change_list.get());
+
+      // TODO(crbug.com/904390): Remove when the investigation is over.
+      if (local_profile != base::nullopt) {
+        // Report only if we delete an existing entity.
+        ReportAutofillProfileDeleteOrigin(
+            is_converted_from_server
+                ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+                : AutofillProfileSyncChangeOrigin::kTrulyLocal);
+      }
       break;
     case AutofillProfileChange::EXPIRE:
       // EXPIRE changes are not being issued for profiles.
@@ -245,7 +292,8 @@
 
 base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
     std::unique_ptr<MetadataChangeList> metadata_change_list,
-    AutofillProfileSyncDifferenceTracker* tracker) {
+    AutofillProfileSyncDifferenceTracker* tracker,
+    AutofillProfileSyncChangeOrigin origin) {
   DCHECK(tracker);
 
   RETURN_IF_ERROR(tracker->FlushToLocal(
@@ -259,6 +307,9 @@
     change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
                             CreateEntityDataFromAutofillProfile(*entry),
                             metadata_change_list.get());
+
+    // TODO(crbug.com/904390): Remove when the investigation is over.
+    ReportAutofillProfileAddOrUpdateOrigin(origin);
   }
 
   return static_cast<syncer::SyncMetadataStoreChangeList*>(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
index a6e50098..9b449f4 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
@@ -29,6 +29,7 @@
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
+enum class AutofillProfileSyncChangeOrigin;
 
 // Sync bridge implementation for AUTOFILL_PROFILE model type. Takes care of
 // propagating local autofill profiles to other clients as well as incorporating
@@ -90,7 +91,9 @@
   // Flushes changes accumulated within |tracker| both to local and to sync.
   base::Optional<syncer::ModelError> FlushSyncTracker(
       std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-      AutofillProfileSyncDifferenceTracker* tracker);
+      AutofillProfileSyncDifferenceTracker* tracker,
+      // TODO(crbug.com/904390): Remove |origin| when the investigation is over.
+      AutofillProfileSyncChangeOrigin origin);
 
   // Synchronously load sync metadata from the autofill table and pass it to the
   // processor so that it can start tracking changes.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index 51d3cb7..f3c90a6d 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -17,6 +17,8 @@
 #include "components/autofill/core/browser/autofill_country.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_profile_comparator.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_sync_util.h"
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/form_group.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
@@ -184,6 +186,10 @@
         syncer::SyncChange(FROM_HERE,
                            syncer::SyncChange::ACTION_ADD,
                            CreateData(*(it.second))));
+
+    // TODO(crbug.com/904390): Remove when the investigation is over.
+    ReportAutofillProfileAddOrUpdateOrigin(
+        AutofillProfileSyncChangeOrigin::kInitial);
     profiles_map_[it.first] = it.second;
   }
 
@@ -192,6 +198,10 @@
         syncer::SyncChange(FROM_HERE,
                            syncer::SyncChange::ACTION_UPDATE,
                            CreateData(*(bundle.profiles_to_sync_back[i]))));
+
+    // TODO(crbug.com/904390): Remove when the investigation is over.
+    ReportAutofillProfileAddOrUpdateOrigin(
+        AutofillProfileSyncChangeOrigin::kInitial);
   }
 
   if (!new_changes.empty()) {
@@ -603,6 +613,24 @@
     return;
   }
 
+  // TODO(crbug.com/904390): Remove when the investigation is over.
+  const AutofillProfile* local_profile = nullptr;
+  if (change.type() == AutofillProfileChange::REMOVE) {
+    if (profiles_map_.find(change.key()) != profiles_map_.end()) {
+      local_profile = profiles_map_[change.key()];
+    }
+  } else {
+    local_profile = change.data_model();
+  }
+  bool is_converted_from_server = false;
+  // |webdata_backend_| may be null in unit-tests.
+  if (local_profile != nullptr && webdata_backend_ != nullptr) {
+    std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+    GetAutofillTable()->GetServerProfiles(&server_profiles);
+    is_converted_from_server = IsLocalProfileEqualToServerProfile(
+        server_profiles, *local_profile, app_locale_);
+  }
+
   syncer::SyncChangeList new_changes;
   DataBundle bundle;
   switch (change.type()) {
@@ -616,6 +644,12 @@
       profiles_.push_back(
           std::make_unique<AutofillProfile>(*(change.data_model())));
       profiles_map_[change.data_model()->guid()] = profiles_.back().get();
+
+      // TODO(crbug.com/904390): Remove when the investigation is over.
+      ReportAutofillProfileAddOrUpdateOrigin(
+          is_converted_from_server
+              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     case AutofillProfileChange::UPDATE: {
       auto it = profiles_map_.find(change.data_model()->guid());
@@ -625,6 +659,12 @@
           syncer::SyncChange(FROM_HERE,
                              syncer::SyncChange::ACTION_UPDATE,
                              CreateData(*(change.data_model()))));
+
+      // TODO(crbug.com/904390): Remove when the investigation is over.
+      ReportAutofillProfileAddOrUpdateOrigin(
+          is_converted_from_server
+              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     }
     case AutofillProfileChange::REMOVE: {
@@ -636,6 +676,11 @@
             syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
                                CreateData(empty_profile)));
         profiles_map_.erase(change.key());
+        // TODO(crbug.com/904390): Remove when the investigation is over.
+        ReportAutofillProfileDeleteOrigin(
+            is_converted_from_server
+                ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+                : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       }
       break;
     }
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc
index 84f22c1..7051642 100644
--- a/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -144,6 +144,11 @@
   MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&));   // NOLINT
   MOCK_METHOD1(AddAutofillProfile, bool(const AutofillProfile&));      // NOLINT
   MOCK_METHOD1(RemoveAutofillProfile, bool(const std::string&));       // NOLINT
+
+  // TODO(crbug.com/904390): Remove when the investigation is over.
+  MOCK_CONST_METHOD1(
+      GetServerProfiles,
+      bool(std::vector<std::unique_ptr<AutofillProfile>>*));  // NOLINT
 };
 
 MATCHER_P(MatchProfiles, profile, "") {
@@ -950,6 +955,10 @@
       "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
       "Orlando", "FL", "32801", "US", "19482937549");
 
+  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
+  // needed in the AutofillProfileChanged() callback.
+  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));
+
   AutofillProfileChange change(AutofillProfileChange::ADD, added_profile.guid(),
                                &added_profile);
   web_data_service()->OnAutofillProfileChanged(change);
@@ -989,6 +998,10 @@
   StartAutofillProfileSyncService(add_autofill.callback());
   ASSERT_TRUE(add_autofill.success());
 
+  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
+  // needed in the AutofillProfileChanged() callback.
+  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));
+
   AutofillProfileChange change(AutofillProfileChange::REMOVE,
                                sync_profile.guid(), nullptr);
   web_data_service()->OnAutofillProfileChanged(change);
diff --git a/components/certificate_transparency/ct_known_logs.h b/components/certificate_transparency/ct_known_logs.h
index 59fbc6a..9e5f081 100644
--- a/components/certificate_transparency/ct_known_logs.h
+++ b/components/certificate_transparency/ct_known_logs.h
@@ -19,16 +19,16 @@
 
 struct CTLogInfo {
   // The DER-encoded SubjectPublicKeyInfo for the log.
-  const char* log_key;
+  const char* const log_key;
   // The length, in bytes, of |log_key|.
-  size_t log_key_length;
+  const size_t log_key_length;
   // The user-friendly log name.
   // Note: This will not be translated.
-  const char* log_name;
+  const char* const log_name;
   // The DNS API endpoint for the log.
   // This is used as the parent domain for all queries about the log.
   // https://github.com/google/certificate-transparency-rfcs/blob/master/dns/draft-ct-over-dns.md.
-  const char* log_dns_domain;
+  const char* const log_dns_domain;
 };
 
 // Returns information about all known logs, which includes those that are
diff --git a/components/content_capture/android/BUILD.gn b/components/content_capture/android/BUILD.gn
new file mode 100644
index 0000000..5b9003f
--- /dev/null
+++ b/components/content_capture/android/BUILD.gn
@@ -0,0 +1,37 @@
+# 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("//build/config/android/rules.gni")
+
+source_set("android") {
+  sources = [
+    "content_capture_receiver_manager_android.cc",
+    "content_capture_receiver_manager_android.h",
+  ]
+  deps = [
+    ":jni_headers",
+    "//components/content_capture/browser",
+  ]
+}
+
+android_library("java") {
+  deps = [
+    "//base:base_java",
+    # "//content/public/android:content_java",
+  ]
+  java_files = [
+    "java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java",
+    "java/src/org/chromium/components/content_capture/ContentCaptureData.java",
+    "java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
+    "java/src/org/chromium/components/content_capture/FrameSession.java",
+  ]
+}
+
+generate_jni("jni_headers") {
+  sources = [
+    "java/src/org/chromium/components/content_capture/ContentCaptureData.java",
+    "java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
+  ]
+  jni_package = "content_capture"
+}
diff --git a/components/content_capture/android/DEPS b/components/content_capture/android/DEPS
new file mode 100644
index 0000000..fb1ebef
--- /dev/null
+++ b/components/content_capture/android/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+  "+content/public/android",
+  "+content/public/browser",
+  "+jni",
+]
\ No newline at end of file
diff --git a/components/content_capture/android/content_capture_receiver_manager_android.cc b/components/content_capture/android/content_capture_receiver_manager_android.cc
new file mode 100644
index 0000000..215f597
--- /dev/null
+++ b/components/content_capture/android/content_capture_receiver_manager_android.cc
@@ -0,0 +1,120 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/android/content_capture_receiver_manager_android.h"
+
+#include <utility>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "content/public/browser/web_contents.h"
+#include "jni/ContentCaptureData_jni.h"
+#include "jni/ContentCaptureReceiverManager_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::JavaRef;
+using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaLongArray;
+
+namespace content_capture {
+
+namespace {
+
+ScopedJavaLocalRef<jobject> ToJavaObjectOfContentCaptureData(
+    JNIEnv* env,
+    const ContentCaptureData& data,
+    const JavaRef<jobject>& parent) {
+  ScopedJavaLocalRef<jstring> jvalue =
+      ConvertUTF16ToJavaString(env, data.value);
+  ScopedJavaLocalRef<jobject> jdata =
+      Java_ContentCaptureData_createContentCaptureData(
+          env, parent, data.id, jvalue, data.bounds.x(), data.bounds.y(),
+          data.bounds.width(), data.bounds.height());
+  if (jdata.is_null())
+    return jdata;
+  for (auto child : data.children) {
+    ToJavaObjectOfContentCaptureData(env, child, jdata);
+  }
+  return jdata;
+}
+
+ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfContentCaptureData(
+    JNIEnv* env,
+    const ContentCaptureSession& session) {
+  ScopedJavaLocalRef<jclass> object_clazz =
+      base::android::GetClass(env, "java/lang/Object");
+  jobjectArray joa =
+      env->NewObjectArray(session.size(), object_clazz.obj(), NULL);
+  jni_generator::CheckException(env);
+
+  for (size_t i = 0; i < session.size(); ++i) {
+    ScopedJavaLocalRef<jobject> item =
+        ToJavaObjectOfContentCaptureData(env, session[i], JavaRef<jobject>());
+    env->SetObjectArrayElement(joa, i, item.obj());
+  }
+  return ScopedJavaLocalRef<jobjectArray>(env, joa);
+}
+
+}  // namespace
+
+ContentCaptureReceiverManagerAndroid::ContentCaptureReceiverManagerAndroid(
+    content::WebContents* web_contents,
+    const JavaRef<jobject>& jcaller)
+    : ContentCaptureReceiverManager(web_contents) {
+  JNIEnv* env = AttachCurrentThread();
+  java_ref_ = JavaObjectWeakGlobalRef(env, jcaller);
+}
+
+ContentCaptureReceiverManagerAndroid::~ContentCaptureReceiverManagerAndroid() =
+    default;
+
+void ContentCaptureReceiverManagerAndroid::Create(
+    content::WebContents* web_contents,
+    const JavaRef<jobject>& jcaller) {
+  if (FromWebContents(web_contents))
+    return;
+  new ContentCaptureReceiverManagerAndroid(web_contents, jcaller);
+}
+
+void ContentCaptureReceiverManagerAndroid::DidCaptureContent(
+    const ContentCaptureSession& parent_session,
+    const ContentCaptureData& data) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+
+  ScopedJavaLocalRef<jobject> jdata =
+      ToJavaObjectOfContentCaptureData(env, data, JavaRef<jobject>());
+  if (jdata.is_null())
+    return;
+  Java_ContentCaptureReceiverManager_didCaptureContent(
+      env, obj, ToJavaArrayOfContentCaptureData(env, parent_session), jdata);
+}
+
+void ContentCaptureReceiverManagerAndroid::DidRemoveContent(
+    const ContentCaptureSession& session,
+    const std::vector<int64_t>& data) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+  Java_ContentCaptureReceiverManager_didRemoveContent(
+      env, obj, ToJavaArrayOfContentCaptureData(env, session),
+      ToJavaLongArray(env, data));
+}
+
+void ContentCaptureReceiverManagerAndroid::DidRemoveSession(
+    const ContentCaptureSession& session) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+  Java_ContentCaptureReceiverManager_didRemoveSession(
+      env, obj, ToJavaArrayOfContentCaptureData(env, session));
+}
+
+}  // namespace content_capture
diff --git a/components/content_capture/android/content_capture_receiver_manager_android.h b/components/content_capture/android/content_capture_receiver_manager_android.h
new file mode 100644
index 0000000..cb98c9a
--- /dev/null
+++ b/components/content_capture/android/content_capture_receiver_manager_android.h
@@ -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.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
+#define COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
+
+#include <vector>
+
+#include "base/android/jni_weak_ref.h"
+#include "components/content_capture/browser/content_capture_receiver_manager.h"
+
+namespace content_capture {
+
+// The Android's implementation of ContentCaptureReceiverManager, it forwards
+// the received message to Java.
+class ContentCaptureReceiverManagerAndroid
+    : public ContentCaptureReceiverManager {
+ public:
+  ~ContentCaptureReceiverManagerAndroid() override;
+  static void Create(content::WebContents* web_contents,
+                     const base::android::JavaRef<jobject>& jcaller);
+
+  void DidCaptureContent(const ContentCaptureSession& parent_session,
+                         const ContentCaptureData& data) override;
+  void DidRemoveContent(const ContentCaptureSession& session,
+                        const std::vector<int64_t>& data) override;
+  void DidRemoveSession(const ContentCaptureSession& session) override;
+
+ private:
+  ContentCaptureReceiverManagerAndroid(
+      content::WebContents* web_contents,
+      const base::android::JavaRef<jobject>& jcaller);
+
+  JavaObjectWeakGlobalRef java_ref_;
+};
+
+}  // namespace content_capture
+
+#endif  // COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
diff --git a/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
new file mode 100644
index 0000000..d9a458dbb
--- /dev/null
+++ b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
@@ -0,0 +1,30 @@
+// 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.components.content_capture;
+
+/**
+ * This interface is for consumer to consume the captured content.
+ */
+public interface ContentCaptureConsumer {
+    /**
+     * Invoked when the content is captured from a frame.
+     * @param parentFrame is the parent of the frame from that the content captured.
+     * @param contentCaptureData is the captured content tree, its root is the frame.
+     */
+    void onContentCaptured(FrameSession parentFrame, ContentCaptureData contentCaptureData);
+
+    /**
+     * Invoked when the session is removed
+     * @param session is the removed frame.
+     */
+    void onSessionRemoved(FrameSession session);
+
+    /**
+     * Invoked when the content is removed from a frame
+     * @param session defines the frame from that the content removed
+     * @param removedIds are array of removed content id.
+     */
+    void onContentRemoved(FrameSession session, long[] removedIds);
+}
diff --git a/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java
new file mode 100644
index 0000000..94baa45
--- /dev/null
+++ b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java
@@ -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.
+
+package org.chromium.components.content_capture;
+
+import android.graphics.Rect;
+
+import org.chromium.base.annotations.CalledByNative;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is Java's representative of components/content_capture/common/content_capture_data.h
+ */
+public class ContentCaptureData {
+    private long mId;
+    private String mValue;
+    private Rect mBounds;
+    private ArrayList<ContentCaptureData> mChildren;
+
+    @CalledByNative
+    private static ContentCaptureData createContentCaptureData(
+            Object parent, long id, String value, int x, int y, int width, int height) {
+        ContentCaptureData data = new ContentCaptureData(id, value, x, y, width, height);
+        if (parent != null) {
+            ((ContentCaptureData) parent).addChild(data);
+        }
+        return data;
+    }
+
+    private ContentCaptureData(long id, String value, int x, int y, int width, int height) {
+        mId = id;
+        mValue = value;
+        mBounds = new Rect(x, y, x + width, y + height);
+    }
+
+    public String getValue() {
+        return mValue;
+    }
+
+    public Rect getBounds() {
+        return mBounds;
+    }
+
+    public List<ContentCaptureData> getChildren() {
+        return mChildren;
+    }
+
+    public boolean hasChildren() {
+        return mChildren != null && !mChildren.isEmpty();
+    }
+
+    public long getId() {
+        return mId;
+    }
+
+    private void addChild(ContentCaptureData data) {
+        if (mChildren == null) mChildren = new ArrayList<ContentCaptureData>();
+        mChildren.add(data);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("id:");
+        sb.append(mId);
+        sb.append(" value:");
+        sb.append(mValue);
+        sb.append(" bounds:");
+        sb.append(mBounds);
+        sb.append('\n');
+        if (hasChildren()) {
+            sb.append("children:");
+            sb.append(mChildren.size());
+            for (ContentCaptureData child : mChildren) {
+                sb.append(child.toString());
+            }
+        }
+        return sb.toString();
+    }
+}
diff --git a/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
new file mode 100644
index 0000000..4e2daef
--- /dev/null
+++ b/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
@@ -0,0 +1,64 @@
+// 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.components.content_capture;
+
+import android.view.ViewGroup;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+
+import java.util.Arrays;
+
+/**
+ * This class receives captured content from native and forwards to ContetnCaptureConsumer.
+ */
+public class ContentCaptureReceiverManager {
+    private static final String TAG = "ContentCapture";
+    private static final boolean DEBUG = false;
+
+    private ContentCaptureConsumer mContentCaptureConsumer;
+
+    public ContentCaptureReceiverManager() {}
+
+    public void onContainerViewChanged(ViewGroup containerView) {
+        // Reset current consumer, the new consumer that associates with contanerView shall be set
+        // from setContentCaptureConsumer().
+        mContentCaptureConsumer = null;
+    }
+
+    public void setContentCaptureConsumer(ContentCaptureConsumer consumer) {
+        mContentCaptureConsumer = consumer;
+    }
+
+    @CalledByNative
+    private void didCaptureContent(Object[] session, ContentCaptureData data) {
+        if (mContentCaptureConsumer != null) {
+            mContentCaptureConsumer.onContentCaptured(toFrameSession(session), data);
+        }
+        if (DEBUG) Log.i(TAG, "Captured Content: %s", data);
+    }
+
+    @CalledByNative
+    private void didRemoveContent(Object[] session, long[] data) {
+        FrameSession frameSession = toFrameSession(session);
+        if (mContentCaptureConsumer != null)
+            mContentCaptureConsumer.onContentRemoved(frameSession, data);
+        if (DEBUG)
+            Log.i(TAG, "Removed Content: %s", frameSession.get(0) + " " + Arrays.toString(data));
+    }
+
+    @CalledByNative
+    private void didRemoveSession(Object[] session) {
+        FrameSession frameSession = toFrameSession(session);
+        if (mContentCaptureConsumer != null) mContentCaptureConsumer.onSessionRemoved(frameSession);
+        if (DEBUG) Log.i(TAG, "Removed Session: %s", frameSession.get(0));
+    }
+
+    private FrameSession toFrameSession(Object[] session) {
+        FrameSession frameSession = new FrameSession(session.length);
+        for (Object s : session) frameSession.add((ContentCaptureData) s);
+        return frameSession;
+    }
+}
diff --git a/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java b/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java
new file mode 100644
index 0000000..b7597cd
--- /dev/null
+++ b/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.content_capture;
+
+import java.util.ArrayList;
+
+/**
+ * This class is used to specify the frame's session by a list of Frame ContentCaptureData from the
+ * interested frame to root.
+ */
+public class FrameSession extends ArrayList<ContentCaptureData> {
+    /**
+     * @param length is reserved frame list length.
+     */
+    public FrameSession(int length) {
+        super(length);
+    }
+}
diff --git a/components/content_settings/core/common/content_settings_pattern_parser.cc b/components/content_settings/core/common/content_settings_pattern_parser.cc
index 00af108..7064c2b 100644
--- a/components/content_settings/core/common/content_settings_pattern_parser.cc
+++ b/components/content_settings/core/common/content_settings_pattern_parser.cc
@@ -20,6 +20,10 @@
 const char kSchemeWildcard[] = "*";
 const char kUrlPathSeparator[] = "/";
 const char kUrlPortSeparator[] = ":";
+// A domain wildcard pattern involves exactly one separating dot,
+// inside the square brackets. This is a common misunderstanding of that
+// pattern that we want to check for. See: https://crbug.com/823706.
+const char kDomainWildcardWithSuperfluousDot[] = "[*.].";
 
 }  // namespace
 
@@ -130,6 +134,12 @@
         return;
       }
 
+      if (base::StartsWith(host_piece, kDomainWildcardWithSuperfluousDot,
+                           base::CompareCase::SENSITIVE)) {
+        builder->Invalid();
+        return;
+      }
+
       host_piece.remove_prefix(kDomainWildcardLength);
       builder->WithDomainWildcard();
       builder->WithHost(host_piece.as_string());
diff --git a/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc b/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
index 20c7c7ac0..244db01 100644
--- a/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
+++ b/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
@@ -150,6 +150,16 @@
       ::testing::Return(&builder));
   content_settings::PatternParser::Parse("www.youtube.com*", &builder);
   ::testing::Mock::VerifyAndClear(&builder);
+
+  // Test for kDomainWildcardWithSuperfluousDot
+  EXPECT_CALL(builder, WithSchemeWildcard())
+      .Times(1)
+      .WillOnce(::testing::Return(&builder));
+  EXPECT_CALL(builder, Invalid())
+      .Times(1)
+      .WillOnce(::testing::Return(&builder));
+  content_settings::PatternParser::Parse("[*.].youtube.com", &builder);
+  ::testing::Mock::VerifyAndClear(&builder);
 }
 
 TEST(ContentSettingsPatternParserTest, ParseFilePatterns) {
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc
index 9bb914b..b53030f 100644
--- a/components/cronet/url_request_context_config.cc
+++ b/components/cronet/url_request_context_config.cc
@@ -66,6 +66,8 @@
 const char kQuicAllowServerMigration[] = "allow_server_migration";
 const char kQuicMigrateSessionsOnNetworkChangeV2[] =
     "migrate_sessions_on_network_change_v2";
+const char kQuicRetransmittableOnWireTimeoutMilliseconds[] =
+    "retransmittable_on_wire_timeout_milliseconds";
 const char kQuicIdleSessionMigrationPeriodSeconds[] =
     "idle_session_migration_period_seconds";
 const char kQuicMaxTimeOnNonDefaultNetworkSeconds[] =
@@ -479,6 +481,14 @@
             quic_migrate_sessions_early_v2;
       }
 
+      int quic_retransmittable_on_wire_timeout_milliseconds = 0;
+      if (quic_args->GetInteger(
+              kQuicRetransmittableOnWireTimeoutMilliseconds,
+              &quic_retransmittable_on_wire_timeout_milliseconds)) {
+        session_params->quic_retransmittable_on_wire_timeout_milliseconds =
+            quic_retransmittable_on_wire_timeout_milliseconds;
+      }
+
       bool quic_retry_on_alternate_network_before_handshake = false;
       if (quic_args->GetBoolean(
               kQuicRetryOnAlternateNetworkBeforeHandshake,
diff --git a/components/cronet/url_request_context_config_unittest.cc b/components/cronet/url_request_context_config_unittest.cc
index cb62f84..fc4cf948 100644
--- a/components/cronet/url_request_context_config_unittest.cc
+++ b/components/cronet/url_request_context_config_unittest.cc
@@ -646,6 +646,7 @@
       "{\"QUIC\":{\"migrate_sessions_on_network_change_v2\":true,"
       "\"migrate_sessions_early_v2\":true,"
       "\"retry_on_alternate_network_before_handshake\":true,"
+      "\"retransmittable_on_wire_timeout_milliseconds\":1000,"
       "\"idle_session_migration_period_seconds\":15,"
       "\"max_time_on_non_default_network_seconds\":10,"
       "\"max_migrations_to_non_default_network_on_write_error\":3,"
@@ -673,6 +674,7 @@
   EXPECT_TRUE(params->quic_migrate_sessions_on_network_change_v2);
   EXPECT_TRUE(params->quic_migrate_sessions_early_v2);
   EXPECT_TRUE(params->quic_retry_on_alternate_network_before_handshake);
+  EXPECT_EQ(1000, params->quic_retransmittable_on_wire_timeout_milliseconds);
   EXPECT_EQ(base::TimeDelta::FromSeconds(15),
             params->quic_idle_session_migration_period);
   EXPECT_EQ(base::TimeDelta::FromSeconds(10),
diff --git a/components/download/public/common/auto_resumption_handler.h b/components/download/public/common/auto_resumption_handler.h
index a66c8c6..1498223 100644
--- a/components/download/public/common/auto_resumption_handler.h
+++ b/components/download/public/common/auto_resumption_handler.h
@@ -40,7 +40,8 @@
       std::unique_ptr<download::TaskManager> task_manager,
       std::unique_ptr<Config> config);
 
-  // Returns the singleton instance of the AutoResumptionHandler.
+  // Returns the singleton instance of the AutoResumptionHandler, or nullptr if
+  // initialization is not yet complete.
   static AutoResumptionHandler* Get();
 
   AutoResumptionHandler(
diff --git a/components/exo/display.h b/components/exo/display.h
index a1fa2d5..34fcb3b 100644
--- a/components/exo/display.h
+++ b/components/exo/display.h
@@ -23,7 +23,7 @@
 
 namespace gfx {
 class ClientNativePixmapFactory;
-};
+}
 
 namespace exo {
 class ClientControlledShellSurface;
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn
index e419eb5..b9a23ec 100644
--- a/components/exo/wayland/BUILD.gn
+++ b/components/exo/wayland/BUILD.gn
@@ -57,6 +57,10 @@
     "wl_shm.h",
     "wl_subcompositor.cc",
     "wl_subcompositor.h",
+    "wp_presentation.cc",
+    "wp_presentation.h",
+    "wp_viewporter.cc",
+    "wp_viewporter.h",
     "zcr_vsync_feedback.cc",
     "zcr_vsync_feedback.h",
   ]
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index 8009398..b53cff4 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -75,6 +75,8 @@
 #include "components/exo/wayland/wl_seat.h"
 #include "components/exo/wayland/wl_shm.h"
 #include "components/exo/wayland/wl_subcompositor.h"
+#include "components/exo/wayland/wp_presentation.h"
+#include "components/exo/wayland/wp_viewporter.h"
 #include "components/exo/wayland/zcr_vsync_feedback.h"
 #include "components/exo/wm_helper.h"
 #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
@@ -89,7 +91,6 @@
 #include "ui/display/screen.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 #include "ui/gfx/buffer_types.h"
-#include "ui/gfx/presentation_feedback.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_observer.h"
 #include "ui/wm/core/coordinate_conversion.h"
@@ -156,10 +157,6 @@
 // Group used for wayland socket.
 const char kWaylandSocketGroup[] = "wayland";
 
-// A property key containing a boolean set to true if a viewport is associated
-// with with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasViewportKey, false)
-
 // A property key containing a boolean set to true if a security object is
 // associated with surface object.
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasSecurityKey, false)
@@ -169,221 +166,6 @@
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasBlendingKey, false)
 
 ////////////////////////////////////////////////////////////////////////////////
-// wp_viewport_interface:
-
-// Implements the viewport interface to a Surface. The "viewport"-state is set
-// to null upon destruction. A window property will be set during the lifetime
-// of this class to prevent multiple instances from being created for the same
-// Surface.
-class Viewport : public SurfaceObserver {
- public:
-  explicit Viewport(Surface* surface) : surface_(surface) {
-    surface_->AddSurfaceObserver(this);
-    surface_->SetProperty(kSurfaceHasViewportKey, true);
-  }
-  ~Viewport() override {
-    if (surface_) {
-      surface_->RemoveSurfaceObserver(this);
-      surface_->SetCrop(gfx::RectF());
-      surface_->SetViewport(gfx::Size());
-      surface_->SetProperty(kSurfaceHasViewportKey, false);
-    }
-  }
-
-  void SetSource(const gfx::RectF& rect) {
-    if (surface_)
-      surface_->SetCrop(rect);
-  }
-
-  void SetDestination(const gfx::Size& size) {
-    if (surface_)
-      surface_->SetViewport(size);
-  }
-
-  // Overridden from SurfaceObserver:
-  void OnSurfaceDestroying(Surface* surface) override {
-    surface->RemoveSurfaceObserver(this);
-    surface_ = nullptr;
-  }
-
- private:
-  Surface* surface_;
-
-  DISALLOW_COPY_AND_ASSIGN(Viewport);
-};
-
-void viewport_destroy(wl_client* client, wl_resource* resource) {
-  wl_resource_destroy(resource);
-}
-
-void viewport_set_source(wl_client* client,
-                         wl_resource* resource,
-                         wl_fixed_t x,
-                         wl_fixed_t y,
-                         wl_fixed_t width,
-                         wl_fixed_t height) {
-  if (x == wl_fixed_from_int(-1) && y == wl_fixed_from_int(-1) &&
-      width == wl_fixed_from_int(-1) && height == wl_fixed_from_int(-1)) {
-    GetUserDataAs<Viewport>(resource)->SetSource(gfx::RectF());
-    return;
-  }
-
-  if (x < 0 || y < 0 || width <= 0 || height <= 0) {
-    wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
-                           "source rectangle must be non-empty (%dx%d) and"
-                           "have positive origin (%d,%d)",
-                           width, height, x, y);
-    return;
-  }
-
-  GetUserDataAs<Viewport>(resource)->SetSource(
-      gfx::RectF(wl_fixed_to_double(x), wl_fixed_to_double(y),
-                 wl_fixed_to_double(width), wl_fixed_to_double(height)));
-}
-
-void viewport_set_destination(wl_client* client,
-                              wl_resource* resource,
-                              int32_t width,
-                              int32_t height) {
-  if (width == -1 && height == -1) {
-    GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size());
-    return;
-  }
-
-  if (width <= 0 || height <= 0) {
-    wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
-                           "destination size must be positive (%dx%d)", width,
-                           height);
-    return;
-  }
-
-  GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size(width, height));
-}
-
-const struct wp_viewport_interface viewport_implementation = {
-    viewport_destroy, viewport_set_source, viewport_set_destination};
-
-////////////////////////////////////////////////////////////////////////////////
-// wp_viewporter_interface:
-
-void viewporter_destroy(wl_client* client, wl_resource* resource) {
-  wl_resource_destroy(resource);
-}
-
-void viewporter_get_viewport(wl_client* client,
-                             wl_resource* resource,
-                             uint32_t id,
-                             wl_resource* surface_resource) {
-  Surface* surface = GetUserDataAs<Surface>(surface_resource);
-  if (surface->GetProperty(kSurfaceHasViewportKey)) {
-    wl_resource_post_error(resource, WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
-                           "a viewport for that surface already exists");
-    return;
-  }
-
-  wl_resource* viewport_resource = wl_resource_create(
-      client, &wp_viewport_interface, wl_resource_get_version(resource), id);
-
-  SetImplementation(viewport_resource, &viewport_implementation,
-                    std::make_unique<Viewport>(surface));
-}
-
-const struct wp_viewporter_interface viewporter_implementation = {
-    viewporter_destroy, viewporter_get_viewport};
-
-void bind_viewporter(wl_client* client,
-                     void* data,
-                     uint32_t version,
-                     uint32_t id) {
-  wl_resource* resource =
-      wl_resource_create(client, &wp_viewporter_interface, 1, id);
-
-  wl_resource_set_implementation(resource, &viewporter_implementation, data,
-                                 nullptr);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// presentation_interface:
-
-void HandleSurfacePresentationCallback(
-    wl_resource* resource,
-    const gfx::PresentationFeedback& feedback) {
-  if (feedback.timestamp.is_null()) {
-    wp_presentation_feedback_send_discarded(resource);
-  } else {
-    int64_t presentation_time_us = feedback.timestamp.ToInternalValue();
-    int64_t seconds = presentation_time_us / base::Time::kMicrosecondsPerSecond;
-    int64_t microseconds =
-        presentation_time_us % base::Time::kMicrosecondsPerSecond;
-    static_assert(
-        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kVSync) ==
-            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_VSYNC),
-        "gfx::PresentationFlags::VSync don't match!");
-    static_assert(
-        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kHWClock) ==
-            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK),
-        "gfx::PresentationFlags::HWClock don't match!");
-    static_assert(
-        static_cast<uint32_t>(
-            gfx::PresentationFeedback::Flags::kHWCompletion) ==
-            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION),
-        "gfx::PresentationFlags::HWCompletion don't match!");
-    static_assert(
-        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kZeroCopy) ==
-            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY),
-        "gfx::PresentationFlags::ZeroCopy don't match!");
-    wp_presentation_feedback_send_presented(
-        resource, seconds >> 32, seconds & 0xffffffff,
-        microseconds * base::Time::kNanosecondsPerMicrosecond,
-        feedback.interval.InMicroseconds() *
-            base::Time::kNanosecondsPerMicrosecond,
-        0, 0, feedback.flags);
-  }
-  wl_client_flush(wl_resource_get_client(resource));
-}
-
-void presentation_destroy(wl_client* client, wl_resource* resource) {
-  wl_resource_destroy(resource);
-}
-
-void presentation_feedback(wl_client* client,
-                           wl_resource* resource,
-                           wl_resource* surface_resource,
-                           uint32_t id) {
-  wl_resource* presentation_feedback_resource =
-      wl_resource_create(client, &wp_presentation_feedback_interface,
-                         wl_resource_get_version(resource), id);
-
-  // base::Unretained is safe as the resource owns the callback.
-  auto cancelable_callback = std::make_unique<
-      base::CancelableCallback<void(const gfx::PresentationFeedback&)>>(
-      base::Bind(&HandleSurfacePresentationCallback,
-                 base::Unretained(presentation_feedback_resource)));
-
-  GetUserDataAs<Surface>(surface_resource)
-      ->RequestPresentationCallback(cancelable_callback->callback());
-
-  SetImplementation(presentation_feedback_resource, nullptr,
-                    std::move(cancelable_callback));
-}
-
-const struct wp_presentation_interface presentation_implementation = {
-    presentation_destroy, presentation_feedback};
-
-void bind_presentation(wl_client* client,
-                       void* data,
-                       uint32_t version,
-                       uint32_t id) {
-  wl_resource* resource =
-      wl_resource_create(client, &wp_presentation_interface, 1, id);
-
-  wl_resource_set_implementation(resource, &presentation_implementation, data,
-                                 nullptr);
-
-  wp_presentation_send_clock_id(resource, CLOCK_MONOTONIC);
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // security_interface:
 
 // Implements the security interface to a Surface. The "only visible on secure
diff --git a/components/exo/wayland/wp_presentation.cc b/components/exo/wayland/wp_presentation.cc
new file mode 100644
index 0000000..d2a4f2d
--- /dev/null
+++ b/components/exo/wayland/wp_presentation.cc
@@ -0,0 +1,104 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wp_presentation.h"
+
+#include <presentation-time-server-protocol.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "components/exo/wayland/server_util.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// presentation_interface:
+
+void HandleSurfacePresentationCallback(
+    wl_resource* resource,
+    const gfx::PresentationFeedback& feedback) {
+  if (feedback.timestamp.is_null()) {
+    wp_presentation_feedback_send_discarded(resource);
+  } else {
+    int64_t presentation_time_us = feedback.timestamp.ToInternalValue();
+    int64_t seconds = presentation_time_us / base::Time::kMicrosecondsPerSecond;
+    int64_t microseconds =
+        presentation_time_us % base::Time::kMicrosecondsPerSecond;
+    static_assert(
+        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kVSync) ==
+            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_VSYNC),
+        "gfx::PresentationFlags::VSync don't match!");
+    static_assert(
+        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kHWClock) ==
+            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK),
+        "gfx::PresentationFlags::HWClock don't match!");
+    static_assert(
+        static_cast<uint32_t>(
+            gfx::PresentationFeedback::Flags::kHWCompletion) ==
+            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION),
+        "gfx::PresentationFlags::HWCompletion don't match!");
+    static_assert(
+        static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kZeroCopy) ==
+            static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY),
+        "gfx::PresentationFlags::ZeroCopy don't match!");
+    wp_presentation_feedback_send_presented(
+        resource, seconds >> 32, seconds & 0xffffffff,
+        microseconds * base::Time::kNanosecondsPerMicrosecond,
+        feedback.interval.InMicroseconds() *
+            base::Time::kNanosecondsPerMicrosecond,
+        0, 0, feedback.flags);
+  }
+  wl_client_flush(wl_resource_get_client(resource));
+}
+
+void presentation_destroy(wl_client* client, wl_resource* resource) {
+  wl_resource_destroy(resource);
+}
+
+void presentation_feedback(wl_client* client,
+                           wl_resource* resource,
+                           wl_resource* surface_resource,
+                           uint32_t id) {
+  wl_resource* presentation_feedback_resource =
+      wl_resource_create(client, &wp_presentation_feedback_interface,
+                         wl_resource_get_version(resource), id);
+
+  // base::Unretained is safe as the resource owns the callback.
+  auto cancelable_callback = std::make_unique<
+      base::CancelableCallback<void(const gfx::PresentationFeedback&)>>(
+      base::Bind(&HandleSurfacePresentationCallback,
+                 base::Unretained(presentation_feedback_resource)));
+
+  GetUserDataAs<Surface>(surface_resource)
+      ->RequestPresentationCallback(cancelable_callback->callback());
+
+  SetImplementation(presentation_feedback_resource, nullptr,
+                    std::move(cancelable_callback));
+}
+
+const struct wp_presentation_interface presentation_implementation = {
+    presentation_destroy, presentation_feedback};
+
+}  // namespace
+
+void bind_presentation(wl_client* client,
+                       void* data,
+                       uint32_t version,
+                       uint32_t id) {
+  wl_resource* resource =
+      wl_resource_create(client, &wp_presentation_interface, 1, id);
+
+  wl_resource_set_implementation(resource, &presentation_implementation, data,
+                                 nullptr);
+
+  wp_presentation_send_clock_id(resource, CLOCK_MONOTONIC);
+}
+
+}  // namespace wayland
+}  // namespace exo
diff --git a/components/exo/wayland/wp_presentation.h b/components/exo/wayland/wp_presentation.h
new file mode 100644
index 0000000..1a46a35
--- /dev/null
+++ b/components/exo/wayland/wp_presentation.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 COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
+#define COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_presentation(wl_client* client,
+                       void* data,
+                       uint32_t version,
+                       uint32_t id);
+
+}  // namespace wayland
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
diff --git a/components/exo/wayland/wp_viewporter.cc b/components/exo/wayland/wp_viewporter.cc
new file mode 100644
index 0000000..4fa7aa8
--- /dev/null
+++ b/components/exo/wayland/wp_viewporter.cc
@@ -0,0 +1,159 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wp_viewporter.h"
+
+#include <viewporter-server-protocol.h>
+
+#include <memory>
+
+#include "components/exo/surface_observer.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+// A property key containing a boolean set to true if a viewport is associated
+// with with surface object.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasViewportKey, false)
+
+////////////////////////////////////////////////////////////////////////////////
+// wp_viewport_interface:
+
+// Implements the viewport interface to a Surface. The "viewport"-state is set
+// to null upon destruction. A window property will be set during the lifetime
+// of this class to prevent multiple instances from being created for the same
+// Surface.
+class Viewport : public SurfaceObserver {
+ public:
+  explicit Viewport(Surface* surface) : surface_(surface) {
+    surface_->AddSurfaceObserver(this);
+    surface_->SetProperty(kSurfaceHasViewportKey, true);
+  }
+  ~Viewport() override {
+    if (surface_) {
+      surface_->RemoveSurfaceObserver(this);
+      surface_->SetCrop(gfx::RectF());
+      surface_->SetViewport(gfx::Size());
+      surface_->SetProperty(kSurfaceHasViewportKey, false);
+    }
+  }
+
+  void SetSource(const gfx::RectF& rect) {
+    if (surface_)
+      surface_->SetCrop(rect);
+  }
+
+  void SetDestination(const gfx::Size& size) {
+    if (surface_)
+      surface_->SetViewport(size);
+  }
+
+  // Overridden from SurfaceObserver:
+  void OnSurfaceDestroying(Surface* surface) override {
+    surface->RemoveSurfaceObserver(this);
+    surface_ = nullptr;
+  }
+
+ private:
+  Surface* surface_;
+
+  DISALLOW_COPY_AND_ASSIGN(Viewport);
+};
+
+void viewport_destroy(wl_client* client, wl_resource* resource) {
+  wl_resource_destroy(resource);
+}
+
+void viewport_set_source(wl_client* client,
+                         wl_resource* resource,
+                         wl_fixed_t x,
+                         wl_fixed_t y,
+                         wl_fixed_t width,
+                         wl_fixed_t height) {
+  if (x == wl_fixed_from_int(-1) && y == wl_fixed_from_int(-1) &&
+      width == wl_fixed_from_int(-1) && height == wl_fixed_from_int(-1)) {
+    GetUserDataAs<Viewport>(resource)->SetSource(gfx::RectF());
+    return;
+  }
+
+  if (x < 0 || y < 0 || width <= 0 || height <= 0) {
+    wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
+                           "source rectangle must be non-empty (%dx%d) and"
+                           "have positive origin (%d,%d)",
+                           width, height, x, y);
+    return;
+  }
+
+  GetUserDataAs<Viewport>(resource)->SetSource(
+      gfx::RectF(wl_fixed_to_double(x), wl_fixed_to_double(y),
+                 wl_fixed_to_double(width), wl_fixed_to_double(height)));
+}
+
+void viewport_set_destination(wl_client* client,
+                              wl_resource* resource,
+                              int32_t width,
+                              int32_t height) {
+  if (width == -1 && height == -1) {
+    GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size());
+    return;
+  }
+
+  if (width <= 0 || height <= 0) {
+    wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
+                           "destination size must be positive (%dx%d)", width,
+                           height);
+    return;
+  }
+
+  GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size(width, height));
+}
+
+const struct wp_viewport_interface viewport_implementation = {
+    viewport_destroy, viewport_set_source, viewport_set_destination};
+
+////////////////////////////////////////////////////////////////////////////////
+// wp_viewporter_interface:
+
+void viewporter_destroy(wl_client* client, wl_resource* resource) {
+  wl_resource_destroy(resource);
+}
+
+void viewporter_get_viewport(wl_client* client,
+                             wl_resource* resource,
+                             uint32_t id,
+                             wl_resource* surface_resource) {
+  Surface* surface = GetUserDataAs<Surface>(surface_resource);
+  if (surface->GetProperty(kSurfaceHasViewportKey)) {
+    wl_resource_post_error(resource, WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
+                           "a viewport for that surface already exists");
+    return;
+  }
+
+  wl_resource* viewport_resource = wl_resource_create(
+      client, &wp_viewport_interface, wl_resource_get_version(resource), id);
+
+  SetImplementation(viewport_resource, &viewport_implementation,
+                    std::make_unique<Viewport>(surface));
+}
+
+const struct wp_viewporter_interface viewporter_implementation = {
+    viewporter_destroy, viewporter_get_viewport};
+
+}  // namespace
+
+void bind_viewporter(wl_client* client,
+                     void* data,
+                     uint32_t version,
+                     uint32_t id) {
+  wl_resource* resource =
+      wl_resource_create(client, &wp_viewporter_interface, 1, id);
+
+  wl_resource_set_implementation(resource, &viewporter_implementation, data,
+                                 nullptr);
+}
+
+}  // namespace wayland
+}  // namespace exo
diff --git a/components/exo/wayland/wp_viewporter.h b/components/exo/wayland/wp_viewporter.h
new file mode 100644
index 0000000..1b4c158b
--- /dev/null
+++ b/components/exo/wayland/wp_viewporter.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 COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
+#define COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_viewporter(wl_client* client,
+                     void* data,
+                     uint32_t version,
+                     uint32_t id);
+
+}  // namespace wayland
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
diff --git a/components/exo/wm_helper_chromeos.cc b/components/exo/wm_helper_chromeos.cc
index 42dd2e9..435cac1 100644
--- a/components/exo/wm_helper_chromeos.cc
+++ b/components/exo/wm_helper_chromeos.cc
@@ -143,10 +143,8 @@
 
 const std::vector<uint8_t>& WMHelperChromeOS::GetDisplayIdentificationData(
     int64_t display_id) const {
-  const auto& displays = ash::Shell::Get()
-                             ->window_tree_host_manager()
-                             ->display_configurator()
-                             ->cached_displays();
+  const auto& displays =
+      ash::Shell::Get()->display_configurator()->cached_displays();
 
   for (display::DisplaySnapshot* display : displays)
     if (display->display_id() == display_id)
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
index 530f0bd..afa581b 100644
--- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
+++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -4,72 +4,100 @@
 
 package org.chromium.components.feature_engagement;
 
+import android.support.annotation.StringDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * FeatureConstants contains the String name of all base::Feature in-product help features declared
  * in //components/feature_engagement/public/feature_constants.h.
  */
-public final class FeatureConstants {
-    public static final String DOWNLOAD_PAGE_FEATURE = "IPH_DownloadPage";
-    public static final String DOWNLOAD_PAGE_SCREENSHOT_FEATURE = "IPH_DownloadPageScreenshot";
-    public static final String DOWNLOAD_HOME_FEATURE = "IPH_DownloadHome";
-    public static final String CHROME_DUET_FEATURE = "IPH_ChromeDuet";
-    public static final String CHROME_HOME_EXPAND_FEATURE = "IPH_ChromeHomeExpand";
-    public static final String CHROME_HOME_PULL_TO_REFRESH_FEATURE = "IPH_ChromeHomePullToRefresh";
-    public static final String CONTEXTUAL_SUGGESTIONS_FEATURE = "IPH_ContextualSuggestions";
-    public static final String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview";
-    public static final String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail";
-    public static final String NTP_BUTTON_FEATURE = "IPH_NewTabPageButton";
-    public static final String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI";
-    public static final String HOMEPAGE_TILE_FEATURE = "IPH_HomepageTile";
-
-    public static final String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton";
+@StringDef({FeatureConstants.DOWNLOAD_PAGE_FEATURE,
+        FeatureConstants.DOWNLOAD_PAGE_SCREENSHOT_FEATURE, FeatureConstants.DOWNLOAD_HOME_FEATURE,
+        FeatureConstants.CHROME_DUET_FEATURE, FeatureConstants.CHROME_HOME_EXPAND_FEATURE,
+        FeatureConstants.CHROME_HOME_PULL_TO_REFRESH_FEATURE,
+        FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE,
+        FeatureConstants.DATA_SAVER_PREVIEW_FEATURE, FeatureConstants.DATA_SAVER_DETAIL_FEATURE,
+        FeatureConstants.NTP_BUTTON_FEATURE, FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE,
+        FeatureConstants.HOMEPAGE_TILE_FEATURE, FeatureConstants.TRANSLATE_MENU_BUTTON_FEATURE,
+        FeatureConstants.CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE,
+        FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE,
+        FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE,
+        FeatureConstants.CONTEXTUAL_SEARCH_OPT_IN_FEATURE,
+        FeatureConstants.DOWNLOAD_SETTINGS_FEATURE,
+        FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE,
+        FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE,
+        FeatureConstants.TAB_GROUPS_QUICKLY_COMPARE_PAGES_FEATURE,
+        FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE,
+        FeatureConstants.TAB_GROUPS_YOUR_TABS_ARE_TOGETHER_FEATURE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface FeatureConstants {
+    String DOWNLOAD_PAGE_FEATURE = "IPH_DownloadPage";
+    String DOWNLOAD_PAGE_SCREENSHOT_FEATURE = "IPH_DownloadPageScreenshot";
+    String DOWNLOAD_HOME_FEATURE = "IPH_DownloadHome";
+    String CHROME_DUET_FEATURE = "IPH_ChromeDuet";
+    String CHROME_HOME_EXPAND_FEATURE = "IPH_ChromeHomeExpand";
+    String CHROME_HOME_PULL_TO_REFRESH_FEATURE = "IPH_ChromeHomePullToRefresh";
+    String CONTEXTUAL_SUGGESTIONS_FEATURE = "IPH_ContextualSuggestions";
+    String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview";
+    String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail";
+    String NTP_BUTTON_FEATURE = "IPH_NewTabPageButton";
+    String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI";
+    String HOMEPAGE_TILE_FEATURE = "IPH_HomepageTile";
+    String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton";
 
     /**
      * An IPH feature that encourages users who search a query from a web page in a new tab, to use
      * Contextual Search instead.
      */
-    public static final String CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE =
-            "IPH_ContextualSearchWebSearch";
+    String CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE = "IPH_ContextualSearchWebSearch";
 
     /**
      * An IPH feature for promoting tap over longpress for activating Contextual Search.
      */
-    public static final String CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE =
-            "IPH_ContextualSearchPromoteTap";
+    String CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE = "IPH_ContextualSearchPromoteTap";
 
     /**
      * An IPH feature for encouraging users to open the Contextual Search Panel.
      */
-    public static final String CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE =
-            "IPH_ContextualSearchPromotePanelOpen";
+    String CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE = "IPH_ContextualSearchPromotePanelOpen";
 
     /**
      * An IPH feature for encouraging users to opt-in for Contextual Search.
      */
-    public static final String CONTEXTUAL_SEARCH_OPT_IN_FEATURE = "IPH_ContextualSearchOptIn";
+    String CONTEXTUAL_SEARCH_OPT_IN_FEATURE = "IPH_ContextualSearchOptIn";
 
     /**
      * An IPH feature indicating to users that there are settings for downloads and they are
      * accessible through Downloads Home.
      */
-    public static final String DOWNLOAD_SETTINGS_FEATURE = "IPH_DownloadSettings";
+    String DOWNLOAD_SETTINGS_FEATURE = "IPH_DownloadSettings";
 
     /**
      * An IPH feature informing the users that even though infobar was closed, downloads are still
      * continuing in the background.
      */
-    public static final String DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE =
-            "IPH_DownloadInfoBarDownloadContinuing";
+    String DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE = "IPH_DownloadInfoBarDownloadContinuing";
 
     /**
      * An IPH feature that points to the download progress infobar and informs users that downloads
      * are now faster than before.
      */
-    public static final String DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE =
-            "IPH_DownloadInfoBarDownloadsAreFaster";
+    String DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE = "IPH_DownloadInfoBarDownloadsAreFaster";
 
     /**
-     * Do not instantiate.
+     * An IPH feature to prompt the user to long press on pages with links to open them in a group.
      */
-    private FeatureConstants() {}
+    String TAB_GROUPS_QUICKLY_COMPARE_PAGES_FEATURE = "IPH_TabGroupsQuicklyComparePages";
+
+    /**
+     * An IPH feature to show when the tabstrip shows to explain what each button does.
+     */
+    String TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE = "IPH_TabGroupsTapToSeeAnotherTab";
+
+    /**
+     * An IPH feature to show on tab switcher cards with multiple tab thumbnails.
+     */
+    String TAB_GROUPS_YOUR_TABS_ARE_TOGETHER_FEATURE = "IPH_TabGroupsYourTabsTogether";
 }
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index 01e6c16..b8e016e 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -55,6 +55,12 @@
     "IPH_NewTabPageButton", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kIPHPreviewsOmniboxUIFeature{
     "IPH_PreviewsOmniboxUI", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsQuicklyComparePagesFeature{
+    "IPH_TabGroupsQuicklyComparePages", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature{
+    "IPH_TabGroupsTapToSeeAnotherTab", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature{
+    "IPH_TabGroupsYourTabsTogether", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kIPHTranslateMenuButtonFeature{
     "IPH_TranslateMenuButton", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // defined(OS_ANDROID)
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index d086149..dd9253e1 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -41,6 +41,9 @@
 extern const base::Feature kIPHHomepageTileFeature;
 extern const base::Feature kIPHNewTabPageButtonFeature;
 extern const base::Feature kIPHPreviewsOmniboxUIFeature;
+extern const base::Feature kIPHTabGroupsQuicklyComparePagesFeature;
+extern const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature;
+extern const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature;
 extern const base::Feature kIPHTranslateMenuButtonFeature;
 #endif  // defined(OS_ANDROID)
 
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index eb0a15a..8048163c7 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -37,6 +37,9 @@
     &kIPHHomepageTileFeature,
     &kIPHNewTabPageButtonFeature,
     &kIPHPreviewsOmniboxUIFeature,
+    &kIPHTabGroupsQuicklyComparePagesFeature,
+    &kIPHTabGroupsTapToSeeAnotherTabFeature,
+    &kIPHTabGroupsYourTabsAreTogetherFeature,
     &kIPHTranslateMenuButtonFeature,
 #endif  // defined(OS_ANDROID)
 #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index 7a2bf57..c63ce60 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -76,6 +76,12 @@
 DEFINE_VARIATION_PARAM(kIPHHomepageTileFeature, "IPH_HomepageTile");
 DEFINE_VARIATION_PARAM(kIPHNewTabPageButtonFeature, "IPH_NewTabPageButton");
 DEFINE_VARIATION_PARAM(kIPHPreviewsOmniboxUIFeature, "IPH_PreviewsOmniboxUI");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsQuicklyComparePagesFeature,
+                       "IPH_IPH_TabGroupsQuicklyComparePages");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsTapToSeeAnotherTabFeature,
+                       "IPH_TabGroupsTapToSeeAnotherTab");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsYourTabsAreTogetherFeature,
+                       "IPH_TabGroupsYourTabsTogether");
 DEFINE_VARIATION_PARAM(kIPHTranslateMenuButtonFeature,
                        "IPH_TranslateMenuButton");
 #endif  // defined(OS_ANDROID)
@@ -122,6 +128,9 @@
         VARIATION_ENTRY(kIPHHomepageTileFeature),
         VARIATION_ENTRY(kIPHNewTabPageButtonFeature),
         VARIATION_ENTRY(kIPHPreviewsOmniboxUIFeature),
+        VARIATION_ENTRY(kIPHTabGroupsQuicklyComparePagesFeature),
+        VARIATION_ENTRY(kIPHTabGroupsTapToSeeAnotherTabFeature),
+        VARIATION_ENTRY(kIPHTabGroupsYourTabsAreTogetherFeature),
         VARIATION_ENTRY(kIPHTranslateMenuButtonFeature),
 #elif BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
         VARIATION_ENTRY(kIPHBookmarkFeature),
diff --git a/components/feed/core/feed_scheduler_host.cc b/components/feed/core/feed_scheduler_host.cc
index 2859788..cad69fddc 100644
--- a/components/feed/core/feed_scheduler_host.cc
+++ b/components/feed/core/feed_scheduler_host.cc
@@ -31,6 +31,33 @@
 using TriggerType = FeedSchedulerHost::TriggerType;
 using UserClass = UserClassifier::UserClass;
 
+// Enum for the relation between boolean fields the Feed and host both track.
+// Reported through UMA and must match the corresponding definition in
+// enums.xml
+enum class FeedHostMismatch {
+  kNeitherAreSet = 0,
+  kFeedIsSetOnly = 1,
+  kHostIsSetOnly = 2,
+  kBothAreSet = 3,
+  kMaxValue = kBothAreSet,
+};
+
+// Copies boolean args into temps to avoid evaluating them multiple times.
+#define UMA_HISTOGRAM_MISMATCH(name, feed_is_set, host_is_set)  \
+  do {                                                          \
+    bool copied_feed_is_set = feed_is_set;                      \
+    bool copied_host_is_set = host_is_set;                      \
+    FeedHostMismatch status = FeedHostMismatch::kNeitherAreSet; \
+    if (copied_feed_is_set && copied_host_is_set) {             \
+      status = FeedHostMismatch::kBothAreSet;                   \
+    } else if (copied_feed_is_set) {                            \
+      status = FeedHostMismatch::kFeedIsSetOnly;                \
+    } else if (copied_host_is_set) {                            \
+      status = FeedHostMismatch::kHostIsSetOnly;                \
+    }                                                           \
+    UMA_HISTOGRAM_ENUMERATION(name, status);                    \
+  } while (false);
+
 struct ParamPair {
   std::string name;
   double default_value;
@@ -268,18 +295,38 @@
     bool has_content,
     base::Time content_creation_date_time,
     bool has_outstanding_request) {
-  // The scheduler may not always know of outstanding requests, but the Feed
-  // should know about them all, and the scheduler should be notified upon
-  // completion of all requests. We should never encounter a scenario where only
-  // the scheduler thinks there is an outstanding request.
+  // Both the Feed and the scheduler track if there are outstanding requests.
+  // It's possible that this data gets out of sync. We treat the Feed as
+  // authoritative and we change our values to match.
+  UMA_HISTOGRAM_MISMATCH("ContentSuggestions.Feed.Scheduler.OutstandingRequest",
+                         has_outstanding_request,
+                         !outstanding_request_until_.is_null());
+  if (has_outstanding_request == outstanding_request_until_.is_null()) {
+    if (has_outstanding_request) {
+      outstanding_request_until_ =
+          clock_->Now() +
+          base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
+    } else {
+      outstanding_request_until_ = base::Time();
+    }
+  }
 
-  // TODO(skym): Update this to use kTimeoutDurationSeconds.
-  // DCHECK(has_outstanding_request || !tracking_oustanding_request_);
-
-  if (outstanding_request_until_.is_null() && has_outstanding_request) {
-    outstanding_request_until_ =
-        clock_->Now() +
-        base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
+  // It seems to be possible for the scheduler's tracking of having content to
+  // get out of sync with the Feed. Root cause is currently unknown, but similar
+  // to outstanding request handling, we can repair with the information we
+  // have.
+  bool scheduler_thinks_has_content =
+      !profile_prefs_->FindPreference(prefs::kLastFetchAttemptTime)
+           ->IsDefaultValue();
+  UMA_HISTOGRAM_MISMATCH("ContentSuggestions.Feed.Scheduler.HasContent",
+                         has_content, scheduler_thinks_has_content);
+  if (has_content != scheduler_thinks_has_content) {
+    if (has_content) {
+      profile_prefs_->SetTime(prefs::kLastFetchAttemptTime,
+                              content_creation_date_time);
+    } else {
+      profile_prefs_->ClearPref(prefs::kLastFetchAttemptTime);
+    }
   }
 
   NativeRequestBehavior behavior;
diff --git a/components/feed/core/feed_scheduler_host_unittest.cc b/components/feed/core/feed_scheduler_host_unittest.cc
index d7ba470..b7bfaca 100644
--- a/components/feed/core/feed_scheduler_host_unittest.cc
+++ b/components/feed/core/feed_scheduler_host_unittest.cc
@@ -918,6 +918,28 @@
   // prevent the OnForegrounded() from requesting a refresh.
   scheduler()->OnForegrounded();
   EXPECT_EQ(0, refresh_call_count());
+
+  EXPECT_EQ(kRequestWithWait,
+            scheduler()->ShouldSessionRequestData(
+                /*has_content*/ false, /*content_creation_date_time*/ Time(),
+                /*has_outstanding_request*/ false));
+}
+
+TEST_F(FeedSchedulerHostTest, IncorporatesExternalHasContent) {
+  Time now = test_clock()->Now();
+  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
+
+  EXPECT_EQ(kNoRequestWithContent,
+            scheduler()->ShouldSessionRequestData(
+                /*has_content*/ true, now, /*has_outstanding_request*/ false));
+  EXPECT_EQ(now, profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
+
+  // Use has_outstanding_request of true to keep the scheduler from actually
+  // triggering the refresh. We want to track the change to its internal state.
+  EXPECT_EQ(kNoRequestWithWait, scheduler()->ShouldSessionRequestData(
+                                    /*has_content*/ false, base::Time(),
+                                    /*has_outstanding_request*/ true));
+  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
 }
 
 TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
@@ -933,7 +955,7 @@
   EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
 
   scheduler()->ShouldSessionRequestData(
-      /*has_content*/ false, now, /*has_outstanding_request*/ false);
+      /*has_content*/ true, now, /*has_outstanding_request*/ false);
   EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
   EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
 
@@ -942,7 +964,7 @@
   EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
 
   scheduler()->ShouldSessionRequestData(
-      /*has_content*/ false, now, /*has_outstanding_request*/ false);
+      /*has_content*/ true, now, /*has_outstanding_request*/ false);
   scheduler()->OnForegrounded();
   EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
   EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
@@ -952,7 +974,7 @@
   scheduler()->OnRequestError(0);
 
   scheduler()->ShouldSessionRequestData(
-      /*has_content*/ false, now, /*has_outstanding_request*/ false);
+      /*has_content*/ true, now, /*has_outstanding_request*/ false);
   scheduler()->OnForegrounded();
   EXPECT_EQ(2, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
   EXPECT_EQ(2, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
diff --git a/components/metrics/call_stack_profile_builder.cc b/components/metrics/call_stack_profile_builder.cc
index 4cf3879..f176a2e 100644
--- a/components/metrics/call_stack_profile_builder.cc
+++ b/components/metrics/call_stack_profile_builder.cc
@@ -91,22 +91,21 @@
     // keep the frame information even if its module is invalid so we have
     // visibility into how often this issue is happening on the server.
     CallStackProfile::Location* location = stack.add_frame();
-    if (!frame.module.is_valid)
+    if (!frame.module->is_valid)
       continue;
 
     // Dedup modules.
-    const base::ModuleCache::Module& module = frame.module;
-    auto module_loc = module_index_.find(module.base_address);
+    auto module_loc = module_index_.find(frame.module);
     if (module_loc == module_index_.end()) {
-      modules_.push_back(module);
+      modules_.push_back(frame.module);
       size_t index = modules_.size() - 1;
-      module_loc = module_index_.emplace(module.base_address, index).first;
+      module_loc = module_index_.emplace(frame.module, index).first;
     }
 
     // Write CallStackProfile::Location protobuf message.
     ptrdiff_t module_offset =
         reinterpret_cast<const char*>(frame.instruction_pointer) -
-        reinterpret_cast<const char*>(module.base_address);
+        reinterpret_cast<const char*>(frame.module->base_address);
     DCHECK_GE(module_offset, 0);
     location->set_address(static_cast<uint64_t>(module_offset));
     location->set_module_id_index(module_loc->second);
@@ -165,11 +164,11 @@
   call_stack_profile->set_sampling_period_ms(sampling_period.InMilliseconds());
 
   // Write CallStackProfile::ModuleIdentifier protobuf message.
-  for (const auto& module : modules_) {
+  for (const auto* module : modules_) {
     CallStackProfile::ModuleIdentifier* module_id =
         call_stack_profile->add_module_id();
-    module_id->set_build_id(module.id);
-    module_id->set_name_md5_prefix(HashModuleFilename(module.filename));
+    module_id->set_build_id(module->id);
+    module_id->set_name_md5_prefix(HashModuleFilename(module->filename));
   }
 
   PassProfilesToMetricsProvider(std::move(sampled_profile_));
diff --git a/components/metrics/call_stack_profile_builder.h b/components/metrics/call_stack_profile_builder.h
index 441193b..f06acd80 100644
--- a/components/metrics/call_stack_profile_builder.h
+++ b/components/metrics/call_stack_profile_builder.h
@@ -120,11 +120,11 @@
   // The indexes of stacks, indexed by stack's address.
   std::map<const CallStackProfile::Stack*, int, StackComparer> stack_index_;
 
-  // The indexes of modules, indexed by module's base_address.
-  std::unordered_map<uintptr_t, size_t> module_index_;
+  // The indexes of modules in the modules_ vector below..
+  std::unordered_map<const base::ModuleCache::Module*, size_t> module_index_;
 
   // The distinct modules in the current profile.
-  std::vector<base::ModuleCache::Module> modules_;
+  std::vector<const base::ModuleCache::Module*> modules_;
 
   // Callback made when sampling a profile completes.
   base::OnceClosure completed_callback_;
diff --git a/components/metrics/call_stack_profile_builder_unittest.cc b/components/metrics/call_stack_profile_builder_unittest.cc
index b8d1853..7481a5c 100644
--- a/components/metrics/call_stack_profile_builder_unittest.cc
+++ b/components/metrics/call_stack_profile_builder_unittest.cc
@@ -86,15 +86,15 @@
 
   const uintptr_t module_base_address1 = 0x1000;
   Module module1 = {module_base_address1, "1", module_path};
-  Frame frame1 = {module_base_address1 + 0x10, module1};
+  Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
   Module module2 = {module_base_address2, "2", module_path};
-  Frame frame2 = {module_base_address2 + 0x10, module2};
+  Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   const uintptr_t module_base_address3 = 0x1010;
   Module module3 = {module_base_address3, "3", module_path};
-  Frame frame3 = {module_base_address3 + 0x10, module3};
+  Frame frame3 = {module_base_address3 + 0x10, &module3};
 
   std::vector<Frame> frames1 = {frame1, frame2};
   std::vector<Frame> frames2 = {frame3};
@@ -166,11 +166,11 @@
 
   const uintptr_t module_base_address1 = 0x1000;
   Module module1 = {module_base_address1, "1", module_path};
-  Frame frame1 = {module_base_address1 + 0x10, module1};
+  Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
   Module module2 = {module_base_address2, "2", module_path};
-  Frame frame2 = {module_base_address2 + 0x10, module2};
+  Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames = {frame1, frame2};
 
@@ -212,11 +212,11 @@
 
   const uintptr_t module_base_address1 = 0x1000;
   Module module1 = {module_base_address1, "1", module_path};
-  Frame frame1 = {module_base_address1 + 0x10, module1};
+  Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
   Module module2 = {module_base_address2, "2", module_path};
-  Frame frame2 = {module_base_address2 + 0x10, module2};
+  Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames1 = {frame1};
   std::vector<Frame> frames2 = {frame2};
@@ -252,7 +252,7 @@
 
   const uintptr_t module_base_address1 = 0x1000;
   Module module1;  // module1 has no information hence invalid.
-  Frame frame1 = {module_base_address1 + 0x10, module1};
+  Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
 #if defined(OS_WIN)
@@ -263,7 +263,7 @@
   base::FilePath module_path("/some/path/to/chrome");
 #endif
   Module module2 = {module_base_address2, "2", module_path};
-  Frame frame2 = {module_base_address2 + 0x10, module2};
+  Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames = {frame1, frame2};
 
@@ -311,11 +311,9 @@
   base::FilePath module_path("/some/path/to/chrome");
 #endif
 
-  Module module1 = {module_base_address, "1", module_path};
-  Frame frame1 = {module_base_address + 0x10, module1};
-
-  Module module2 = {module_base_address, "1", module_path};
-  Frame frame2 = {module_base_address + 0x20, module2};
+  Module module = {module_base_address, "1", module_path};
+  Frame frame1 = {module_base_address + 0x10, &module};
+  Frame frame2 = {module_base_address + 0x20, &module};
 
   std::vector<Frame> frames = {frame1, frame2};
 
@@ -334,8 +332,8 @@
   ASSERT_EQ(1, profile.stack_size());
   ASSERT_EQ(2, profile.stack(0).frame_size());
 
-  // Since module1 and module2 have the same base address, they are considered
-  // the same module and therefore deduped.
+  // The two frames share the same module, which should be deduped in the
+  // output.
   ASSERT_TRUE(profile.stack(0).frame(0).has_module_id_index());
   EXPECT_EQ(0, profile.stack(0).frame(0).module_id_index());
   ASSERT_TRUE(profile.stack(0).frame(0).has_address());
@@ -372,7 +370,7 @@
 #endif
 
   Module module = {0x1000, "1", module_path};
-  Frame frame = {0x1000 + 0x10, module};
+  Frame frame = {0x1000 + 0x10, &module};
 
   // Id 0 means the message loop hasn't been started yet, so the sample should
   // not have continued_work set.
@@ -429,7 +427,7 @@
 #endif
 
   Module module = {0x1000, "1", module_path};
-  Frame frame = {0x1000 + 0x10, module};
+  Frame frame = {0x1000 + 0x10, &module};
 
   metadata_recorder.current_value = 5;
   profile_builder->OnSampleCompleted({frame});
diff --git a/components/metrics/enabled_state_provider.cc b/components/metrics/enabled_state_provider.cc
index 31f2964..a8ebe03 100644
--- a/components/metrics/enabled_state_provider.cc
+++ b/components/metrics/enabled_state_provider.cc
@@ -4,10 +4,18 @@
 
 #include "components/metrics/enabled_state_provider.h"
 
+#include "base/base_switches.h"
+#include "base/command_line.h"
+
 namespace metrics {
 
 bool EnabledStateProvider::IsReportingEnabled() const {
-  return IsConsentGiven();
+  // Disable metrics reporting when field trials are forced, as otherwise this
+  // would pollute experiment results in UMA. Note: This is done here and not
+  // in IsConsentGiven() as we do not want this to affect field trial entropy
+  // logic (i.e. high entropy source should still be used if UMA is on).
+  return IsConsentGiven() && !base::CommandLine::ForCurrentProcess()->HasSwitch(
+                                 switches::kForceFieldTrials);
 }
 
 }  // namespace metrics
diff --git a/components/metrics/metrics_service_accessor.cc b/components/metrics/metrics_service_accessor.cc
index f00d2e8..6cfa202 100644
--- a/components/metrics/metrics_service_accessor.cc
+++ b/components/metrics/metrics_service_accessor.cc
@@ -17,12 +17,7 @@
 bool g_force_official_enabled_test = false;
 
 bool IsMetricsReportingEnabledForOfficialBuild(PrefService* pref_service) {
-  // In official builds, disable metrics when reporting field trials are
-  // forced; otherwise, use the value of the user's preference to determine
-  // whether to enable metrics reporting.
-  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
-             switches::kForceFieldTrials) &&
-         pref_service->GetBoolean(prefs::kMetricsReportingEnabled);
+  return pref_service->GetBoolean(prefs::kMetricsReportingEnabled);
 }
 
 }  // namespace
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc
index 711ea17..d93d765 100644
--- a/components/network_session_configurator/browser/network_session_configurator.cc
+++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -337,6 +337,18 @@
   return 0;
 }
 
+int GetQuicRetransmittableOnWireTimeoutMilliseconds(
+    const VariationParameters& quic_trial_params) {
+  int value;
+  if (base::StringToInt(
+          GetVariationParam(quic_trial_params,
+                            "retransmittable_on_wire_timeout_milliseconds"),
+          &value)) {
+    return value;
+  }
+  return 0;
+}
+
 int GetQuicIdleSessionMigrationPeriodSeconds(
     const VariationParameters& quic_trial_params) {
   int value;
@@ -482,6 +494,12 @@
         ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params);
     params->quic_go_away_on_path_degrading =
         ShouldQuicGoawayOnPathDegrading(quic_trial_params);
+    int retransmittable_on_wire_timeout_milliseconds =
+        GetQuicRetransmittableOnWireTimeoutMilliseconds(quic_trial_params);
+    if (retransmittable_on_wire_timeout_milliseconds > 0) {
+      params->quic_retransmittable_on_wire_timeout_milliseconds =
+          retransmittable_on_wire_timeout_milliseconds;
+    }
     int idle_session_migration_period_seconds =
         GetQuicIdleSessionMigrationPeriodSeconds(quic_trial_params);
     if (idle_session_migration_period_seconds > 0) {
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
index 9d2ec009..393d52f 100644
--- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc
+++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -125,6 +125,8 @@
   EXPECT_FALSE(params_.quic_go_away_on_path_degrading);
   EXPECT_FALSE(params_.quic_allow_server_migration);
   EXPECT_TRUE(params_.quic_host_whitelist.empty());
+  EXPECT_EQ(net::kDefaultRetransmittableOnWireTimeoutMillisecs,
+            params_.quic_retransmittable_on_wire_timeout_milliseconds);
 
   net::HttpNetworkSession::Params default_params;
   EXPECT_EQ(default_params.quic_supported_versions,
@@ -222,6 +224,18 @@
 }
 
 TEST_F(NetworkSessionConfiguratorTest,
+       QuicRetransmittableOnWireTimeoutMillisecondsFieldTrialParams) {
+  std::map<std::string, std::string> field_trial_params;
+  field_trial_params["retransmittable_on_wire_timeout_milliseconds"] = "1000";
+  variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
+  base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
+
+  ParseFieldTrials();
+
+  EXPECT_EQ(1000, params_.quic_retransmittable_on_wire_timeout_milliseconds);
+}
+
+TEST_F(NetworkSessionConfiguratorTest,
        QuicIdleConnectionTimeoutSecondsFieldTrialParams) {
   std::map<std::string, std::string> field_trial_params;
   field_trial_params["idle_connection_timeout_seconds"] = "300";
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 7723b9b6..6ce9bfb 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -711,6 +711,8 @@
       'policies': [
         'AlternativeBrowserPath',
         'AlternativeBrowserParameters',
+        'BrowserSwitcherChromePath',
+        'BrowserSwitcherChromeParameters',
         'BrowserSwitcherDelay',
         'BrowserSwitcherEnabled',
         'BrowserSwitcherExternalSitelistUrl',
@@ -964,6 +966,7 @@
       'desc': '''Controls settings for Google Assistant.''',
       'policies': [
         'VoiceInteractionContextEnabled',
+        'VoiceInteractionHotwordEnabled',
       ]
     },
     {
@@ -14333,6 +14336,63 @@
       Environment variables are expanded. On Windows, %ABC% is replaced with the value of the ABC environment variable. On Mac OS X and Linux, ${ABC} is replaced with the value of the ABC environment variable.''',
     },
     {
+      'id': 530,
+      'name': 'BrowserSwitcherChromePath',
+      'future': True,
+      'type': 'string',
+      'schema': {'type': 'string'},
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'example_value': '${chrome}',
+      'supported_on': ['chrome.win:74-'],
+      'caption': '''Path to Chrome for switching from the alternative browser.''',
+      'tags': [],
+      'desc': '''This policy controls the command to use to open URLs in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when switching from Internet Explorer.
+
+      If the 'Legacy Browser Support' add-in for Internet Explorer is not installed, this policy has no effect.
+
+      When this policy is left unset, Internet Explorer will auto-detect <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s own executable path when launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer.
+
+      When this policy is set, it will be used to launch <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when switching launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer.
+
+      This policy can be set to an executable file path, or ${chrome} to auto-detect Chrome's install location.''',
+    },
+    {
+      'id': 531,
+      'name': 'BrowserSwitcherChromeParameters',
+      'future': True,
+      'type': 'list',
+      'schema': {
+        'type': 'array',
+        'items': {'type': 'string'},
+      },
+      'example_value': [
+        '--force-dark-mode',
+      ],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'supported_on': ['chrome.win:74-'],
+      'caption': '''Command-line parameters for switching from the alternative browser.''',
+      'tags': [],
+      'desc': '''This policy controls command-line parameters for Chrome from Internet Explorer.
+
+      If the 'Legacy Browser Support' add-in for Internet Explorer is not installed, this policy has no effect.
+
+      When this policy is left unset, Internet Explorer only passes the URL to Chrome as a command-line parameter.
+
+      When this policy is set to a list of strings, the strings are joined with spaces and passed to Chrome as command-line parameters.
+
+      If an element contains ${url}, it gets replaced with the URL of the page to open.
+
+      If no element contains ${url}, the URL is appended at the end of the command line.
+
+      Environment variables are expanded. On Windows, %ABC% is replaced with the value of the ABC environment variable.''',
+    },
+    {
       'id': 496,
       'name': 'BrowserSwitcherUrlList',
       'future': True,
@@ -14819,6 +14879,26 @@
       If the policy is disabled, Google Assistant will not be allowed to access screen context.
       If not set, users can decide whether to allow Google Assistant to access screen context or not''',
     },
+    {
+      'name': 'VoiceInteractionHotwordEnabled',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome_os:74-'],
+      'tags' : [],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'example_value': True,
+      'id': 529,
+      'caption': '''"Allow Google Access Assistant to listen for the voice activation phrase"''',
+      'desc': '''This policy gives Google Assistant permission to listen for the voice activation phrase.
+
+      If the policy is enabled, Google Assistant would listen for the voice activation phrase.
+      If the policy is disabled, Google Assistant would not listen for the voice activation phrase.
+      If not set, users can decide whether to allow Google Assistant to listen to the voice activation phrase.
+      ''',
+    },
   ],
 
   'messages': {
@@ -14984,5 +15064,5 @@
   },
   'placeholders': [],
   'deleted_policy_ids': [412],
-  'highest_id_currently_used':  528
+  'highest_id_currently_used':  531
 }
diff --git a/components/safe_search_api/OWNERS b/components/safe_search_api/OWNERS
index 009f486..408a9bd 100644
--- a/components/safe_search_api/OWNERS
+++ b/components/safe_search_api/OWNERS
@@ -1 +1,2 @@
+michaelpg@chromium.org
 treib@chromium.org
diff --git a/components/signin/core/browser/account_reconcilor_delegate.cc b/components/signin/core/browser/account_reconcilor_delegate.cc
index c1eb4e2..0f642b6 100644
--- a/components/signin/core/browser/account_reconcilor_delegate.cc
+++ b/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -100,10 +100,14 @@
   if (first_account_it == ordered_accounts.end()) {
     // The first account was not already in the cookies, add it in the first
     // empty spot, or at the end if there is no available spot.
-    first_account_it = ordered_accounts.insert(
-        std::find(ordered_accounts.begin(), ordered_accounts.end(),
-                  std::string()),
-        first_account);
+    first_account_it = std::find(ordered_accounts.begin(),
+                                 ordered_accounts.end(), std::string());
+    if (first_account_it == ordered_accounts.end()) {
+      first_account_it =
+          ordered_accounts.insert(first_account_it, first_account);
+    } else {
+      *first_account_it = first_account;
+    }
     chrome_accounts_set.erase(first_account);
   }
   std::iter_swap(ordered_accounts.begin(), first_account_it);
diff --git a/components/signin/core/browser/account_reconcilor_delegate_unittest.cc b/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
index a146d379..c8bdedf 100644
--- a/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
+++ b/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
@@ -45,6 +45,8 @@
    // Cookie was lost.
    { "A",              "",             'A',         "A"              },
    { "ABCD",           "",             'A',         "ABCD"           },
+   // B kept in place.
+   { "ADB",            "CB",           'A',         "ABD"            },
    // ACEG kept in place.
    { "ABCDEFGH",       "ACEG",         'A',         "ACEGBDFH"       },
    // C kept in place, but not B.
diff --git a/components/storage_monitor/image_capture_device_manager_unittest.mm b/components/storage_monitor/image_capture_device_manager_unittest.mm
index df88619..a0f39249 100644
--- a/components/storage_monitor/image_capture_device_manager_unittest.mm
+++ b/components/storage_monitor/image_capture_device_manager_unittest.mm
@@ -286,7 +286,7 @@
   DetachDevice(&manager, device);
   devices = monitor_->GetAllAvailableStorages();
   ASSERT_EQ(0U, devices.size());
-};
+}
 
 TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) {
   ImageCaptureDeviceManager manager;
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
new file mode 100644
index 0000000..9a8d080
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+66f3464c0e885ffa17cc094bd9a55f248e9a6f40
\ 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
new file mode 100644
index 0000000..9fda43c
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_bottom.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+00ad1fb237c5b608c5305034bd8b19a6ab6c3b39
\ 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
new file mode 100644
index 0000000..4779365
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+200aff88733aad23c72b7776c342ddec5a3ba29e
\ 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
new file mode 100644
index 0000000..b854b14
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_left.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+4c4dc76e6922166019129b1abcfb7a0acb9fb164
\ 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
new file mode 100644
index 0000000..bcd04ce
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+461168a6069c053be9aea5546145f93696612cba
\ 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
new file mode 100644
index 0000000..713f746b
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_right.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+cf653d95288c47e9a922e3547b8af20c0f14ee25
\ 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
new file mode 100644
index 0000000..523e243
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+a3a55fb5bac792c5be3e87fa37d2f8e1028202f7
\ 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
new file mode 100644
index 0000000..8640882
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_clicking_top.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+aeb9f806ce58b9721787474532008d8877aff506
\ 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
new file mode 100644
index 0000000..c5507c3
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+22a1452e97861e5436c9316ebd4215dfea7d937b
\ 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
new file mode 100644
index 0000000..070c8174
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_middle.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+4ed1ba491463f6d5850966bb67208481fc83bd24
\ 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
new file mode 100644
index 0000000..eb78fef
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-25.png.sha1
@@ -0,0 +1 @@
+9945ec8cf622180e3aa7a6be754f4013e421747e
\ 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
new file mode 100644
index 0000000..1a9f8cd
--- /dev/null
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.suggestion_hovering_top.Pixel_XL-26.png.sha1
@@ -0,0 +1 @@
+6009239091198462e429f1c6842ee2c57290989a
\ No newline at end of file
diff --git a/components/tracing/common/native_stack_sampler_android.cc b/components/tracing/common/native_stack_sampler_android.cc
index fe45d16b..4cb51b0 100644
--- a/components/tracing/common/native_stack_sampler_android.cc
+++ b/components/tracing/common/native_stack_sampler_android.cc
@@ -4,6 +4,8 @@
 
 #include "components/tracing/common/native_stack_sampler_android.h"
 
+#include "base/no_destructor.h"
+#include "base/sampling_heap_profiler/module_cache.h"
 #include "base/trace_event/trace_event.h"
 
 namespace tracing {
@@ -22,6 +24,7 @@
 NativeStackSamplerAndroid::RecordStackFrames(
     StackBuffer* stack_buffer,
     base::StackSamplingProfiler::ProfileBuilder* profile_builder) {
+  static base::NoDestructor<base::ModuleCache::Module> invalid_module;
   if (!unwinder_.is_initialized()) {
     // May block on disk access. This function is executed on the profiler
     // thread, so this will only block profiling execution.
@@ -36,7 +39,7 @@
   for (size_t i = 0; i < depth; ++i) {
     // TODO(ssid): Add support for obtaining modules here.
     frames.emplace_back(reinterpret_cast<uintptr_t>(pcs[i]),
-                        base::ModuleCache::Module());
+                        invalid_module.get());
   }
   return frames;
 }
diff --git a/components/tracing/common/tracing_sampler_profiler.cc b/components/tracing/common/tracing_sampler_profiler.cc
index c64aa5d..98aae72 100644
--- a/components/tracing/common/tracing_sampler_profiler.cc
+++ b/components/tracing/common/tracing_sampler_profiler.cc
@@ -110,12 +110,12 @@
       if (frame_name.empty())
         frame_name = "Unknown";
 #else
-      module_name = frame.module.filename.BaseName().MaybeAsASCII();
+      module_name = frame.module->filename.BaseName().MaybeAsASCII();
       frame_name = GetFrameNameFromOffsetAddr(frame.instruction_pointer -
-                                              frame.module.base_address);
+                                              frame.module->base_address);
 #endif
       base::StringAppendF(&result, "%s - %s [%s]\n", frame_name.c_str(),
-                          module_name.c_str(), frame.module.id.c_str());
+                          module_name.c_str(), frame.module->id.c_str());
     }
 
     TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
diff --git a/components/viz/common/surfaces/child_local_surface_id_allocator.cc b/components/viz/common/surfaces/child_local_surface_id_allocator.cc
index ca3a0d2a..70f406d 100644
--- a/components/viz/common/surfaces/child_local_surface_id_allocator.cc
+++ b/components/viz/common/surfaces/child_local_surface_id_allocator.cc
@@ -53,9 +53,29 @@
     // than the one provided by the parent, then the merged LocalSurfaceId
     // is actually a new LocalSurfaceId and so we report its allocation time
     // as now.
+    if (current_local_surface_id != parent_allocated_local_surface_id) {
+      TRACE_EVENT_WITH_FLOW2(
+          TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+          "ChildLocalSurfaceIdAllocator::UpdateFromParent New Id Allocation",
+          TRACE_ID_LOCAL(
+              parent_allocated_local_surface_id.submission_trace_id()),
+          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "current",
+          current_local_surface_id_allocation_.ToString(), "parent",
+          parent_local_surface_id_allocation.ToString());
+    }
     current_local_surface_id_allocation_.allocation_time_ =
         tick_clock_->NowTicks();
   } else {
+    if (current_local_surface_id != parent_allocated_local_surface_id) {
+      TRACE_EVENT_WITH_FLOW2(
+          TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+          "ChildLocalSurfaceIdAllocator::UpdateFromParent Synchronization",
+          TRACE_ID_LOCAL(
+              parent_allocated_local_surface_id.submission_trace_id()),
+          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "current",
+          current_local_surface_id_allocation_.ToString(), "parent",
+          parent_local_surface_id_allocation.ToString());
+    }
     current_local_surface_id_allocation_.allocation_time_ =
         parent_local_surface_id_allocation.allocation_time();
   }
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator.cc b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
index 4cf2fe2..98f4eea 100644
--- a/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
@@ -45,9 +45,19 @@
     // than the one provided by the child, then the merged LocalSurfaceId
     // is actually a new LocalSurfaceId and so we report its allocation time
     // as now.
+    TRACE_EVENT2(
+        TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+        "ParentLocalSurfaceIdAllocator::UpdateFromChild New Allocation",
+        "current", current_local_surface_id_allocation_.ToString(), "child",
+        child_local_surface_id_allocation.ToString());
     current_local_surface_id_allocation_.allocation_time_ =
         tick_clock_->NowTicks();
   } else {
+    TRACE_EVENT2(
+        TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+        "ParentLocalSurfaceIdAllocator::UpdateFromChild Synchronization",
+        "current", current_local_surface_id_allocation_.ToString(), "child",
+        child_local_surface_id_allocation.ToString());
     current_local_surface_id_allocation_.allocation_time_ =
         child_local_surface_id_allocation.allocation_time();
   }
diff --git a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
index 9e54cd1..41d8528 100644
--- a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
+++ b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
@@ -3018,4 +3018,157 @@
   EXPECT_FALSE(IsMarkedForDestruction(child_id3));
 }
 
+// If a parent CompositorFrame is blocked on the child, don't throttle child's
+// surface to avoid a deadlock. In this variation of the test, parent's
+// CompositorFrame arrives first.
+TEST_F(SurfaceSynchronizationTest, ChildNotThrottledWhenParentBlocked1) {
+  const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
+  const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
+  const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 1, 2);
+  const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 2, 2);
+  const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink1, 2, 3);
+  const SurfaceId child_id5 = MakeSurfaceId(kChildFrameSink1, 2, 4);
+
+  // The parent embeds |child_surface3|. This should avoid the child getting
+  // throttled when it submits to |child_id2|.
+  parent_support().SubmitCompositorFrame(
+      parent_id.local_surface_id(),
+      MakeCompositorFrame({child_id3}, {SurfaceRange(base::nullopt, child_id3)},
+                          std::vector<TransferableResource>(),
+                          MakeDefaultDeadline()));
+
+  // |child_id1| Surface should immediately activate because it's the child's
+  // first surface.
+  child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface1 = GetSurfaceForId(child_id1);
+  ASSERT_NE(nullptr, child_surface1);
+  EXPECT_FALSE(child_surface1->HasPendingFrame());
+  EXPECT_TRUE(child_surface1->HasActiveFrame());
+
+  // |child_id2| would normally get throttled, but in this case it shouldn't
+  // because the parent is blocked.
+  child_support1().SubmitCompositorFrame(
+      child_id2.local_surface_id(),
+      MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
+                          std::vector<TransferableResource>(),
+                          MakeDeadline(1u)));
+  Surface* child_surface2 = GetSurfaceForId(child_id2);
+  ASSERT_NE(nullptr, child_surface2);
+  EXPECT_FALSE(child_surface2->HasPendingFrame());
+  EXPECT_TRUE(child_surface2->HasActiveFrame());
+
+  // After this submission, the parent will be unblocked.
+  Surface* parent_surface = GetSurfaceForId(parent_id);
+  ASSERT_NE(nullptr, parent_surface);
+  EXPECT_TRUE(parent_surface->HasPendingFrame());
+  EXPECT_FALSE(parent_surface->HasActiveFrame());
+  child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface3 = GetSurfaceForId(child_id3);
+  ASSERT_NE(nullptr, child_surface3);
+  EXPECT_FALSE(child_surface3->HasPendingFrame());
+  EXPECT_TRUE(child_surface3->HasActiveFrame());
+  EXPECT_FALSE(parent_surface->HasPendingFrame());
+  EXPECT_TRUE(parent_surface->HasActiveFrame());
+
+  // This is the first surface after the parent got unblocked. It will not get
+  // throttled.
+  child_support1().SubmitCompositorFrame(child_id4.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface4 = GetSurfaceForId(child_id4);
+  ASSERT_NE(nullptr, child_surface4);
+  EXPECT_FALSE(child_surface4->HasPendingFrame());
+  EXPECT_TRUE(child_surface4->HasActiveFrame());
+
+  // This is the second surface after the parent got unblocked. It will get
+  // throttled.
+  child_support1().SubmitCompositorFrame(child_id5.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface5 = GetSurfaceForId(child_id5);
+  ASSERT_NE(nullptr, child_surface5);
+  EXPECT_TRUE(child_surface5->HasPendingFrame());
+  EXPECT_FALSE(child_surface5->HasActiveFrame());
+}
+
+// If a parent CompositorFrame is blocked on the child, don't throttle child's
+// surface to avoid a deadlock. In this variation of the test, child's
+// CompositorFrame arrives first.
+TEST_F(SurfaceSynchronizationTest, ChildNotThrottledWhenParentBlocked2) {
+  const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
+  const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
+  const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 1, 2);
+  const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 2, 1);
+  const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink1, 2, 2);
+  const SurfaceId child_id5 = MakeSurfaceId(kChildFrameSink1, 2, 3);
+  const SurfaceId child_id6 = MakeSurfaceId(kChildFrameSink1, 2, 4);
+
+  // |child_id1| Surface should immediately activate.
+  child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface1 = GetSurfaceForId(child_id1);
+  ASSERT_NE(nullptr, child_surface1);
+  EXPECT_FALSE(child_surface1->HasPendingFrame());
+  EXPECT_TRUE(child_surface1->HasActiveFrame());
+
+  // |child_id2| Surface should not activate because |child_id1| was never
+  // added as a dependency by a parent.
+  child_support1().SubmitCompositorFrame(
+      child_id2.local_surface_id(),
+      MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
+                          std::vector<TransferableResource>(),
+                          MakeDeadline(1u)));
+  Surface* child_surface2 = GetSurfaceForId(child_id2);
+  ASSERT_NE(nullptr, child_surface2);
+  EXPECT_TRUE(child_surface2->HasPendingFrame());
+  EXPECT_FALSE(child_surface2->HasActiveFrame());
+  EXPECT_TRUE(child_surface2->has_deadline());
+
+  FrameDeadline deadline = MakeDefaultDeadline();
+  base::TimeTicks deadline_wall_time = deadline.ToWallTime();
+  EXPECT_EQ(deadline_wall_time, child_surface2->deadline_for_testing());
+
+  // The parent gets blocked on the child. The child should get unthrottled to
+  // avoid deadlocks.
+  parent_support().SubmitCompositorFrame(
+      parent_id.local_surface_id(),
+      MakeCompositorFrame({child_id3}, {SurfaceRange(base::nullopt, child_id3)},
+                          std::vector<TransferableResource>(),
+                          MakeDefaultDeadline()));
+  EXPECT_FALSE(child_surface2->HasPendingFrame());
+  EXPECT_TRUE(child_surface2->HasActiveFrame());
+
+  // After this submission, the parent will be unblocked.
+  Surface* parent_surface = GetSurfaceForId(parent_id);
+  ASSERT_NE(nullptr, parent_surface);
+  EXPECT_TRUE(parent_surface->HasPendingFrame());
+  EXPECT_FALSE(parent_surface->HasActiveFrame());
+  child_support1().SubmitCompositorFrame(child_id4.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface4 = GetSurfaceForId(child_id4);
+  ASSERT_NE(nullptr, child_surface4);
+  EXPECT_FALSE(child_surface4->HasPendingFrame());
+  EXPECT_TRUE(child_surface4->HasActiveFrame());
+  EXPECT_FALSE(parent_surface->HasPendingFrame());
+  EXPECT_TRUE(parent_surface->HasActiveFrame());
+
+  // This is the first surface after the parent got unblocked. It will not get
+  // throttled.
+  child_support1().SubmitCompositorFrame(child_id5.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface5 = GetSurfaceForId(child_id5);
+  ASSERT_NE(nullptr, child_surface5);
+  EXPECT_FALSE(child_surface5->HasPendingFrame());
+  EXPECT_TRUE(child_surface5->HasActiveFrame());
+
+  // This is the second surface after the parent got unblocked. It will get
+  // throttled.
+  child_support1().SubmitCompositorFrame(child_id6.local_surface_id(),
+                                         MakeDefaultCompositorFrame());
+  Surface* child_surface6 = GetSurfaceForId(child_id6);
+  ASSERT_NE(nullptr, child_surface6);
+  EXPECT_TRUE(child_surface6->HasPendingFrame());
+  EXPECT_FALSE(child_surface6->HasActiveFrame());
+}
+
 }  // namespace viz
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc
index 738b07c..e0765fe6 100644
--- a/components/viz/service/surfaces/surface.cc
+++ b/components/viz/service/surfaces/surface.cc
@@ -229,9 +229,11 @@
   surface_client_->ReceiveFromChild(frame.resource_list);
 
   if (!seen_first_surface_dependency_) {
+    // We should not throttle this client if there is another client blocked on
+    // it, in order to avoid deadlocks.
     seen_first_surface_dependency_ =
         surface_manager_->dependency_tracker()->HasSurfaceBlockedOn(
-            surface_id());
+            surface_id().frame_sink_id());
   }
 
   bool block_activation =
@@ -350,17 +352,6 @@
   ActivatePendingFrame(base::nullopt);
 }
 
-bool Surface::IsBlockedOn(const SurfaceId& surface_id) const {
-  for (const SurfaceId& dependency : activation_dependencies_) {
-    if (dependency.frame_sink_id() != surface_id.frame_sink_id())
-      continue;
-
-    if (dependency.local_surface_id() <= surface_id.local_surface_id())
-      return true;
-  }
-  return false;
-}
-
 void Surface::ActivatePendingFrameForDeadline(
     base::Optional<base::TimeDelta> duration) {
   if (!pending_frame_data_)
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h
index cf47e98..4ff0194f 100644
--- a/components/viz/service/surfaces/surface.h
+++ b/components/viz/service/surfaces/surface.h
@@ -140,10 +140,6 @@
   // frame.
   void NotifySurfaceIdAvailable(const SurfaceId& surface_id);
 
-  // Returns whether the Surface is blocked on the provided |surface_id| or a
-  // predecessor.
-  bool IsBlockedOn(const SurfaceId& surface_id) const;
-
   // Called if a deadline has been hit and this surface is not yet active but
   // it's marked as respecting deadlines.
   void ActivatePendingFrameForDeadline(
diff --git a/components/viz/service/surfaces/surface_dependency_tracker.cc b/components/viz/service/surfaces/surface_dependency_tracker.cc
index b325cf56..55542b4 100644
--- a/components/viz/service/surfaces/surface_dependency_tracker.cc
+++ b/components/viz/service/surfaces/surface_dependency_tracker.cc
@@ -51,18 +51,10 @@
 }
 
 bool SurfaceDependencyTracker::HasSurfaceBlockedOn(
-    const SurfaceId& surface_id) const {
-  auto it = blocked_surfaces_from_dependency_.find(surface_id.frame_sink_id());
-  if (it == blocked_surfaces_from_dependency_.end())
-    return false;
-
-  for (const SurfaceId& blocked_surface_by_id : it->second) {
-    Surface* blocked_surface =
-        surface_manager_->GetSurfaceForId(blocked_surface_by_id);
-    if (blocked_surface && blocked_surface->IsBlockedOn(surface_id))
-      return true;
-  }
-  return false;
+    const FrameSinkId& frame_sink_id) const {
+  auto it = blocked_surfaces_from_dependency_.find(frame_sink_id);
+  DCHECK(it == blocked_surfaces_from_dependency_.end() || !it->second.empty());
+  return it != blocked_surfaces_from_dependency_.end();
 }
 
 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) {
diff --git a/components/viz/service/surfaces/surface_dependency_tracker.h b/components/viz/service/surfaces/surface_dependency_tracker.h
index 81542ac..e8fbd88 100644
--- a/components/viz/service/surfaces/surface_dependency_tracker.h
+++ b/components/viz/service/surfaces/surface_dependency_tracker.h
@@ -38,8 +38,8 @@
   void RequestSurfaceResolution(Surface* surface);
 
   // Returns whether the dependency tracker has a surface blocked on the
-  // provided |surface_id|.
-  bool HasSurfaceBlockedOn(const SurfaceId& surface_id) const;
+  // provided |frame_sink_id|.
+  bool HasSurfaceBlockedOn(const FrameSinkId& frame_sink_id) const;
 
   void OnSurfaceActivated(Surface* surface);
   void OnSurfaceDependencyAdded(const SurfaceId& surface_id);
diff --git a/components/viz/test/BUILD.gn b/components/viz/test/BUILD.gn
index a3c905b..18b2bf8 100644
--- a/components/viz/test/BUILD.gn
+++ b/components/viz/test/BUILD.gn
@@ -25,6 +25,8 @@
     "fake_host_frame_sink_client.h",
     "fake_output_surface.cc",
     "fake_output_surface.h",
+    "fake_skia_output_surface.cc",
+    "fake_skia_output_surface.h",
     "fake_surface_observer.cc",
     "fake_surface_observer.h",
     "gpu_host_impl_test_api.cc",
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc
new file mode 100644
index 0000000..fc2c3436
--- /dev/null
+++ b/components/viz/test/fake_skia_output_surface.cc
@@ -0,0 +1,306 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/test/fake_skia_output_surface.h"
+
+#include "base/bind.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
+#include "components/viz/common/resources/resource_format_utils.h"
+#include "components/viz/service/display/output_surface_client.h"
+#include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/resource_metadata.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
+#include "ui/gl/gl_utils.h"
+
+namespace viz {
+
+FakeSkiaOutputSurface::FakeSkiaOutputSurface(
+    scoped_refptr<ContextProvider> context_provider)
+    : context_provider_(std::move(context_provider)), weak_ptr_factory_(this) {}
+
+FakeSkiaOutputSurface::~FakeSkiaOutputSurface() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+void FakeSkiaOutputSurface::BindToClient(OutputSurfaceClient* client) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(client);
+  DCHECK(!client_);
+  client_ = client;
+}
+
+void FakeSkiaOutputSurface::EnsureBackbuffer() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  NOTIMPLEMENTED();
+}
+
+void FakeSkiaOutputSurface::DiscardBackbuffer() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  NOTIMPLEMENTED();
+}
+
+void FakeSkiaOutputSurface::BindFramebuffer() {
+  // TODO(penghuang): remove this method when GLRenderer is removed.
+}
+
+void FakeSkiaOutputSurface::SetDrawRectangle(const gfx::Rect& draw_rectangle) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  NOTIMPLEMENTED();
+}
+
+void FakeSkiaOutputSurface::Reshape(const gfx::Size& size,
+                                    float device_scale_factor,
+                                    const gfx::ColorSpace& color_space,
+                                    bool has_alpha,
+                                    bool use_stencil) {
+  auto& sk_surface = sk_surfaces_[0];
+  SkColorType color_type = kRGBA_8888_SkColorType;
+  SkImageInfo image_info =
+      SkImageInfo::Make(size.width(), size.height(), color_type,
+                        kPremul_SkAlphaType, color_space.ToSkColorSpace());
+  sk_surface =
+      SkSurface::MakeRenderTarget(gr_context(), SkBudgeted::kNo, image_info);
+
+  DCHECK(sk_surface);
+}
+
+void FakeSkiaOutputSurface::SwapBuffers(OutputSurfaceFrame frame) {
+  NOTIMPLEMENTED();
+}
+
+uint32_t FakeSkiaOutputSurface::GetFramebufferCopyTextureFormat() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return GL_RGB;
+}
+
+OverlayCandidateValidator* FakeSkiaOutputSurface::GetOverlayCandidateValidator()
+    const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return nullptr;
+}
+
+bool FakeSkiaOutputSurface::IsDisplayedAsOverlayPlane() const {
+  return false;
+}
+
+unsigned FakeSkiaOutputSurface::GetOverlayTextureId() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return 0;
+}
+
+gfx::BufferFormat FakeSkiaOutputSurface::GetOverlayBufferFormat() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return gfx::BufferFormat::RGBX_8888;
+}
+
+bool FakeSkiaOutputSurface::HasExternalStencilTest() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return false;
+}
+
+void FakeSkiaOutputSurface::ApplyExternalStencil() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+#if BUILDFLAG(ENABLE_VULKAN)
+gpu::VulkanSurface* FakeSkiaOutputSurface::GetVulkanSurface() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+#endif
+
+unsigned FakeSkiaOutputSurface::UpdateGpuFence() {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+void FakeSkiaOutputSurface::SetNeedsSwapSizeNotifications(
+    bool needs_swap_size_notifications) {
+  NOTIMPLEMENTED();
+}
+
+SkCanvas* FakeSkiaOutputSurface::BeginPaintCurrentFrame() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  auto& sk_surface = sk_surfaces_[0];
+  DCHECK(sk_surface);
+  DCHECK_EQ(current_render_pass_id_, 0u);
+  return sk_surface->getCanvas();
+}
+
+sk_sp<SkImage> FakeSkiaOutputSurface::MakePromiseSkImage(
+    ResourceMetadata metadata) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  GrBackendTexture backend_texture;
+  if (!GetGrBackendTexture(metadata, &backend_texture)) {
+    DLOG(ERROR) << "Failed to GetGrBackendTexture from mailbox.";
+    return nullptr;
+  }
+
+  auto sk_color_type = ResourceFormatToClosestSkColorType(
+      true /* gpu_compositing */, metadata.resource_format);
+  return SkImage::MakeFromTexture(
+      gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, sk_color_type,
+      metadata.alpha_type, metadata.color_space.ToSkColorSpace());
+}
+
+sk_sp<SkImage> FakeSkiaOutputSurface::MakePromiseSkImageFromYUV(
+    std::vector<ResourceMetadata> metadatas,
+    SkYUVColorSpace yuv_color_space,
+    bool has_alpha) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+gpu::SyncToken FakeSkiaOutputSurface::ReleasePromiseSkImages(
+    std::vector<sk_sp<SkImage>> images) {
+  gpu::SyncToken sync_token;
+  if (images.empty())
+    return sync_token;
+  images.clear();
+  context_provider()->ContextGL()->GenSyncTokenCHROMIUM(sync_token.GetData());
+  return sync_token;
+}
+
+void FakeSkiaOutputSurface::SkiaSwapBuffers(OutputSurfaceFrame frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(&FakeSkiaOutputSurface::SwapBuffersAck,
+                                weak_ptr_factory_.GetWeakPtr()));
+}
+
+SkCanvas* FakeSkiaOutputSurface::BeginPaintRenderPass(
+    const RenderPassId& id,
+    const gfx::Size& surface_size,
+    ResourceFormat format,
+    bool mipmap,
+    sk_sp<SkColorSpace> color_space) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  // Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
+  DCHECK_EQ(current_render_pass_id_, 0u);
+  auto& sk_surface = sk_surfaces_[id];
+
+  if (!sk_surface) {
+    SkColorType color_type =
+        ResourceFormatToClosestSkColorType(true /* gpu_compositing */, format);
+    SkImageInfo image_info = SkImageInfo::Make(
+        surface_size.width(), surface_size.height(), color_type,
+        kPremul_SkAlphaType, std::move(color_space));
+    sk_surface =
+        SkSurface::MakeRenderTarget(gr_context(), SkBudgeted::kNo, image_info);
+  }
+  return sk_surface->getCanvas();
+}
+
+gpu::SyncToken FakeSkiaOutputSurface::SubmitPaint() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  sk_surfaces_[current_render_pass_id_]->flush();
+  current_render_pass_id_ = 0;
+
+  gpu::SyncToken sync_token;
+  context_provider()->ContextGL()->GenSyncTokenCHROMIUM(sync_token.GetData());
+  return sync_token;
+}
+
+sk_sp<SkImage> FakeSkiaOutputSurface::MakePromiseSkImageFromRenderPass(
+    const RenderPassId& id,
+    const gfx::Size& size,
+    ResourceFormat format,
+    bool mipmap,
+    sk_sp<SkColorSpace> color_space) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  auto it = sk_surfaces_.find(id);
+  DCHECK(it != sk_surfaces_.end());
+  return it->second->makeImageSnapshot();
+}
+
+void FakeSkiaOutputSurface::RemoveRenderPassResource(
+    std::vector<RenderPassId> ids) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(!ids.empty());
+
+  for (const auto& id : ids) {
+    auto it = sk_surfaces_.find(id);
+    DCHECK(it != sk_surfaces_.end());
+    sk_surfaces_.erase(it);
+  }
+}
+
+void FakeSkiaOutputSurface::CopyOutput(
+    RenderPassId id,
+    const copy_output::RenderPassGeometry& geometry,
+    const gfx::ColorSpace& color_space,
+    std::unique_ptr<CopyOutputRequest> request) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  DCHECK(sk_surfaces_.find(id) != sk_surfaces_.end());
+  auto* surface = sk_surfaces_[id].get();
+  if (request->result_format() != CopyOutputResult::Format::RGBA_BITMAP ||
+      request->is_scaled() ||
+      geometry.result_bounds != geometry.result_selection) {
+    // TODO(crbug.com/644851): Complete the implementation for all request
+    // types, scaling, etc.
+    NOTIMPLEMENTED();
+    return;
+  }
+  auto copy_image = surface->makeImageSnapshot()->makeSubset(
+      RectToSkIRect(geometry.sampling_bounds));
+  // Send copy request by copying into a bitmap.
+  SkBitmap bitmap;
+  copy_image->asLegacyBitmap(&bitmap);
+  // TODO(crbug.com/795132): Plumb color space throughout SkiaRenderer up to
+  // the SkSurface/SkImage here. Until then, play "musical chairs" with the
+  // SkPixelRef to hack-in the RenderPass's |color_space|.
+  sk_sp<SkPixelRef> pixels(SkSafeRef(bitmap.pixelRef()));
+  SkIPoint origin = bitmap.pixelRefOrigin();
+  bitmap.setInfo(bitmap.info().makeColorSpace(color_space.ToSkColorSpace()),
+                 bitmap.rowBytes());
+  bitmap.setPixelRef(std::move(pixels), origin.x(), origin.y());
+  request->SendResult(std::make_unique<CopyOutputSkBitmapResult>(
+      geometry.result_bounds, bitmap));
+}
+
+void FakeSkiaOutputSurface::AddContextLostObserver(
+    ContextLostObserver* observer) {
+  NOTIMPLEMENTED();
+}
+
+void FakeSkiaOutputSurface::RemoveContextLostObserver(
+    ContextLostObserver* observer) {
+  NOTIMPLEMENTED();
+}
+
+bool FakeSkiaOutputSurface::GetGrBackendTexture(
+    const ResourceMetadata& metadata,
+    GrBackendTexture* backend_texture) {
+  DCHECK(!metadata.mailbox_holder.mailbox.IsZero());
+
+  auto* gl = context_provider()->ContextGL();
+  gl->WaitSyncTokenCHROMIUM(metadata.mailbox_holder.sync_token.GetConstData());
+  auto texture_id =
+      gl->CreateAndConsumeTextureCHROMIUM(metadata.mailbox_holder.mailbox.name);
+  auto gl_format = TextureStorageFormat(metadata.resource_format);
+  GrGLTextureInfo gl_texture_info = {metadata.mailbox_holder.texture_target,
+                                     texture_id, gl_format};
+  *backend_texture =
+      GrBackendTexture(metadata.size.width(), metadata.size.height(),
+                       GrMipMapped::kNo, gl_texture_info);
+  return true;
+}
+
+void FakeSkiaOutputSurface::SwapBuffersAck() {
+  client_->DidReceiveSwapBuffersAck();
+  client_->DidReceivePresentationFeedback(
+      {base::TimeTicks::Now(), base::TimeDelta(), 0});
+}
+
+}  // namespace viz
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h
new file mode 100644
index 0000000..35487d79
--- /dev/null
+++ b/components/viz/test/fake_skia_output_surface.h
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_TEST_FAKE_SKIA_OUTPUT_SURFACE_H_
+#define COMPONENTS_VIZ_TEST_FAKE_SKIA_OUTPUT_SURFACE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "components/viz/service/display/skia_output_surface.h"
+#include "components/viz/test/test_context_provider.h"
+#include "gpu/command_buffer/common/sync_token.h"
+
+namespace viz {
+
+class FakeSkiaOutputSurface : public SkiaOutputSurface {
+ public:
+  static std::unique_ptr<FakeSkiaOutputSurface> Create3d() {
+    auto provider = TestContextProvider::Create();
+    provider->BindToCurrentThread();
+    return base::WrapUnique(new FakeSkiaOutputSurface(std::move(provider)));
+  }
+
+  ~FakeSkiaOutputSurface() override;
+
+  // OutputSurface implementation:
+  void BindToClient(OutputSurfaceClient* client) override;
+  void EnsureBackbuffer() override;
+  void DiscardBackbuffer() override;
+  void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& draw_rectangle) override;
+  void Reshape(const gfx::Size& size,
+               float device_scale_factor,
+               const gfx::ColorSpace& color_space,
+               bool has_alpha,
+               bool use_stencil) override;
+  void SwapBuffers(OutputSurfaceFrame frame) override;
+  uint32_t GetFramebufferCopyTextureFormat() override;
+  OverlayCandidateValidator* GetOverlayCandidateValidator() const override;
+  bool IsDisplayedAsOverlayPlane() const override;
+  unsigned GetOverlayTextureId() const override;
+  gfx::BufferFormat GetOverlayBufferFormat() const override;
+  bool HasExternalStencilTest() const override;
+  void ApplyExternalStencil() override;
+#if BUILDFLAG(ENABLE_VULKAN)
+  gpu::VulkanSurface* GetVulkanSurface() override;
+#endif
+  unsigned UpdateGpuFence() override;
+  void SetNeedsSwapSizeNotifications(
+      bool needs_swap_size_notifications) override;
+
+  // SkiaOutputSurface implementation:
+  SkCanvas* BeginPaintCurrentFrame() override;
+  sk_sp<SkImage> MakePromiseSkImageFromYUV(
+      std::vector<ResourceMetadata> metadatas,
+      SkYUVColorSpace yuv_color_space,
+      bool has_alpha) override;
+  void SkiaSwapBuffers(OutputSurfaceFrame frame) override;
+  SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
+                                 const gfx::Size& surface_size,
+                                 ResourceFormat format,
+                                 bool mipmap,
+                                 sk_sp<SkColorSpace> color_space) override;
+  gpu::SyncToken SubmitPaint() override;
+  sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) override;
+  sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
+      const RenderPassId& id,
+      const gfx::Size& size,
+      ResourceFormat format,
+      bool mipmap,
+      sk_sp<SkColorSpace> color_space) override;
+  gpu::SyncToken ReleasePromiseSkImages(
+      std::vector<sk_sp<SkImage>> images) override;
+
+  void RemoveRenderPassResource(std::vector<RenderPassId> ids) override;
+  void CopyOutput(RenderPassId id,
+                  const copy_output::RenderPassGeometry& geometry,
+                  const gfx::ColorSpace& color_space,
+                  std::unique_ptr<CopyOutputRequest> request) override;
+  void AddContextLostObserver(ContextLostObserver* observer) override;
+  void RemoveContextLostObserver(ContextLostObserver* observer) override;
+
+ private:
+  explicit FakeSkiaOutputSurface(
+      scoped_refptr<ContextProvider> context_provider);
+
+  ContextProvider* context_provider() { return context_provider_.get(); }
+  GrContext* gr_context() { return context_provider()->GrContext(); }
+
+  bool GetGrBackendTexture(const ResourceMetadata& metadata,
+                           GrBackendTexture* backend_texture);
+  void SwapBuffersAck();
+
+  scoped_refptr<ContextProvider> context_provider_;
+  OutputSurfaceClient* client_ = nullptr;
+
+  // The current render pass id set by BeginPaintRenderPass.
+  RenderPassId current_render_pass_id_ = 0;
+
+  // SkSurfaces for render passes, sk_surfaces_[0] is the root surface.
+  base::flat_map<RenderPassId, sk_sp<SkSurface>> sk_surfaces_;
+
+  THREAD_CHECKER(thread_checker_);
+
+  base::WeakPtrFactory<FakeSkiaOutputSurface> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeSkiaOutputSurface);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_TEST_FAKE_SKIA_OUTPUT_SURFACE_H_
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index 95176f8..1d687b90 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -16,6 +16,7 @@
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "components/viz/service/display/direct_renderer.h"
 #include "components/viz/service/display/output_surface.h"
+#include "components/viz/service/display/skia_output_surface.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 
@@ -76,8 +77,16 @@
   frame_sink_manager_ =
       std::make_unique<FrameSinkManagerImpl>(shared_bitmap_manager_.get());
 
-  std::unique_ptr<OutputSurface> display_output_surface =
-      test_client_->CreateDisplayOutputSurface(context_provider());
+  std::unique_ptr<OutputSurface> display_output_surface;
+  SkiaOutputSurface* display_skia_output_surface = nullptr;
+  if (renderer_settings_.use_skia_renderer) {
+    auto output_surface = test_client_->CreateDisplaySkiaOutputSurface();
+    display_skia_output_surface = output_surface.get();
+    display_output_surface = std::move(output_surface);
+  } else {
+    display_output_surface =
+        test_client_->CreateDisplayOutputSurface(context_provider());
+  }
 
   std::unique_ptr<DisplayScheduler> scheduler;
   if (!synchronous_composite_) {
@@ -105,7 +114,7 @@
   display_ = std::make_unique<Display>(
       shared_bitmap_manager_.get(), renderer_settings_, frame_sink_id_,
       std::move(display_output_surface), std::move(scheduler),
-      compositor_task_runner_);
+      compositor_task_runner_, display_skia_output_surface);
 
   constexpr bool is_root = true;
   constexpr bool needs_sync_points = true;
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h
index 8400a37..f728ceb 100644
--- a/components/viz/test/test_layer_tree_frame_sink.h
+++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -33,6 +33,9 @@
  public:
   virtual ~TestLayerTreeFrameSinkClient() {}
 
+  virtual std::unique_ptr<SkiaOutputSurface>
+  CreateDisplaySkiaOutputSurface() = 0;
+
   // This passes the ContextProvider being used by LayerTreeHostImpl which
   // can be used for the OutputSurface optionally.
   virtual std::unique_ptr<OutputSurface> CreateDisplayOutputSurface(
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 169065b..2dcfdab40 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -98,7 +98,8 @@
   void SetUpSampleParagraphInScrollableEditable(
       Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text,
       ui::AXMode accessibility_mode = ui::kAXModeComplete);
-
+  BrowserAccessibility* FindNode(ax::mojom::Role role, const std::string& name);
+  BrowserAccessibilityManager* GetManager();
   static Microsoft::WRL::ComPtr<IAccessible> GetAccessibleFromVariant(
       IAccessible* parent,
       VARIANT* var);
@@ -123,7 +124,9 @@
       Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
   void SetUpSampleParagraphHelper(
       Microsoft::WRL::ComPtr<IAccessibleText>* accessible_text);
-
+  BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
+                                          ax::mojom::Role role,
+                                          const std::string& name);
   DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
 };
 
@@ -474,6 +477,35 @@
   ASSERT_HRESULT_SUCCEEDED(paragraph.CopyTo(accessible_text->GetAddressOf()));
 }
 
+BrowserAccessibility* AccessibilityWinBrowserTest::FindNode(
+    ax::mojom::Role role,
+    const std::string& name) {
+  BrowserAccessibility* root = GetManager()->GetRoot();
+  CHECK(root);
+  return FindNodeInSubtree(*root, role, name);
+}
+
+BrowserAccessibilityManager* AccessibilityWinBrowserTest::GetManager() {
+  WebContentsImpl* web_contents =
+      static_cast<WebContentsImpl*>(shell()->web_contents());
+  return web_contents->GetRootBrowserAccessibilityManager();
+}
+
+BrowserAccessibility* AccessibilityWinBrowserTest::FindNodeInSubtree(
+    BrowserAccessibility& node,
+    ax::mojom::Role role,
+    const std::string& name) {
+  if (node.GetRole() == role &&
+      node.GetStringAttribute(ax::mojom::StringAttribute::kName) == name)
+    return &node;
+  for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) {
+    BrowserAccessibility* result =
+        FindNodeInSubtree(*node.PlatformGetChild(i), role, name);
+    if (result)
+      return result;
+  }
+  return nullptr;
+}
 // Static helpers ------------------------------------------------
 
 Microsoft::WRL::ComPtr<IAccessible>
@@ -3142,4 +3174,138 @@
   win_event_waiter.Wait();
 }
 
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestIScrollProvider) {
+  LoadInitialAccessibilityTreeFromHtml(
+      R"HTML(
+      <!DOCTYPE html>
+      <html>
+        <body>
+          <div aria-label='not'>
+            not scrollable
+          </div>
+          <div style='width:10px; overflow:scroll' aria-label='x'>
+              scrollable in x
+            </div>
+          <div style='height:10px; overflow:scroll' aria-label='y'>
+            scrollable in y
+          </div>
+          <div style='width:10px; height:10px; overflow:scroll' aria-label='xy'>
+            scrollable in x and y
+          </div>
+        </body>
+      </html>
+    )HTML");
+
+  struct ScrollTestData {
+    std::string node_name;
+    bool can_scroll_horizontal;
+    bool can_scroll_vertical;
+    double size_horizontal;
+    double size_vertical;
+  };
+  double error = 0.01f;
+  std::vector<ScrollTestData> all_expected = {{"not", false, false, 0, 0},
+                                              {"x", true, false, 12.65, 0},
+                                              {"y", false, true, 0, 28.57},
+                                              {"xy", true, true, 12.65, 9.34}};
+  for (auto& expected : all_expected) {
+    BrowserAccessibility* browser_accessibility =
+        FindNode(ax::mojom::Role::kGenericContainer, expected.node_name);
+    EXPECT_NE(browser_accessibility, nullptr);
+
+    BrowserAccessibilityComWin* browser_accessibility_com_win =
+        ToBrowserAccessibilityWin(browser_accessibility)->GetCOM();
+    CComPtr<IScrollProvider> scroll_provider;
+
+    EXPECT_HRESULT_SUCCEEDED(browser_accessibility_com_win->GetPatternProvider(
+        UIA_ScrollPatternId, reinterpret_cast<IUnknown**>(&scroll_provider)));
+
+    if (expected.can_scroll_vertical || expected.can_scroll_horizontal) {
+      ASSERT_NE(nullptr, scroll_provider);
+
+      BOOL can_scroll_horizontal;
+      EXPECT_HRESULT_SUCCEEDED(
+          scroll_provider->get_HorizontallyScrollable(&can_scroll_horizontal));
+      ASSERT_EQ(expected.can_scroll_horizontal, can_scroll_horizontal);
+      if (expected.can_scroll_horizontal) {
+        double size_horizontal;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_HorizontalViewSize(&size_horizontal));
+        EXPECT_NEAR(expected.size_horizontal, size_horizontal, error);
+
+        double x_before;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_HorizontalScrollPercent(&x_before));
+        EXPECT_NEAR(0, x_before, error);
+
+        AccessibilityNotificationWaiter waiter(
+            shell()->web_contents(), ui::kAXModeComplete,
+            ax::mojom::Event::kScrollPositionChanged);
+
+        EXPECT_HRESULT_SUCCEEDED(scroll_provider->Scroll(
+            ScrollAmount_SmallIncrement, ScrollAmount_NoAmount));
+        waiter.WaitForNotification();
+
+        double x_after;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_HorizontalScrollPercent(&x_after));
+        EXPECT_GT(x_after, x_before);
+
+        AccessibilityNotificationWaiter waiter2(
+            shell()->web_contents(), ui::kAXModeComplete,
+            ax::mojom::Event::kScrollPositionChanged);
+
+        EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(0.0, 0.0));
+        waiter2.WaitForNotification();
+
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_HorizontalScrollPercent(&x_after));
+        EXPECT_NEAR(0, x_after, error);
+      }
+
+      BOOL can_scroll_vertical;
+      EXPECT_HRESULT_SUCCEEDED(
+          scroll_provider->get_VerticallyScrollable(&can_scroll_vertical));
+      ASSERT_EQ(expected.can_scroll_vertical, can_scroll_vertical);
+      if (expected.can_scroll_vertical) {
+        double size_vertical;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_VerticalViewSize(&size_vertical));
+        EXPECT_NEAR(expected.size_vertical, size_vertical, error);
+
+        double y_before;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_VerticalScrollPercent(&y_before));
+        EXPECT_NEAR(0, y_before, error);
+
+        AccessibilityNotificationWaiter waiter(
+            shell()->web_contents(), ui::kAXModeComplete,
+            ax::mojom::Event::kScrollPositionChanged);
+
+        EXPECT_HRESULT_SUCCEEDED(scroll_provider->Scroll(
+            ScrollAmount_NoAmount, ScrollAmount_SmallIncrement));
+        waiter.WaitForNotification();
+
+        double y_after;
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_VerticalScrollPercent(&y_after));
+        EXPECT_GT(y_after, y_before);
+
+        AccessibilityNotificationWaiter waiter2(
+            shell()->web_contents(), ui::kAXModeComplete,
+            ax::mojom::Event::kScrollPositionChanged);
+
+        EXPECT_HRESULT_SUCCEEDED(scroll_provider->SetScrollPercent(0.0, 0.0));
+        waiter2.WaitForNotification();
+
+        EXPECT_HRESULT_SUCCEEDED(
+            scroll_provider->get_VerticalScrollPercent(&y_after));
+        EXPECT_NEAR(0, y_after, error);
+      }
+    } else {
+      EXPECT_EQ(nullptr, scroll_provider);
+    }
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index ed27057c..1ef1b51 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -76,6 +76,8 @@
 }
 
 bool BrowserAccessibility::CanFireEvents() const {
+  if (!instance_active())
+    return false;
   // Allow events unless this object would be trimmed away.
   return !PlatformIsChildOfLeaf();
 }
@@ -1233,6 +1235,9 @@
     case ax::mojom::Action::kScrollToMakeVisible:
       manager_->ScrollToMakeVisible(*this, data.target_rect);
       return true;
+    case ax::mojom::Action::kSetScrollOffset:
+      manager_->SetScrollOffset(*this, data.target_point);
+      return true;
     case ax::mojom::Action::kSetSelection:
       manager_->SetSelection(data);
       return true;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index 773557b..0f8f6cfe 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -108,9 +108,9 @@
 // static
 BrowserAccessibilityManager* BrowserAccessibilityManager::FromID(
     ui::AXTreeID ax_tree_id) {
-  AXTreeIDMap* ax_tree_id_map = g_ax_tree_id_map.Pointer();
-  auto iter = ax_tree_id_map->find(ax_tree_id);
-  return iter == ax_tree_id_map->end() ? nullptr : iter->second;
+  AXTreeIDMap& ax_tree_id_map = g_ax_tree_id_map.Get();
+  AXTreeIDMap::iterator iter = ax_tree_id_map.find(ax_tree_id);
+  return iter == ax_tree_id_map.end() ? nullptr : iter->second;
 }
 
 BrowserAccessibilityManager::BrowserAccessibilityManager(
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index ccadab5..6175110 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -227,6 +227,8 @@
 }
 
 bool BrowserAccessibilityManagerWin::CanFireEvents() {
+  if (!BrowserAccessibilityManager::CanFireEvents())
+    return false;
   BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
   if (!root_delegate)
     return false;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 0b8d10a..ba17a64 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -145,7 +145,7 @@
 #include "sql/sql_memory_dump_provider.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/ui_base_features.h"
-#include "ui/display/display_switches.h"
+#include "ui/display/display_features.h"
 #include "ui/gfx/font_render_params.h"
 #include "ui/gfx/switches.h"
 
@@ -1322,7 +1322,7 @@
   }
 
 #if defined(OS_WIN)
-  if (base::FeatureList::IsEnabled(features::kHighDynamicRange))
+  if (base::FeatureList::IsEnabled(display::features::kHighDynamicRange))
     HDRProxy::Initialize();
   system_message_window_.reset(new media::SystemMessageWindowWin);
 #elif defined(OS_LINUX) && defined(USE_UDEV)
diff --git a/content/browser/devtools/protocol/native_input_event_builder_mac.mm b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
index 3faae03..b1ffe55 100644
--- a/content/browser/devtools/protocol/native_input_event_builder_mac.mm
+++ b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
@@ -43,7 +43,7 @@
         charactersIgnoringModifiers:character
                           isARepeat:NO
                             keyCode:event.native_key_code] retain];
-};
+}
 
 }  // namespace protocol
 }  // namespace content
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc
index 2d76b76..1a47982 100644
--- a/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -333,6 +333,17 @@
 void CrossProcessFrameConnector::OnSynchronizeVisualProperties(
     const viz::FrameSinkId& frame_sink_id,
     const FrameVisualProperties& visual_properties) {
+  TRACE_EVENT_WITH_FLOW2(
+      TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+      "CrossProcessFrameConnector::OnSynchronizeVisualProperties Receive "
+      "Message",
+      TRACE_ID_GLOBAL(
+          visual_properties.local_surface_id_allocation.local_surface_id()
+              .submission_trace_id()),
+      TRACE_EVENT_FLAG_FLOW_IN, "message",
+      "FrameHostMsg_SynchronizeVisualProperties", "new_local_surface_id",
+      visual_properties.local_surface_id_allocation.local_surface_id()
+          .ToString());
   // If the |screen_space_rect| or |screen_info| of the frame has changed, then
   // the viz::LocalSurfaceId must also change.
   if ((last_received_local_frame_size_ != visual_properties.local_frame_size ||
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 6b5787a5..1387bd6c 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -14,7 +14,6 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/stl_util.h"
@@ -33,8 +32,6 @@
 #include "content/browser/indexed_db/indexed_db_tracing.h"
 #include "content/browser/indexed_db/indexed_db_transaction.h"
 #include "content/browser/indexed_db/indexed_db_value.h"
-#include "content/browser/indexed_db/scopes/scope_lock.h"
-#include "content/browser/indexed_db/scopes/scopes_lock_manager.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_channel.h"
 #include "storage/browser/blob/blob_data_handle.h"
@@ -127,9 +124,7 @@
  public:
   OpenRequest(scoped_refptr<IndexedDBDatabase> db,
               std::unique_ptr<IndexedDBPendingConnection> pending_connection)
-      : ConnectionRequest(db),
-        pending_(std::move(pending_connection)),
-        weak_factory_(this) {}
+      : ConnectionRequest(db), pending_(std::move(pending_connection)) {}
 
   void Perform() override {
     if (db_->metadata_.id == kInvalidId) {
@@ -205,13 +200,7 @@
     DCHECK_GT(new_version, old_version);
 
     if (db_->connections_.empty()) {
-      std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
-          {kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
-           ScopesLockManager::LockType::kExclusive}};
-      db_->lock_manager_->AcquireLocks(
-          std::move(lock_requests),
-          base::BindOnce(&IndexedDBDatabase::OpenRequest::StartUpgrade,
-                         weak_factory_.GetWeakPtr()));
+      StartUpgrade();
       return;
     }
 
@@ -245,19 +234,13 @@
     if (!db_->connections_.empty())
       return;
 
-    std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
-        {kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
-         ScopesLockManager::LockType::kExclusive}};
-    db_->lock_manager_->AcquireLocks(
-        std::move(lock_requests),
-        base::BindOnce(&IndexedDBDatabase::OpenRequest::StartUpgrade,
-                       weak_factory_.GetWeakPtr()));
+    StartUpgrade();
   }
 
   // Initiate the upgrade. The bulk of the work actually happens in
   // IndexedDBDatabase::VersionChangeOperation in order to kick the
   // transaction into the correct state.
-  void StartUpgrade(std::vector<ScopeLock> locks) {
+  void StartUpgrade() {
     connection_ = db_->CreateConnection(pending_->database_callbacks,
                                         pending_->child_process_id);
     DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL);
@@ -269,10 +252,11 @@
         std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()),
         blink::mojom::IDBTransactionMode::VersionChange,
         new IndexedDBBackingStore::Transaction(db_->backing_store()));
+    db_->RegisterAndScheduleTransaction(transaction);
+
     transaction->ScheduleTask(
         base::BindOnce(&IndexedDBDatabase::VersionChangeOperation, db_,
                        pending_->version, pending_->callbacks));
-    transaction->Start(std::move(locks));
   }
 
   // Called when the upgrade transaction has started executing.
@@ -312,7 +296,6 @@
   // transferred to the IndexedDBDispatcherHost via OnUpgradeNeeded.
   std::unique_ptr<IndexedDBConnection> connection_;
 
-  base::WeakPtrFactory<OpenRequest> weak_factory_;
   DISALLOW_COPY_AND_ASSIGN(OpenRequest);
 };
 
@@ -321,18 +304,12 @@
  public:
   DeleteRequest(scoped_refptr<IndexedDBDatabase> db,
                 scoped_refptr<IndexedDBCallbacks> callbacks)
-      : ConnectionRequest(db), callbacks_(callbacks), weak_factory_(this) {}
+      : ConnectionRequest(db), callbacks_(callbacks) {}
 
   void Perform() override {
     if (db_->connections_.empty()) {
       // No connections, so delete immediately.
-      std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
-          {kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
-           ScopesLockManager::LockType::kExclusive}};
-      db_->lock_manager_->AcquireLocks(
-          std::move(lock_requests),
-          base::BindOnce(&IndexedDBDatabase::DeleteRequest::DoDelete,
-                         weak_factory_.GetWeakPtr()));
+      DoDelete();
       return;
     }
 
@@ -351,17 +328,10 @@
   void OnConnectionClosed(IndexedDBConnection* connection) override {
     if (!db_->connections_.empty())
       return;
-
-    std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
-        {kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
-         ScopesLockManager::LockType::kExclusive}};
-    db_->lock_manager_->AcquireLocks(
-        std::move(lock_requests),
-        base::BindOnce(&IndexedDBDatabase::DeleteRequest::DoDelete,
-                       weak_factory_.GetWeakPtr()));
+    DoDelete();
   }
 
-  void DoDelete(std::vector<ScopeLock> locks) {
+  void DoDelete() {
     Status s;
     if (db_->backing_store_)
       s = db_->backing_store_->DeleteDatabase(db_->metadata_.name);
@@ -404,7 +374,6 @@
  private:
   scoped_refptr<IndexedDBCallbacks> callbacks_;
 
-  base::WeakPtrFactory<DeleteRequest> weak_factory_;
   DISALLOW_COPY_AND_ASSIGN(DeleteRequest);
 };
 
@@ -1837,28 +1806,18 @@
   return Status::OK();
 }
 
-void IndexedDBDatabase::TransactionCreated() {
-  UMA_HISTOGRAM_COUNTS_1000(
-      "WebCore.IndexedDB.Database.OutstandingTransactionCount",
-      transaction_count_);
-  ++transaction_count_;
-}
-
-void IndexedDBDatabase::TransactionFinished(
-    blink::mojom::IDBTransactionMode mode,
-    bool committed) {
+void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
+                                            bool committed) {
+  IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id",
+             transaction->id());
   --transaction_count_;
   DCHECK_GE(transaction_count_, 0);
 
-  // TODO(dmurph): To help remove this integration with IndexedDBDatabase, make
-  // a 'committed' listener closure on all transactions. Then the request can
-  // just listen for that.
-
   // This may be an unrelated transaction finishing while waiting for
   // connections to close, or the actual upgrade transaction from an active
   // request. Notify the active request if it's the latter.
   if (active_request_ &&
-      mode == blink::mojom::IDBTransactionMode::VersionChange) {
+      transaction->mode() == blink::mojom::IDBTransactionMode::VersionChange) {
     active_request_->UpgradeTransactionFinished(committed);
   }
 }
@@ -1902,6 +1861,11 @@
     IndexedDBTransaction* transaction) {
   IDB_TRACE1("IndexedDBDatabase::RegisterAndScheduleTransaction", "txn.id",
              transaction->id());
+
+  UMA_HISTOGRAM_COUNTS_1000(
+      "WebCore.IndexedDB.Database.OutstandingTransactionCount",
+      transaction_count_);
+  transaction_count_++;
   std::vector<ScopesLockManager::ScopeLockRequest> lock_requests;
   lock_requests.reserve(1 + transaction->scope().size());
   lock_requests.emplace_back(
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index f7f669d..d29251f9 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -103,8 +103,8 @@
                          int64_t object_store_id,
                          const base::string16& new_name);
 
-  // TODO(dmurph): Remove this method and have transactions be directly
-  // scheduled using the lock manager.
+  // Returns a pointer to a newly created transaction. The object is owned
+  // by the connection.
   void RegisterAndScheduleTransaction(IndexedDBTransaction* transaction);
   void Close(IndexedDBConnection* connection, bool forced);
   void ForceClose();
@@ -136,9 +136,7 @@
     return lock_manager_;
   }
 
-  void TransactionCreated();
-  void TransactionFinished(blink::mojom::IDBTransactionMode mode,
-                           bool committed);
+  void TransactionFinished(IndexedDBTransaction* transaction, bool committed);
 
   void AbortAllTransactionsForConnections();
 
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc
index 3b501662..d418674 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -119,8 +119,6 @@
   IDB_ASYNC_TRACE_BEGIN("IndexedDBTransaction::lifetime", this);
   callbacks_ = connection_->callbacks();
   database_ = connection_->database();
-  if (database_)
-    database_->TransactionCreated();
 
   diagnostics_.tasks_scheduled = 0;
   diagnostics_.tasks_completed = 0;
@@ -239,7 +237,7 @@
   if (callbacks_.get())
     callbacks_->OnAbort(*this, error);
 
-  database_->TransactionFinished(mode_, false);
+  database_->TransactionFinished(this, false);
 
   // RemoveTransaction will delete |this|.
   // Note: During force-close situations, the connection can be destroyed during
@@ -462,7 +460,7 @@
     if (!pending_observers_.empty() && connection_)
       connection_->ActivatePendingObservers(std::move(pending_observers_));
 
-    database_->TransactionFinished(mode_, true);
+    database_->TransactionFinished(this, true);
     // RemoveTransaction will delete |this|.
     connection_->RemoveTransaction(id_);
     return s;
@@ -481,7 +479,7 @@
                                  "Internal error committing transaction.");
     }
     callbacks_->OnAbort(*this, error);
-    database_->TransactionFinished(mode_, false);
+    database_->TransactionFinished(this, false);
   }
   return s;
 }
diff --git a/content/browser/renderer_host/render_view_host_delegate_view.h b/content/browser/renderer_host/render_view_host_delegate_view.h
index 3b77252..b00c4a1 100644
--- a/content/browser/renderer_host/render_view_host_delegate_view.h
+++ b/content/browser/renderer_host/render_view_host_delegate_view.h
@@ -98,10 +98,10 @@
                              int selected_item,
                              const std::vector<MenuItem>& items,
                              bool right_aligned,
-                             bool allow_multiple_selection) {};
+                             bool allow_multiple_selection) {}
 
   // Hides a popup menu opened by ShowPopupMenu().
-  virtual void HidePopupMenu() {};
+  virtual void HidePopupMenu() {}
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 3115d21..40307f9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1066,6 +1066,15 @@
   bool sent_visual_properties = false;
   if (Send(new WidgetMsg_SynchronizeVisualProperties(routing_id_,
                                                      *visual_properties))) {
+    TRACE_EVENT_WITH_FLOW2(
+        TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+        "RenderWidgetHostImpl::SynchronizeVisualProperties send message",
+        visual_properties->local_surface_id_allocation->local_surface_id()
+            .submission_trace_id(),
+        TRACE_EVENT_FLAG_FLOW_OUT, "message",
+        "WidgetMsg_SynchronizeVisualProperties", "local_surface_id",
+        visual_properties->local_surface_id_allocation->local_surface_id()
+            .ToString());
     visual_properties_ack_pending_ = needs_ack;
     old_visual_properties_.swap(visual_properties);
     sent_visual_properties = true;
@@ -2384,8 +2393,20 @@
 
 void RenderWidgetHostImpl::DidUpdateVisualProperties(
     const cc::RenderFrameMetadata& metadata) {
-  TRACE_EVENT0("renderer_host",
-               "RenderWidgetHostImpl::DidUpdateVisualProperties");
+  TRACE_EVENT_WITH_FLOW1(
+      "renderer_host,disabled-by-default-viz.surface_id_flow",
+      "RenderWidgetHostImpl::DidUpdateVisualProperties",
+      metadata.local_surface_id_allocation &&
+              metadata.local_surface_id_allocation->IsValid()
+          ? metadata.local_surface_id_allocation->local_surface_id()
+                    .submission_trace_id() +
+                metadata.local_surface_id_allocation->local_surface_id()
+                    .embed_trace_id()
+          : 0,
+      TRACE_EVENT_FLAG_FLOW_IN, "local_surface_id_allocation",
+      metadata.local_surface_id_allocation
+          ? metadata.local_surface_id_allocation->ToString()
+          : "null");
 
   // Update our knowledge of the RenderWidget's size.
   DCHECK(!metadata.viewport_size_in_pixels.IsEmpty());
diff --git a/content/child/child_process_sandbox_support_impl_mac.h b/content/child/child_process_sandbox_support_impl_mac.h
index b9e53e1..b6f8e5b0 100644
--- a/content/child/child_process_sandbox_support_impl_mac.h
+++ b/content/child/child_process_sandbox_support_impl_mac.h
@@ -39,6 +39,6 @@
   DISALLOW_COPY_AND_ASSIGN(WebSandboxSupportMac);
 };
 
-};  // namespace content
+}  // namespace content
 
 #endif  // CONTENT_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_IMPL_MAC_H_
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index a9ce636..dbd92542 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -105,7 +105,7 @@
 void _LSSetApplicationLaunchServicesServerConnectionStatus(
     uint64_t flags,
     bool (^connection_allowed)(CFDictionaryRef));
-};
+}
 #endif  // defined(OS_MACOSX)
 
 namespace content {
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/content/renderer/media/webrtc/mock_peer_connection_impl.cc
index c26a010..f1f5900 100644
--- a/content/renderer/media/webrtc/mock_peer_connection_impl.cc
+++ b/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <utility>
 #include <vector>
 
 #include "base/logging.h"
@@ -154,7 +155,7 @@
   return {};
 }
 
-webrtc::RtpParameters FakeRtpSender::GetParameters() {
+webrtc::RtpParameters FakeRtpSender::GetParameters() const {
   NOTIMPLEMENTED();
   return webrtc::RtpParameters();
 }
@@ -240,7 +241,7 @@
     : media_type_(media_type),
       sender_(std::move(sender)),
       receiver_(std::move(receiver)),
-      mid_(ToAbslOptional(mid)),
+      mid_(ToAbslOptional(std::move(mid))),
       stopped_(stopped),
       direction_(direction),
       current_direction_(ToAbslOptional(current_direction)) {}
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.h b/content/renderer/media/webrtc/mock_peer_connection_impl.h
index 1d691c26..389ca3c 100644
--- a/content/renderer/media/webrtc/mock_peer_connection_impl.h
+++ b/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -38,7 +38,7 @@
   std::vector<std::string> stream_ids() const override;
   std::vector<webrtc::RtpEncodingParameters> init_send_encodings()
       const override;
-  webrtc::RtpParameters GetParameters() override;
+  webrtc::RtpParameters GetParameters() const override;
   webrtc::RTCError SetParameters(
       const webrtc::RtpParameters& parameters) override;
   rtc::scoped_refptr<webrtc::DtmfSenderInterface> GetDtmfSender()
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
index 57f11a0..b69258d 100644
--- a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
+++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
@@ -287,7 +287,6 @@
 
 int32_t RTCVideoDecoderAdapter::Release() {
   DVLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
 
   base::AutoLock auto_lock(lock_);
   pending_buffers_.clear();
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter.h b/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
index 22a1933a..048962ad 100644
--- a/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
+++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
@@ -72,7 +72,7 @@
                  bool missing_frames,
                  const webrtc::CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
-  // Called on the worker thread.
+  // Called on the worker thread and on the DecodingThread.
   int32_t Release() override;
   // Called on the worker thread and on the DecodingThread.
   const char* ImplementationName() const override;
diff --git a/content/renderer/media/webrtc/webrtc_util.h b/content/renderer/media/webrtc/webrtc_util.h
index 425c0ec..d43ac52b 100644
--- a/content/renderer/media/webrtc/webrtc_util.h
+++ b/content/renderer/media/webrtc/webrtc_util.h
@@ -16,11 +16,23 @@
 }
 
 template <typename OptionalT>
+base::Optional<typename OptionalT::value_type> ToBaseOptional(
+    OptionalT&& optional) {
+  return optional ? base::make_optional(*optional) : base::nullopt;
+}
+
+template <typename OptionalT>
 absl::optional<typename OptionalT::value_type> ToAbslOptional(
     const OptionalT& optional) {
   return optional ? absl::make_optional(*optional) : absl::nullopt;
 }
 
+template <typename OptionalT>
+absl::optional<typename OptionalT::value_type> ToAbslOptional(
+    OptionalT&& optional) {
+  return optional ? absl::make_optional(*optional) : absl::nullopt;
+}
+
 template <typename OptionalT1, typename OptionalT2>
 bool OptionalEquals(const OptionalT1& lhs, const OptionalT2& rhs) {
   if (!lhs)
diff --git a/content/renderer/render_frame_metadata_observer_impl.cc b/content/renderer/render_frame_metadata_observer_impl.cc
index dd216915..31fe9a0 100644
--- a/content/renderer/render_frame_metadata_observer_impl.cc
+++ b/content/renderer/render_frame_metadata_observer_impl.cc
@@ -81,6 +81,21 @@
         needs_activation_notification;
     render_frame_metadata_observer_client_->OnRenderFrameMetadataChanged(
         needs_activation_notification ? last_frame_token_ : 0u, metadata_copy);
+    TRACE_EVENT_WITH_FLOW1(
+        TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+        "RenderFrameMetadataObserverImpl::OnRenderFrameSubmission",
+        metadata_copy.local_surface_id_allocation &&
+                metadata_copy.local_surface_id_allocation->IsValid()
+            ? metadata_copy.local_surface_id_allocation->local_surface_id()
+                      .submission_trace_id() +
+                  metadata_copy.local_surface_id_allocation->local_surface_id()
+                      .embed_trace_id()
+            : 0,
+        TRACE_EVENT_FLAG_FLOW_OUT, "local_surface_id_allocation",
+        metadata_copy.local_surface_id_allocation
+            ? metadata_copy.local_surface_id_allocation->local_surface_id()
+                  .ToString()
+            : "null");
   }
 
   // Always cache the initial frame token, so that if a test connects later on
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 0ebc3bdd..770b355 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -709,6 +709,17 @@
       routing_id_, frame_sink_id_, pending_visual_properties_));
   sent_visual_properties_ = pending_visual_properties_;
 
+  TRACE_EVENT_WITH_FLOW2(
+      TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+      "RenderFrameProxy::SynchronizeVisualProperties Send Message",
+      TRACE_ID_GLOBAL(pending_visual_properties_.local_surface_id_allocation
+                          .local_surface_id()
+                          .submission_trace_id()),
+      TRACE_EVENT_FLAG_FLOW_OUT, "message",
+      "FrameHostMsg_SynchronizeVisualProperties", "local_surface_id",
+      pending_visual_properties_.local_surface_id_allocation.local_surface_id()
+          .ToString());
+
   // The visible rect that the OOPIF needs to raster depends partially on
   // parameters that might have changed. If they affect the raster area, resend
   // the intersection rects.
diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm
index b7142c28..d6e9a70 100644
--- a/content/renderer/renderer_main_platform_delegate_mac.mm
+++ b/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -25,7 +25,7 @@
 
 extern "C" {
 CGError CGSSetDenyWindowServerConnections(bool);
-};
+}
 
 namespace content {
 
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index f0a7f5e..6369d5f3 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -349,13 +349,7 @@
   // TODO(crbug.com/907311): Remove this instrumentation after we identified
   // the cause of crash.
   if (report_debug_log_ && context_) {
-    std::string log;
-    for (const auto& entry : debug_log_) {
-      log += entry + " ";
-    }
-    DEBUG_ALIAS_FOR_CSTR(debug_log, log.c_str(), 1024);
-    CHECK(false) << "Destructing ServiceWorkerContextClient without calling "
-                    "WillDestroyWorkerContext()";
+    CrashWithDebugLog("DTOR");
   }
 }
 
@@ -429,6 +423,10 @@
   // Initialize pending callback maps. This needs to be freed on the
   // same thread before the worker context goes away in
   // willDestroyWorkerContext.
+  if (context_) {
+    CrashWithDebugLog("WCS");
+    return;
+  }
   context_ = std::make_unique<WorkerContextData>(this);
 
   CHECK(pending_service_worker_request_.is_pending());
@@ -777,6 +775,10 @@
     int event_id,
     blink::mojom::ServiceWorkerEventStatus status) {
   CHECK(worker_task_runner_->RunsTasksInCurrentSequence());
+  if (!context_) {
+    CrashWithDebugLog("DHFE");
+    return;
+  }
   // This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
   // events have completed. (crbug.com/736697)
   TRACE_EVENT_WITH_FLOW1("ServiceWorker",
@@ -1034,6 +1036,10 @@
     blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
     DispatchFetchEventCallback callback) {
   CHECK(worker_task_runner_->RunsTasksInCurrentSequence());
+  if (!context_) {
+    CrashWithDebugLog("DOQFE");
+    return;
+  }
   TRACE_EVENT2("ServiceWorker",
                "ServiceWorkerContextClient::DispatchOrQueueFetchEvent", "url",
                params->request->url.spec(), "queued",
@@ -1464,6 +1470,10 @@
     blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
     DispatchFetchEventCallback callback) {
   CHECK(worker_task_runner_->RunsTasksInCurrentSequence());
+  if (!context_) {
+    CrashWithDebugLog("DFE");
+    return;
+  }
   int event_id = context_->timeout_timer->StartEvent(
       CreateAbortCallback(&context_->fetch_event_callbacks));
   context_->fetch_event_callbacks.emplace(event_id, std::move(callback));
@@ -1682,4 +1692,15 @@
     debug_log_.pop_front();
 }
 
+void ServiceWorkerContextClient::CrashWithDebugLog(const std::string& reason) {
+  base::AutoLock lock(debug_log_lock_);
+  std::string log;
+  for (const auto& entry : debug_log_) {
+    log += entry + " ";
+  }
+  DEBUG_ALIAS_FOR_CSTR(debug_log, log.c_str(), 1024);
+  DEBUG_ALIAS_FOR_CSTR(reason_log, reason.c_str(), 32);
+  CHECK(false);
+}
+
 }  // namespace content
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index 426d03ed..b2d96aa 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -369,6 +369,7 @@
 
   // TODO(crbug.com/907311): Remove after we identified the cause of crash.
   void RecordDebugLog(const char* message);
+  void CrashWithDebugLog(const std::string& reason);
 
   const int64_t service_worker_version_id_;
   const GURL service_worker_scope_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index c70425c..f273e9420 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -648,6 +648,7 @@
   deps = [
     ":test_support",
     "//cc",
+    "//components/viz/service",
     "//components/viz/test:test_support",
     "//content/browser:for_content_tests",
     "//content/child:for_content_tests",
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 9b8ea8c..7cc9353d 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -803,6 +803,10 @@
     self.Flaky('conformance/textures/image_bitmap_from_video/' +
         'tex-2d-rgb-rgb-unsigned_byte.html',
         ['android', ('qualcomm', 'Adreno (TM) 418'), 'no_angle'], bug=716496)
+    self.Flaky('conformance/textures/misc/texture-npot-video.html',
+        ['android', 'android-chromium',
+         ('qualcomm', 'Adreno (TM) 418'), 'no_angle'],
+        bug=934545)
     self.Skip('conformance/uniforms/uniform-samplers-test.html',
         ['android', ('qualcomm', 'Adreno (TM) 418')],
         bug=610951)
diff --git a/content/test/web_test_support.cc b/content/test/web_test_support.cc
index 1e7e7e1..bd92504 100644
--- a/content/test/web_test_support.cc
+++ b/content/test/web_test_support.cc
@@ -20,6 +20,7 @@
 #include "cc/test/pixel_test_output_surface.h"
 #include "components/viz/common/features.h"
 #include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/service/display/skia_output_surface.h"
 #include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
@@ -287,6 +288,14 @@
   }
 
   // TestLayerTreeFrameSinkClient implementation.
+  std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
+      override {
+    // No test is requesting SkiaRenderer with this WebTestDependenciesImpl,
+    // so return nullptr for now. 
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+
   std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
       scoped_refptr<viz::ContextProvider> compositor_context_provider)
       override {
diff --git a/dbus/property.cc b/dbus/property.cc
index e1fb05a..7ec7eb7 100644
--- a/dbus/property.cc
+++ b/dbus/property.cc
@@ -681,15 +681,23 @@
       return false;
 
     std::string key;
-    MessageReader value_varient_reader(nullptr);
-    if (!entry_reader.PopString(&key) ||
-        !entry_reader.PopVariant(&value_varient_reader))
+    if (!entry_reader.PopString(&key))
       return false;
 
     const uint8_t* bytes = nullptr;
     size_t length = 0;
-    if (!value_varient_reader.PopArrayOfBytes(&bytes, &length))
-      return false;
+
+    if (entry_reader.GetDataType() == Message::VARIANT) {
+      // Make BlueZ happy since it wraps the array of bytes with a variant.
+      MessageReader value_variant_reader(nullptr);
+      if (!entry_reader.PopVariant(&value_variant_reader))
+        return false;
+      if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
+        return false;
+    } else {
+      if (!entry_reader.PopArrayOfBytes(&bytes, &length))
+        return false;
+    }
 
     value_[key].assign(bytes, bytes + length);
   }
@@ -745,15 +753,23 @@
       return false;
 
     uint16_t key;
-    MessageReader value_varient_reader(nullptr);
-    if (!entry_reader.PopUint16(&key) ||
-        !entry_reader.PopVariant(&value_varient_reader))
+    if (!entry_reader.PopUint16(&key))
       return false;
 
     const uint8_t* bytes = nullptr;
     size_t length = 0;
-    if (!value_varient_reader.PopArrayOfBytes(&bytes, &length))
-      return false;
+
+    if (entry_reader.GetDataType() == Message::VARIANT) {
+      // Make BlueZ happy since it wraps the array of bytes with a variant.
+      MessageReader value_variant_reader(nullptr);
+      if (!entry_reader.PopVariant(&value_variant_reader))
+        return false;
+      if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
+        return false;
+    } else {
+      if (!entry_reader.PopArrayOfBytes(&bytes, &length))
+        return false;
+    }
 
     value_[key].assign(bytes, bytes + length);
   }
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc
index 4fbb6ad8..4846328 100644
--- a/dbus/property_unittest.cc
+++ b/dbus/property_unittest.cc
@@ -432,7 +432,7 @@
   EXPECT_EQ(test_list, ip_list.value());
 }
 
-TEST(PropertyTestStatic, ReadWriteStringToByteVectorMap) {
+TEST(PropertyTestStatic, ReadWriteStringToByteVectorMapVariantWrapped) {
   std::unique_ptr<Response> message(Response::CreateEmpty());
   MessageWriter writer(message.get());
   MessageWriter variant_writer(nullptr);
@@ -469,6 +469,39 @@
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
+TEST(PropertyTestStatic, ReadWriteStringToByteVectorMap) {
+  std::unique_ptr<Response> message(Response::CreateEmpty());
+  MessageWriter writer(message.get());
+  MessageWriter variant_writer(nullptr);
+  MessageWriter dict_writer(nullptr);
+
+  writer.OpenVariant("a{say}", &variant_writer);
+  variant_writer.OpenArray("{say}", &dict_writer);
+
+  const char* keys[] = {"One", "Two", "Three", "Four"};
+  const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
+  for (unsigned i = 0; i < base::size(keys); ++i) {
+    MessageWriter entry_writer(nullptr);
+    dict_writer.OpenDictEntry(&entry_writer);
+
+    entry_writer.AppendString(keys[i]);
+    entry_writer.AppendArrayOfBytes(values[i].data(), values[i].size());
+
+    dict_writer.CloseContainer(&entry_writer);
+  }
+
+  variant_writer.CloseContainer(&dict_writer);
+  writer.CloseContainer(&variant_writer);
+
+  MessageReader reader(message.get());
+  Property<std::map<std::string, std::vector<uint8_t>>> test_property;
+  EXPECT_TRUE(test_property.PopValueFromReader(&reader));
+
+  ASSERT_EQ(base::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < base::size(keys); ++i)
+    EXPECT_EQ(values[i], test_property.value().at(keys[i]));
+}
+
 TEST(PropertyTestStatic, SerializeStringToByteVectorMap) {
   std::map<std::string, std::vector<uint8_t>> test_map;
   test_map["Hi"] = {1, 2, 3};
@@ -487,7 +520,7 @@
   EXPECT_EQ(test_map, test_property.value());
 }
 
-TEST(PropertyTestStatic, ReadWriteUInt16ToByteVectorMap) {
+TEST(PropertyTestStatic, ReadWriteUInt16ToByteVectorMapVariantWrapped) {
   std::unique_ptr<Response> message(Response::CreateEmpty());
   MessageWriter writer(message.get());
   MessageWriter variant_writer(nullptr);
@@ -524,6 +557,39 @@
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
+TEST(PropertyTestStatic, ReadWriteUInt16ToByteVectorMap) {
+  std::unique_ptr<Response> message(Response::CreateEmpty());
+  MessageWriter writer(message.get());
+  MessageWriter variant_writer(nullptr);
+  MessageWriter dict_writer(nullptr);
+
+  writer.OpenVariant("a{qay}", &variant_writer);
+  variant_writer.OpenArray("{qay}", &dict_writer);
+
+  const uint16_t keys[] = {11, 12, 13, 14};
+  const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
+  for (unsigned i = 0; i < base::size(keys); ++i) {
+    MessageWriter entry_writer(nullptr);
+    dict_writer.OpenDictEntry(&entry_writer);
+
+    entry_writer.AppendUint16(keys[i]);
+    entry_writer.AppendArrayOfBytes(values[i].data(), values[i].size());
+
+    dict_writer.CloseContainer(&entry_writer);
+  }
+
+  variant_writer.CloseContainer(&dict_writer);
+  writer.CloseContainer(&variant_writer);
+
+  MessageReader reader(message.get());
+  Property<std::map<uint16_t, std::vector<uint8_t>>> test_property;
+  EXPECT_TRUE(test_property.PopValueFromReader(&reader));
+
+  ASSERT_EQ(base::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < base::size(keys); ++i)
+    EXPECT_EQ(values[i], test_property.value().at(keys[i]));
+}
+
 TEST(PropertyTestStatic, SerializeUInt16ToByteVectorMap) {
   std::map<uint16_t, std::vector<uint8_t>> test_map;
   test_map[11] = {1, 2, 3};
diff --git a/device/bluetooth/bluetooth_low_energy_peripheral_delegate.mm b/device/bluetooth/bluetooth_low_energy_peripheral_delegate.mm
index f838aab..a26cdee 100644
--- a/device/bluetooth/bluetooth_low_energy_peripheral_delegate.mm
+++ b/device/bluetooth/bluetooth_low_energy_peripheral_delegate.mm
@@ -25,11 +25,11 @@
 
   void DidDiscoverPrimaryServices(NSError* error) {
     device_mac_->DidDiscoverPrimaryServices(error);
-  };
+  }
 
   void DidDiscoverCharacteristics(CBService* service, NSError* error) {
     device_mac_->DidDiscoverCharacteristics(service, error);
-  };
+  }
 
   void DidUpdateValue(CBCharacteristic* characteristic, NSError* error) {
     device_mac_->DidUpdateValue(characteristic, error);
diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm
index 5f218f2..fb26159 100644
--- a/device/bluetooth/test/bluetooth_test_mac.mm
+++ b/device/bluetooth/test/bluetooth_test_mac.mm
@@ -38,7 +38,7 @@
   }
 
   // Returns MockCentralManager instance.
-  MockCentralManager* get() { return mock_central_manager_; };
+  MockCentralManager* get() { return mock_central_manager_; }
 
  private:
   scoped_nsobject<MockCentralManager> mock_central_manager_;
diff --git a/device/fido/mac/get_assertion_operation_unittest_mac.mm b/device/fido/mac/get_assertion_operation_unittest_mac.mm
index 447d4be..be3cb5c 100644
--- a/device/fido/mac/get_assertion_operation_unittest_mac.mm
+++ b/device/fido/mac/get_assertion_operation_unittest_mac.mm
@@ -80,8 +80,8 @@
   ASSERT_TRUE(opt_response);
   ASSERT_TRUE(opt_response->credential());
   EXPECT_FALSE(opt_response->credential()->id().empty());
-};
 }
+}  // namespace
 }  // namespace mac
 }  // namespace fido
 }  // namespace device
diff --git a/device/fido/mac/make_credential_operation_unittest_mac.mm b/device/fido/mac/make_credential_operation_unittest_mac.mm
index 07c5f98..d389007 100644
--- a/device/fido/mac/make_credential_operation_unittest_mac.mm
+++ b/device/fido/mac/make_credential_operation_unittest_mac.mm
@@ -59,7 +59,7 @@
   EXPECT_EQ(CtapDeviceResponseCode::kSuccess, error);
   auto opt_response = std::move(std::get<1>(result));
   ASSERT_TRUE(opt_response);
-};
+}
 
 }  // namespace
 }  // namespace mac
diff --git a/device/fido/pin.cc b/device/fido/pin.cc
index ecdd059d..60041407 100644
--- a/device/fido/pin.cc
+++ b/device/fido/pin.cc
@@ -12,6 +12,7 @@
 #include "components/cbor/writer.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/pin.h"
+#include "device/fido/pin_internal.h"
 #include "third_party/boringssl/src/include/openssl/aes.h"
 #include "third_party/boringssl/src/include/openssl/bn.h"
 #include "third_party/boringssl/src/include/openssl/ec.h"
@@ -25,32 +26,6 @@
 namespace device {
 namespace pin {
 
-// kProtocolVersion is the version of the PIN protocol that this code
-// implements.
-constexpr int kProtocolVersion = 1;
-
-// Subcommand enumerates the subcommands to the main |authenticatorClientPIN|
-// command. See
-// https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#authenticatorClientPIN
-enum class Subcommand : uint8_t {
-  kGetRetries = 0x01,
-  kGetKeyAgreement = 0x02,
-  kSetPIN = 0x03,
-  kChangePIN = 0x04,
-  kGetPINToken = 0x05,
-};
-
-// CommandKeys enumerates the keys in the top-level CBOR map for all PIN
-// commands.
-enum class CommandKeys : int {
-  kProtocol = 1,
-  kSubcommand = 2,
-  kKeyAgreement = 3,
-  kPINAuth = 4,
-  kNewPINEnc = 5,
-  kPINHashEnc = 6,
-};
-
 // HasAtLeastFourCodepoints returns true if |pin| is UTF-8 encoded and contains
 // four or more code points. This reflects the "4 Unicode characters"
 // requirement in CTAP2.
@@ -72,8 +47,8 @@
     Subcommand subcommand,
     std::function<void(cbor::Value::MapValue*)> add_additional = nullptr) {
   cbor::Value::MapValue map;
-  map.emplace(static_cast<int>(CommandKeys::kProtocol), kProtocolVersion);
-  map.emplace(static_cast<int>(CommandKeys::kSubcommand),
+  map.emplace(static_cast<int>(RequestKey::kProtocol), kProtocolVersion);
+  map.emplace(static_cast<int>(RequestKey::kSubcommand),
               static_cast<int>(subcommand));
 
   if (add_additional) {
@@ -109,7 +84,8 @@
   }
   const auto& response_map = decoded_response->GetMap();
 
-  auto it = response_map.find(cbor::Value(3));
+  auto it =
+      response_map.find(cbor::Value(static_cast<int>(ResponseKey::kRetries)));
   if (it == response_map.end() || !it->second.is_unsigned()) {
     return base::nullopt;
   }
@@ -128,7 +104,7 @@
 // PointFromKeyAgreementResponse returns an |EC_POINT| that represents the same
 // P-256 point as |response|. It returns |nullopt| if |response| encodes an
 // invalid point.
-static base::Optional<bssl::UniquePtr<EC_POINT>> PointFromKeyAgreementResponse(
+base::Optional<bssl::UniquePtr<EC_POINT>> PointFromKeyAgreementResponse(
     const EC_GROUP* group,
     const KeyAgreementResponse& response) {
   bssl::UniquePtr<EC_POINT> ret(EC_POINT_new(group));
@@ -167,13 +143,20 @@
   }
   const auto& response_map = decoded_response->GetMap();
 
-  // The ephemeral key is encoded as a COSE structure under key 1.
-  auto it = response_map.find(cbor::Value(1));
+  // The ephemeral key is encoded as a COSE structure.
+  auto it = response_map.find(
+      cbor::Value(static_cast<int>(ResponseKey::kKeyAgreement)));
   if (it == response_map.end() || !it->second.is_map()) {
     return base::nullopt;
   }
   const auto& cose_key = it->second.GetMap();
 
+  return ParseFromCOSE(cose_key);
+}
+
+// static
+base::Optional<KeyAgreementResponse> KeyAgreementResponse::ParseFromCOSE(
+    const cbor::Value::MapValue& cose_key) {
   // The COSE key must be a P-256 point. See
   // https://tools.ietf.org/html/rfc8152#section-7.1
   for (const auto& pair : std::vector<std::pair<int, int>>({
@@ -239,32 +222,30 @@
   return out;
 }
 
-// CalculateSharedKey generates and returns an ephemeral key, and writes the
-// shared key between that ephemeral key and the authenticator's ephemeral key
-// (from |peers_key|) to |out_shared_key|.
-static cbor::Value::MapValue CalculateSharedKey(
-    const KeyAgreementResponse& peers_key,
-    uint8_t out_shared_key[SHA256_DIGEST_LENGTH]) {
-  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
-  CHECK(EC_KEY_generate_key(key.get()));
-  auto peers_point =
-      PointFromKeyAgreementResponse(EC_KEY_get0_group(key.get()), peers_key);
+// CalculateSharedKey writes the CTAP2 shared key between |key| and |peers_key|
+// to |out_shared_key|.
+void CalculateSharedKey(const EC_KEY* key,
+                        const EC_POINT* peers_key,
+                        uint8_t out_shared_key[SHA256_DIGEST_LENGTH]) {
   CHECK_EQ(static_cast<int>(SHA256_DIGEST_LENGTH),
-           ECDH_compute_key(out_shared_key, SHA256_DIGEST_LENGTH,
-                            peers_point->get(), key.get(), SHA256KDF));
+           ECDH_compute_key(out_shared_key, SHA256_DIGEST_LENGTH, peers_key,
+                            key, SHA256KDF));
+}
 
+// EncodeCOSEPublicKey returns the public part of |key| as a COSE structure.
+cbor::Value::MapValue EncodeCOSEPublicKey(const EC_KEY* key) {
   // X9.62 is the standard for serialising elliptic-curve points.
   uint8_t x962[1 /* type byte */ + 32 /* x */ + 32 /* y */];
-  CHECK_EQ(sizeof(x962),
-           EC_POINT_point2oct(EC_KEY_get0_group(key.get()),
-                              EC_KEY_get0_public_key(key.get()),
-                              POINT_CONVERSION_UNCOMPRESSED, x962, sizeof(x962),
-                              nullptr /* BN_CTX */));
+  CHECK_EQ(
+      sizeof(x962),
+      EC_POINT_point2oct(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key),
+                         POINT_CONVERSION_UNCOMPRESSED, x962, sizeof(x962),
+                         nullptr /* BN_CTX */));
 
   cbor::Value::MapValue cose_key;
   cose_key.emplace(1 /* key type */, 2 /* uncompressed elliptic curve */);
   cose_key.emplace(3 /* algorithm */,
-                   2 /* ECDH, ephemeral–static, HKDF-SHA-256 */);
+                   -25 /* ECDH, ephemeral–static, HKDF-SHA-256 */);
   cose_key.emplace(-1 /* curve */, 1 /* P-256 */);
   cose_key.emplace(-2 /* x */, base::span<const uint8_t>(x962 + 1, 32));
   cose_key.emplace(-3 /* y */, base::span<const uint8_t>(x962 + 33, 32));
@@ -272,23 +253,47 @@
   return cose_key;
 }
 
-std::vector<uint8_t> SetRequest::EncodeAsCBOR() const {
-  // See
-  // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#settingNewPin
-  uint8_t shared_key[SHA256_DIGEST_LENGTH];
-  auto cose_key = CalculateSharedKey(peer_key_, shared_key);
+// GenerateSharedKey generates and returns an ephemeral key, and writes the
+// shared key between that ephemeral key and the authenticator's ephemeral key
+// (from |peers_key|) to |out_shared_key|.
+static cbor::Value::MapValue GenerateSharedKey(
+    const KeyAgreementResponse& peers_key,
+    uint8_t out_shared_key[SHA256_DIGEST_LENGTH]) {
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  CHECK(EC_KEY_generate_key(key.get()));
+  auto peers_point =
+      PointFromKeyAgreementResponse(EC_KEY_get0_group(key.get()), peers_key);
+  CalculateSharedKey(key.get(), peers_point->get(), out_shared_key);
+  return EncodeCOSEPublicKey(key.get());
+}
+
+// Encrypt encrypts |plaintext| using |key|, writing the ciphertext to
+// |out_ciphertext|. |plaintext| must be a whole number of AES blocks.
+void Encrypt(const uint8_t key[SHA256_DIGEST_LENGTH],
+             base::span<const uint8_t> plaintext,
+             uint8_t* out_ciphertext) {
+  DCHECK_EQ(0u, plaintext.size() % AES_BLOCK_SIZE);
 
   EVP_CIPHER_CTX aes_ctx;
   EVP_CIPHER_CTX_init(&aes_ctx);
   const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
-  CHECK(EVP_EncryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr, shared_key,
-                           kZeroIV));
+  CHECK(EVP_EncryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr, key, kZeroIV));
+  CHECK(EVP_CIPHER_CTX_set_padding(&aes_ctx, 0 /* no padding */));
+  CHECK(
+      EVP_Cipher(&aes_ctx, out_ciphertext, plaintext.data(), plaintext.size()));
+  EVP_CIPHER_CTX_cleanup(&aes_ctx);
+}
+
+std::vector<uint8_t> SetRequest::EncodeAsCBOR() const {
+  // See
+  // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#settingNewPin
+  uint8_t shared_key[SHA256_DIGEST_LENGTH];
+  auto cose_key = GenerateSharedKey(peer_key_, shared_key);
 
   static_assert((sizeof(pin_) % AES_BLOCK_SIZE) == 0,
                 "pin_ is not a multiple of the AES block size");
-  uint8_t encrypted_pin[sizeof(pin_) + AES_BLOCK_SIZE];
-  CHECK(EVP_Cipher(&aes_ctx, encrypted_pin, pin_, sizeof(pin_)));
-  EVP_CIPHER_CTX_cleanup(&aes_ctx);
+  uint8_t encrypted_pin[sizeof(pin_)];
+  Encrypt(shared_key, pin_, encrypted_pin);
 
   uint8_t pin_auth[SHA256_DIGEST_LENGTH];
   unsigned hmac_bytes;
@@ -299,13 +304,12 @@
   return EncodePINCommand(
       Subcommand::kSetPIN,
       [&cose_key, &encrypted_pin, &pin_auth](cbor::Value::MapValue* map) {
-        map->emplace(static_cast<int>(CommandKeys::kKeyAgreement),
+        map->emplace(static_cast<int>(RequestKey::kKeyAgreement),
                      std::move(cose_key));
-        map->emplace(static_cast<int>(CommandKeys::kNewPINEnc),
-                     // Note that the final AES block of |encrypted_pin| is
-                     // discarded because CTAP2 doesn't include any padding.
-                     base::span<const uint8_t>(encrypted_pin, sizeof(pin_)));
-        map->emplace(static_cast<int>(CommandKeys::kPINAuth),
+        map->emplace(
+            static_cast<int>(RequestKey::kNewPINEnc),
+            base::span<const uint8_t>(encrypted_pin, sizeof(encrypted_pin)));
+        map->emplace(static_cast<int>(RequestKey::kPINAuth),
                      base::span<const uint8_t>(pin_auth));
       });
 }
@@ -341,35 +345,22 @@
   // See
   // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#changingExistingPin
   uint8_t shared_key[SHA256_DIGEST_LENGTH];
-  auto cose_key = CalculateSharedKey(peer_key_, shared_key);
+  auto cose_key = GenerateSharedKey(peer_key_, shared_key);
 
-  EVP_CIPHER_CTX aes_ctx;
-  EVP_CIPHER_CTX_init(&aes_ctx);
-  const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
-
-  CHECK(EVP_EncryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr, shared_key,
-                           kZeroIV));
   static_assert((sizeof(new_pin_) % AES_BLOCK_SIZE) == 0,
                 "new_pin_ is not a multiple of the AES block size");
-  uint8_t encrypted_pin[sizeof(new_pin_) + AES_BLOCK_SIZE];
-  CHECK(EVP_Cipher(&aes_ctx, encrypted_pin, new_pin_, sizeof(new_pin_)));
+  uint8_t encrypted_pin[sizeof(new_pin_)];
+  Encrypt(shared_key, new_pin_, encrypted_pin);
 
-  CHECK(EVP_EncryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr, shared_key,
-                           kZeroIV));
   static_assert((sizeof(old_pin_hash_) % AES_BLOCK_SIZE) == 0,
                 "old_pin_hash_ is not a multiple of the AES block size");
-  uint8_t old_pin_hash_enc[sizeof(old_pin_hash_) + AES_BLOCK_SIZE];
-  CHECK(EVP_Cipher(&aes_ctx, old_pin_hash_enc, old_pin_hash_,
-                   sizeof(old_pin_hash_)));
+  uint8_t old_pin_hash_enc[sizeof(old_pin_hash_)];
+  Encrypt(shared_key, old_pin_hash_, old_pin_hash_enc);
 
-  EVP_CIPHER_CTX_cleanup(&aes_ctx);
-
-  uint8_t ciphertexts_concat[sizeof(new_pin_) + sizeof(old_pin_hash_)];
-  // Note that the final AES blocks of |encrypted_pin| and |old_pin_hash_enc|
-  // are discarded because CTAP2 doesn't include any padding.
-  memcpy(ciphertexts_concat, encrypted_pin, sizeof(new_pin_));
-  memcpy(ciphertexts_concat + sizeof(new_pin_), old_pin_hash_enc,
-         sizeof(old_pin_hash_));
+  uint8_t ciphertexts_concat[sizeof(encrypted_pin) + sizeof(old_pin_hash_enc)];
+  memcpy(ciphertexts_concat, encrypted_pin, sizeof(encrypted_pin));
+  memcpy(ciphertexts_concat + sizeof(encrypted_pin), old_pin_hash_enc,
+         sizeof(old_pin_hash_enc));
 
   uint8_t pin_auth[SHA256_DIGEST_LENGTH];
   unsigned hmac_bytes;
@@ -380,15 +371,15 @@
   return EncodePINCommand(
       Subcommand::kChangePIN, [&cose_key, &encrypted_pin, &old_pin_hash_enc,
                                &pin_auth](cbor::Value::MapValue* map) {
-        map->emplace(static_cast<int>(CommandKeys::kKeyAgreement),
+        map->emplace(static_cast<int>(RequestKey::kKeyAgreement),
                      std::move(cose_key));
+        map->emplace(static_cast<int>(RequestKey::kPINHashEnc),
+                     base::span<const uint8_t>(old_pin_hash_enc,
+                                               sizeof(old_pin_hash_enc)));
         map->emplace(
-            static_cast<int>(CommandKeys::kPINHashEnc),
-            base::span<const uint8_t>(old_pin_hash_enc, sizeof(old_pin_hash_)));
-        map->emplace(
-            static_cast<int>(CommandKeys::kNewPINEnc),
-            base::span<const uint8_t>(encrypted_pin, sizeof(new_pin_)));
-        map->emplace(static_cast<int>(CommandKeys::kPINAuth),
+            static_cast<int>(RequestKey::kNewPINEnc),
+            base::span<const uint8_t>(encrypted_pin, sizeof(encrypted_pin)));
+        map->emplace(static_cast<int>(RequestKey::kPINAuth),
                      base::span<const uint8_t>(pin_auth));
       });
 }
@@ -399,7 +390,7 @@
 
 TokenRequest::TokenRequest(const std::string& pin,
                            const KeyAgreementResponse& peer_key)
-    : cose_key_(CalculateSharedKey(peer_key, shared_key_.data())) {
+    : cose_key_(GenerateSharedKey(peer_key, shared_key_.data())) {
   DCHECK_EQ(static_cast<size_t>(SHA256_DIGEST_LENGTH), shared_key_.size());
   uint8_t digest[SHA256_DIGEST_LENGTH];
   SHA256(reinterpret_cast<const uint8_t*>(pin.data()), pin.size(), digest);
@@ -413,26 +404,19 @@
 }
 
 std::vector<uint8_t> TokenRequest::EncodeAsCBOR() const {
-  EVP_CIPHER_CTX aes_ctx;
-  EVP_CIPHER_CTX_init(&aes_ctx);
-  const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
-
-  CHECK(EVP_EncryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr,
-                           shared_key_.data(), kZeroIV));
   static_assert((sizeof(pin_hash_) % AES_BLOCK_SIZE) == 0,
                 "pin_hash_ is not a multiple of the AES block size");
-  uint8_t encrypted_pin[sizeof(pin_hash_) + AES_BLOCK_SIZE];
-  CHECK(EVP_Cipher(&aes_ctx, encrypted_pin, pin_hash_, sizeof(pin_hash_)));
-  EVP_CIPHER_CTX_cleanup(&aes_ctx);
+  uint8_t encrypted_pin[sizeof(pin_hash_)];
+  Encrypt(shared_key_.data(), pin_hash_, encrypted_pin);
 
   return EncodePINCommand(
       Subcommand::kGetPINToken,
       [this, &encrypted_pin](cbor::Value::MapValue* map) {
-        map->emplace(static_cast<int>(CommandKeys::kKeyAgreement),
+        map->emplace(static_cast<int>(RequestKey::kKeyAgreement),
                      std::move(this->cose_key_));
         map->emplace(
-            static_cast<int>(CommandKeys::kPINHashEnc),
-            base::span<const uint8_t>(encrypted_pin, sizeof(pin_hash_)));
+            static_cast<int>(RequestKey::kPINHashEnc),
+            base::span<const uint8_t>(encrypted_pin, sizeof(encrypted_pin)));
       });
 }
 
@@ -440,6 +424,24 @@
 TokenResponse::~TokenResponse() = default;
 TokenResponse::TokenResponse(const TokenResponse&) = default;
 
+// Decrypt AES-256 CBC decrypts some number of whole blocks from |ciphertext|
+// into |plaintext|, using |key|.
+void Decrypt(const uint8_t key[SHA256_DIGEST_LENGTH],
+             base::span<const uint8_t> ciphertext,
+             uint8_t* out_plaintext) {
+  DCHECK_EQ(0u, ciphertext.size() % AES_BLOCK_SIZE);
+
+  EVP_CIPHER_CTX aes_ctx;
+  EVP_CIPHER_CTX_init(&aes_ctx);
+  const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
+  CHECK(EVP_DecryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr, key, kZeroIV));
+  CHECK(EVP_CIPHER_CTX_set_padding(&aes_ctx, 0 /* no padding */));
+
+  CHECK(EVP_Cipher(&aes_ctx, out_plaintext, ciphertext.data(),
+                   ciphertext.size()));
+  EVP_CIPHER_CTX_cleanup(&aes_ctx);
+}
+
 base::Optional<TokenResponse> TokenResponse::Parse(
     std::array<uint8_t, 32> shared_key,
     base::span<const uint8_t> buffer) {
@@ -456,8 +458,8 @@
   }
   const auto& response_map = decoded_response->GetMap();
 
-  // The encrypted PIN-token is under key 2.
-  auto it = response_map.find(cbor::Value(2));
+  auto it =
+      response_map.find(cbor::Value(static_cast<int>(ResponseKey::kPINToken)));
   if (it == response_map.end() || !it->second.is_bytestring()) {
     return base::nullopt;
   }
@@ -466,18 +468,9 @@
     return base::nullopt;
   }
 
-  EVP_CIPHER_CTX aes_ctx;
-  EVP_CIPHER_CTX_init(&aes_ctx);
-  const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0};
-  CHECK(EVP_DecryptInit_ex(&aes_ctx, EVP_aes_256_cbc(), nullptr,
-                           shared_key.data(), kZeroIV));
-  CHECK(EVP_CIPHER_CTX_set_padding(&aes_ctx, 0 /* no padding */));
-
   TokenResponse ret;
   ret.token_.resize(encrypted_token.size());
-  CHECK(EVP_Cipher(&aes_ctx, ret.token_.data(), encrypted_token.data(),
-                   encrypted_token.size()));
-  EVP_CIPHER_CTX_cleanup(&aes_ctx);
+  Decrypt(shared_key.data(), encrypted_token, ret.token_.data());
 
   return ret;
 }
diff --git a/device/fido/pin.h b/device/fido/pin.h
index aa9efe46..352639e8 100644
--- a/device/fido/pin.h
+++ b/device/fido/pin.h
@@ -66,6 +66,8 @@
 struct KeyAgreementResponse {
   static base::Optional<KeyAgreementResponse> Parse(
       base::span<const uint8_t> buffer);
+  static base::Optional<KeyAgreementResponse> ParseFromCOSE(
+      const cbor::Value::MapValue& cose_key);
 
   // x and y contain the big-endian coordinates of a P-256 point. It is ensured
   // that this is a valid point on the curve.
diff --git a/device/fido/pin_internal.h b/device/fido/pin_internal.h
new file mode 100644
index 0000000..870c6bb
--- /dev/null
+++ b/device/fido/pin_internal.h
@@ -0,0 +1,87 @@
+// 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.
+
+// This file contains additional declarations for CTAP2 PIN support. Only
+// implementations of the PIN protocol should need to include this file. For all
+// other code, see |pin.h|.
+
+#ifndef DEVICE_FIDO_PIN_INTERNAL_H_
+#define DEVICE_FIDO_PIN_INTERNAL_H_
+
+#include <stdint.h>
+
+#include "components/cbor/values.h"
+#include "device/fido/pin.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+
+namespace device {
+namespace pin {
+
+// kProtocolVersion is the version of the PIN protocol that this code
+// implements.
+constexpr int kProtocolVersion = 1;
+
+// Subcommand enumerates the subcommands to the main |authenticatorClientPIN|
+// command. See
+// https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#authenticatorClientPIN
+enum class Subcommand : uint8_t {
+  kGetRetries = 0x01,
+  kGetKeyAgreement = 0x02,
+  kSetPIN = 0x03,
+  kChangePIN = 0x04,
+  kGetPINToken = 0x05,
+};
+
+// RequestKey enumerates the keys in the top-level CBOR map for all PIN
+// commands.
+enum class RequestKey : int {
+  kProtocol = 1,
+  kSubcommand = 2,
+  kKeyAgreement = 3,
+  kPINAuth = 4,
+  kNewPINEnc = 5,
+  kPINHashEnc = 6,
+};
+
+// ResponseKey enumerates the keys in the top-level CBOR map for all PIN
+// responses.
+enum class ResponseKey : int {
+  kKeyAgreement = 1,
+  kPINToken = 2,
+  kRetries = 3,
+};
+
+// PointFromKeyAgreementResponse returns an |EC_POINT| that represents the same
+// P-256 point as |response|. It returns |nullopt| if |response| encodes an
+// invalid point.
+base::Optional<bssl::UniquePtr<EC_POINT>> PointFromKeyAgreementResponse(
+    const EC_GROUP* group,
+    const KeyAgreementResponse& response);
+
+// CalculateSharedKey writes the CTAP2 shared key between |key| and |peers_key|
+// to |out_shared_key|.
+void CalculateSharedKey(const EC_KEY* key,
+                        const EC_POINT* peers_key,
+                        uint8_t out_shared_key[SHA256_DIGEST_LENGTH]);
+
+// EncodeCOSEPublicKey returns the public part of |key| as a COSE structure.
+cbor::Value::MapValue EncodeCOSEPublicKey(const EC_KEY* key);
+
+// Encrypt encrypts |plaintext| using |key|, writing the ciphertext to
+// |out_ciphertext|. |plaintext| must be a whole number of AES blocks.
+void Encrypt(const uint8_t key[SHA256_DIGEST_LENGTH],
+             base::span<const uint8_t> plaintext,
+             uint8_t* out_ciphertext);
+
+// Decrypt AES-256 CBC decrypts some number of whole blocks from |ciphertext|
+// into |plaintext|, using |key|.
+void Decrypt(const uint8_t key[SHA256_DIGEST_LENGTH],
+             base::span<const uint8_t> ciphertext,
+             uint8_t* out_plaintext);
+
+}  // namespace pin
+}  // namespace device
+
+#endif  // DEVICE_FIDO_PIN_INTERNAL_H_
diff --git a/extensions/common/api/system_display.idl b/extensions/common/api/system_display.idl
index 594d71f..9fc0d9d 100644
--- a/extensions/common/api/system_display.idl
+++ b/extensions/common/api/system_display.idl
@@ -90,6 +90,9 @@
 
     // True if the display mode is currently selected.
     boolean isSelected;
+
+    // True if this mode is interlaced.
+    boolean isInterlaced;
   };
 
   // Layout position, i.e. edge of parent that the display is attached to.
diff --git a/extensions/common/error_utils_unittest.cc b/extensions/common/error_utils_unittest.cc
index 6cf8b22..fc43d43 100644
--- a/extensions/common/error_utils_unittest.cc
+++ b/extensions/common/error_utils_unittest.cc
@@ -50,15 +50,24 @@
   } cases[] = {{"Hello * Bye * *", "arg1", "arg2", "More placeholders"},
                {"Hello * Bye", "arg1", "arg2", "Fewer placeholders"}};
 
+  auto get_death_regex = [](const char* death_message_regex) {
+// String arguments aren't passed to CHECK() in official builds.
+#if defined(OFFICIAL_BUILD) && defined(NDEBUG)
+    return "";
+#else
+    return death_message_regex;
+#endif
+  };
+
   for (const auto& test_case : cases) {
     SCOPED_TRACE(test_case.format);
 
     EXPECT_DEATH(ErrorUtils::FormatErrorMessage(test_case.format, test_case.s1,
                                                 test_case.s2),
-                 test_case.death_message_regex);
+                 get_death_regex(test_case.death_message_regex));
     EXPECT_DEATH(ErrorUtils::FormatErrorMessageUTF16(
                      test_case.format, test_case.s1, test_case.s2),
-                 test_case.death_message_regex);
+                 get_death_regex(test_case.death_message_regex));
   }
 }
 #endif  // defined(GTEST_HAS_DEATH_TEST)
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc
index 2871bba5..e9fc1e281 100644
--- a/extensions/common/url_pattern.cc
+++ b/extensions/common/url_pattern.cc
@@ -176,9 +176,15 @@
 
 URLPattern::URLPattern(const URLPattern& other) = default;
 
+URLPattern::URLPattern(URLPattern&& other) = default;
+
 URLPattern::~URLPattern() {
 }
 
+URLPattern& URLPattern::operator=(const URLPattern& other) = default;
+
+URLPattern& URLPattern::operator=(URLPattern&& other) = default;
+
 bool URLPattern::operator<(const URLPattern& other) const {
   return GetAsString() < other.GetAsString();
 }
diff --git a/extensions/common/url_pattern.h b/extensions/common/url_pattern.h
index f639dc47..fc5d41a 100644
--- a/extensions/common/url_pattern.h
+++ b/extensions/common/url_pattern.h
@@ -108,8 +108,12 @@
 
   URLPattern();
   URLPattern(const URLPattern& other);
+  URLPattern(URLPattern&& other);
   ~URLPattern();
 
+  URLPattern& operator=(const URLPattern& other);
+  URLPattern& operator=(URLPattern&& other);
+
   bool operator<(const URLPattern& other) const;
   bool operator>(const URLPattern& other) const;
   bool operator==(const URLPattern& other) const;
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index ed4bcdd..5fd86f9 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -66,18 +66,19 @@
 
  private:
   // HeadlessWebContentsObserver implementation.
-  void DevToolsTargetReady() override {
-    HeadlessAsyncDevTooledBrowserTest::DevToolsTargetReady();
+  void RunDevTooledTest() override {
+    browser_devtools_client_->SetRawProtocolListener(this);
     devtools_client_->GetRuntime()->GetExperimental()->AddObserver(this);
     devtools_client_->GetRuntime()->Enable();
     devtools_client_->GetRuntime()->GetExperimental()->AddBinding(
         headless::runtime::AddBindingParams::Builder()
             .SetName("sendProtocolMessage")
-            .Build());
-    browser_devtools_client_->SetRawProtocolListener(this);
+            .Build(),
+        base::BindOnce(&HeadlessProtocolBrowserTest::BindingCreated,
+                       base::Unretained(this)));
   }
 
-  void RunDevTooledTest() override {
+  void BindingCreated(std::unique_ptr<headless::runtime::AddBindingResult>) {
     base::ScopedAllowBlockingForTesting allow_blocking;
     base::FilePath src_dir;
     CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
diff --git a/infra/config/lint-luci-milo.py b/infra/config/lint-luci-milo.py
index 124bbe00..5ca1484 100755
--- a/infra/config/lint-luci-milo.py
+++ b/infra/config/lint-luci-milo.py
@@ -69,10 +69,15 @@
         subwaterfalls[subwaterfall].append(builder)
 
   # subwaterfalls contains the waterfalls referenced by the main console
-  # Check that every referenced subwaterfall has its own console.
-  all_console_names = set([console.id for console in project.consoles])
+  # Check that every referenced subwaterfall has its own console, unless it's
+  # explicitly excluded below.
+  excluded_names = [
+      # This is the chrome/chromium.chrome console in src-internal.
+      'chromium.chrome',
+  ]
+  all_console_names = [console.id for console in project.consoles]
   referenced_names = set(subwaterfalls.keys())
-  missing_names = referenced_names - all_console_names
+  missing_names = referenced_names - set(all_console_names + excluded_names)
   if missing_names:
     print 'Missing subwaterfall console for', missing_names
     return 1
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg
index e91efc4..a203161b 100644
--- a/infra/config/luci-milo.cfg
+++ b/infra/config/luci-milo.cfg
@@ -100,7 +100,7 @@
     }
     links {
       text: "coverage"
-      url: "https://chromium-coverage.appspot.com"
+      url: "https://analysis.chromium.org/p/chromium/coverage"
       alt: "Chromium code coverage dashboard"
     }
     links {
@@ -1051,31 +1051,6 @@
 
 consoles {
   header_id: "chromium"
-  id: "chromium.chrome"
-  name: "chromium.chrome"
-  repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "refs/heads/master"
-  manifest_name: "REVISION"
-  builders {
-    name: "buildbucket/luci.chrome.ci/Google Chrome Win"
-    short_name: "win"
-  }
-  builders {
-    name: "buildbucket/luci.chrome.ci/Google Chrome Linux x64"
-    short_name: "lnx"
-  }
-  builders {
-    name: "buildbucket/luci.chrome.ci/Google Chrome Mac"
-    short_name: "mac"
-  }
-  builders {
-    name: "buildbucket/luci.chrome.ci/Google Chrome ChromeOS"
-    short_name: "cro"
-  }
-}
-
-consoles {
-  header_id: "chromium"
   id: "chromium.memory"
   name: "chromium.memory"
   repo_url: "https://chromium.googlesource.com/chromium/src"
diff --git a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
index b3f0031..7a06ea4 100644
--- a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
+++ b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
@@ -21,6 +21,7 @@
     "all"
   ],
   "configuration": "Debug",
+  "expiration_time": 7200,
   "tests": [
     {
       "xcode parallelization": true,
diff --git a/ios/testing/embedded_test_server_handlers.cc b/ios/testing/embedded_test_server_handlers.cc
index 9482709d..b28783f 100644
--- a/ios/testing/embedded_test_server_handlers.cc
+++ b/ios/testing/embedded_test_server_handlers.cc
@@ -78,9 +78,18 @@
     const net::test_server::HttpRequest& request) {
   auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
   http_response->set_content_type("text/html");
-  http_response->set_content(base::StringPrintf(
-      "<html><head></head><body><iframe src='%s'></iframe></body></html>",
-      ExtractUlrSpecFromQuery(request).c_str()));
+  http_response->set_content(
+      base::StringPrintf("<html><head></head><body><iframe "
+                         "src='%s'></iframe>Main frame text</body></html>",
+                         ExtractUlrSpecFromQuery(request).c_str()));
+  return std::move(http_response);
+}
+
+std::unique_ptr<net::test_server::HttpResponse> HandlePageWithContents(
+    const net::test_server::HttpRequest& request) {
+  auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
+  http_response->set_content_type("text/html");
+  http_response->set_content(request.GetURL().query());
   return std::move(http_response);
 }
 
diff --git a/ios/testing/embedded_test_server_handlers.h b/ios/testing/embedded_test_server_handlers.h
index 1b06887f..187016a 100644
--- a/ios/testing/embedded_test_server_handlers.h
+++ b/ios/testing/embedded_test_server_handlers.h
@@ -26,6 +26,10 @@
 std::unique_ptr<net::test_server::HttpResponse> HandleIFrame(
     const net::test_server::HttpRequest& request);
 
+// Returns a page with contetns of URL request query.
+std::unique_ptr<net::test_server::HttpResponse> HandlePageWithContents(
+    const net::test_server::HttpRequest& request);
+
 // Returns a page with content of URL request query if |responds_with_content|
 // is true. Closes the socket otherwise. Can be used to simulate the state where
 // there is no internet connection.
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index bbadf5ac..5b92183 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -566,6 +566,7 @@
     "//ios/web:resources_grit",
     "//ios/web/download:download_inttests",
     "//ios/web/navigation:core",
+    "//ios/web/public/find_in_page",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//ios/web/public/test/http_server",
@@ -585,6 +586,7 @@
   ]
   sources = [
     "browser_state_web_view_partition_inttest.mm",
+    "find_in_page/find_in_page_manager_inttest.mm",
     "navigation/history_state_operations_inttest.mm",
     "navigation/window_location_inttest.mm",
     "public/test/http_server_inttest.mm",
diff --git a/ios/web/find_in_page/BUILD.gn b/ios/web/find_in_page/BUILD.gn
index 0150e60..a876b97 100644
--- a/ios/web/find_in_page/BUILD.gn
+++ b/ios/web/find_in_page/BUILD.gn
@@ -6,6 +6,7 @@
   deps = [
     "//base",
     "//ios/web/public/",
+    "//ios/web/public/find_in_page",
     "//ios/web/web_state:web_frame",
     "//ios/web/web_state:web_state_impl_header",
   ]
diff --git a/ios/web/find_in_page/find_in_page_manager_inttest.mm b/ios/web/find_in_page/find_in_page_manager_inttest.mm
new file mode 100644
index 0000000..b3eb3f04
--- /dev/null
+++ b/ios/web/find_in_page/find_in_page_manager_inttest.mm
@@ -0,0 +1,135 @@
+// 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 "base/test/ios/wait_util.h"
+#include "ios/testing/embedded_test_server_handlers.h"
+#import "ios/web/public/find_in_page/find_in_page_manager.h"
+#import "ios/web/public/test/fakes/fake_find_in_page_manager_delegate.h"
+#import "ios/web/public/test/navigation_test_util.h"
+#import "ios/web/public/test/web_test_with_web_state.h"
+#include "ios/web/public/web_state/web_frame_util.h"
+#include "net/base/escape.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using base::test::ios::kWaitForJSCompletionTimeout;
+using base::test::ios::WaitUntilConditionOrTimeout;
+using base::test::ios::kWaitForPageLoadTimeout;
+
+namespace {
+// Page with text "Main frame body" and iframe with src URL equal to the URL
+// query string.
+const char kFindPageUrl[] = "/iframe?";
+// URL of iframe with text contents "iframe body".
+const char kFindInPageIFrameUrl[] = "/echo-query?iframe text";
+}
+
+namespace web {
+
+// Tests the FindInPageManager and verifies that values passed to
+// FindInPageManagerDelegate are correct.
+class FindInPageManagerTest : public WebTestWithWebState {
+ protected:
+  void SetUp() override {
+    WebTestWithWebState::SetUp();
+    test_server_.RegisterRequestHandler(base::BindRepeating(
+        &net::test_server::HandlePrefixedRequest, "/echo-query",
+        base::BindRepeating(&testing::HandlePageWithContents)));
+    test_server_.RegisterRequestHandler(
+        base::BindRepeating(&net::test_server::HandlePrefixedRequest, "/iframe",
+                            base::BindRepeating(&testing::HandleIFrame)));
+    ASSERT_TRUE(test_server_.Start());
+    GetFindInPageManager()->SetDelegate(&delegate_);
+  }
+
+  // Returns the FindInPageManager associated with |web_state()|.
+  FindInPageManager* GetFindInPageManager() {
+    return web::FindInPageManager::FromWebState(web_state());
+  }
+
+  net::EmbeddedTestServer test_server_;
+
+  FakeFindInPageManagerDelegate delegate_;
+};
+
+// Tests that find in page returns a single match for text which exists only in
+// the main frame.
+TEST_F(FindInPageManagerTest, FindMatchInMainFrame) {
+  // TODO(crbug.com/872818): Remove if check after deprecate iOS 10.
+  // WebFrame will not have a key on iOS 10, so function cannot be called.
+  if (@available(iOS 11.0, *)) {
+    std::string url_spec =
+        kFindPageUrl +
+        net::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
+    test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
+    ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
+      return GetAllWebFrames(web_state()).size() == 2;
+    }));
+
+    GetFindInPageManager()->Find(@"Main frame text",
+                                 FindInPageOptions::FindInPageSearch);
+
+    EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
+      return delegate_.state();
+    }));
+    EXPECT_EQ(1, delegate_.state()->match_count);
+    EXPECT_EQ(web_state(), delegate_.state()->web_state);
+  }
+};
+
+// Checks that find in page finds text that exists within the main frame and
+// an iframe.
+TEST_F(FindInPageManagerTest, FindMatchInMainFrameAndIFrame) {
+  // TODO(crbug.com/872818): Remove if check after deprecate iOS 10.
+  // WebFrame will not have a key on iOS 10, so function cannot be called.
+  if (@available(iOS 11.0, *)) {
+    std::string url_spec =
+        kFindPageUrl +
+        net::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
+    test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
+    ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
+      return GetAllWebFrames(web_state()).size() == 2;
+    }));
+
+    GetFindInPageManager()->Find(@"frame", FindInPageOptions::FindInPageSearch);
+
+    EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
+      return delegate_.state();
+    }));
+    EXPECT_EQ(2, delegate_.state()->match_count);
+    EXPECT_EQ(web_state(), delegate_.state()->web_state);
+  }
+};
+
+// Checks that find in page returns no matches for text not contained on the
+// page.
+TEST_F(FindInPageManagerTest, FindNoMatch) {
+  // TODO(crbug.com/872818): Remove if check after deprecate iOS 10.
+  // WebFrame will not have a key on iOS 10, so function cannot be called.
+  if (@available(iOS 11.0, *)) {
+    std::string url_spec =
+        kFindPageUrl +
+        net::EscapeQueryParamValue(kFindInPageIFrameUrl, /*use_plus=*/true);
+    test::LoadUrl(web_state(), test_server_.GetURL(url_spec));
+    ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout, ^{
+      return GetAllWebFrames(web_state()).size() == 2;
+    }));
+
+    GetFindInPageManager()->Find(@"foobar",
+                                 FindInPageOptions::FindInPageSearch);
+
+    EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
+      return delegate_.state();
+    }));
+    EXPECT_EQ(0, delegate_.state()->match_count);
+    EXPECT_EQ(web_state(), delegate_.state()->web_state);
+  }
+};
+
+}  // namespace web
diff --git a/ios/web/public/find_in_page/find_in_page_manager_delegate.h b/ios/web/public/find_in_page/find_in_page_manager_delegate.h
index f9fb9126..edab868 100644
--- a/ios/web/public/find_in_page/find_in_page_manager_delegate.h
+++ b/ios/web/public/find_in_page/find_in_page_manager_delegate.h
@@ -7,6 +7,8 @@
 
 #include <string>
 
+#include "base/macros.h"
+
 namespace web {
 
 class WebState;
diff --git a/ios/web/public/test/fakes/BUILD.gn b/ios/web/public/test/fakes/BUILD.gn
index baa2b5d..157c1ea4 100644
--- a/ios/web/public/test/fakes/BUILD.gn
+++ b/ios/web/public/test/fakes/BUILD.gn
@@ -9,6 +9,7 @@
   deps = [
     "//base",
     "//ios/web/public/download",
+    "//ios/web/public/find_in_page",
     "//ios/web/test:test_constants",
     "//ios/web/web_state:navigation_context",
     "//ios/web/web_state:web_frame",
@@ -35,6 +36,8 @@
     "fake_download_controller_delegate.mm",
     "fake_download_task.h",
     "fake_download_task.mm",
+    "fake_find_in_page_manager_delegate.h",
+    "fake_find_in_page_manager_delegate.mm",
     "fake_navigation_context.h",
     "fake_navigation_context.mm",
     "fake_web_frame.cc",
diff --git a/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.h b/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.h
new file mode 100644
index 0000000..ef3f132
--- /dev/null
+++ b/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.h
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_PUBLIC_TEST_FAKES_FAKE_FIND_IN_PAGE_MANAGER_DELEGATE_H_
+#define IOS_WEB_PUBLIC_TEST_FAKES_FAKE_FIND_IN_PAGE_MANAGER_DELEGATE_H_
+
+#include <memory>
+#include <string>
+
+#import "ios/web/public/find_in_page/find_in_page_manager_delegate.h"
+
+namespace web {
+
+class WebState;
+
+// Use this as the delegate for FindInPageManager responses in test suites.
+class FakeFindInPageManagerDelegate : public FindInPageManagerDelegate {
+ public:
+  FakeFindInPageManagerDelegate();
+  ~FakeFindInPageManagerDelegate() override;
+
+  // FindInPageManagerDelegate override
+  void DidCountMatches(WebState* web_state,
+                       int match_count,
+                       const std::string& query) override;
+  void DidHighlightMatch(WebState* web_state, int index) override;
+
+  // Holds the last response values passed to DidCountMatches.
+  struct State {
+    State();
+    ~State();
+    WebState* web_state = nullptr;
+    int match_count = -1;
+    std::string query;
+  };
+
+  // Returns the current State.
+  const State* state() const { return delegate_state_.get(); }
+
+ private:
+  std::unique_ptr<State> delegate_state_;
+  DISALLOW_COPY_AND_ASSIGN(FakeFindInPageManagerDelegate);
+};
+
+}  // namespace web
+
+#endif  // IOS_WEB_PUBLIC_TEST_FAKES_FAKE_FIND_IN_PAGE_MANAGER_DELEGATE_H_
diff --git a/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.mm b/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.mm
new file mode 100644
index 0000000..9daa1679
--- /dev/null
+++ b/ios/web/public/test/fakes/fake_find_in_page_manager_delegate.mm
@@ -0,0 +1,33 @@
+// 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/web/public/test/fakes/fake_find_in_page_manager_delegate.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace web {
+
+FakeFindInPageManagerDelegate::State::State() = default;
+
+FakeFindInPageManagerDelegate::State::~State() = default;
+
+FakeFindInPageManagerDelegate::FakeFindInPageManagerDelegate() = default;
+
+FakeFindInPageManagerDelegate::~FakeFindInPageManagerDelegate() = default;
+
+void FakeFindInPageManagerDelegate::DidCountMatches(WebState* web_state,
+                                                    int match_count,
+                                                    const std::string& query) {
+  delegate_state_ = std::make_unique<State>();
+  delegate_state_->web_state = web_state;
+  delegate_state_->match_count = match_count;
+  delegate_state_->query = query;
+}
+
+void FakeFindInPageManagerDelegate::DidHighlightMatch(WebState* web_state,
+                                                      int index) {}
+
+}  // namespace web
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc
index 6ff5e24..4984572 100644
--- a/ipc/ipc_send_fds_test.cc
+++ b/ipc/ipc_send_fds_test.cc
@@ -8,7 +8,7 @@
 #if defined(OS_MACOSX)
 extern "C" {
 #include <sandbox.h>
-};
+}
 #endif
 #include <fcntl.h>
 #include <stddef.h>
diff --git a/media/base/bit_reader_core.cc b/media/base/bit_reader_core.cc
index 32c872b..cd3e896 100644
--- a/media/base/bit_reader_core.cc
+++ b/media/base/bit_reader_core.cc
@@ -113,6 +113,7 @@
     // empty the current bit register for that purpose.
     nbits_ = 0;
     reg_ = 0;
+    *out = 0;
     return false;
   }
 
diff --git a/media/base/bit_reader_core.h b/media/base/bit_reader_core.h
index 11962987..1ba856a 100644
--- a/media/base/bit_reader_core.h
+++ b/media/base/bit_reader_core.h
@@ -56,9 +56,10 @@
   // integer type.
   template<typename T> bool ReadBits(int num_bits, T* out) {
     DCHECK_LE(num_bits, static_cast<int>(sizeof(T) * 8));
-    uint64_t temp;
+    uint64_t temp = 0;
     bool ret = ReadBitsInternal(num_bits, &temp);
-    *out = static_cast<T>(temp);
+    if (ret)
+      *out = static_cast<T>(temp);
     return ret;
   }
 
diff --git a/media/base/container_names.cc b/media/base/container_names.cc
index 434aa0a..64fb0218 100644
--- a/media/base/container_names.cc
+++ b/media/base/container_names.cc
@@ -73,11 +73,17 @@
 }
 
 // Helper function to read up to 64 bits from a bit stream.
+// TODO(chcunningham): Delete this helper and replace with direct calls to
+// reader that handle read failure. As-is, we hide failure because returning 0
+// is valid for both a successful and failed read.
 static uint64_t ReadBits(BitReader* reader, int num_bits) {
   DCHECK_GE(reader->bits_available(), num_bits);
   DCHECK((num_bits > 0) && (num_bits <= 64));
-  uint64_t value;
-  reader->ReadBits(num_bits, &value);
+  uint64_t value = 0;
+
+  if (!reader->ReadBits(num_bits, &value))
+    return 0;
+
   return value;
 }
 
@@ -304,7 +310,9 @@
     reader.SkipBits(6);
 
     // Verify core audio sampling frequency is an allowed value.
-    RCHECK(kSamplingFrequencyValid[ReadBits(&reader, 4)]);
+    size_t sampling_freq_index = ReadBits(&reader, 4);
+    RCHECK(sampling_freq_index < base::size(kSamplingFrequencyValid));
+    RCHECK(kSamplingFrequencyValid[sampling_freq_index]);
 
     // Verify transmission bit rate is valid.
     RCHECK(ReadBits(&reader, 5) <= 25);
@@ -316,7 +324,9 @@
     reader.SkipBits(1 + 1 + 1 + 1);
 
     // Verify extension audio descriptor flag is an allowed value.
-    RCHECK(kExtAudioIdValid[ReadBits(&reader, 3)]);
+    size_t audio_id_index = ReadBits(&reader, 3);
+    RCHECK(audio_id_index < base::size(kExtAudioIdValid));
+    RCHECK(kExtAudioIdValid[audio_id_index]);
 
     // Skip extended coding flag and audio sync word insertion flag.
     reader.SkipBits(1 + 1);
diff --git a/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm b/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
index 156e536..ca95f53 100644
--- a/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
+++ b/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
@@ -45,4 +45,4 @@
   }));
 }
 
-};  // namespace media
+}  // namespace media
diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc
index ee4f570..408cacc 100644
--- a/net/base/mime_sniffer.cc
+++ b/net/base/mime_sniffer.cc
@@ -101,11 +101,11 @@
 static const size_t kBytesRequiredForMagic = 42;
 
 struct MagicNumber {
-  const char* mime_type;
-  const char* magic;
+  const char* const mime_type;
+  const char* const magic;
   size_t magic_len;
   bool is_string;
-  const char* mask;  // if set, must have same length as |magic|
+  const char* const mask;  // if set, must have same length as |magic|
 };
 
 #define MAGIC_NUMBER(mime_type, magic) \
@@ -196,7 +196,7 @@
 
 struct OfficeExtensionType {
   OfficeDocType doc_type;
-  const char* extension;
+  const char* const extension;
   size_t extension_len;
 };
 
diff --git a/net/filter/gzip_source_stream_fuzzer.cc b/net/filter/gzip_source_stream_fuzzer.cc
index d6f67a3..a7cbbadb 100644
--- a/net/filter/gzip_source_stream_fuzzer.cc
+++ b/net/filter/gzip_source_stream_fuzzer.cc
@@ -4,6 +4,8 @@
 
 #include "net/filter/gzip_source_stream.h"
 
+#include <algorithm>
+
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/test/fuzzed_data_provider.h"
@@ -20,12 +22,20 @@
   std::unique_ptr<net::FuzzedSourceStream> fuzzed_source_stream(
       new net::FuzzedSourceStream(&data_provider));
 
+  // Gzip has a maximum compression ratio of 1032x. While, strictly speaking,
+  // linear, this means the fuzzer will often get stuck. Stop reading at a more
+  // modest compression ratio of 10x, or 2 MiB, whichever is larger. See
+  // https://crbug.com/921075.
+  size_t max_output =
+      std::max(10u * size, static_cast<size_t>(2 * 1024 * 1024));
+
   const net::SourceStream::SourceType kGzipTypes[] = {
       net::SourceStream::TYPE_GZIP, net::SourceStream::TYPE_DEFLATE};
   net::SourceStream::SourceType type =
       data_provider.PickValueInArray(kGzipTypes);
   std::unique_ptr<net::GzipSourceStream> gzip_stream =
       net::GzipSourceStream::Create(std::move(fuzzed_source_stream), type);
+  size_t bytes_read = 0;
   while (true) {
     scoped_refptr<net::IOBufferWithSize> io_buffer =
         base::MakeRefCounted<net::IOBufferWithSize>(64);
@@ -34,7 +44,11 @@
     // Releasing the pointer to IOBuffer immediately is more likely to lead to a
     // use-after-free.
     io_buffer = nullptr;
-    if (callback.GetResult(result) <= 0)
+    result = callback.GetResult(result);
+    if (result <= 0)
+      break;
+    bytes_read += static_cast<size_t>(result);
+    if (bytes_read >= max_output)
       break;
   }
 
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 667a6ff..983c689 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -119,6 +119,8 @@
       quic_goaway_sessions_on_ip_change(false),
       quic_idle_connection_timeout_seconds(kIdleConnectionTimeoutSeconds),
       quic_reduced_ping_timeout_seconds(quic::kPingTimeoutSecs),
+      quic_retransmittable_on_wire_timeout_milliseconds(
+          kDefaultRetransmittableOnWireTimeoutMillisecs),
       quic_max_time_before_crypto_handshake_seconds(
           quic::kMaxTimeForCryptoHandshakeSecs),
       quic_max_idle_time_before_crypto_handshake_seconds(
@@ -223,6 +225,7 @@
           params.mark_quic_broken_when_network_blackholes,
           params.quic_idle_connection_timeout_seconds,
           params.quic_reduced_ping_timeout_seconds,
+          params.quic_retransmittable_on_wire_timeout_milliseconds,
           params.quic_max_time_before_crypto_handshake_seconds,
           params.quic_max_idle_time_before_crypto_handshake_seconds,
           params.quic_migrate_sessions_on_network_change_v2,
@@ -386,6 +389,8 @@
                    params_.quic_migrate_sessions_on_network_change_v2);
   dict->SetBoolean("migrate_sessions_early_v2",
                    params_.quic_migrate_sessions_early_v2);
+  dict->SetInteger("retransmittable_on_wire_timeout_milliseconds",
+                   params_.quic_retransmittable_on_wire_timeout_milliseconds);
   dict->SetBoolean("retry_on_alternate_network_before_handshake",
                    params_.quic_retry_on_alternate_network_before_handshake);
   dict->SetInteger("idle_session_migration_period_seconds",
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index cdc00e0..e489b8f 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -175,6 +175,9 @@
     // Specifies the reduced ping timeout subsequent connections should use when
     // a connection was timed out with open streams.
     int quic_reduced_ping_timeout_seconds;
+    // Maximum time that a session can have no retransmittable packets on the
+    // wire.
+    int quic_retransmittable_on_wire_timeout_milliseconds;
     // Maximum time the session can be alive before crypto handshake is
     // finished.
     int quic_max_time_before_crypto_handshake_seconds;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index e20860ca..50a99c15 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -128,14 +128,9 @@
 
 HttpNetworkTransaction::~HttpNetworkTransaction() {
 #if BUILDFLAG(ENABLE_REPORTING)
-  // Report a success if we have not already done so. Errors would have been
-  // reported from DoCallback(), DoReadBodyComplete(), HandleIOError(), or
-  // DoReadHeadersComplete().
-  // Note: This may incorrectly report an error as a success, e.g. if the
-  // request is cancelled after successfully receiving headers but would
-  // otherwise have encountered an error on reading the body.
-  if (headers_valid_ && next_state_ == STATE_NONE)
-    GenerateNetworkErrorLoggingReport(OK);
+  // If no error or success report has been generated yet at this point, then
+  // this network transaction was prematurely cancelled.
+  GenerateNetworkErrorLoggingReport(ERR_ABORTED);
 #endif  // BUILDFLAG(ENABLE_REPORTING)
   if (stream_.get()) {
     // TODO(mbelshe): The stream_ should be able to compute whether or not the
@@ -1255,12 +1250,15 @@
   ProcessNetworkErrorLoggingHeader();
 
   // Generate NEL report here if we have to report an HTTP error (4xx or 5xx
-  // code), or if the response body will not be read.
+  // code), or if the response body will not be read, or on a redirect.
+  // Note: This will report a success for a redirect even if an error is
+  // encountered later while draining the body.
   int response_code = response_.headers->response_code();
   if ((response_code >= 400 && response_code < 600) ||
       response_code == HTTP_NO_CONTENT || response_code == HTTP_RESET_CONTENT ||
       response_code == HTTP_NOT_MODIFIED || request_->method == "HEAD" ||
-      response_.headers->GetContentLength() == 0) {
+      response_.headers->GetContentLength() == 0 ||
+      response_.headers->IsRedirect(nullptr /* location */)) {
     GenerateNetworkErrorLoggingReport(OK);
   }
 #endif  // BUILDFLAG(ENABLE_REPORTING)
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 580cc8e..c5dc3d1 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -18248,6 +18248,11 @@
     request.traffic_annotation =
         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
 
+    MockWrite data_writes[] = {
+        MockWrite("GET / HTTP/1.1\r\n"
+                  "Host: www.example.org\r\n"
+                  "Connection: keep-alive\r\n\r\n"),
+    };
     MockRead data_reads[] = {
         MockRead("HTTP/1.0 200 OK\r\n"),
         MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
@@ -18257,11 +18262,6 @@
         MockRead("hello world"),
         MockRead(SYNCHRONOUS, OK),
     };
-    MockWrite data_writes[] = {
-        MockWrite("GET / HTTP/1.1\r\n"
-                  "Host: www.example.org\r\n"
-                  "Connection: keep-alive\r\n\r\n"),
-    };
 
     StaticSocketDataProvider reads(data_reads, data_writes);
     session_deps_.socket_factory->AddSocketDataProvider(&reads);
@@ -18376,13 +18376,6 @@
   // Makes an HTTPS request that should install a valid NEL policy.
   void RequestPolicy(CertStatus cert_status = 0) {
     std::string extra_header_string = extra_headers_.ToString();
-    MockRead data_reads[] = {
-        MockRead("HTTP/1.0 200 OK\r\n"),
-        MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
-        MockRead("\r\n"),
-        MockRead("hello world"),
-        MockRead(SYNCHRONOUS, OK),
-    };
     MockWrite data_writes[] = {
         MockWrite("GET / HTTP/1.1\r\n"
                   "Host: www.example.org\r\n"
@@ -18390,6 +18383,13 @@
         MockWrite(ASYNC, extra_header_string.data(),
                   extra_header_string.size()),
     };
+    MockRead data_reads[] = {
+        MockRead("HTTP/1.0 200 OK\r\n"),
+        MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
+        MockRead("\r\n"),
+        MockRead("hello world"),
+        MockRead(SYNCHRONOUS, OK),
+    };
 
     StaticSocketDataProvider reads(data_reads, data_writes);
     session_deps_.socket_factory->AddSocketDataProvider(&reads);
@@ -18608,18 +18608,18 @@
 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
        CreateReportReadBodyError) {
   std::string extra_header_string = extra_headers_.ToString();
-  MockRead data_reads[] = {
-      MockRead("HTTP/1.0 200 OK\r\n"),
-      MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
-      MockRead("hello world"),
-      MockRead(SYNCHRONOUS, OK),
-  };
   MockWrite data_writes[] = {
       MockWrite("GET / HTTP/1.1\r\n"
                 "Host: www.example.org\r\n"
                 "Connection: keep-alive\r\n"),
       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
   };
+  MockRead data_reads[] = {
+      MockRead("HTTP/1.0 200 OK\r\n"),
+      MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
+      MockRead("hello world"),
+      MockRead(SYNCHRONOUS, OK),
+  };
 
   StaticSocketDataProvider reads(data_reads, data_writes);
   session_deps_.socket_factory->AddSocketDataProvider(&reads);
@@ -18662,18 +18662,18 @@
 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
        CreateReportReadBodyErrorAsync) {
   std::string extra_header_string = extra_headers_.ToString();
-  MockRead data_reads[] = {
-      MockRead("HTTP/1.0 200 OK\r\n"),
-      MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
-      MockRead("hello world"),
-      MockRead(ASYNC, OK),
-  };
   MockWrite data_writes[] = {
       MockWrite("GET / HTTP/1.1\r\n"
                 "Host: www.example.org\r\n"
                 "Connection: keep-alive\r\n"),
       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
   };
+  MockRead data_reads[] = {
+      MockRead("HTTP/1.0 200 OK\r\n"),
+      MockRead("Content-Length: 100\r\n\r\n"),  // wrong content length
+      MockRead("hello world"),
+      MockRead(ASYNC, OK),
+  };
 
   StaticSocketDataProvider reads(data_reads, data_writes);
   session_deps_.socket_factory->AddSocketDataProvider(&reads);
@@ -19239,6 +19239,67 @@
   EXPECT_EQ(0, error3.reporting_upload_depth);
 }
 
+TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
+       CreateReportCancelAfterStart) {
+  StaticSocketDataProvider data;
+  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+  TestCompletionCallback callback;
+  auto session = CreateSession(&session_deps_);
+  auto trans =
+      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
+  int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
+  EXPECT_EQ(rv, ERR_IO_PENDING);
+
+  // Cancel after start.
+  trans.reset();
+
+  ASSERT_EQ(1u, network_error_logging_service()->errors().size());
+  CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
+              IPAddress() /* server_ip */);
+}
+
+TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
+       CreateReportCancelBeforeReadingBody) {
+  std::string extra_header_string = extra_headers_.ToString();
+  MockWrite data_writes[] = {
+      MockWrite("GET / HTTP/1.1\r\n"
+                "Host: www.example.org\r\n"
+                "Connection: keep-alive\r\n"),
+      MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
+  };
+  MockRead data_reads[] = {
+      MockRead("HTTP/1.0 200 OK\r\n"),
+      MockRead("Content-Length: 100\r\n\r\n"),  // Body is never read.
+  };
+
+  StaticSocketDataProvider data(data_reads, data_writes);
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+  SSLSocketDataProvider ssl(ASYNC, OK);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  TestCompletionCallback callback;
+  auto session = CreateSession(&session_deps_);
+  auto trans =
+      std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
+  int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
+  EXPECT_THAT(callback.GetResult(rv), IsOk());
+
+  const HttpResponseInfo* response = trans->GetResponseInfo();
+  ASSERT_TRUE(response);
+
+  EXPECT_TRUE(response->headers);
+  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
+
+  // Cancel before reading the body.
+  trans.reset();
+
+  ASSERT_EQ(1u, network_error_logging_service()->errors().size());
+  CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
+}
+
 TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
   base::HistogramTester histograms;
   RequestPolicy();
@@ -19259,8 +19320,8 @@
       MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
   };
 
-  StaticSocketDataProvider reads(data_reads, data_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&reads);
+  StaticSocketDataProvider data(data_reads, data_writes);
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
 
   // Insecure url
   url_ = "http://www.example.org/";
diff --git a/net/http/http_proxy_client_socket_wrapper.cc b/net/http/http_proxy_client_socket_wrapper.cc
index f128a49..d7187b3a 100644
--- a/net/http/http_proxy_client_socket_wrapper.cc
+++ b/net/http/http_proxy_client_socket_wrapper.cc
@@ -509,7 +509,8 @@
 int HttpProxyClientSocketWrapper::DoTransportConnect() {
   next_state_ = STATE_TCP_CONNECT_COMPLETE;
   nested_connect_job_ = TransportConnectJob::CreateTransportConnectJob(
-      transport_params_, priority_, common_connect_job_params_, this);
+      transport_params_, priority_, common_connect_job_params_, this,
+      &net_log_);
   return nested_connect_job_->Connect();
 }
 
@@ -555,7 +556,7 @@
   next_state_ = STATE_SSL_CONNECT_COMPLETE;
   nested_connect_job_ = std::make_unique<SSLConnectJob>(
       priority_, common_connect_job_params_, ssl_params_,
-      nullptr /* http_proxy_pool */, this);
+      nullptr /* http_proxy_pool */, this, &net_log_);
   return nested_connect_job_->Connect();
 }
 
diff --git a/net/http/http_proxy_client_socket_wrapper_unittest.cc b/net/http/http_proxy_client_socket_wrapper_unittest.cc
index c715842..aadc039 100644
--- a/net/http/http_proxy_client_socket_wrapper_unittest.cc
+++ b/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -139,6 +139,8 @@
         /*goaway_sessions_on_ip_change=*/false,
         /*mark_quic_broken_when_network_blackholes=*/false,
         idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_,
+        /*retransmittable_on_wire_timeout_milliseconds=*/
+        kDefaultRetransmittableOnWireTimeoutMillisecs,
         /*max_time_before_crypto_handshake_seconds=*/
         quic::kMaxTimeForCryptoHandshakeSecs,
         /*max_idle_time_before_crypto_handshake_seconds=*/
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index a820e4c8..abc3cd4e 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -165,14 +165,15 @@
     RequestPriority priority,
     const CommonConnectJobParams& common_connect_job_params,
     const scoped_refptr<HttpProxySocketParams>& params,
-    Delegate* delegate)
-    : ConnectJob(
-          priority,
-          base::TimeDelta() /* The socket takes care of timeouts */,
-          common_connect_job_params,
-          delegate,
-          NetLogWithSource::Make(common_connect_job_params.net_log,
-                                 NetLogSourceType::HTTP_PROXY_CONNECT_JOB)),
+    Delegate* delegate,
+    const NetLogWithSource* net_log)
+    : ConnectJob(priority,
+                 base::TimeDelta() /* The socket takes care of timeouts */,
+                 common_connect_job_params,
+                 delegate,
+                 net_log,
+                 NetLogSourceType::HTTP_PROXY_CONNECT_JOB,
+                 NetLogEventType::HTTP_PROXY_CONNECT_JOB_CONNECT),
       client_socket_(std::make_unique<HttpProxyClientSocketWrapper>(
           priority,
           ConnectionTimeout(
diff --git a/net/http/http_proxy_connect_job.h b/net/http/http_proxy_connect_job.h
index 1ffa46b..068a59f 100644
--- a/net/http/http_proxy_connect_job.h
+++ b/net/http/http_proxy_connect_job.h
@@ -103,7 +103,8 @@
   HttpProxyConnectJob(RequestPriority priority,
                       const CommonConnectJobParams& common_connect_job_params,
                       const scoped_refptr<HttpProxySocketParams>& params,
-                      Delegate* delegate);
+                      Delegate* delegate,
+                      const NetLogWithSource* net_log);
   ~HttpProxyConnectJob() override;
 
   // ConnectJob methods.
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index e55fa43a..1647777d 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -201,7 +201,7 @@
             nullptr /* socket_performance_watcher_factory */,
             &network_quality_estimator_, nullptr /* net_log */,
             nullptr /* websocket_endpoint_lock_manager */),
-        std::move(http_proxy_socket_params), delegate);
+        std::move(http_proxy_socket_params), delegate, nullptr /* net_log */);
   }
 
   void InitProxyDelegate() {
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index af42b59..4e94f2d 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -709,7 +709,7 @@
 EVENT_TYPE(UDP_SEND_ERROR)
 
 // ------------------------------------------------------------------------
-// ClientSocketPoolBase::ConnectJob
+// ConnectJob
 // ------------------------------------------------------------------------
 
 // The start/end of a ConnectJob.
@@ -719,10 +719,7 @@
 //   {
 //     "group_name": <The group name for the socket request.>,
 //   }
-EVENT_TYPE(SOCKET_POOL_CONNECT_JOB)
-
-// The start/end of the ConnectJob::Connect().
-EVENT_TYPE(SOCKET_POOL_CONNECT_JOB_CONNECT)
+EVENT_TYPE(CONNECT_JOB)
 
 // This event is logged whenever the ConnectJob gets a new socket
 // association. The event parameters point to that socket:
@@ -733,7 +730,26 @@
 EVENT_TYPE(CONNECT_JOB_SET_SOCKET)
 
 // Whether the connect job timed out.
-EVENT_TYPE(SOCKET_POOL_CONNECT_JOB_TIMED_OUT)
+EVENT_TYPE(CONNECT_JOB_TIMED_OUT)
+
+// ------------------------------------------------------------------------
+// ConnectJob subclasses
+// ------------------------------------------------------------------------
+
+// The start/end of the TransportConnectJob::Connect().
+EVENT_TYPE(TRANSPORT_CONNECT_JOB_CONNECT)
+
+// The start/end of the SSLConnectJob::Connect().
+EVENT_TYPE(SSL_CONNECT_JOB_CONNECT)
+
+// The start/end of the SOCKSConnectJob::Connect().
+EVENT_TYPE(SOCKS_CONNECT_JOB_CONNECT)
+
+// The start/end of the HttpProxyConnectJob::Connect().
+EVENT_TYPE(HTTP_PROXY_CONNECT_JOB_CONNECT)
+
+// The start/end of the WebSocketConnectJob::Connect().
+EVENT_TYPE(WEB_SOCKET_TRANSPORT_CONNECT_JOB_CONNECT)
 
 // ------------------------------------------------------------------------
 // ClientSocketPoolBaseHelper
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 1dfb060..b5737a3 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -514,6 +514,8 @@
         /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
         /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kDefaultRetransmittableOnWireTimeoutMillisecs),
         base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
         base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
         kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 2436487a..8f8c0ffa 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -75,12 +75,6 @@
 // The maximum size of uncompressed QUIC headers that will be allowed.
 const size_t kMaxUncompressedHeaderSize = 256 * 1024;
 
-// The maximum time allowed to have no retransmittable packets on the wire
-// (after sending the first retransmittable packet) if
-// |migrate_session_early_v2_| is true. PING frames will be sent as needed to
-// enforce this.
-const size_t kDefaultRetransmittableOnWireTimeoutMillisecs = 100;
-
 // Histograms for tracking down the crashes from http://crbug.com/354669
 // Note: these values must be kept in sync with the corresponding values in:
 // tools/metrics/histograms/histograms.xml
@@ -684,6 +678,7 @@
     bool migrate_session_early_v2,
     bool migrate_sessions_on_network_change_v2,
     NetworkChangeNotifier::NetworkHandle default_network,
+    quic::QuicTime::Delta retransmittable_on_wire_timeout,
     base::TimeDelta idle_migration_period,
     base::TimeDelta max_time_on_non_default_network,
     int max_migrations_to_non_default_network_on_write_error,
@@ -793,8 +788,7 @@
   connect_timing_.dns_end = dns_resolution_end_time;
   if (migrate_session_early_v2_) {
     connection->set_retransmittable_on_wire_timeout(
-        quic::QuicTime::Delta::FromMilliseconds(
-            kDefaultRetransmittableOnWireTimeoutMillisecs));
+        retransmittable_on_wire_timeout);
   }
 }
 
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h
index 15f6a81..bfcc5f9 100644
--- a/net/quic/quic_chromium_client_session.h
+++ b/net/quic/quic_chromium_client_session.h
@@ -376,6 +376,7 @@
       bool migrate_sesion_early_v2,
       bool migrate_session_on_network_change_v2,
       NetworkChangeNotifier::NetworkHandle default_network,
+      quic::QuicTime::Delta retransmittable_on_wire_timeout,
       base::TimeDelta idle_migration_period,
       base::TimeDelta max_time_on_non_default_network,
       int max_migrations_to_non_default_network_on_write_error,
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index f2cd10e..d3e28d6c 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -163,6 +163,8 @@
         /*require_confirmation=*/false, migrate_session_early_v2_,
         /*migrate_session_on_network_change_v2=*/false,
         /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kDefaultRetransmittableOnWireTimeoutMillisecs),
         base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
         base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
         kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 734c258..1d14ef04 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -324,6 +324,8 @@
         /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
         /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kDefaultRetransmittableOnWireTimeoutMillisecs),
         base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
         base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
         kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index d075d0b..35868a5f 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -213,6 +213,8 @@
         /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
         /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kDefaultRetransmittableOnWireTimeoutMillisecs),
         base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
         base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
         kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index f1728a8..5487152 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -1006,6 +1006,7 @@
     bool mark_quic_broken_when_network_blackholes,
     int idle_connection_timeout_seconds,
     int reduced_ping_timeout_seconds,
+    int retransmittable_on_wire_timeout_milliseconds,
     int max_time_before_crypto_handshake_seconds,
     int max_idle_time_before_crypto_handshake_seconds,
     bool migrate_sessions_on_network_change_v2,
@@ -1056,6 +1057,8 @@
       ping_timeout_(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs)),
       reduced_ping_timeout_(
           quic::QuicTime::Delta::FromSeconds(reduced_ping_timeout_seconds)),
+      retransmittable_on_wire_timeout_(quic::QuicTime::Delta::FromMilliseconds(
+          retransmittable_on_wire_timeout_milliseconds)),
       yield_after_packets_(kQuicYieldAfterPacketsRead),
       yield_after_duration_(quic::QuicTime::Delta::FromMilliseconds(
           kQuicYieldAfterDurationMilliseconds)),
@@ -1825,8 +1828,8 @@
       clock_, transport_security_state_, ssl_config_service_,
       std::move(server_info), key.session_key(), require_confirmation,
       migrate_sessions_early_v2_, migrate_sessions_on_network_change_v2_,
-      default_network_, idle_session_migration_period_,
-      max_time_on_non_default_network_,
+      default_network_, retransmittable_on_wire_timeout_,
+      idle_session_migration_period_, max_time_on_non_default_network_,
       max_migrations_to_non_default_network_on_write_error_,
       max_migrations_to_non_default_network_on_path_degrading_,
       yield_after_packets_, yield_after_duration_, go_away_on_path_degrading_,
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index 9211ad7..bd271be 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -83,6 +83,12 @@
 // Sessions can migrate if they have been idle for less than this period.
 const int kDefaultIdleSessionMigrationPeriodSeconds = 30;
 
+// The maximum time allowed to have no retransmittable packets on the wire
+// (after sending the first retransmittable packet) if
+// |migrate_session_early_v2_| is true. PING frames will be sent as needed to
+// enforce this.
+const int64_t kDefaultRetransmittableOnWireTimeoutMillisecs = 100;
+
 // The default maximum time QUIC session could be on non-default network before
 // migrate back to default network.
 const int64_t kMaxTimeOnNonDefaultNetworkSecs = 128;
@@ -250,6 +256,7 @@
       bool mark_quic_broken_when_network_blackholes,
       int idle_connection_timeout_seconds,
       int reduced_ping_timeout_seconds,
+      int retransmittable_on_wire_timeout_milliseconds_,
       int max_time_before_crypto_handshake_seconds,
       int max_idle_time_before_crypto_handshake_seconds,
       bool migrate_sessions_on_network_change_v2,
@@ -527,6 +534,9 @@
   quic::QuicTime::Delta ping_timeout_;
   quic::QuicTime::Delta reduced_ping_timeout_;
 
+  // Timeout for how long the wire can have no retransmittable packets.
+  quic::QuicTime::Delta retransmittable_on_wire_timeout_;
+
   // If more than |yield_after_packets_| packets have been read or more than
   // |yield_after_duration_| time has passed, then
   // QuicChromiumPacketReader::StartReading() yields by doing a PostTask().
diff --git a/net/quic/quic_stream_factory_fuzzer.cc b/net/quic/quic_stream_factory_fuzzer.cc
index 20ab390..5c741443 100644
--- a/net/quic/quic_stream_factory_fuzzer.cc
+++ b/net/quic/quic_stream_factory_fuzzer.cc
@@ -135,6 +135,7 @@
           goaway_sessions_on_ip_change,
           mark_quic_broken_when_network_blackholes,
           kIdleConnectionTimeoutSeconds, quic::kPingTimeoutSecs,
+          kDefaultRetransmittableOnWireTimeoutMillisecs,
           quic::kMaxTimeForCryptoHandshakeSecs, quic::kInitialIdleTimeoutSecs,
           migrate_sessions_on_network_change_v2, migrate_sessions_early_v2,
           retry_on_alternate_network_before_handshake,
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index 63505fd..87cf7f85 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -276,6 +276,7 @@
         test_params_.mark_quic_broken_when_network_blackholes,
         test_params_.quic_idle_connection_timeout_seconds,
         test_params_.quic_reduced_ping_timeout_seconds,
+        test_params_.quic_retransmittable_on_wire_timeout_milliseconds,
         test_params_.quic_max_time_before_crypto_handshake_seconds,
         test_params_.quic_max_idle_time_before_crypto_handshake_seconds,
         test_params_.quic_migrate_sessions_on_network_change_v2,
@@ -2610,7 +2611,7 @@
 // available):
 // - default network disconnected is delivered: session attempts connection
 //   migration but found not alternate network. Session waits for a new network
-//   comes up in the next kWaitTimeForNewNetworkSecs seonds.
+//   comes up in the next kWaitTimeForNewNetworkSecs seconds.
 // - no new network is connected, migration times out. Session is closed.
 TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
   InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index b63f49d..335c26e 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -329,26 +329,26 @@
                  ConnectJob::Delegate* delegate,
                  MockClientSocketFactory* client_socket_factory,
                  NetLog* net_log)
-      : ConnectJob(
-            request.priority(),
-            timeout_duration,
-            CommonConnectJobParams(
-                group_name,
-                request.socket_tag(),
-                request.respect_limits() ==
-                    ClientSocketPool::RespectLimits::ENABLED,
-                nullptr /* client_socket_factory */,
-                nullptr /* host_resolver */,
-                nullptr /* proxy_delegate */,
-                SSLClientSocketContext(),
-                SSLClientSocketContext(),
-                nullptr /* socket_performance_watcher_factory */,
-                nullptr /* network_quality_estimator */,
-                net_log,
-                nullptr /* websocket_endpoint_lock_manager */),
-            delegate,
-            NetLogWithSource::Make(net_log,
-                                   NetLogSourceType::TRANSPORT_CONNECT_JOB)),
+      : ConnectJob(request.priority(),
+                   timeout_duration,
+                   CommonConnectJobParams(
+                       group_name,
+                       request.socket_tag(),
+                       request.respect_limits() ==
+                           ClientSocketPool::RespectLimits::ENABLED,
+                       nullptr /* client_socket_factory */,
+                       nullptr /* host_resolver */,
+                       nullptr /* proxy_delegate */,
+                       SSLClientSocketContext(),
+                       SSLClientSocketContext(),
+                       nullptr /* socket_performance_watcher_factory */,
+                       nullptr /* network_quality_estimator */,
+                       net_log,
+                       nullptr /* websocket_endpoint_lock_manager */),
+                   delegate,
+                   nullptr /* net_log */,
+                   NetLogSourceType::TRANSPORT_CONNECT_JOB,
+                   NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
         job_type_(job_type),
         client_socket_factory_(client_socket_factory),
         load_state_(LOAD_STATE_IDLE),
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index c49e228..a218d94 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -55,20 +55,35 @@
                        base::TimeDelta timeout_duration,
                        const CommonConnectJobParams& common_connect_job_params,
                        Delegate* delegate,
-                       const NetLogWithSource& net_log)
+                       const NetLogWithSource* net_log,
+                       NetLogSourceType net_log_source_type,
+                       NetLogEventType net_log_connect_event_type)
     : timeout_duration_(timeout_duration),
       priority_(priority),
       common_connect_job_params_(common_connect_job_params),
       delegate_(delegate),
-      net_log_(net_log) {
+      top_level_job_(net_log == nullptr),
+      net_log_(net_log
+                   ? *net_log
+                   : NetLogWithSource::Make(common_connect_job_params.net_log,
+                                            net_log_source_type)),
+      net_log_connect_event_type_(net_log_connect_event_type) {
   DCHECK(delegate);
-  net_log.BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB,
-                     NetLog::StringCallback(
-                         "group_name", &common_connect_job_params.group_name));
+  if (top_level_job_) {
+    net_log_.BeginEvent(
+        NetLogEventType::CONNECT_JOB,
+        NetLog::StringCallback("group_name",
+                               &common_connect_job_params.group_name));
+  }
 }
 
 ConnectJob::~ConnectJob() {
-  net_log().EndEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB);
+  // Log end of Connect event if ConnectJob was still in-progress when
+  // destroyed.
+  if (delegate_)
+    LogConnectCompletion(ERR_ABORTED);
+  if (top_level_job_)
+    net_log().EndEvent(NetLogEventType::CONNECT_JOB);
 }
 
 std::unique_ptr<StreamSocket> ConnectJob::PassSocket() {
@@ -100,10 +115,8 @@
 }
 
 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) {
-  if (socket) {
-    net_log().AddEvent(NetLogEventType::CONNECT_JOB_SET_SOCKET,
-                       socket->NetLog().source().ToEventParametersCallback());
-  }
+  if (socket)
+    net_log().AddEvent(NetLogEventType::CONNECT_JOB_SET_SOCKET);
   socket_ = std::move(socket);
 }
 
@@ -124,20 +137,19 @@
 
 void ConnectJob::LogConnectStart() {
   connect_timing_.connect_start = base::TimeTicks::Now();
-  net_log().BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT);
+  net_log().BeginEvent(net_log_connect_event_type_);
 }
 
 void ConnectJob::LogConnectCompletion(int net_error) {
   connect_timing_.connect_end = base::TimeTicks::Now();
-  net_log().EndEventWithNetErrorCode(
-      NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT, net_error);
+  net_log().EndEventWithNetErrorCode(net_log_connect_event_type_, net_error);
 }
 
 void ConnectJob::OnTimeout() {
   // Make sure the socket is NULL before calling into |delegate|.
   SetSocket(nullptr);
 
-  net_log_.AddEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT);
+  net_log_.AddEvent(NetLogEventType::CONNECT_JOB_TIMED_OUT);
 
   NotifyDelegateOfCompletion(ERR_TIMED_OUT);
 }
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index d8cfac6..34e202b 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -104,14 +104,20 @@
     DISALLOW_COPY_AND_ASSIGN(Delegate);
   };
 
-  // A |timeout_duration| of 0 corresponds to no timeout. |group_name| is a
-  // caller-provided opaque string, only used for logging and the corresponding
-  // accessor.
+  // A |timeout_duration| of 0 corresponds to no timeout.
+  //
+  // If |net_log| is non-NULL, the ConnectJob will use it for logging.
+  // Otherwise, a new one will be created of type |net_log_source_type|.
+  //
+  // |net_log_connect_event_type| is the NetLog event type logged on Connect()
+  // and connect completion.
   ConnectJob(RequestPriority priority,
              base::TimeDelta timeout_duration,
              const CommonConnectJobParams& common_connect_job_params,
              Delegate* delegate,
-             const NetLogWithSource& net_log);
+             const NetLogWithSource* net_log,
+             NetLogSourceType net_log_source_type,
+             NetLogEventType net_log_connect_event_type);
   virtual ~ConnectJob();
 
   // Accessors
@@ -231,7 +237,12 @@
   base::OneShotTimer timer_;
   Delegate* delegate_;
   std::unique_ptr<StreamSocket> socket_;
+  // Indicates if this is the topmost ConnectJob. The topmost ConnectJob logs an
+  // extra begin and end event, to allow callers to log extra data before the
+  // ConnectJob has started / after it has completed.
+  const bool top_level_job_;
   NetLogWithSource net_log_;
+  const NetLogEventType net_log_connect_event_type_;
 
   DISALLOW_COPY_AND_ASSIGN(ConnectJob);
 };
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index 0c03c97..32f5ea9 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -36,25 +36,25 @@
                  base::TimeDelta timeout_duration,
                  ConnectJob::Delegate* delegate,
                  NetLog* net_log)
-      : ConnectJob(
-            DEFAULT_PRIORITY,
-            timeout_duration,
-            CommonConnectJobParams(
-                "group_name",
-                SocketTag(),
-                true /* respect_limits */,
-                nullptr /* client_socket_factory */,
-                nullptr /* host_resolver */,
-                nullptr /* proxy_delegate */,
-                SSLClientSocketContext(),
-                SSLClientSocketContext(),
-                nullptr /* socket_performance_watcher_factory */,
-                nullptr /* network_quality_estimator */,
-                nullptr /* net_log */,
-                nullptr /* websocket_endpoint_lock_manager */),
-            delegate,
-            NetLogWithSource::Make(net_log,
-                                   NetLogSourceType::TRANSPORT_CONNECT_JOB)),
+      : ConnectJob(DEFAULT_PRIORITY,
+                   timeout_duration,
+                   CommonConnectJobParams(
+                       "group_name",
+                       SocketTag(),
+                       true /* respect_limits */,
+                       nullptr /* client_socket_factory */,
+                       nullptr /* host_resolver */,
+                       nullptr /* proxy_delegate */,
+                       SSLClientSocketContext(),
+                       SSLClientSocketContext(),
+                       nullptr /* socket_performance_watcher_factory */,
+                       nullptr /* network_quality_estimator */,
+                       net_log,
+                       nullptr /* websocket_endpoint_lock_manager */),
+                   delegate,
+                   nullptr /* net_log */,
+                   NetLogSourceType::TRANSPORT_CONNECT_JOB,
+                   NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
         job_type_(job_type),
         last_seen_priority_(DEFAULT_PRIORITY) {
     switch (job_type_) {
@@ -181,20 +181,18 @@
   log.GetEntries(&entries);
 
   EXPECT_EQ(6u, entries.size());
-  EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
-                                    NetLogEventType::SOCKET_POOL_CONNECT_JOB));
+  EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
   EXPECT_TRUE(LogContainsBeginEvent(
-      entries, 1, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
+      entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
   EXPECT_TRUE(LogContainsEvent(entries, 2,
                                NetLogEventType::CONNECT_JOB_SET_SOCKET,
                                NetLogEventPhase::NONE));
-  EXPECT_TRUE(LogContainsEvent(
-      entries, 3, NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
-      NetLogEventPhase::NONE));
+  EXPECT_TRUE(LogContainsEvent(entries, 3,
+                               NetLogEventType::CONNECT_JOB_TIMED_OUT,
+                               NetLogEventPhase::NONE));
   EXPECT_TRUE(LogContainsEndEvent(
-      entries, 4, NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT));
-  EXPECT_TRUE(LogContainsEndEvent(entries, 5,
-                                  NetLogEventType::SOCKET_POOL_CONNECT_JOB));
+      entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
+  EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
 }
 
 TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
diff --git a/net/socket/socks_connect_job.cc b/net/socket/socks_connect_job.cc
index 59eb246..8db05f1 100644
--- a/net/socket/socks_connect_job.cc
+++ b/net/socket/socks_connect_job.cc
@@ -38,16 +38,22 @@
     RequestPriority priority,
     const CommonConnectJobParams& common_connect_job_params,
     const scoped_refptr<SOCKSSocketParams>& socks_params,
-    ConnectJob::Delegate* delegate)
+    ConnectJob::Delegate* delegate,
+    const NetLogWithSource* net_log)
     : ConnectJob(priority,
                  ConnectionTimeout(),
                  common_connect_job_params,
                  delegate,
-                 NetLogWithSource::Make(common_connect_job_params.net_log,
-                                        NetLogSourceType::SOCKS_CONNECT_JOB)),
+                 net_log,
+                 NetLogSourceType::SOCKS_CONNECT_JOB,
+                 NetLogEventType::SOCKS_CONNECT_JOB_CONNECT),
       socks_params_(socks_params) {}
 
-SOCKSConnectJob::~SOCKSConnectJob() {}
+SOCKSConnectJob::~SOCKSConnectJob() {
+  // In the case the job was canceled, need to delete nested job first to
+  // correctly order NetLog events.
+  transport_connect_job_.reset();
+}
 
 LoadState SOCKSConnectJob::GetLoadState() const {
   switch (next_state_) {
@@ -124,7 +130,7 @@
   next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
   transport_connect_job_ = TransportConnectJob::CreateTransportConnectJob(
       socks_params_->transport_params(), priority(),
-      common_connect_job_params(), this);
+      common_connect_job_params(), this, &net_log());
   return transport_connect_job_->Connect();
 }
 
diff --git a/net/socket/socks_connect_job.h b/net/socket/socks_connect_job.h
index 919da9d..2807161 100644
--- a/net/socket/socks_connect_job.h
+++ b/net/socket/socks_connect_job.h
@@ -64,7 +64,8 @@
   SOCKSConnectJob(RequestPriority priority,
                   const CommonConnectJobParams& common_connect_job_params,
                   const scoped_refptr<SOCKSSocketParams>& socks_params,
-                  ConnectJob::Delegate* delegate);
+                  ConnectJob::Delegate* delegate,
+                  const NetLogWithSource* net_log);
   ~SOCKSConnectJob() override;
 
   // ConnectJob methods.
diff --git a/net/socket/socks_connect_job_unittest.cc b/net/socket/socks_connect_job_unittest.cc
index df41f3a..497e705 100644
--- a/net/socket/socks_connect_job_unittest.cc
+++ b/net/socket/socks_connect_job_unittest.cc
@@ -95,7 +95,7 @@
     TestConnectJobDelegate test_delegate;
     SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                       CreateSOCKSParams(SOCKSVersion::V5),
-                                      &test_delegate);
+                                      &test_delegate, nullptr /* net_log */);
     test_delegate.StartJobExpectingResult(
         &socks_connect_job, ERR_PROXY_CONNECTION_FAILED, failure_synchronous);
   }
@@ -123,7 +123,7 @@
       TestConnectJobDelegate test_delegate;
       SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V5),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
       test_delegate.StartJobExpectingResult(
           &socks_connect_job, ERR_UNEXPECTED,
           host_resolution_synchronous && write_failure_synchronous);
@@ -156,7 +156,7 @@
       TestConnectJobDelegate test_delegate;
       SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V4),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
       test_delegate.StartJobExpectingResult(
           &socks_connect_job, OK,
           host_resolution_synchronous && read_and_writes_synchronous);
@@ -192,7 +192,7 @@
       TestConnectJobDelegate test_delegate;
       SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V5),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
       test_delegate.StartJobExpectingResult(
           &socks_connect_job, OK,
           host_resolution_synchronous && read_and_writes_synchronous);
@@ -219,7 +219,7 @@
   TestConnectJobDelegate test_delegate;
   SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                     CreateSOCKSParams(SOCKSVersion::V4),
-                                    &test_delegate);
+                                    &test_delegate, nullptr /* net_log */);
   socks_connect_job.Connect();
   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, socks_connect_job.GetLoadState());
   EXPECT_FALSE(socks_connect_job.HasEstablishedConnection());
@@ -249,7 +249,7 @@
   TestConnectJobDelegate test_delegate;
   SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                     CreateSOCKSParams(SOCKSVersion::V5),
-                                    &test_delegate);
+                                    &test_delegate, nullptr /* net_log */);
   socks_connect_job.Connect();
 
   // Just before the TransportConnectJob's timeout, nothing should have
@@ -286,7 +286,7 @@
   TestConnectJobDelegate test_delegate;
   SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                     CreateSOCKSParams(SOCKSVersion::V5),
-                                    &test_delegate);
+                                    &test_delegate, nullptr /* net_log */);
   socks_connect_job.Connect();
 
   // Just before the TransportConnectJob's timeout, nothing should have
@@ -330,7 +330,8 @@
       TestConnectJobDelegate test_delegate;
       SOCKSConnectJob socks_connect_job(
           static_cast<RequestPriority>(initial_priority), CreateCommonParams(),
-          CreateSOCKSParams(SOCKSVersion::V4), &test_delegate);
+          CreateSOCKSParams(SOCKSVersion::V4), &test_delegate,
+          nullptr /* net_log */);
       ASSERT_THAT(socks_connect_job.Connect(), test::IsError(ERR_IO_PENDING));
       ASSERT_TRUE(host_resolver_.has_pending_requests());
       int request_id = host_resolver_.num_resolve();
@@ -375,7 +376,7 @@
   TestConnectJobDelegate test_delegate;
   SOCKSConnectJob socks_connect_job(DEFAULT_PRIORITY, CreateCommonParams(),
                                     CreateSOCKSParams(SOCKSVersion::V5),
-                                    &test_delegate);
+                                    &test_delegate, nullptr /* net_log */);
   base::TimeTicks start = base::TimeTicks::Now();
   socks_connect_job.Connect();
 
@@ -414,7 +415,7 @@
   std::unique_ptr<SOCKSConnectJob> socks_connect_job =
       std::make_unique<SOCKSConnectJob>(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V5),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
   socks_connect_job->Connect();
 
   EXPECT_TRUE(host_resolver_.has_pending_requests());
@@ -437,7 +438,7 @@
   std::unique_ptr<SOCKSConnectJob> socks_connect_job =
       std::make_unique<SOCKSConnectJob>(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V5),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
   socks_connect_job->Connect();
   // Host resolution should resolve immediately. The ConnectJob should currently
   // be trying to connect.
@@ -465,7 +466,7 @@
   std::unique_ptr<SOCKSConnectJob> socks_connect_job =
       std::make_unique<SOCKSConnectJob>(DEFAULT_PRIORITY, CreateCommonParams(),
                                         CreateSOCKSParams(SOCKSVersion::V5),
-                                        &test_delegate);
+                                        &test_delegate, nullptr /* net_log */);
   socks_connect_job->Connect();
   // Host resolution should resolve immediately. The socket connecting, and the
   // ConnectJob should currently be trying to send the SOCKS handshake.
diff --git a/net/socket/ssl_connect_job.cc b/net/socket/ssl_connect_job.cc
index 0da918b..7962ef9 100644
--- a/net/socket/ssl_connect_job.cc
+++ b/net/socket/ssl_connect_job.cc
@@ -96,21 +96,27 @@
     const CommonConnectJobParams& common_connect_job_params,
     const scoped_refptr<SSLSocketParams>& params,
     TransportClientSocketPool* http_proxy_pool,
-    ConnectJob::Delegate* delegate)
+    ConnectJob::Delegate* delegate,
+    const NetLogWithSource* net_log)
     : ConnectJob(priority,
                  ConnectionTimeout(
                      *params,
                      common_connect_job_params.network_quality_estimator),
                  common_connect_job_params,
                  delegate,
-                 NetLogWithSource::Make(common_connect_job_params.net_log,
-                                        NetLogSourceType::SSL_CONNECT_JOB)),
+                 net_log,
+                 NetLogSourceType::SSL_CONNECT_JOB,
+                 NetLogEventType::SSL_CONNECT_JOB_CONNECT),
       params_(params),
       http_proxy_pool_(http_proxy_pool),
       callback_(base::BindRepeating(&SSLConnectJob::OnIOComplete,
                                     base::Unretained(this))) {}
 
-SSLConnectJob::~SSLConnectJob() = default;
+SSLConnectJob::~SSLConnectJob() {
+  // In the case the job was canceled, need to delete nested job first to
+  // correctly order NetLog events.
+  nested_connect_job_.reset();
+}
 
 LoadState SSLConnectJob::GetLoadState() const {
   switch (next_state_) {
@@ -248,7 +254,7 @@
   next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
   nested_connect_job_ = TransportConnectJob::CreateTransportConnectJob(
       params_->GetDirectConnectionParams(), priority(),
-      common_connect_job_params(), this);
+      common_connect_job_params(), this, &net_log());
   return nested_connect_job_->Connect();
 }
 
@@ -276,7 +282,7 @@
   next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
   nested_connect_job_ = std::make_unique<SOCKSConnectJob>(
       priority(), common_connect_job_params(),
-      params_->GetSocksProxyConnectionParams(), this);
+      params_->GetSocksProxyConnectionParams(), this, &net_log());
   return nested_connect_job_->Connect();
 }
 
diff --git a/net/socket/ssl_connect_job.h b/net/socket/ssl_connect_job.h
index 775f68f..8de588d 100644
--- a/net/socket/ssl_connect_job.h
+++ b/net/socket/ssl_connect_job.h
@@ -85,7 +85,8 @@
                 const CommonConnectJobParams& common_connect_job_params,
                 const scoped_refptr<SSLSocketParams>& params,
                 TransportClientSocketPool* http_proxy_pool,
-                ConnectJob::Delegate* delegate);
+                ConnectJob::Delegate* delegate,
+                const NetLogWithSource* net_log);
   ~SSLConnectJob() override;
 
   // ConnectJob methods.
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index fb8740d..fc06def 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -167,7 +167,7 @@
         SSLParams(proxy_scheme),
         proxy_scheme == ProxyServer::SCHEME_HTTP ? &http_proxy_socket_pool_
                                                  : nullptr,
-        test_delegate);
+        test_delegate, nullptr /* net_log */);
   }
 
   scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index da3119d3..2afe9480 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -42,7 +42,7 @@
   DCHECK(!http_proxy_pool_for_ssl_pool);
   return TransportConnectJob::CreateTransportConnectJob(
       std::move(transport_socket_params), priority, common_connect_job_params,
-      delegate);
+      delegate, nullptr /* net_log */);
 }
 
 std::unique_ptr<ConnectJob> CreateSOCKSConnectJob(
@@ -54,7 +54,7 @@
   DCHECK(!http_proxy_pool_for_ssl_pool);
   return std::make_unique<SOCKSConnectJob>(priority, common_connect_job_params,
                                            std::move(socks_socket_params),
-                                           delegate);
+                                           delegate, nullptr /* net_log */);
 }
 
 std::unique_ptr<ConnectJob> CreateSSLConnectJob(
@@ -65,7 +65,7 @@
     TransportClientSocketPool* http_proxy_pool_for_ssl_pool) {
   return std::make_unique<SSLConnectJob>(
       priority, common_connect_job_params, std::move(ssl_socket_params),
-      http_proxy_pool_for_ssl_pool, delegate);
+      http_proxy_pool_for_ssl_pool, delegate, nullptr /* net_log */);
 }
 
 std::unique_ptr<ConnectJob> CreateHttpProxyConnectJob(
@@ -77,7 +77,7 @@
   DCHECK(!http_proxy_pool_for_ssl_pool);
   return std::make_unique<HttpProxyConnectJob>(
       priority, common_connect_job_params, std::move(http_proxy_socket_params),
-      delegate);
+      delegate, nullptr /* net_log */);
 }
 
 }  // namespace
diff --git a/net/socket/transport_connect_job.cc b/net/socket/transport_connect_job.cc
index 96b6642..d2d612e 100644
--- a/net/socket/transport_connect_job.cc
+++ b/net/socket/transport_connect_job.cc
@@ -71,28 +71,32 @@
     scoped_refptr<TransportSocketParams> transport_client_params,
     RequestPriority priority,
     const CommonConnectJobParams& common_connect_job_params,
-    ConnectJob::Delegate* delegate) {
+    ConnectJob::Delegate* delegate,
+    const NetLogWithSource* net_log) {
   if (!common_connect_job_params.websocket_endpoint_lock_manager) {
     return std::make_unique<TransportConnectJob>(
-        priority, common_connect_job_params, transport_client_params, delegate);
+        priority, common_connect_job_params, transport_client_params, delegate,
+        net_log);
   }
 
   return std::make_unique<WebSocketTransportConnectJob>(
-      priority, common_connect_job_params, transport_client_params, delegate);
+      priority, common_connect_job_params, transport_client_params, delegate,
+      net_log);
 }
 
 TransportConnectJob::TransportConnectJob(
     RequestPriority priority,
     const CommonConnectJobParams& common_connect_job_params,
     const scoped_refptr<TransportSocketParams>& params,
-    Delegate* delegate)
-    : ConnectJob(
-          priority,
-          ConnectionTimeout(),
-          common_connect_job_params,
-          delegate,
-          NetLogWithSource::Make(common_connect_job_params.net_log,
-                                 NetLogSourceType::TRANSPORT_CONNECT_JOB)),
+    Delegate* delegate,
+    const NetLogWithSource* net_log)
+    : ConnectJob(priority,
+                 ConnectionTimeout(),
+                 common_connect_job_params,
+                 delegate,
+                 net_log,
+                 NetLogSourceType::TRANSPORT_CONNECT_JOB,
+                 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
       params_(params),
       next_state_(STATE_NONE),
       resolve_result_(OK) {
diff --git a/net/socket/transport_connect_job.h b/net/socket/transport_connect_job.h
index 17b1605..ff8af775 100644
--- a/net/socket/transport_connect_job.h
+++ b/net/socket/transport_connect_job.h
@@ -91,12 +91,14 @@
       scoped_refptr<TransportSocketParams> transport_client_params,
       RequestPriority priority,
       const CommonConnectJobParams& common_connect_job_params,
-      ConnectJob::Delegate* delegate);
+      ConnectJob::Delegate* delegate,
+      const NetLogWithSource* net_log);
 
   TransportConnectJob(RequestPriority priority,
                       const CommonConnectJobParams& common_connect_job_params,
                       const scoped_refptr<TransportSocketParams>& params,
-                      Delegate* delegate);
+                      Delegate* delegate,
+                      const NetLogWithSource* net_log);
   ~TransportConnectJob() override;
 
   // ConnectJob methods.
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index 90b4bf3..c74f9cb 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -132,9 +132,9 @@
   for (bool host_resolution_synchronous : {false, true}) {
     host_resolver_.set_synchronous_mode(host_resolution_synchronous);
     TestConnectJobDelegate test_delegate;
-    TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                             DefaultCommonConnectJobParams(),
-                                             DefaultParams(), &test_delegate);
+    TransportConnectJob transport_conect_job(
+        DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+        &test_delegate, nullptr /* net_log */);
     test_delegate.StartJobExpectingResult(&transport_conect_job,
                                           ERR_NAME_NOT_RESOLVED,
                                           host_resolution_synchronous);
@@ -152,9 +152,9 @@
                     MOCK_PENDING_FAILING_CLIENT_SOCKET);
       ClientSocketHandle handle;
       TestConnectJobDelegate test_delegate;
-      TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                               DefaultCommonConnectJobParams(),
-                                               DefaultParams(), &test_delegate);
+      TransportConnectJob transport_conect_job(
+          DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+          &test_delegate, nullptr /* net_log */);
       test_delegate.StartJobExpectingResult(
           &transport_conect_job, ERR_CONNECTION_FAILED,
           host_resolution_synchronous && connection_synchronous);
@@ -172,9 +172,9 @@
               : MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
       ClientSocketHandle handle;
       TestConnectJobDelegate test_delegate;
-      TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                               DefaultCommonConnectJobParams(),
-                                               DefaultParams(), &test_delegate);
+      TransportConnectJob transport_conect_job(
+          DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+          &test_delegate, nullptr /* net_log */);
       test_delegate.StartJobExpectingResult(
           &transport_conect_job, OK,
           host_resolution_synchronous && connection_synchronous);
@@ -199,9 +199,9 @@
                                            std::string());
 
   TestConnectJobDelegate test_delegate;
-  TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                           DefaultCommonConnectJobParams(),
-                                           DefaultParams(), &test_delegate);
+  TransportConnectJob transport_conect_job(
+      DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+      &test_delegate, nullptr /* net_log */);
   test_delegate.StartJobExpectingResult(&transport_conect_job, OK,
                                         false /* expect_sync_result */);
 
@@ -239,9 +239,9 @@
                                            std::string());
 
   TestConnectJobDelegate test_delegate;
-  TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                           DefaultCommonConnectJobParams(),
-                                           DefaultParams(), &test_delegate);
+  TransportConnectJob transport_conect_job(
+      DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+      &test_delegate, nullptr /* net_log */);
   test_delegate.StartJobExpectingResult(&transport_conect_job, OK,
                                         false /* expect_sync_result */);
 
@@ -269,9 +269,9 @@
       kHostName, "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
 
   TestConnectJobDelegate test_delegate;
-  TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                           DefaultCommonConnectJobParams(),
-                                           DefaultParams(), &test_delegate);
+  TransportConnectJob transport_conect_job(
+      DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+      &test_delegate, nullptr /* net_log */);
   test_delegate.StartJobExpectingResult(&transport_conect_job, OK,
                                         false /* expect_sync_result */);
 
@@ -292,9 +292,9 @@
   host_resolver_.rules()->AddIPLiteralRule(kHostName, "1.1.1.1", std::string());
 
   TestConnectJobDelegate test_delegate;
-  TransportConnectJob transport_conect_job(DEFAULT_PRIORITY,
-                                           DefaultCommonConnectJobParams(),
-                                           DefaultParams(), &test_delegate);
+  TransportConnectJob transport_conect_job(
+      DEFAULT_PRIORITY, DefaultCommonConnectJobParams(), DefaultParams(),
+      &test_delegate, nullptr /* net_log */);
   test_delegate.StartJobExpectingResult(&transport_conect_job, OK,
                                         false /* expect_sync_result */);
 
diff --git a/net/socket/websocket_transport_connect_job.cc b/net/socket/websocket_transport_connect_job.cc
index ebe2365..4f9e9be 100644
--- a/net/socket/websocket_transport_connect_job.cc
+++ b/net/socket/websocket_transport_connect_job.cc
@@ -25,14 +25,15 @@
     RequestPriority priority,
     const CommonConnectJobParams& common_connect_job_params,
     const scoped_refptr<TransportSocketParams>& params,
-    Delegate* delegate)
+    Delegate* delegate,
+    const NetLogWithSource* net_log)
     : ConnectJob(priority,
                  TransportConnectJob::ConnectionTimeout(),
                  common_connect_job_params,
                  delegate,
-                 NetLogWithSource::Make(
-                     common_connect_job_params.net_log,
-                     NetLogSourceType::WEB_SOCKET_TRANSPORT_CONNECT_JOB)),
+                 net_log,
+                 NetLogSourceType::WEB_SOCKET_TRANSPORT_CONNECT_JOB,
+                 NetLogEventType::WEB_SOCKET_TRANSPORT_CONNECT_JOB_CONNECT),
       params_(params),
       next_state_(STATE_NONE),
       race_result_(TransportConnectJob::RACE_UNKNOWN),
diff --git a/net/socket/websocket_transport_connect_job.h b/net/socket/websocket_transport_connect_job.h
index b146c35e..57a7660f 100644
--- a/net/socket/websocket_transport_connect_job.h
+++ b/net/socket/websocket_transport_connect_job.h
@@ -41,7 +41,8 @@
       RequestPriority priority,
       const CommonConnectJobParams& common_connect_job_params,
       const scoped_refptr<TransportSocketParams>& params,
-      Delegate* delegate);
+      Delegate* delegate,
+      const NetLogWithSource* net_log);
   ~WebSocketTransportConnectJob() override;
 
   // ConnectJob methods.
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index ebcaea5..154cfc7 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -121,7 +121,8 @@
           nullptr /* socket_performance_watcher_factory */,
           nullptr /* network_quality_estimator */, session_deps->net_log,
           nullptr /* websocket_endpoint_lock_manager */),
-      ssl_params, nullptr /* http_proxy_pool */, &connect_job_delegate);
+      ssl_params, nullptr /* http_proxy_pool */, &connect_job_delegate,
+      nullptr /* net_log */);
   connect_job_delegate.StartJobExpectingResult(&connect_job, OK,
                                                false /* expect_sync_result */);
 
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 5c960a8..e8aad11 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -7053,6 +7053,42 @@
 
 #if BUILDFLAG(ENABLE_REPORTING)
 
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_DontReportIfNetworkNotAccessed) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  GURL request_url = https_test_server.GetURL("/cachetime");
+
+  TestNetworkErrorLoggingService nel_service;
+  TestURLRequestContext context(true);
+  context.set_network_error_logging_service(&nel_service);
+  context.Init();
+
+  // Populate the cache.
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(context.CreateRequest(
+      request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  ASSERT_EQ(1u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error =
+      nel_service.errors()[0];
+  EXPECT_EQ(request_url, error.uri);
+  EXPECT_EQ(200, error.status_code);
+  EXPECT_EQ(OK, error.type);
+
+  request = context.CreateRequest(request_url, DEFAULT_PRIORITY, &d,
+                                  TRAFFIC_ANNOTATION_FOR_TESTS);
+  request->Start();
+  d.RunUntilComplete();
+
+  EXPECT_FALSE(request->response_info().network_accessed);
+  EXPECT_TRUE(request->response_info().was_cached);
+  // No additional NEL report was generated.
+  EXPECT_EQ(1u, nel_service.errors().size());
+}
+
 TEST_F(URLRequestTestHTTP, NetworkErrorLogging_BasicSuccess) {
   EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_test_server.ServeFilesFromSourceDirectory(
@@ -7136,6 +7172,33 @@
   EXPECT_EQ(OK, error2.type);
 }
 
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_RedirectWithoutLocationHeader) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  GURL request_url = https_test_server.GetURL("/308-without-location-header");
+
+  TestNetworkErrorLoggingService nel_service;
+  TestURLRequestContext context(true);
+  context.set_network_error_logging_service(&nel_service);
+  context.Init();
+
+  TestDelegate d;
+  std::unique_ptr<URLRequest> request(context.CreateRequest(
+      request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  ASSERT_EQ(1u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error =
+      nel_service.errors()[0];
+  EXPECT_EQ(request_url, error.uri);
+  EXPECT_EQ(308, error.status_code);
+  // The body of the response was successfully read.
+  EXPECT_EQ(OK, error.type);
+}
+
 TEST_F(URLRequestTestHTTP, NetworkErrorLogging_Auth) {
   EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
@@ -7167,7 +7230,62 @@
   EXPECT_EQ(OK, error2.type);
 }
 
-TEST_F(URLRequestTestHTTP, NetworkErrorLogging_Cancel) {
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_304Response) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  GURL request_url = https_test_server.GetURL("/auth-basic");
+
+  TestNetworkErrorLoggingService nel_service;
+  TestURLRequestContext context(true);
+  context.set_network_error_logging_service(&nel_service);
+  context.Init();
+
+  // populate the cache
+  {
+    TestDelegate d;
+    d.set_credentials(AuthCredentials(kUser, kSecret));
+    std::unique_ptr<URLRequest> r(context.CreateRequest(
+        request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+    r->Start();
+    d.RunUntilComplete();
+  }
+  ASSERT_EQ(2u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error1 =
+      nel_service.errors()[0];
+  EXPECT_EQ(request_url, error1.uri);
+  EXPECT_EQ(401, error1.status_code);
+  EXPECT_EQ(OK, error1.type);
+  const TestNetworkErrorLoggingService::RequestDetails& error2 =
+      nel_service.errors()[1];
+  EXPECT_EQ(request_url, error2.uri);
+  EXPECT_EQ(200, error2.status_code);
+  EXPECT_EQ(OK, error2.type);
+
+  // repeat request with end-to-end validation.  since auth-basic results in a
+  // cachable page, we expect this test to result in a 304.  in which case, the
+  // response should be fetched from the cache.
+  {
+    TestDelegate d;
+    d.set_credentials(AuthCredentials(kUser, kSecret));
+    std::unique_ptr<URLRequest> r(context.CreateRequest(
+        request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+    r->SetLoadFlags(LOAD_VALIDATE_CACHE);
+    r->Start();
+    d.RunUntilComplete();
+
+    // Should be the same cached document.
+    EXPECT_TRUE(r->was_cached());
+  }
+  ASSERT_EQ(3u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error3 =
+      nel_service.errors()[2];
+  EXPECT_EQ(request_url, error3.uri);
+  EXPECT_EQ(304, error3.status_code);
+  EXPECT_EQ(OK, error3.type);
+}
+
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_CancelInResponseStarted) {
   EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_test_server.ServeFilesFromSourceDirectory(
       base::FilePath(kTestFilePath));
@@ -7191,6 +7309,63 @@
       nel_service.errors()[0];
   EXPECT_EQ(request_url, error.uri);
   EXPECT_EQ(200, error.status_code);
+  // Headers were received and the body should have been read but was not.
+  EXPECT_EQ(ERR_ABORTED, error.type);
+}
+
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_CancelOnDataReceived) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  GURL request_url = https_test_server.GetURL("/simple.html");
+
+  TestNetworkErrorLoggingService nel_service;
+  TestURLRequestContext context(true);
+  context.set_network_error_logging_service(&nel_service);
+  context.Init();
+
+  TestDelegate d;
+  d.set_cancel_in_received_data(true);
+  std::unique_ptr<URLRequest> request(context.CreateRequest(
+      request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  ASSERT_EQ(1u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error =
+      nel_service.errors()[0];
+  EXPECT_EQ(request_url, error.uri);
+  EXPECT_EQ(200, error.status_code);
+  // Data was received but the body was not completely read.
+  EXPECT_EQ(ERR_ABORTED, error.type);
+}
+
+TEST_F(URLRequestTestHTTP, NetworkErrorLogging_CancelRedirect) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+  GURL request_url = https_test_server.GetURL("/redirect-test.html");
+
+  TestNetworkErrorLoggingService nel_service;
+  TestURLRequestContext context(true);
+  context.set_network_error_logging_service(&nel_service);
+  context.Init();
+
+  TestDelegate d;
+  d.set_cancel_in_received_redirect(true);
+  std::unique_ptr<URLRequest> request(context.CreateRequest(
+      request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  request->Start();
+  d.RunUntilComplete();
+
+  ASSERT_EQ(1u, nel_service.errors().size());
+  const TestNetworkErrorLoggingService::RequestDetails& error =
+      nel_service.errors()[0];
+  EXPECT_EQ(request_url, error.uri);
+  EXPECT_EQ(302, error.status_code);
+  // A valid HTTP response was received, even though the request was cancelled.
   EXPECT_EQ(OK, error.type);
 }
 
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index ff592fd..647f01c 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -124,6 +124,7 @@
     "desktop_capturer_proxy.h",
     "desktop_display_info.cc",
     "desktop_display_info.h",
+    "desktop_display_info_mac.mm",
     "desktop_environment.h",
     "desktop_environment_options.cc",
     "desktop_environment_options.h",
diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc
index 267134a..359e6e654 100644
--- a/remoting/host/basic_desktop_environment.cc
+++ b/remoting/host/basic_desktop_environment.cc
@@ -90,8 +90,8 @@
 BasicDesktopEnvironment::CreateVideoCapturer() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
-  std::unique_ptr<DesktopCapturerProxy> result(
-      new DesktopCapturerProxy(video_capture_task_runner_));
+  std::unique_ptr<DesktopCapturerProxy> result(new DesktopCapturerProxy(
+      video_capture_task_runner_, client_session_control_));
   result->CreateCapturer(desktop_capture_options());
   return std::move(result);
 }
@@ -102,12 +102,14 @@
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     ui::SystemInputInjectorFactory* system_input_injector_factory,
+    base::WeakPtr<ClientSessionControl> client_session_control,
     const DesktopEnvironmentOptions& options)
     : caller_task_runner_(caller_task_runner),
       video_capture_task_runner_(video_capture_task_runner),
       input_task_runner_(input_task_runner),
       ui_task_runner_(ui_task_runner),
       system_input_injector_factory_(system_input_injector_factory),
+      client_session_control_(client_session_control),
       options_(options) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 #if defined(USE_X11)
diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h
index 21edc6d..1c6f8e2 100644
--- a/remoting/host/basic_desktop_environment.h
+++ b/remoting/host/basic_desktop_environment.h
@@ -58,6 +58,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       ui::SystemInputInjectorFactory* system_input_injector_factory,
+      base::WeakPtr<ClientSessionControl> client_session_control,
       const DesktopEnvironmentOptions& options);
 
   scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner() const {
@@ -110,6 +111,9 @@
   // Passed to InputInjector.
   ui::SystemInputInjectorFactory* system_input_injector_factory_;
 
+  // Used to send messages directly to the client session.
+  base::WeakPtr<ClientSessionControl> client_session_control_;
+
   DesktopEnvironmentOptions options_;
 
   DISALLOW_COPY_AND_ASSIGN(BasicDesktopEnvironment);
diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h
index 8e4eef4..4d5ae53 100644
--- a/remoting/host/chromoting_messages.h
+++ b/remoting/host/chromoting_messages.h
@@ -314,8 +314,10 @@
 IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_CloseFile,
                     uint64_t /* file_id */)
 
-// Requests that the desktop process cancel the currently-being-written file
-// identified by |file_id|, which will be deleted. There is no response message.
+// Requests that the desktop process cancel the file identified by |file_id|.
+// If the file is being written, the partial file will be deleted. If the file
+// is being read, it will be closed. In either case, there is no response
+// message.
 IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_CancelFile,
                     uint64_t /* file_id */)
 
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index fca6646..33508e6 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -550,17 +550,22 @@
   for (int display_id = 0; display_id < displays->video_track_size();
        display_id++) {
     protocol::VideoTrackLayout track = displays->video_track(display_id);
-    int x = track.position_x();
-    int y = track.position_y();
-    min_x = std::min(x, min_x);
-    min_y = std::min(y, min_y);
-    max_x = std::max(x + track.width(), max_x);
-    max_y = std::max(y + track.height(), max_y);
-
     if (dpi_x == 0)
       dpi_x = track.x_dpi();
     if (dpi_y == 0)
       dpi_y = track.y_dpi();
+
+    // The WebRTC desktop only includes displays that match the main display's
+    // DPI. Here, we filter out non-matching displays so that our desktop
+    // geometry matches what WebRTC can handle.
+    if (dpi_x == track.x_dpi() && dpi_y == track.y_dpi()) {
+      int x = track.position_x();
+      int y = track.position_y();
+      min_x = std::min(x, min_x);
+      min_y = std::min(y, min_y);
+      max_x = std::max(x + track.width(), max_x);
+      max_y = std::max(y + track.height(), max_y);
+    }
   }
 
   // Calc desktop scaled geometry (in DIPs)
diff --git a/remoting/host/desktop_capturer_proxy.cc b/remoting/host/desktop_capturer_proxy.cc
index d30fec6..db088a36 100644
--- a/remoting/host/desktop_capturer_proxy.cc
+++ b/remoting/host/desktop_capturer_proxy.cc
@@ -15,6 +15,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "remoting/host/client_session_control.h"
 #include "remoting/proto/control.pb.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
@@ -124,8 +126,12 @@
 }
 
 DesktopCapturerProxy::DesktopCapturerProxy(
-    scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner)
-    : capture_task_runner_(capture_task_runner), weak_factory_(this) {
+    scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
+    base::WeakPtr<ClientSessionControl> client_session_control)
+    : capture_task_runner_(capture_task_runner),
+      client_session_control_(client_session_control),
+      desktop_display_info_(new DesktopDisplayInfo()),
+      weak_factory_(this) {
   core_.reset(new Core(weak_factory_.GetWeakPtr()));
 }
 
@@ -182,8 +188,14 @@
   return false;
 }
 
-bool DesktopCapturerProxy::SelectSource(SourceId id) {
+bool DesktopCapturerProxy::SelectSource(SourceId id_index) {
   DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(desktop_display_info_);
+  SourceId id = -1;
+  if (id_index >= 0 && id_index < desktop_display_info_->NumDisplays()) {
+    DisplayGeometry display = desktop_display_info_->displays()[id_index];
+    id = display.id;
+  }
   capture_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&Core::SelectSource, base::Unretained(core_.get()), id));
@@ -196,6 +208,33 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   callback_->OnCaptureResult(result, std::move(frame));
+
+// On Windows, this is handled in the DesktopSessionAgent.
+// Once WebRTC has a callback with the display geometry, then we can remove
+// this and rely on WebRTC to pass this through the callbacks up to the
+// ClientSession.
+// See https://bugs.chromium.org/p/webrtc/issues/detail?id=10122
+#if !defined(OS_WIN)
+  if (client_session_control_) {
+    auto info = std::make_unique<DesktopDisplayInfo>();
+    info->LoadCurrentDisplayInfo();
+    if (*desktop_display_info_ != *info) {
+      desktop_display_info_ = std::move(info);
+
+      auto layout = std::make_unique<protocol::VideoLayout>();
+      for (auto display : desktop_display_info_->displays()) {
+        protocol::VideoTrackLayout* track = layout->add_video_track();
+        track->set_position_x(display.x);
+        track->set_position_y(display.y);
+        track->set_width(display.width);
+        track->set_height(display.height);
+        track->set_x_dpi(display.dpi);
+        track->set_y_dpi(display.dpi);
+      }
+      client_session_control_->OnDesktopDisplayChanged(std::move(layout));
+    }
+  }
+#endif
 }
 
 }  // namespace remoting
diff --git a/remoting/host/desktop_capturer_proxy.h b/remoting/host/desktop_capturer_proxy.h
index a24294f..eab6fd94b 100644
--- a/remoting/host/desktop_capturer_proxy.h
+++ b/remoting/host/desktop_capturer_proxy.h
@@ -11,6 +11,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
+#include "remoting/host/desktop_display_info.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 
 namespace base {
@@ -23,6 +24,8 @@
 
 namespace remoting {
 
+class ClientSessionControl;
+
 // DesktopCapturerProxy is responsible for calling webrtc::DesktopCapturer on
 // the capturer thread and then returning results to the caller's thread.
 // GetSourceList() and SelectSource() functions are not implemented by this
@@ -30,7 +33,8 @@
 class DesktopCapturerProxy : public webrtc::DesktopCapturer {
  public:
   explicit DesktopCapturerProxy(
-      scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner);
+      scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
+      base::WeakPtr<ClientSessionControl> client_session_control);
   ~DesktopCapturerProxy() override;
 
   // CreateCapturer() should be used if the capturer needs to be created on the
@@ -59,6 +63,14 @@
   scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
   webrtc::DesktopCapturer::Callback* callback_;
 
+  // Used to disconnect the client session.
+  // Note: This cannot be used on Windows because the ClientSession is not in
+  // the same process as the DesktopCapturerProxy.
+  base::WeakPtr<ClientSessionControl> client_session_control_;
+
+  // Contains the most recently gathered info about the desktop displays.
+  std::unique_ptr<DesktopDisplayInfo> desktop_display_info_;
+
   base::WeakPtrFactory<DesktopCapturerProxy> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(DesktopCapturerProxy);
diff --git a/remoting/host/desktop_display_info.cc b/remoting/host/desktop_display_info.cc
index 2529cee..cb72773 100644
--- a/remoting/host/desktop_display_info.cc
+++ b/remoting/host/desktop_display_info.cc
@@ -22,7 +22,8 @@
     for (size_t display = 0; display < displays_.size(); display++) {
       DisplayGeometry this_display = displays_[display];
       DisplayGeometry other_display = other.displays_[display];
-      if (this_display.x != other_display.x ||
+      if (this_display.id != other_display.id ||
+          this_display.x != other_display.x ||
           this_display.y != other_display.y ||
           this_display.width != other_display.width ||
           this_display.height != other_display.height ||
@@ -80,6 +81,7 @@
   displays_.push_back(*display);
 }
 
+#if !defined(OS_MACOSX)
 void DesktopDisplayInfo::LoadCurrentDisplayInfo() {
   displays_.clear();
 
@@ -87,6 +89,7 @@
   BOOL enum_result = TRUE;
   for (int device_index = 0;; ++device_index) {
     DisplayGeometry info;
+    info.id = device_index;
 
     DISPLAY_DEVICE device = {};
     device.cb = sizeof(device);
@@ -118,7 +121,8 @@
     info.bpp = devmode.dmBitsPerPel;
     displays_.push_back(info);
   }
-#endif
+#endif  // OS_WIN
 }
+#endif  // !OS_MACOSX
 
 }  // namespace remoting
diff --git a/remoting/host/desktop_display_info.h b/remoting/host/desktop_display_info.h
index d5cf5f9..4d80197 100644
--- a/remoting/host/desktop_display_info.h
+++ b/remoting/host/desktop_display_info.h
@@ -14,6 +14,7 @@
 namespace remoting {
 
 struct DisplayGeometry {
+  int32_t id;
   int32_t x, y;
   uint32_t width, height;
   uint32_t dpi;     // Number of pixels per logical inch.
diff --git a/remoting/host/desktop_display_info_mac.mm b/remoting/host/desktop_display_info_mac.mm
new file mode 100644
index 0000000..b12319a
--- /dev/null
+++ b/remoting/host/desktop_display_info_mac.mm
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/desktop_display_info.h"
+
+#include <Cocoa/Cocoa.h>
+
+namespace remoting {
+
+constexpr int kDefaultScreenDpi = 96;
+
+void DesktopDisplayInfo::LoadCurrentDisplayInfo() {
+  displays_.clear();
+
+  NSArray* screens = [NSScreen screens];
+  DCHECK(screens);
+
+  // Each display origin is the bottom left corner, so we need to record the
+  // height of the main display (#0) so that we can adjust the origin of
+  // the secondary displays.
+  int main_display_height = 0;
+
+  for (NSUInteger i = 0; i < [screens count]; ++i) {
+    DisplayGeometry info;
+
+    NSScreen* screen = [screens objectAtIndex:i];
+    NSDictionary* device = [screen deviceDescription];
+    CGDirectDisplayID id = static_cast<CGDirectDisplayID>(
+        [[device objectForKey:@"NSScreenNumber"] intValue]);
+    info.id = id;
+
+    float dsf = 1.0f;
+    if ([screen respondsToSelector:@selector(backingScaleFactor)])
+      dsf = [screen backingScaleFactor];
+
+    NSRect bounds = [screen frame];
+    int x = bounds.origin.x;
+    int y = bounds.origin.y;
+    int height = bounds.size.height;
+
+    if (i == 0) {
+      DCHECK(x == 0);
+      DCHECK(y == 0);
+      info.is_default = true;
+      main_display_height = height;
+    } else {
+      info.is_default = false;
+    }
+
+    info.x = x;
+    // Convert origin from lower left to upper left (based on main display).
+    info.y = main_display_height - y - height;
+    info.width = bounds.size.width;
+    info.height = height;
+    info.dpi = (int)(kDefaultScreenDpi * dsf);
+    info.bpp = 24;
+
+    displays_.push_back(info);
+  }
+}
+
+}  // namespace remoting
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc
index 969cb5e..5355cb6 100644
--- a/remoting/host/desktop_session_agent.cc
+++ b/remoting/host/desktop_session_agent.cc
@@ -198,6 +198,12 @@
                           OnExecuteActionRequestEvent)
       IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution,
                           SetScreenResolution)
+      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFile,
+                          &*session_file_operations_handler_,
+                          SessionFileOperationsHandler::ReadFile)
+      IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_ReadFileChunk,
+                          &*session_file_operations_handler_,
+                          SessionFileOperationsHandler::ReadChunk)
       IPC_MESSAGE_FORWARD(ChromotingNetworkDesktopMsg_WriteFile,
                           &*session_file_operations_handler_,
                           SessionFileOperationsHandler::WriteFile)
@@ -386,6 +392,7 @@
     protocol::VideoLayout layout;
     for (auto display : desktop_display_info_->displays()) {
       protocol::VideoTrackLayout* track = layout.add_video_track();
+      track->set_id(display.id);
       track->set_position_x(display.x);
       track->set_position_y(display.y);
       track->set_width(display.width);
@@ -452,6 +459,22 @@
       file_id, std::move(result)));
 }
 
+void DesktopSessionAgent::OnInfoResult(std::uint64_t file_id,
+                                       ResultHandler::InfoResult result) {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+  SendToNetwork(std::make_unique<ChromotingDesktopNetworkMsg_FileInfoResult>(
+      file_id, std::move(result)));
+}
+
+void DesktopSessionAgent::OnDataResult(std::uint64_t file_id,
+                                       ResultHandler::DataResult result) {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+  SendToNetwork(std::make_unique<ChromotingDesktopNetworkMsg_FileDataResult>(
+      file_id, std::move(result)));
+}
+
 mojo::ScopedMessagePipeHandle DesktopSessionAgent::Start(
     const base::WeakPtr<Delegate>& delegate) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h
index 94d8ba4..34d8ab5 100644
--- a/remoting/host/desktop_session_agent.h
+++ b/remoting/host/desktop_session_agent.h
@@ -106,6 +106,10 @@
 
   // IpcFileOperations::ResultHandler implementation.
   void OnResult(std::uint64_t file_id, ResultHandler::Result result) override;
+  void OnInfoResult(std::uint64_t file_id,
+                    ResultHandler::InfoResult result) override;
+  void OnDataResult(std::uint64_t file_id,
+                    ResultHandler::DataResult result) override;
 
   // Creates desktop integration components and a connected IPC channel to be
   // used to access them. The client end of the channel is returned.
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index 133bd72..598eb29 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -215,6 +215,12 @@
     IPC_MESSAGE_FORWARD(ChromotingDesktopNetworkMsg_FileResult,
                         &ipc_file_operations_factory_,
                         IpcFileOperations::ResultHandler::OnResult)
+    IPC_MESSAGE_FORWARD(ChromotingDesktopNetworkMsg_FileInfoResult,
+                        &ipc_file_operations_factory_,
+                        IpcFileOperations::ResultHandler::OnInfoResult)
+    IPC_MESSAGE_FORWARD(ChromotingDesktopNetworkMsg_FileDataResult,
+                        &ipc_file_operations_factory_,
+                        IpcFileOperations::ResultHandler::OnDataResult)
   IPC_END_MESSAGE_MAP()
 
   CHECK(handled) << "Received unexpected IPC type: " << message.type();
@@ -434,6 +440,18 @@
   SendToDesktop(new ChromotingNetworkDesktopMsg_ExecuteActionRequest(request));
 }
 
+void DesktopSessionProxy::ReadFile(std::uint64_t file_id) {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+  SendToDesktop(new ChromotingNetworkDesktopMsg_ReadFile(file_id));
+}
+
+void DesktopSessionProxy::ReadChunk(std::uint64_t file_id, std::uint64_t size) {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+  SendToDesktop(new ChromotingNetworkDesktopMsg_ReadFileChunk(file_id, size));
+}
+
 void DesktopSessionProxy::WriteFile(uint64_t file_id,
                                     const base::FilePath& filename) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h
index ccaa367..0df547b 100644
--- a/remoting/host/desktop_session_proxy.h
+++ b/remoting/host/desktop_session_proxy.h
@@ -143,6 +143,8 @@
   void ExecuteAction(const protocol::ActionRequest& request);
 
   // IpcFileOperations::RequestHandler implementation.
+  void ReadFile(std::uint64_t file_id) override;
+  void ReadChunk(std::uint64_t file_id, std::uint64_t size) override;
   void WriteFile(std::uint64_t file_id,
                  const base::FilePath& filename) override;
   void WriteChunk(std::uint64_t file_id, std::string data) override;
diff --git a/remoting/host/fake_desktop_environment.cc b/remoting/host/fake_desktop_environment.cc
index 5aca053..88fd127 100644
--- a/remoting/host/fake_desktop_environment.cc
+++ b/remoting/host/fake_desktop_environment.cc
@@ -90,7 +90,7 @@
     fake_capturer->set_frame_generator(frame_generator_);
 
   std::unique_ptr<DesktopCapturerProxy> result(
-      new DesktopCapturerProxy(capture_thread_));
+      new DesktopCapturerProxy(capture_thread_, nullptr));
   result->set_capturer(std::move(fake_capturer));
   return std::move(result);
 }
diff --git a/remoting/host/file_transfer/BUILD.gn b/remoting/host/file_transfer/BUILD.gn
index f542c47..ffaaa0b 100644
--- a/remoting/host/file_transfer/BUILD.gn
+++ b/remoting/host/file_transfer/BUILD.gn
@@ -90,6 +90,7 @@
   sources = [
     "buffered_file_writer_unittest.cc",
     "file_transfer_message_handler_unittest.cc",
+    "ipc_file_operations_unittest.cc",
     "local_file_operations_unittest.cc",
   ]
 
diff --git a/remoting/host/file_transfer/ipc_file_operations.cc b/remoting/host/file_transfer/ipc_file_operations.cc
index e5cccd4..e325cf75 100644
--- a/remoting/host/file_transfer/ipc_file_operations.cc
+++ b/remoting/host/file_transfer/ipc_file_operations.cc
@@ -8,12 +8,38 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/files/file_path.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "remoting/protocol/file_transfer_helpers.h"
 
 namespace remoting {
 
+class IpcFileOperations::IpcReader : public FileOperations::Reader {
+ public:
+  IpcReader(std::uint64_t file_id, base::WeakPtr<SharedState> shared_state);
+  ~IpcReader() override;
+
+  // FileOperations::Reader implementation.
+  void Open(OpenCallback callback) override;
+  void ReadChunk(std::size_t size, ReadCallback callback) override;
+  const base::FilePath& filename() const override;
+  std::uint64_t size() const override;
+  State state() const override;
+
+ private:
+  void OnOpenResult(OpenCallback callback, ResultHandler::InfoResult result);
+  void OnReadResult(ReadCallback callback, ResultHandler::DataResult result);
+
+  State state_ = kCreated;
+  std::uint64_t file_id_;
+  base::FilePath filename_;
+  std::uint64_t size_ = 0;
+  base::WeakPtr<SharedState> shared_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(IpcReader);
+};
+
 class IpcFileOperations::IpcWriter : public FileOperations::Writer {
  public:
   IpcWriter(std::uint64_t file_id, base::WeakPtr<SharedState> shared_state);
@@ -36,29 +62,65 @@
   DISALLOW_COPY_AND_ASSIGN(IpcWriter);
 };
 
+IpcFileOperations::IpcFileOperations(base::WeakPtr<SharedState> shared_state)
+    : shared_state_(std::move(shared_state)) {}
+
 IpcFileOperations::~IpcFileOperations() = default;
 
 std::unique_ptr<FileOperations::Reader> IpcFileOperations::CreateReader() {
-  NOTIMPLEMENTED();
-  return nullptr;
+  return std::make_unique<IpcReader>(GetNextFileId(), shared_state_);
 }
 
 std::unique_ptr<FileOperations::Writer> IpcFileOperations::CreateWriter() {
+  return std::make_unique<IpcWriter>(GetNextFileId(), shared_state_);
+}
+
+std::uint64_t IpcFileOperations::GetNextFileId() {
   // If shared_state_ is invalid, it means the connection is being torn down.
-  // We can still return an IpcWriter, it just won't do anything due to its own
-  // checks of shared_state_. That should be okay, because our caller should be
-  // torn down soon, too.
-  std::uint64_t file_id = shared_state_ ? shared_state_->next_file_id++ : 0;
-  return std::make_unique<IpcWriter>(file_id, shared_state_);
+  // Using a dummy id is okay in that case, as the IpcReader/IpcWriter won't
+  // actually do anything with an invalid shared_state_, and our call should be
+  // torn down soon, as well.
+  return shared_state_ ? shared_state_->next_file_id++ : 0;
 }
 
 IpcFileOperations::SharedState::SharedState(RequestHandler* request_handler)
     : request_handler(request_handler), weak_ptr_factory(this) {}
 
-IpcFileOperations::SharedState::~SharedState() = default;
+void IpcFileOperations::SharedState::Abort(std::uint64_t file_id) {
+  request_handler->Cancel(file_id);
 
-IpcFileOperations::IpcFileOperations(base::WeakPtr<SharedState> shared_state)
-    : shared_state_(std::move(shared_state)) {}
+  protocol::FileTransfer_Error error = protocol::MakeFileTransferError(
+      FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR);
+
+  // Any given file_id is expected to have at most one callback at a time, so
+  // the order in which we search the maps is arbitrary.
+
+  auto callback_iter = result_callbacks.find(file_id);
+  if (callback_iter != result_callbacks.end()) {
+    IpcFileOperations::ResultCallback callback =
+        std::move(callback_iter->second);
+    result_callbacks.erase(callback_iter);
+    std::move(callback).Run(error);
+  }
+
+  auto info_callback_iter = info_result_callbacks.find(file_id);
+  if (info_callback_iter != info_result_callbacks.end()) {
+    IpcFileOperations::InfoResultCallback info_callback =
+        std::move(info_callback_iter->second);
+    info_result_callbacks.erase(info_callback_iter);
+    std::move(info_callback).Run(error);
+  }
+
+  auto data_callback_iter = data_result_callbacks.find(file_id);
+  if (data_callback_iter != data_result_callbacks.end()) {
+    IpcFileOperations::DataResultCallback data_callback =
+        std::move(data_callback_iter->second);
+    data_result_callbacks.erase(data_callback_iter);
+    std::move(data_callback).Run(error);
+  }
+}
+
+IpcFileOperations::SharedState::~SharedState() = default;
 
 IpcFileOperationsFactory::IpcFileOperationsFactory(
     IpcFileOperations::RequestHandler* request_handler)
@@ -74,12 +136,136 @@
 
 void IpcFileOperationsFactory::OnResult(uint64_t file_id, Result result) {
   auto callback_iter = shared_state_.result_callbacks.find(file_id);
-  if (callback_iter != shared_state_.result_callbacks.end()) {
-    IpcFileOperations::ResultCallback callback =
-        std::move(callback_iter->second);
-    shared_state_.result_callbacks.erase(callback_iter);
-    std::move(callback).Run(std::move(result));
+  if (callback_iter == shared_state_.result_callbacks.end()) {
+    shared_state_.Abort(file_id);
+    return;
   }
+
+  IpcFileOperations::ResultCallback callback = std::move(callback_iter->second);
+  shared_state_.result_callbacks.erase(callback_iter);
+  std::move(callback).Run(std::move(result));
+}
+
+void IpcFileOperationsFactory::OnInfoResult(std::uint64_t file_id,
+                                            InfoResult result) {
+  auto callback_iter = shared_state_.info_result_callbacks.find(file_id);
+  if (callback_iter == shared_state_.info_result_callbacks.end()) {
+    shared_state_.Abort(file_id);
+    return;
+  }
+
+  IpcFileOperations::InfoResultCallback callback =
+      std::move(callback_iter->second);
+  shared_state_.info_result_callbacks.erase(callback_iter);
+  std::move(callback).Run(std::move(result));
+}
+
+void IpcFileOperationsFactory::OnDataResult(std::uint64_t file_id,
+                                            DataResult result) {
+  auto callback_iter = shared_state_.data_result_callbacks.find(file_id);
+  if (callback_iter == shared_state_.data_result_callbacks.end()) {
+    shared_state_.Abort(file_id);
+    return;
+  }
+
+  IpcFileOperations::DataResultCallback callback =
+      std::move(callback_iter->second);
+  shared_state_.data_result_callbacks.erase(callback_iter);
+  std::move(callback).Run(std::move(result));
+}
+
+IpcFileOperations::IpcReader::IpcReader(std::uint64_t file_id,
+                                        base::WeakPtr<SharedState> shared_state)
+    : file_id_(file_id), shared_state_(std::move(shared_state)) {}
+
+IpcFileOperations::IpcReader::~IpcReader() {
+  if (!shared_state_ || state_ == kCreated || state_ == kComplete ||
+      state_ == kFailed) {
+    return;
+  }
+
+  shared_state_->request_handler->Cancel(file_id_);
+
+  // Destroy any pending callbacks.
+  auto info_callback_iter = shared_state_->info_result_callbacks.find(file_id_);
+  if (info_callback_iter != shared_state_->info_result_callbacks.end()) {
+    shared_state_->info_result_callbacks.erase(info_callback_iter);
+  }
+
+  auto data_callback_iter = shared_state_->data_result_callbacks.find(file_id_);
+  if (data_callback_iter != shared_state_->data_result_callbacks.end()) {
+    shared_state_->data_result_callbacks.erase(data_callback_iter);
+  }
+}
+
+void IpcFileOperations::IpcReader::Open(OpenCallback callback) {
+  DCHECK_EQ(kCreated, state_);
+  if (!shared_state_) {
+    return;
+  }
+
+  state_ = kBusy;
+  // Unretained is sound because we destroy any pending callbacks in our
+  // destructor.
+  shared_state_->info_result_callbacks.emplace(
+      file_id_, base::BindOnce(&IpcReader::OnOpenResult, base::Unretained(this),
+                               std::move(callback)));
+  shared_state_->request_handler->ReadFile(file_id_);
+}
+
+void IpcFileOperations::IpcReader::ReadChunk(
+    std::size_t size,
+    FileOperations::Reader::ReadCallback callback) {
+  DCHECK_EQ(kReady, state_);
+  if (!shared_state_) {
+    return;
+  }
+
+  state_ = kBusy;
+  // Unretained is sound because we destroy any pending callbacks in our
+  // destructor.
+  shared_state_->data_result_callbacks.emplace(
+      file_id_, base::BindOnce(&IpcReader::OnReadResult, base::Unretained(this),
+                               std::move(callback)));
+  shared_state_->request_handler->ReadChunk(file_id_, size);
+}
+
+const base::FilePath& IpcFileOperations::IpcReader::filename() const {
+  return filename_;
+}
+
+std::uint64_t IpcFileOperations::IpcReader::size() const {
+  return size_;
+}
+
+FileOperations::State IpcFileOperations::IpcReader::state() const {
+  return state_;
+}
+
+void IpcFileOperations::IpcReader::OnOpenResult(
+    OpenCallback callback,
+    ResultHandler::InfoResult result) {
+  if (!result) {
+    state_ = kFailed;
+    std::move(callback).Run(result.error());
+    return;
+  }
+
+  state_ = kReady;
+  filename_ = std::move(std::get<0>(*result));
+  size_ = std::move(std::get<1>(*result));
+  std::move(callback).Run(kSuccessTag);
+}
+
+void IpcFileOperations::IpcReader::OnReadResult(
+    ReadCallback callback,
+    ResultHandler::DataResult result) {
+  if (result) {
+    state_ = result->size() == 0 ? kComplete : kReady;
+  } else {
+    state_ = kFailed;
+  }
+  std::move(callback).Run(std::move(result));
 }
 
 IpcFileOperations::IpcWriter::IpcWriter(std::uint64_t file_id,
@@ -123,12 +309,12 @@
   }
 
   state_ = kBusy;
-  shared_state_->request_handler->WriteChunk(file_id_, data);
   // Unretained is sound because IpcWriter will destroy any outstanding callback
   // in its destructor.
   shared_state_->result_callbacks.emplace(
       file_id_, base::BindOnce(&IpcWriter::OnOperationResult,
                                base::Unretained(this), std::move(callback)));
+  shared_state_->request_handler->WriteChunk(file_id_, data);
 }
 
 void IpcFileOperations::IpcWriter::Close(Callback callback) {
diff --git a/remoting/host/file_transfer/ipc_file_operations.h b/remoting/host/file_transfer/ipc_file_operations.h
index e0f6e3ac..44f998f 100644
--- a/remoting/host/file_transfer/ipc_file_operations.h
+++ b/remoting/host/file_transfer/ipc_file_operations.h
@@ -6,6 +6,8 @@
 #define REMOTING_HOST_FILE_TRANSFER_IPC_FILE_OPERATIONS_H_
 
 #include <cstdint>
+#include <string>
+#include <tuple>
 
 #include "base/containers/flat_map.h"
 #include "base/memory/weak_ptr.h"
@@ -28,6 +30,8 @@
    public:
     virtual ~RequestHandler() = default;
 
+    virtual void ReadFile(std::uint64_t file_id) = 0;
+    virtual void ReadChunk(std::uint64_t file_id, std::uint64_t size) = 0;
     virtual void WriteFile(std::uint64_t file_id,
                            const base::FilePath& filename) = 0;
     virtual void WriteChunk(std::uint64_t file_id, std::string data) = 0;
@@ -39,9 +43,14 @@
   class ResultHandler {
    public:
     using Result = protocol::FileTransferResult<Monostate>;
+    using InfoResult =
+        protocol::FileTransferResult<std::tuple<base::FilePath, uint64_t>>;
+    using DataResult = remoting::protocol::FileTransferResult<std::string>;
 
     virtual ~ResultHandler() = default;
     virtual void OnResult(std::uint64_t file_id, Result result) = 0;
+    virtual void OnInfoResult(std::uint64_t file_id, InfoResult result) = 0;
+    virtual void OnDataResult(std::uint64_t file_id, DataResult result) = 0;
   };
 
   ~IpcFileOperations() override;
@@ -52,7 +61,12 @@
 
  private:
   using ResultCallback = base::OnceCallback<void(ResultHandler::Result)>;
+  using InfoResultCallback =
+      base::OnceCallback<void(ResultHandler::InfoResult)>;
+  using DataResultCallback =
+      base::OnceCallback<void(ResultHandler::DataResult)>;
 
+  class IpcReader;
   class IpcWriter;
 
   struct SharedState {
@@ -60,12 +74,19 @@
     explicit SharedState(RequestHandler* request_handler);
     ~SharedState();
 
+    // Send a Cancel request for |file_id| and provide an error response to any
+    // pending response callbacks for it. Called in the event of an unexpected
+    // message from the Desktop process.
+    void Abort(std::uint64_t file_id);
+
     // File ID to use for the next file opened.
     std::uint64_t next_file_id = 0;
 
     // Pending callbacks awaiting responses from the desktop process, keyed by
     // the file_id of the waiting Reader or Writer.
     base::flat_map<std::uint64_t, ResultCallback> result_callbacks;
+    base::flat_map<std::uint64_t, InfoResultCallback> info_result_callbacks;
+    base::flat_map<std::uint64_t, DataResultCallback> data_result_callbacks;
 
     // The associated RequestHandler.
     RequestHandler* request_handler;
@@ -78,6 +99,8 @@
 
   explicit IpcFileOperations(base::WeakPtr<SharedState> shared_state);
 
+  std::uint64_t GetNextFileId();
+
   // Contains shared state used by all instances tied to a given
   // RequestHandler.
   base::WeakPtr<SharedState> shared_state_;
@@ -101,6 +124,8 @@
 
   // ResultHandler implementation.
   void OnResult(std::uint64_t file_id, Result result) override;
+  void OnInfoResult(std::uint64_t file_id, InfoResult result) override;
+  void OnDataResult(std::uint64_t file_id, DataResult result) override;
 
  private:
   IpcFileOperations::SharedState shared_state_;
diff --git a/remoting/host/file_transfer/ipc_file_operations_unittest.cc b/remoting/host/file_transfer/ipc_file_operations_unittest.cc
new file mode 100644
index 0000000..7a99c24
--- /dev/null
+++ b/remoting/host/file_transfer/ipc_file_operations_unittest.cc
@@ -0,0 +1,369 @@
+// 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 "remoting/host/file_transfer/ipc_file_operations.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/containers/queue.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/test/scoped_path_override.h"
+#include "base/test/scoped_task_environment.h"
+#include "remoting/host/file_transfer/fake_file_chooser.h"
+#include "remoting/host/file_transfer/local_file_operations.h"
+#include "remoting/host/file_transfer/session_file_operations_handler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+
+namespace {
+
+// BindOnce disallows binding lambdas with captures. This is reasonable in
+// production code, as it requires one to either explicitly pass owned objects
+// or pointers using Owned, Unretained, et cetera. This helps to avoid use after
+// free bugs in async code. In test code, though, where the lambda is
+// immediately invoked in the test method using, e.g., RunUntilIdle, the ability
+// to capture can make the code much easier to read and write.
+template <typename T>
+auto BindLambda(T lambda) {
+  return base::BindOnce(&T::operator(),
+                        base::Owned(new auto(std::move(lambda))));
+}
+
+class IpcTestBridge : public IpcFileOperations::RequestHandler,
+                      public IpcFileOperations::ResultHandler,
+                      public FileOperations {
+ public:
+  explicit IpcTestBridge(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner)
+      : ipc_file_operations_factory_(this),
+        session_file_operations_handler_(
+            this,
+            std::make_unique<LocalFileOperations>(std::move(ui_task_runner))),
+        file_operations_(ipc_file_operations_factory_.CreateFileOperations()) {}
+
+  ~IpcTestBridge() override = default;
+
+  // IpcFileOperations::RequestHandler implementation.
+  void ReadFile(std::uint64_t file_id) override {
+    session_file_operations_handler_.ReadFile(file_id);
+  }
+  void ReadChunk(std::uint64_t file_id, std::uint64_t size) override {
+    session_file_operations_handler_.ReadChunk(file_id, size);
+  }
+  void WriteFile(std::uint64_t file_id,
+                 const base::FilePath& filename) override {
+    session_file_operations_handler_.WriteFile(file_id, filename);
+  }
+  void WriteChunk(std::uint64_t file_id, std::string data) override {
+    session_file_operations_handler_.WriteChunk(file_id, std::move(data));
+  }
+  void Close(std::uint64_t file_id) override {
+    session_file_operations_handler_.Close(file_id);
+  }
+  void Cancel(std::uint64_t file_id) override {
+    session_file_operations_handler_.Cancel(file_id);
+  }
+
+  // ResultHandler implementation.
+  void OnResult(std::uint64_t file_id, Result result) override {
+    ipc_file_operations_factory_.OnResult(file_id, std::move(result));
+  }
+  void OnInfoResult(std::uint64_t file_id, InfoResult result) override {
+    ipc_file_operations_factory_.OnInfoResult(file_id, std::move(result));
+  }
+  void OnDataResult(std::uint64_t file_id, DataResult result) override {
+    ipc_file_operations_factory_.OnDataResult(file_id, std::move(result));
+  }
+
+  // FileOperations implementation.
+  std::unique_ptr<Reader> CreateReader() override {
+    return file_operations_->CreateReader();
+  }
+  std::unique_ptr<Writer> CreateWriter() override {
+    return file_operations_->CreateWriter();
+  }
+
+ private:
+  IpcFileOperationsFactory ipc_file_operations_factory_;
+  SessionFileOperationsHandler session_file_operations_handler_;
+  std::unique_ptr<FileOperations> file_operations_;
+
+  DISALLOW_COPY_AND_ASSIGN(IpcTestBridge);
+};
+
+}  // namespace
+
+class IpcFileOperationsTest : public testing::Test {
+ public:
+  IpcFileOperationsTest();
+  ~IpcFileOperationsTest() override;
+
+ protected:
+  const base::FilePath kTestFilename =
+      base::FilePath::FromUTF8Unsafe("test-file.txt");
+  const std::string kTestDataOne = "this is the first test string";
+  const std::string kTestDataTwo = "this is the second test string";
+  const std::string kTestDataThree = "this is the third test string";
+
+  base::FilePath TestDir();
+
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+  base::ScopedPathOverride scoped_path_override_;
+  std::unique_ptr<FileOperations> file_operations_;
+
+  DISALLOW_COPY_AND_ASSIGN(IpcFileOperationsTest);
+};
+
+IpcFileOperationsTest::IpcFileOperationsTest()
+    : scoped_task_environment_(
+          base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
+          base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED),
+      // Points DIR_USER_DESKTOP at a scoped temporary directory.
+      scoped_path_override_(base::DIR_USER_DESKTOP),
+      file_operations_(std::make_unique<IpcTestBridge>(
+          scoped_task_environment_.GetMainThreadTaskRunner())) {}
+
+IpcFileOperationsTest::~IpcFileOperationsTest() = default;
+
+base::FilePath IpcFileOperationsTest::TestDir() {
+  base::FilePath result;
+  EXPECT_TRUE(base::PathService::Get(base::DIR_USER_DESKTOP, &result));
+  return result;
+}
+
+// Verifies that a file consisting of three chunks can be written successfully.
+TEST_F(IpcFileOperationsTest, WritesThreeChunks) {
+  std::unique_ptr<FileOperations::Writer> writer =
+      file_operations_->CreateWriter();
+  ASSERT_EQ(FileOperations::kCreated, writer->state());
+
+  base::Optional<FileOperations::Writer::Result> open_result;
+  writer->Open(kTestFilename,
+               BindLambda([&](FileOperations::Writer::Result result) {
+                 open_result = std::move(result);
+               }));
+  ASSERT_EQ(FileOperations::kBusy, writer->state());
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_EQ(FileOperations::kReady, writer->state());
+  ASSERT_TRUE(open_result);
+  ASSERT_TRUE(*open_result);
+
+  for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
+    base::Optional<FileOperations::Writer::Result> write_result;
+    writer->WriteChunk(chunk,
+                       BindLambda([&](FileOperations::Writer::Result result) {
+                         write_result = std::move(result);
+                       }));
+    ASSERT_EQ(FileOperations::kBusy, writer->state());
+    scoped_task_environment_.RunUntilIdle();
+    ASSERT_EQ(FileOperations::kReady, writer->state());
+    ASSERT_TRUE(write_result);
+    ASSERT_TRUE(*write_result);
+  }
+
+  base::Optional<FileOperations::Writer::Result> close_result;
+  writer->Close(BindLambda([&](FileOperations::Writer::Result result) {
+    close_result = std::move(result);
+  }));
+  ASSERT_EQ(FileOperations::kBusy, writer->state());
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(FileOperations::kComplete, writer->state());
+
+  std::string actual_file_data;
+  ASSERT_TRUE(base::ReadFileToString(TestDir().Append(kTestFilename),
+                                     &actual_file_data));
+  EXPECT_EQ(kTestDataOne + kTestDataTwo + kTestDataThree, actual_file_data);
+}
+
+// Verifies that dropping early cancels the remote writer.
+TEST_F(IpcFileOperationsTest, DroppingCancelsRemote) {
+  std::unique_ptr<FileOperations::Writer> writer =
+      file_operations_->CreateWriter();
+
+  base::Optional<FileOperations::Writer::Result> open_result;
+  writer->Open(kTestFilename,
+               BindLambda([&](FileOperations::Writer::Result result) {
+                 open_result = std::move(result);
+               }));
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_TRUE(open_result && *open_result);
+
+  for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
+    base::Optional<FileOperations::Writer::Result> write_result;
+    writer->WriteChunk(chunk,
+                       BindLambda([&](FileOperations::Writer::Result result) {
+                         write_result = std::move(result);
+                       }));
+    scoped_task_environment_.RunUntilIdle();
+    ASSERT_TRUE(write_result && *write_result);
+  }
+
+  writer.reset();
+  scoped_task_environment_.RunUntilIdle();
+
+  EXPECT_TRUE(base::IsDirectoryEmpty(TestDir()));
+}
+
+// Verifies that dropping works while an operation is pending.
+TEST_F(IpcFileOperationsTest, CancelsWhileOperationPending) {
+  std::unique_ptr<FileOperations::Writer> writer =
+      file_operations_->CreateWriter();
+
+  base::Optional<FileOperations::Writer::Result> open_result;
+  writer->Open(kTestFilename,
+               BindLambda([&](FileOperations::Writer::Result result) {
+                 open_result = std::move(result);
+               }));
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_TRUE(open_result && *open_result);
+
+  base::Optional<FileOperations::Writer::Result> write_result;
+  writer->WriteChunk(std::string(kTestDataOne),
+                     BindLambda([&](FileOperations::Writer::Result result) {
+                       write_result = std::move(result);
+                     }));
+
+  EXPECT_EQ(FileOperations::kBusy, writer->state());
+  writer.reset();
+  scoped_task_environment_.RunUntilIdle();
+
+  EXPECT_FALSE(write_result);
+  EXPECT_TRUE(base::IsDirectoryEmpty(TestDir()));
+}
+
+// Verifies that a file can be successfully read in three chunks.
+TEST_F(IpcFileOperationsTest, ReadsThreeChunks) {
+  base::FilePath path = TestDir().Append(kTestFilename);
+  std::string contents = kTestDataOne + kTestDataTwo + kTestDataThree;
+  ASSERT_EQ(static_cast<int>(contents.size()),
+            base::WriteFile(path, contents.data(), contents.size()));
+
+  std::unique_ptr<FileOperations::Reader> reader =
+      file_operations_->CreateReader();
+  ASSERT_EQ(FileOperations::kCreated, reader->state());
+
+  FakeFileChooser::SetResult(path);
+  base::Optional<FileOperations::Reader::OpenResult> open_result;
+  reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
+    open_result = std::move(result);
+  }));
+  ASSERT_EQ(FileOperations::kBusy, reader->state());
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(FileOperations::kReady, reader->state());
+  ASSERT_TRUE(open_result);
+  ASSERT_TRUE(*open_result);
+
+  for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
+    base::Optional<FileOperations::Reader::ReadResult> read_result;
+    reader->ReadChunk(
+        chunk.size(),
+        BindLambda([&](FileOperations::Reader::ReadResult result) {
+          read_result = std::move(result);
+        }));
+    ASSERT_EQ(FileOperations::kBusy, reader->state());
+    scoped_task_environment_.RunUntilIdle();
+    ASSERT_EQ(FileOperations::kReady, reader->state());
+    ASSERT_TRUE(read_result);
+    ASSERT_TRUE(*read_result);
+    EXPECT_EQ(chunk, **read_result);
+  }
+}
+
+// Verifies proper EOF handling.
+TEST_F(IpcFileOperationsTest, ReaderHandlesEof) {
+  constexpr std::size_t kOverreadAmount = 5;
+  base::FilePath path = TestDir().Append(kTestFilename);
+  std::string contents = kTestDataOne + kTestDataTwo + kTestDataThree;
+  ASSERT_EQ(static_cast<int>(contents.size()),
+            base::WriteFile(path, contents.data(), contents.size()));
+
+  std::unique_ptr<FileOperations::Reader> reader =
+      file_operations_->CreateReader();
+
+  FakeFileChooser::SetResult(path);
+  base::Optional<FileOperations::Reader::OpenResult> open_result;
+  reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
+    open_result = std::move(result);
+  }));
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_TRUE(open_result && *open_result);
+
+  base::Optional<FileOperations::Reader::ReadResult> read_result;
+  reader->ReadChunk(
+      contents.size() +
+          kOverreadAmount,  // Attempt to read more than is in file.
+      BindLambda([&](FileOperations::Reader::ReadResult result) {
+        read_result = std::move(result);
+      }));
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_EQ(FileOperations::kReady, reader->state());
+  ASSERT_TRUE(read_result);
+  ASSERT_TRUE(*read_result);
+  EXPECT_EQ(contents, **read_result);
+
+  read_result.reset();
+  reader->ReadChunk(kOverreadAmount,
+                    BindLambda([&](FileOperations::Reader::ReadResult result) {
+                      read_result = std::move(result);
+                    }));
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(FileOperations::kComplete, reader->state());
+  ASSERT_TRUE(read_result);
+  ASSERT_TRUE(*read_result);
+  EXPECT_EQ(std::size_t{0}, (*read_result)->size());
+}
+
+// Verifies proper handling of zero-size file
+TEST_F(IpcFileOperationsTest, ReaderHandlesZeroSize) {
+  constexpr std::size_t kChunkSize = 5;
+  base::FilePath path = TestDir().Append(kTestFilename);
+  ASSERT_EQ(0, base::WriteFile(path, "", 0));
+
+  std::unique_ptr<FileOperations::Reader> reader =
+      file_operations_->CreateReader();
+
+  FakeFileChooser::SetResult(path);
+  base::Optional<FileOperations::Reader::OpenResult> open_result;
+  reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
+    open_result = std::move(result);
+  }));
+  scoped_task_environment_.RunUntilIdle();
+  ASSERT_TRUE(open_result && *open_result);
+
+  base::Optional<FileOperations::Reader::ReadResult> read_result;
+  reader->ReadChunk(kChunkSize,
+                    BindLambda([&](FileOperations::Reader::ReadResult result) {
+                      read_result = std::move(result);
+                    }));
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(FileOperations::kComplete, reader->state());
+  ASSERT_TRUE(read_result);
+  ASSERT_TRUE(*read_result);
+  EXPECT_EQ(std::size_t{0}, (*read_result)->size());
+}
+
+// Verifies error is propagated.
+TEST_F(IpcFileOperationsTest, ReaderPropagatesError) {
+  std::unique_ptr<FileOperations::Reader> reader =
+      file_operations_->CreateReader();
+
+  // Currently non-existent file.
+  FakeFileChooser::SetResult(TestDir().Append(kTestFilename));
+  base::Optional<FileOperations::Reader::OpenResult> open_result;
+  reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
+    open_result = std::move(result);
+  }));
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(FileOperations::kFailed, reader->state());
+  ASSERT_TRUE(open_result);
+  ASSERT_FALSE(*open_result);
+}
+
+}  // namespace remoting
diff --git a/remoting/host/file_transfer/session_file_operations_handler.cc b/remoting/host/file_transfer/session_file_operations_handler.cc
index 6afe7db..fae615a 100644
--- a/remoting/host/file_transfer/session_file_operations_handler.cc
+++ b/remoting/host/file_transfer/session_file_operations_handler.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include "remoting/host/file_transfer/session_file_operations_handler.h"
+
 #include "base/bind.h"
+#include "base/files/file_path.h"
 #include "remoting/protocol/file_transfer_helpers.h"
 
 namespace remoting {
@@ -14,6 +16,40 @@
     : result_handler_(result_handler),
       file_operations_(std::move(file_operations)) {}
 
+void SessionFileOperationsHandler::ReadFile(std::uint64_t file_id) {
+  auto location = readers_.emplace(file_id, file_operations_->CreateReader());
+  if (!location.second) {
+    // Strange, we've already received a ReadFile message for this ID. Cancel
+    // it and send an error to be safe.
+    readers_.erase(location.first);
+    result_handler_->OnInfoResult(
+        file_id,
+        protocol::MakeFileTransferError(
+            FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
+    return;
+  }
+  // Unretained is sound because no Reader callbacks will be invoked after the
+  // Writer is destroyed.
+  location.first->second->Open(
+      base::BindOnce(&SessionFileOperationsHandler::OnReaderOpenResult,
+                     base::Unretained(this), file_id));
+}
+
+void SessionFileOperationsHandler::ReadChunk(std::uint64_t file_id,
+                                             std::uint64_t size) {
+  auto reader_iter = readers_.find(file_id);
+  if (reader_iter == readers_.end()) {
+    result_handler_->OnDataResult(
+        file_id,
+        protocol::MakeFileTransferError(
+            FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
+    return;
+  }
+  reader_iter->second->ReadChunk(
+      size, base::BindOnce(&SessionFileOperationsHandler::OnReaderReadResult,
+                           base::Unretained(this), file_id));
+}
+
 void SessionFileOperationsHandler::WriteFile(uint64_t file_id,
                                              const base::FilePath& filename) {
   auto location = writers_.emplace(file_id, file_operations_->CreateWriter());
@@ -30,8 +66,9 @@
   // Unretained is sound because no Writer callbacks will be invoked after the
   // Writer is destroyed.
   location.first->second->Open(
-      filename, base::BindOnce(&SessionFileOperationsHandler::OnOperationResult,
-                               base::Unretained(this), file_id));
+      filename,
+      base::BindOnce(&SessionFileOperationsHandler::OnWriterOperationResult,
+                     base::Unretained(this), file_id));
 }
 
 void SessionFileOperationsHandler::WriteChunk(uint64_t file_id,
@@ -46,37 +83,78 @@
   }
   writer_iter->second->WriteChunk(
       std::move(data),
-      base::BindOnce(&SessionFileOperationsHandler::OnOperationResult,
+      base::BindOnce(&SessionFileOperationsHandler::OnWriterOperationResult,
                      base::Unretained(this), file_id));
 }
 
 void SessionFileOperationsHandler::Close(uint64_t file_id) {
-  auto writer_iter = writers_.find(file_id);
-  if (writer_iter == writers_.end()) {
-    result_handler_->OnResult(
-        file_id,
-        protocol::MakeFileTransferError(
-            FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
+  auto reader_iter = readers_.find(file_id);
+  if (reader_iter != readers_.end()) {
+    readers_.erase(reader_iter);
     return;
   }
-  writer_iter->second->Close(
-      base::BindOnce(&SessionFileOperationsHandler::OnCloseResult,
-                     base::Unretained(this), file_id));
+
+  auto writer_iter = writers_.find(file_id);
+  if (writer_iter != writers_.end()) {
+    writer_iter->second->Close(
+        base::BindOnce(&SessionFileOperationsHandler::OnWriterCloseResult,
+                       base::Unretained(this), file_id));
+    return;
+  }
+
+  // |file_id| is not a known reader or writer. Send an error in case the
+  // network process is waiting for a response.
+  result_handler_->OnResult(
+      file_id,
+      protocol::MakeFileTransferError(
+          FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
 }
 
 void SessionFileOperationsHandler::Cancel(uint64_t file_id) {
+  // It's possible for a cancel request and an error response (from a previous
+  // request) to pass each other in the message pipe, so the lack of a reader or
+  // writer matching |file_id| is not necessarily an error. Since a cancel
+  // request doesn't expect a response, it's fine to do nothing in that case.
+
+  auto reader_iter = readers_.find(file_id);
+  if (reader_iter != readers_.end()) {
+    readers_.erase(reader_iter);
+  }
+
   auto writer_iter = writers_.find(file_id);
-  if (writer_iter == writers_.end()) {
-    // No need to send an error in response to a Cancel request, as it does not
-    // expect a response.
+  if (writer_iter != writers_.end()) {
+    writers_.erase(writer_iter);
+  }
+}
+
+void SessionFileOperationsHandler::OnReaderOpenResult(
+    std::uint64_t file_id,
+    FileOperations::Reader::OpenResult result) {
+  if (!result) {
+    readers_.erase(file_id);
+    result_handler_->OnInfoResult(file_id, std::move(result.error()));
     return;
   }
 
-  // Writer will implicitly Cancel when destroyed.
-  writers_.erase(writer_iter);
+  auto reader_iter = readers_.find(file_id);
+  // Should never get a callback if the reader has been destroyed.
+  DCHECK(reader_iter != readers_.end());
+  result_handler_->OnInfoResult(file_id,
+                                {kSuccessTag, reader_iter->second->filename(),
+                                 reader_iter->second->size()});
 }
 
-void SessionFileOperationsHandler::OnOperationResult(
+void SessionFileOperationsHandler::OnReaderReadResult(
+    std::uint64_t file_id,
+    FileOperations::Reader::ReadResult result) {
+  if (!result || result->size() == 0) {
+    readers_.erase(file_id);
+  }
+
+  result_handler_->OnDataResult(file_id, std::move(result));
+}
+
+void SessionFileOperationsHandler::OnWriterOperationResult(
     uint64_t file_id,
     FileOperations::Writer::Result result) {
   if (!result) {
@@ -85,7 +163,7 @@
   result_handler_->OnResult(file_id, std::move(result));
 }
 
-void SessionFileOperationsHandler::OnCloseResult(
+void SessionFileOperationsHandler::OnWriterCloseResult(
     uint64_t file_id,
     FileOperations::Writer::Result result) {
   writers_.erase(file_id);
diff --git a/remoting/host/file_transfer/session_file_operations_handler.h b/remoting/host/file_transfer/session_file_operations_handler.h
index 3184495..54fd7f6 100644
--- a/remoting/host/file_transfer/session_file_operations_handler.h
+++ b/remoting/host/file_transfer/session_file_operations_handler.h
@@ -26,6 +26,8 @@
   ~SessionFileOperationsHandler() override;
 
   // IpcFileOperations::RequestHandler implementation
+  void ReadFile(std::uint64_t file_id) override;
+  void ReadChunk(std::uint64_t file_id, std::uint64_t size) override;
   void WriteFile(std::uint64_t file_id,
                  const base::FilePath& filename) override;
   void WriteChunk(std::uint64_t file_id, std::string data) override;
@@ -33,15 +35,21 @@
   void Cancel(std::uint64_t file_id) override;
 
  private:
-  void OnOperationResult(std::uint64_t file_id,
-                         FileOperations::Writer::Result result);
-  void OnCloseResult(std::uint64_t file_id,
-                     FileOperations::Writer::Result result);
+  void OnReaderOpenResult(std::uint64_t file_id,
+                          FileOperations::Reader::OpenResult result);
+  void OnReaderReadResult(std::uint64_t file_id,
+                          FileOperations::Reader::ReadResult result);
+  void OnWriterOperationResult(std::uint64_t file_id,
+                               FileOperations::Writer::Result result);
+  void OnWriterCloseResult(std::uint64_t file_id,
+                           FileOperations::Writer::Result result);
 
   IpcFileOperations::ResultHandler* result_handler_;
   std::unique_ptr<FileOperations> file_operations_;
   base::flat_map<std::uint64_t, std::unique_ptr<FileOperations::Writer>>
       writers_;
+  base::flat_map<std::uint64_t, std::unique_ptr<FileOperations::Reader>>
+      readers_;
 };
 
 }  // namespace remoting
diff --git a/remoting/host/it2me_desktop_environment.cc b/remoting/host/it2me_desktop_environment.cc
index 7bd066b..4203732 100644
--- a/remoting/host/it2me_desktop_environment.cc
+++ b/remoting/host/it2me_desktop_environment.cc
@@ -39,6 +39,7 @@
                               input_task_runner,
                               ui_task_runner,
                               system_input_injector_factory,
+                              client_session_control,
                               options) {
   DCHECK(caller_task_runner->BelongsToCurrentThread());
 
diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc
index cb81cd15..49a7060b 100644
--- a/remoting/host/me2me_desktop_environment.cc
+++ b/remoting/host/me2me_desktop_environment.cc
@@ -93,12 +93,14 @@
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     ui::SystemInputInjectorFactory* system_input_injector_factory,
+    base::WeakPtr<ClientSessionControl> client_session_control,
     const DesktopEnvironmentOptions& options)
     : BasicDesktopEnvironment(caller_task_runner,
                               video_capture_task_runner,
                               input_task_runner,
                               ui_task_runner,
                               system_input_injector_factory,
+                              client_session_control,
                               options) {
   DCHECK(caller_task_runner->BelongsToCurrentThread());
 
@@ -189,10 +191,10 @@
   DCHECK(caller_task_runner()->BelongsToCurrentThread());
 
   std::unique_ptr<Me2MeDesktopEnvironment> desktop_environment(
-      new Me2MeDesktopEnvironment(caller_task_runner(),
-                                  video_capture_task_runner(),
-                                  input_task_runner(), ui_task_runner(),
-                                  system_input_injector_factory(), options));
+      new Me2MeDesktopEnvironment(
+          caller_task_runner(), video_capture_task_runner(),
+          input_task_runner(), ui_task_runner(),
+          system_input_injector_factory(), client_session_control, options));
   if (!desktop_environment->InitializeSecurity(client_session_control)) {
     return nullptr;
   }
diff --git a/remoting/host/me2me_desktop_environment.h b/remoting/host/me2me_desktop_environment.h
index fffd28e..df16816b 100644
--- a/remoting/host/me2me_desktop_environment.h
+++ b/remoting/host/me2me_desktop_environment.h
@@ -34,6 +34,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       ui::SystemInputInjectorFactory* system_input_injector_factory,
+      base::WeakPtr<ClientSessionControl> client_session_control,
       const DesktopEnvironmentOptions& options);
 
   // Initializes security features of the desktop environment (the curtain mode
diff --git a/remoting/host/single_window_desktop_environment.cc b/remoting/host/single_window_desktop_environment.cc
index 4a5228e..b85d85e 100644
--- a/remoting/host/single_window_desktop_environment.cc
+++ b/remoting/host/single_window_desktop_environment.cc
@@ -85,6 +85,7 @@
                               input_task_runner,
                               ui_task_runner,
                               system_input_injector_factory,
+                              client_session_control,
                               options),
       window_id_(window_id) {}
 
diff --git a/remoting/host/win/session_desktop_environment.cc b/remoting/host/win/session_desktop_environment.cc
index 1828409..d959749 100644
--- a/remoting/host/win/session_desktop_environment.cc
+++ b/remoting/host/win/session_desktop_environment.cc
@@ -46,6 +46,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     ui::SystemInputInjectorFactory* system_input_injector_factory,
+    base::WeakPtr<ClientSessionControl> client_session_control,
     const base::RepeatingClosure& inject_sas,
     const base::RepeatingClosure& lock_workstation,
     const DesktopEnvironmentOptions& options)
@@ -54,6 +55,7 @@
                               input_task_runner,
                               ui_task_runner,
                               system_input_injector_factory,
+                              client_session_control,
                               options),
       inject_sas_(inject_sas),
       lock_workstation_(lock_workstation) {}
@@ -84,11 +86,11 @@
   DCHECK(caller_task_runner()->BelongsToCurrentThread());
 
   std::unique_ptr<SessionDesktopEnvironment> desktop_environment(
-      new SessionDesktopEnvironment(caller_task_runner(),
-                                    video_capture_task_runner(),
-                                    input_task_runner(), ui_task_runner(),
-                                    system_input_injector_factory(),
-                                    inject_sas_, lock_workstation_, options));
+      new SessionDesktopEnvironment(
+          caller_task_runner(), video_capture_task_runner(),
+          input_task_runner(), ui_task_runner(),
+          system_input_injector_factory(), client_session_control, inject_sas_,
+          lock_workstation_, options));
   if (!desktop_environment->InitializeSecurity(client_session_control)) {
     return nullptr;
   }
diff --git a/remoting/host/win/session_desktop_environment.h b/remoting/host/win/session_desktop_environment.h
index aa0fcf9..226bdc1 100644
--- a/remoting/host/win/session_desktop_environment.h
+++ b/remoting/host/win/session_desktop_environment.h
@@ -32,6 +32,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       ui::SystemInputInjectorFactory* system_input_injector_factory,
+      base::WeakPtr<ClientSessionControl> client_session_control,
       const base::RepeatingClosure& inject_sas,
       const base::RepeatingClosure& lock_workstation,
       const DesktopEnvironmentOptions& options);
diff --git a/remoting/proto/control.proto b/remoting/proto/control.proto
index c020e6a..8829120 100644
--- a/remoting/proto/control.proto
+++ b/remoting/proto/control.proto
@@ -85,6 +85,9 @@
 }
 
 message VideoTrackLayout {
+  // Unique display identifier.
+  optional int32 id = 8;
+
   // Name of the video track.
   optional string track_name = 1;
 
diff --git a/rlz/lib/crc8.h b/rlz/lib/crc8.h
index 6c3c848..2365568 100644
--- a/rlz/lib/crc8.h
+++ b/rlz/lib/crc8.h
@@ -19,6 +19,6 @@
                      unsigned char checksum,
                      bool * matches);
 };
-};  // namespace rlz_lib
+}  // namespace rlz_lib
 
 #endif  // RLZ_LIB_CRC8_H_
diff --git a/rlz/lib/net_response_check.h b/rlz/lib/net_response_check.h
index 67d13ca9..7098da7 100644
--- a/rlz/lib/net_response_check.h
+++ b/rlz/lib/net_response_check.h
@@ -22,6 +22,6 @@
 // Access: No restrictions.
 bool RLZ_LIB_API IsPingResponseValid(const char* response, int* checksum_idx);
 
-};  // namespace rlz_lib
+}  // namespace rlz_lib
 
 #endif  // RLZ_LIB_NET_RESPONSE_CHECK_H_
diff --git a/rlz/lib/string_utils.h b/rlz/lib/string_utils.h
index 0893a6c1..223f854 100644
--- a/rlz/lib/string_utils.h
+++ b/rlz/lib/string_utils.h
@@ -21,6 +21,6 @@
 
 int HexStringToInteger(const char* text);
 
-};  // namespace
+}  // namespace rlz_lib
 
 #endif  // RLZ_LIB_STRING_UTILS_H_
diff --git a/sandbox/mac/seatbelt.cc b/sandbox/mac/seatbelt.cc
index dfba0bd..e0c31170 100644
--- a/sandbox/mac/seatbelt.cc
+++ b/sandbox/mac/seatbelt.cc
@@ -19,7 +19,7 @@
 // 1 if sandboxed. Note `type` is actually a sandbox_filter_type enum value, but
 // it is unused currently.
 int sandbox_check(pid_t pid, const char* operation, int type, ...);
-};
+}
 
 namespace sandbox {
 
diff --git a/sandbox/mac/seatbelt_extension_unittest.cc b/sandbox/mac/seatbelt_extension_unittest.cc
index 6b1744f..2a74688 100644
--- a/sandbox/mac/seatbelt_extension_unittest.cc
+++ b/sandbox/mac/seatbelt_extension_unittest.cc
@@ -134,7 +134,7 @@
   PCHECK(fd.get() > 0);
 
   return 0;
-};
+}
 
 }  // namespace
 }  // namespace sandbox
diff --git a/services/device/geolocation/wifi_data_provider_mac.mm b/services/device/geolocation/wifi_data_provider_mac.mm
index 278a5385..023645f9 100644
--- a/services/device/geolocation/wifi_data_provider_mac.mm
+++ b/services/device/geolocation/wifi_data_provider_mac.mm
@@ -110,7 +110,7 @@
   // one interface did not fail.
   return interface_error_count == 0 ||
          [supported_interfaces count] > interface_error_count;
-};
+}
 
 // The time periods, in milliseconds, between successive polls of the wifi data.
 const int kDefaultPollingInterval = 120000;                // 2 mins
diff --git a/services/tracing/coordinator.cc b/services/tracing/coordinator.cc
index b426897..fecd79da6 100644
--- a/services/tracing/coordinator.cc
+++ b/services/tracing/coordinator.cc
@@ -277,6 +277,7 @@
 Coordinator::Coordinator(AgentRegistry* agent_registry,
                          const base::RepeatingClosure& on_disconnect_callback)
     : task_runner_(base::SequencedTaskRunnerHandle::Get()),
+      agent_registry_(agent_registry),
       on_disconnect_callback_(std::move(on_disconnect_callback)),
       binding_(this),
       // USER_VISIBLE because the task posted from StopAndFlushInternal() is
@@ -287,7 +288,6 @@
       backend_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
           {base::TaskPriority::USER_VISIBLE, base::MayBlock(),
            base::WithBaseSyncPrimitives()})),
-      agent_registry_(agent_registry),
       weak_ptr_factory_(this) {
   DCHECK(agent_registry_);
 }
diff --git a/services/tracing/coordinator.h b/services/tracing/coordinator.h
index 50b5381..409720f 100644
--- a/services/tracing/coordinator.h
+++ b/services/tracing/coordinator.h
@@ -69,6 +69,7 @@
   base::trace_event::TraceConfig parsed_config_;
   StartTracingCallback start_tracing_callback_;
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+  AgentRegistry* agent_registry_;
 
  private:
   friend std::default_delete<Coordinator>;
@@ -107,7 +108,6 @@
   base::RepeatingClosure on_disconnect_callback_;
   mojo::Binding<mojom::Coordinator> binding_;
   const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
-  AgentRegistry* agent_registry_;
   std::string config_;
   bool is_tracing_ = false;
 
diff --git a/services/tracing/perfetto/perfetto_service.cc b/services/tracing/perfetto/perfetto_service.cc
index 44ee817..af25716 100644
--- a/services/tracing/perfetto/perfetto_service.cc
+++ b/services/tracing/perfetto/perfetto_service.cc
@@ -8,6 +8,8 @@
 
 #include "base/bind.h"
 #include "base/no_destructor.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/task/post_task.h"
 #include "services/service_manager/public/cpp/bind_source_info.h"
 #include "services/tracing/perfetto/producer_host.h"
@@ -16,12 +18,6 @@
 
 namespace tracing {
 
-namespace {
-
-const char kPerfettoProducerName[] = "org.chromium.perfetto_producer";
-
-}  // namespace
-
 // static
 PerfettoService* PerfettoService::GetInstance() {
   static base::NoDestructor<PerfettoService> perfetto_service;
@@ -44,16 +40,19 @@
   return service_.get();
 }
 
-void PerfettoService::BindRequest(mojom::PerfettoServiceRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+void PerfettoService::BindRequest(mojom::PerfettoServiceRequest request,
+                                  uint32_t pid) {
+  bindings_.AddBinding(this, std::move(request), pid);
 }
 
 void PerfettoService::ConnectToProducerHost(
     mojom::ProducerClientPtr producer_client,
     mojom::ProducerHostRequest producer_host_request) {
   auto new_producer = std::make_unique<ProducerHost>();
+  uint32_t producer_pid = bindings_.dispatch_context();
   new_producer->Initialize(std::move(producer_client), service_.get(),
-                           kPerfettoProducerName);
+                           base::StrCat({mojom::kPerfettoProducerName, ".",
+                                         base::NumberToString(producer_pid)}));
   producer_bindings_.AddBinding(std::move(new_producer),
                                 std::move(producer_host_request));
 }
diff --git a/services/tracing/perfetto/perfetto_service.h b/services/tracing/perfetto/perfetto_service.h
index 4d9490b..0bec063 100644
--- a/services/tracing/perfetto/perfetto_service.h
+++ b/services/tracing/perfetto/perfetto_service.h
@@ -32,7 +32,7 @@
 
   static PerfettoService* GetInstance();
 
-  void BindRequest(mojom::PerfettoServiceRequest request);
+  void BindRequest(mojom::PerfettoServiceRequest request, uint32_t pid);
 
   // mojom::PerfettoService implementation.
   void ConnectToProducerHost(mojom::ProducerClientPtr producer_client,
@@ -46,7 +46,7 @@
 
   PerfettoTaskRunner perfetto_task_runner_;
   std::unique_ptr<perfetto::TracingService> service_;
-  mojo::BindingSet<mojom::PerfettoService> bindings_;
+  mojo::BindingSet<mojom::PerfettoService, uint32_t> bindings_;
   mojo::StrongBindingSet<mojom::ProducerHost> producer_bindings_;
 
   DISALLOW_COPY_AND_ASSIGN(PerfettoService);
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.cc b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
index a02b533b..27d64c5d 100644
--- a/services/tracing/perfetto/perfetto_tracing_coordinator.cc
+++ b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
@@ -9,6 +9,8 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_log.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/system/data_pipe_utils.h"
@@ -58,8 +60,15 @@
     // blocked by the sandboxed and isn't needed for Chrome regardless.
     trace_config.set_disable_clock_snapshotting(true);
 
-    auto* trace_event_config =
-        trace_config.add_data_sources()->mutable_config();
+    auto* trace_event_data_source = trace_config.add_data_sources();
+    for (auto& enabled_pid : chrome_trace_config_obj.process_filter_config()
+                                 .included_process_ids()) {
+      *trace_event_data_source->add_producer_name_filter() =
+          base::StrCat({mojom::kPerfettoProducerName, ".",
+                        base::NumberToString(enabled_pid)});
+    }
+
+    auto* trace_event_config = trace_event_data_source->mutable_config();
     trace_event_config->set_name(mojom::kTraceEventDataSourceName);
     trace_event_config->set_target_buffer(0);
     auto* chrome_config = trace_event_config->mutable_chrome_config();
@@ -200,11 +209,6 @@
       binding_(this),
       weak_factory_(this) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
-
-  agent_registry->SetAgentInitializationCallback(
-      base::BindRepeating(&PerfettoTracingCoordinator::OnNewAgentConnected,
-                          weak_factory_.GetWeakPtr()),
-      false /* call_on_new_agents_only */);
 }
 
 PerfettoTracingCoordinator::~PerfettoTracingCoordinator() {
@@ -235,11 +239,19 @@
       config, base::BindOnce(&PerfettoTracingCoordinator::OnTracingOverCallback,
                              weak_factory_.GetWeakPtr()));
 
+  agent_registry_->SetAgentInitializationCallback(
+      base::BindRepeating(&PerfettoTracingCoordinator::PingAgent,
+                          weak_factory_.GetWeakPtr()),
+      false /* call_on_new_agents_only */);
+
   SetStartTracingCallback(std::move(callback));
 }
 
-void PerfettoTracingCoordinator::OnNewAgentConnected(
+void PerfettoTracingCoordinator::PingAgent(
     AgentRegistry::AgentEntry* agent_entry) {
+  if (!parsed_config_.process_filter_config().IsEnabled(agent_entry->pid()))
+    return;
+
   // TODO(oysteine): While we're still using the Agent
   // system as a fallback when using Perfetto, rather than
   // the browser directly using a Consumer interface, we have to
@@ -258,7 +270,7 @@
         DCHECK(removed);
 
         if (coordinator) {
-          coordinator->RemoveExpectedPID(agent_entry->pid());
+          coordinator->CallStartTracingCallbackIfNeeded();
         }
       },
       weak_factory_.GetWeakPtr(), base::Unretained(agent_entry));
@@ -267,6 +279,7 @@
                                     base::BindOnce(closure, 0, 0));
 
   agent_entry->agent()->RequestBufferStatus(closure);
+  RemoveExpectedPID(agent_entry->pid());
 }
 
 void PerfettoTracingCoordinator::OnTracingOverCallback() {
@@ -298,6 +311,8 @@
     return;
   }
 
+  agent_registry_->SetAgentInitializationCallback(
+      base::DoNothing(), true /* call_on_new_agents_only */);
   tracing_session_->StopAndFlush(std::move(stream), agent_label,
                                  std::move(callback));
 }
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.h b/services/tracing/perfetto/perfetto_tracing_coordinator.h
index 1a8318db..422a97a 100644
--- a/services/tracing/perfetto/perfetto_tracing_coordinator.h
+++ b/services/tracing/perfetto/perfetto_tracing_coordinator.h
@@ -50,7 +50,7 @@
  private:
   void OnTracingOverCallback();
   void OnClientConnectionError() override;
-  void OnNewAgentConnected(AgentRegistry::AgentEntry* agent_entry);
+  void PingAgent(AgentRegistry::AgentEntry* agent_entry);
   void StopAndFlushInternal(mojo::ScopedDataPipeProducerHandle stream,
                             const std::string& agent_label,
                             StopAndFlushCallback callback);
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom
index f8d71577..a65bb001 100644
--- a/services/tracing/public/mojom/perfetto_service.mojom
+++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -4,6 +4,7 @@
 
 module tracing.mojom;
 
+const string kPerfettoProducerName = "org.chromium.perfetto_producer";
 const string kTraceEventDataSourceName = "org.chromium.trace_event";
 const string kMetaDataSourceName = "org.chromium.trace_metadata";
 const string kSystemTraceDataSourceName = "org.chromium.trace_system";
diff --git a/services/tracing/tracing_service.cc b/services/tracing/tracing_service.cc
index d277c63..3e474ed 100644
--- a/services/tracing/tracing_service.cc
+++ b/services/tracing/tracing_service.cc
@@ -42,25 +42,6 @@
     binding_.Bind(std::move(request));
   }
 
-  void ConnectProcessToTracingService(
-      const service_manager::Identity& identity) {
-    mojom::TracedProcessPtr traced_process;
-    connector_->BindInterface(
-        service_manager::ServiceFilter::ForExactIdentity(identity),
-        mojo::MakeRequest(&traced_process),
-        service_manager::mojom::BindInterfacePriority::kBestEffort);
-
-    auto new_connection_request = mojom::ConnectToTracingRequest::New();
-
-    PerfettoService::GetInstance()->BindRequest(
-        mojo::MakeRequest(&new_connection_request->perfetto_service));
-
-    agent_registry_->BindAgentRegistryRequest(
-        mojo::MakeRequest(&new_connection_request->agent_registry));
-
-    traced_process->ConnectToTracingService(std::move(new_connection_request));
-  }
-
   size_t CountServicesWithPID(uint32_t pid) {
     return std::count_if(service_pid_map_.begin(), service_pid_map_.end(),
                          [pid](decltype(service_pid_map_)::value_type p) {
@@ -71,11 +52,31 @@
   void ServiceAddedWithPID(const service_manager::Identity& identity,
                            uint32_t pid) {
     service_pid_map_[identity] = pid;
-    // First service with this PID added; expect a connection from it.
-    if (CountServicesWithPID(pid) == 1) {
-      coordinator_->AddExpectedPID(pid);
-      ConnectProcessToTracingService(identity);
+    // Not the first service added, so we're already sent it a connection
+    // request.
+    if (CountServicesWithPID(pid) > 1) {
+      return;
     }
+
+    // Let the Coordinator know it should be expecting a connection
+    // from this process.
+    coordinator_->AddExpectedPID(pid);
+
+    mojom::TracedProcessPtr traced_process;
+    connector_->BindInterface(
+        service_manager::ServiceFilter::ForExactIdentity(identity),
+        mojo::MakeRequest(&traced_process),
+        service_manager::mojom::BindInterfacePriority::kBestEffort);
+
+    auto new_connection_request = mojom::ConnectToTracingRequest::New();
+
+    PerfettoService::GetInstance()->BindRequest(
+        mojo::MakeRequest(&new_connection_request->perfetto_service), pid);
+
+    agent_registry_->BindAgentRegistryRequest(
+        mojo::MakeRequest(&new_connection_request->agent_registry));
+
+    traced_process->ConnectToTracingService(std::move(new_connection_request));
   }
 
   void ServiceRemoved(const service_manager::Identity& identity) {
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index 4bd78c4..bf98887 100644
--- a/storage/browser/quota/quota_manager.cc
+++ b/storage/browser/quota/quota_manager.cc
@@ -901,14 +901,18 @@
     settings_.refresh_interval = base::TimeDelta();
     get_settings_task_runner_ = base::ThreadTaskRunnerHandle::Get();
   }
+  DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
 void QuotaManager::SetQuotaSettings(const QuotaSettings& settings) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   settings_ = settings;
   settings_timestamp_ = base::TimeTicks::Now();
 }
 
 void QuotaManager::GetUsageInfo(GetUsageInfoCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   GetUsageInfoTask* get_usage_info =
       new GetUsageInfoTask(this, std::move(callback));
@@ -918,6 +922,7 @@
 void QuotaManager::GetUsageAndQuotaForWebApps(const url::Origin& origin,
                                               StorageType type,
                                               UsageAndQuotaCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   GetUsageAndQuotaWithBreakdown(
       origin, type,
       base::BindOnce(&DidGetUsageAndQuotaForWebApps, std::move(callback)));
@@ -927,6 +932,7 @@
     const url::Origin& origin,
     StorageType type,
     UsageAndQuotaWithBreakdownCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!IsSupportedType(type) ||
       (is_incognito_ && !IsSupportedIncognitoType(type))) {
     std::move(callback).Run(
@@ -950,6 +956,7 @@
 void QuotaManager::GetUsageAndQuota(const url::Origin& origin,
                                     StorageType type,
                                     UsageAndQuotaCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (IsStorageUnlimited(origin, type)) {
     // TODO(michaeln): This seems like a non-obvious odd behavior, probably for
     // apps/extensions, but it would be good to eliminate this special case.
@@ -963,6 +970,7 @@
 void QuotaManager::NotifyStorageAccessed(QuotaClient::ID client_id,
                                          const url::Origin& origin,
                                          StorageType type) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   NotifyStorageAccessedInternal(client_id, origin, type, base::Time::Now());
 }
 
@@ -970,16 +978,19 @@
                                          const url::Origin& origin,
                                          StorageType type,
                                          int64_t delta) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   NotifyStorageModifiedInternal(client_id, origin, type, delta,
                                 base::Time::Now());
 }
 
 void QuotaManager::NotifyOriginInUse(const url::Origin& origin) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
   origins_in_use_[origin]++;
 }
 
 void QuotaManager::NotifyOriginNoLongerInUse(const url::Origin& origin) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
   DCHECK(IsOriginInUse(origin));
   int& count = origins_in_use_[origin];
@@ -991,6 +1002,7 @@
                                         const url::Origin& origin,
                                         StorageType type,
                                         bool enabled) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled);
@@ -1000,6 +1012,7 @@
                                     StorageType type,
                                     int quota_client_mask,
                                     StatusCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DeleteOriginDataInternal(origin, type, quota_client_mask, false,
                            std::move(callback));
 }
@@ -1007,6 +1020,7 @@
 void QuotaManager::PerformStorageCleanup(StorageType type,
                                          int quota_client_mask,
                                          base::OnceClosure callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   StorageCleanupHelper* deleter = new StorageCleanupHelper(
       this, type, quota_client_mask, std::move(callback));
   deleter->Start();
@@ -1016,6 +1030,7 @@
                                   StorageType type,
                                   int quota_client_mask,
                                   StatusCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   if (host.empty() || clients_.empty()) {
     std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk);
@@ -1029,6 +1044,7 @@
 
 void QuotaManager::GetPersistentHostQuota(const std::string& host,
                                           QuotaCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   if (host.empty()) {
     // This could happen if we are called on file:///.
@@ -1053,6 +1069,7 @@
 void QuotaManager::SetPersistentHostQuota(const std::string& host,
                                           int64_t new_quota,
                                           QuotaCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   if (host.empty()) {
     // This could happen if we are called on file:///.
@@ -1088,6 +1105,7 @@
 
 void QuotaManager::GetGlobalUsage(StorageType type,
                                   GlobalUsageCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   GetUsageTracker(type)->GetGlobalUsage(std::move(callback));
@@ -1096,6 +1114,7 @@
 void QuotaManager::GetHostUsage(const std::string& host,
                                 StorageType type,
                                 UsageCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   GetUsageTracker(type)->GetHostUsage(host, std::move(callback));
@@ -1105,6 +1124,7 @@
                                 StorageType type,
                                 QuotaClient::ID client_id,
                                 UsageCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   ClientUsageTracker* tracker =
@@ -1120,6 +1140,7 @@
     const std::string& host,
     StorageType type,
     UsageWithBreakdownCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   GetUsageTracker(type)->GetHostUsageWithBreakdown(host, std::move(callback));
@@ -1127,11 +1148,13 @@
 
 bool QuotaManager::IsTrackingHostUsage(StorageType type,
                                        QuotaClient::ID client_id) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   UsageTracker* tracker = GetUsageTracker(type);
   return tracker && tracker->GetClientTracker(client_id);
 }
 
 std::map<std::string, std::string> QuotaManager::GetStatistics() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   std::map<std::string, std::string> statistics;
   if (temporary_storage_evictor_) {
     std::map<std::string, int64_t> stats;
@@ -1146,6 +1169,7 @@
 
 bool QuotaManager::IsStorageUnlimited(const url::Origin& origin,
                                       StorageType type) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // For syncable storage we should always enforce quota (since the
   // quota must be capped by the server limit).
   if (type == StorageType::kSyncable)
@@ -1159,6 +1183,7 @@
 void QuotaManager::GetOriginsModifiedSince(StorageType type,
                                            base::Time modified_since,
                                            GetOriginsCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   GetModifiedSinceHelper* helper = new GetModifiedSinceHelper;
   PostTaskAndReplyWithResultForDBThread(
@@ -1171,6 +1196,7 @@
 }
 
 bool QuotaManager::ResetUsageTracker(StorageType type) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(GetUsageTracker(type));
   if (GetUsageTracker(type)->IsWorking())
     return false;
@@ -1198,11 +1224,13 @@
 
 void QuotaManager::AddStorageObserver(
     StorageObserver* observer, const StorageObserver::MonitorParams& params) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(observer);
   storage_monitor_->AddObserver(observer, params);
 }
 
 void QuotaManager::RemoveStorageObserver(StorageObserver* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(observer);
   storage_monitor_->RemoveObserver(observer);
 }
@@ -1221,6 +1249,7 @@
 QuotaManager::EvictionContext::~EvictionContext() = default;
 
 void QuotaManager::LazyInitialize() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
   if (database_) {
     // Already initialized.
@@ -1256,6 +1285,7 @@
 }
 
 void QuotaManager::FinishLazyInitialize(bool is_database_bootstrapped) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   is_database_bootstrapped_ = is_database_bootstrapped;
   StartEviction();
 }
@@ -1264,6 +1294,7 @@
     GetOriginCallback did_get_origin_callback,
     int64_t usage,
     int64_t unlimited_usage) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // The usage cache should be fully populated now so we can
   // seed the database with origins we know about.
   std::set<url::Origin>* origins = new std::set<url::Origin>;
@@ -1279,17 +1310,20 @@
 void QuotaManager::DidBootstrapDatabase(
     GetOriginCallback did_get_origin_callback,
     bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   is_database_bootstrapped_ = success;
   DidDatabaseWork(success);
   GetLRUOrigin(StorageType::kTemporary, std::move(did_get_origin_callback));
 }
 
 void QuotaManager::RegisterClient(QuotaClient* client) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!database_.get());
   clients_.push_back(client);
 }
 
 UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   switch (type) {
     case StorageType::kTemporary:
       return temporary_usage_tracker_.get();
@@ -1307,6 +1341,7 @@
 
 void QuotaManager::GetCachedOrigins(StorageType type,
                                     std::set<url::Origin>* origins) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(origins);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
@@ -1317,6 +1352,7 @@
                                                  const url::Origin& origin,
                                                  StorageType type,
                                                  base::Time accessed_time) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   if (type == StorageType::kTemporary && is_getting_eviction_origin_) {
     // Record the accessed origins while GetLRUOrigin task is runing
@@ -1338,6 +1374,7 @@
                                                  StorageType type,
                                                  int64_t delta,
                                                  base::Time modified_time) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   DCHECK(GetUsageTracker(type));
   GetUsageTracker(type)->UpdateUsageCache(client_id, origin, delta);
@@ -1351,6 +1388,7 @@
 }
 
 void QuotaManager::DumpQuotaTable(DumpQuotaTableCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DumpQuotaTableHelper* helper = new DumpQuotaTableHelper;
   PostTaskAndReplyWithResultForDBThread(
       FROM_HERE,
@@ -1362,6 +1400,7 @@
 }
 
 void QuotaManager::DumpOriginInfoTable(DumpOriginInfoTableCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DumpOriginInfoTableHelper* helper = new DumpOriginInfoTableHelper;
   PostTaskAndReplyWithResultForDBThread(
       FROM_HERE,
@@ -1373,6 +1412,7 @@
 }
 
 void QuotaManager::StartEviction() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!temporary_storage_evictor_.get());
   if (eviction_disabled_)
     return;
@@ -1384,6 +1424,7 @@
 void QuotaManager::DeleteOriginFromDatabase(const url::Origin& origin,
                                             StorageType type,
                                             bool is_eviction) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   if (db_disabled_)
     return;
@@ -1396,6 +1437,7 @@
 }
 
 void QuotaManager::DidOriginDataEvicted(blink::mojom::QuotaStatusCode status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
 
   // We only try evict origins that are not in use, so basically
@@ -1413,6 +1455,7 @@
                                             int quota_client_mask,
                                             bool is_eviction,
                                             StatusCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
 
   if (clients_.empty()) {
@@ -1426,6 +1469,7 @@
 }
 
 void QuotaManager::ReportHistogram() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!is_incognito_);
   GetGlobalUsage(
       StorageType::kTemporary,
@@ -1436,6 +1480,7 @@
 void QuotaManager::DidGetTemporaryGlobalUsageForHistogram(
     int64_t usage,
     int64_t unlimited_usage) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfTemporaryStorage", usage);
 
   std::set<url::Origin> origins;
@@ -1463,6 +1508,7 @@
 void QuotaManager::DidGetPersistentGlobalUsageForHistogram(
     int64_t usage,
     int64_t unlimited_usage) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage);
 
   std::set<url::Origin> origins;
@@ -1490,6 +1536,7 @@
 
 void QuotaManager::DidDumpOriginInfoTableForHistogram(
     const OriginInfoTableEntries& entries) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   using UsageMap = std::map<url::Origin, int64_t>;
   UsageMap usage_map;
   GetUsageTracker(StorageType::kTemporary)->GetCachedOriginsUsage(&usage_map);
@@ -1519,6 +1566,7 @@
 
 std::set<url::Origin> QuotaManager::GetEvictionOriginExceptions(
     const std::set<url::Origin>& extra_exceptions) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   std::set<url::Origin> exceptions = extra_exceptions;
   for (const auto& p : origins_in_use_) {
     if (p.second > 0)
@@ -1536,6 +1584,7 @@
 void QuotaManager::DidGetEvictionOrigin(
     GetOriginCallback callback,
     const base::Optional<url::Origin>& origin) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Make sure the returned origin is (still) not in the origin_in_use_ set
   // and has not been accessed since we posted the task.
   DCHECK(!origin.has_value() || !origin->GetURL().is_empty());
@@ -1556,6 +1605,7 @@
     const std::set<url::Origin>& extra_exceptions,
     int64_t global_quota,
     GetOriginCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   // This must not be called while there's an in-flight task.
   DCHECK(!is_getting_eviction_origin_);
@@ -1580,6 +1630,7 @@
 void QuotaManager::EvictOriginData(const url::Origin& origin,
                                    StorageType type,
                                    StatusCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
   DCHECK_EQ(type, StorageType::kTemporary);
 
@@ -1593,6 +1644,7 @@
 }
 
 void QuotaManager::GetEvictionRoundInfo(EvictionRoundInfoCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(io_thread_->BelongsToCurrentThread());
   LazyInitialize();
   EvictionRoundInfoHelper* helper =
@@ -1601,6 +1653,7 @@
 }
 
 void QuotaManager::GetLRUOrigin(StorageType type, GetOriginCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LazyInitialize();
   // This must not be called while there's an in-flight task.
   DCHECK(lru_origin_callback_.is_null());
@@ -1625,6 +1678,7 @@
 void QuotaManager::DidGetPersistentHostQuota(const std::string& host,
                                              const int64_t* quota,
                                              bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DidDatabaseWork(success);
   persistent_host_quota_callbacks_.Run(
       host, blink::mojom::QuotaStatusCode::kOk,
@@ -1635,6 +1689,7 @@
                                              QuotaCallback callback,
                                              const int64_t* new_quota,
                                              bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DidDatabaseWork(success);
   std::move(callback).Run(
       success ? blink::mojom::QuotaStatusCode::kOk
@@ -1645,6 +1700,7 @@
 void QuotaManager::DidGetLRUOrigin(
     std::unique_ptr<base::Optional<url::Origin>> origin,
     bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DidDatabaseWork(success);
 
   std::move(lru_origin_callback_).Run(*origin);
@@ -1660,6 +1716,7 @@
 }  // namespace
 
 void QuotaManager::GetQuotaSettings(QuotaSettingsCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (base::TimeTicks::Now() - settings_timestamp_ <
       settings_.refresh_interval) {
     std::move(callback).Run(settings_);
@@ -1684,6 +1741,7 @@
 
 void QuotaManager::DidGetSettings(base::TimeTicks start_ticks,
                                   base::Optional<QuotaSettings> settings) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!settings) {
     settings = settings_;
     settings->refresh_interval = base::TimeDelta::FromMinutes(1);
@@ -1698,6 +1756,7 @@
 }
 
 void QuotaManager::GetStorageCapacity(StorageCapacityCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!storage_capacity_callbacks_.Add(std::move(callback)))
     return;
   if (is_incognito_) {
@@ -1716,6 +1775,7 @@
 
 void QuotaManager::ContinueIncognitoGetStorageCapacity(
     const QuotaSettings& settings) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   int64_t current_usage =
       GetUsageTracker(StorageType::kTemporary)->GetCachedUsage();
   current_usage += GetUsageTracker(StorageType::kPersistent)->GetCachedUsage();
@@ -1726,11 +1786,13 @@
 
 void QuotaManager::DidGetStorageCapacity(
     const std::tuple<int64_t, int64_t>& total_and_available) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   storage_capacity_callbacks_.Run(std::get<0>(total_and_available),
                                   std::get<1>(total_and_available));
 }
 
 void QuotaManager::DidDatabaseWork(bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   db_disabled_ = !success;
 }
 
@@ -1746,6 +1808,7 @@
     const base::Location& from_here,
     base::OnceCallback<bool(QuotaDatabase*)> task,
     base::OnceCallback<void(bool)> reply) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Deleting manager will post another task to DB sequence to delete
   // |database_|, therefore we can be sure that database_ is alive when this
   // task runs.
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h
index 8393f2f..188a436 100644
--- a/storage/browser/quota/quota_manager.h
+++ b/storage/browser/quota/quota_manager.h
@@ -23,6 +23,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "base/sequence_checker.h"
 #include "base/stl_util.h"
 #include "base/timer/timer.h"
 #include "storage/browser/quota/quota_callbacks.h"
@@ -178,6 +179,7 @@
   void NotifyOriginInUse(const url::Origin& origin);
   void NotifyOriginNoLongerInUse(const url::Origin& origin);
   bool IsOriginInUse(const url::Origin& origin) const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     return base::ContainsKey(origins_in_use_, origin);
   }
 
@@ -423,7 +425,8 @@
   const bool is_incognito_;
   const base::FilePath profile_path_;
 
-  scoped_refptr<QuotaManagerProxy> proxy_;
+  // proxy_ can be accessed by any thread so it must be thread-safe
+  const scoped_refptr<QuotaManagerProxy> proxy_;
   bool db_disabled_;
   bool eviction_disabled_;
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
@@ -477,6 +480,8 @@
 
   std::unique_ptr<StorageMonitor> storage_monitor_;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   base::WeakPtrFactory<QuotaManager> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(QuotaManager);
diff --git a/testing/scripts/common.py b/testing/scripts/common.py
index 1e60d71..d131ba3 100644
--- a/testing/scripts/common.py
+++ b/testing/scripts/common.py
@@ -17,6 +17,7 @@
 # Add src/testing/ into sys.path for importing xvfb.
 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
 import xvfb
+import test_env
 
 # Unfortunately we need to copy these variables from ../test_env.py.
 # Importing it and using its get_sandbox_env breaks test runs on Linux
@@ -79,7 +80,7 @@
 
 def run_command(argv, env=None, cwd=None):
   print 'Running %r in %r (env: %r)' % (argv, cwd, env)
-  rc = subprocess.call(argv, env=env, cwd=cwd)
+  rc = test_env.run_command(argv, env=env, cwd=cwd)
   print 'Command %r returned exit code %d' % (argv, rc)
   return rc
 
@@ -198,20 +199,6 @@
   return filter_list.split('::')
 
 
-def run_integration_test(script_to_run, extra_args, log_file, output):
-  integration_test_res = subprocess.call(
-      [sys.executable, script_to_run] + extra_args)
-
-  with open(log_file) as f:
-    failures = json.load(f)
-  json.dump({
-      'valid': integration_test_res == 0,
-      'failures': failures,
-  }, output)
-
-  return integration_test_res
-
-
 class BaseIsolatedScriptArgsAdapter(object):
   """The base class for all script adapters that need to translate flags
   set by isolated script test contract into the specific test script's flags.
@@ -350,7 +337,7 @@
       if self.options.xvfb:
         exit_code = xvfb.run_executable(cmd, env)
       else:
-        exit_code = subprocess.call(cmd, env=env)
+        exit_code = test_env.run_command(cmd, env=env)
       print 'Command returned exit code %d' % exit_code
       return exit_code
     except Exception:
diff --git a/testing/test_env.py b/testing/test_env.py
index 96e54630..95fefcce 100755
--- a/testing/test_env.py
+++ b/testing/test_env.py
@@ -174,7 +174,13 @@
 
 
 def run_command_with_output(argv, stdoutfile, env=None, cwd=None):
-  """ Run command and stream its stdout/stderr to the console & |stdoutfile|.
+  """Run command and stream its stdout/stderr to the console & |stdoutfile|.
+
+  Also forward_signals to obey
+  https://chromium.googlesource.com/infra/luci/luci-py/+/master/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
+
+  Returns:
+    integer returncode of the subprocess.
   """
   print('Running %r in %r (env: %r)' % (argv, cwd, env))
   assert stdoutfile
@@ -185,6 +191,8 @@
     forward_signals([process])
     while process.poll() is None:
       sys.stdout.write(reader.read())
+      # This sleep is needed for signal propagation. See the
+      # wait_with_signals() docstring.
       time.sleep(0.1)
     # Read the remaining.
     sys.stdout.write(reader.read())
@@ -192,6 +200,44 @@
     return process.returncode
 
 
+def run_command(argv, env=None, cwd=None, log=True):
+  """Run command and stream its stdout/stderr both to stdout.
+
+  Also forward_signals to obey
+  https://chromium.googlesource.com/infra/luci/luci-py/+/master/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
+
+  Returns:
+    integer returncode of the subprocess.
+  """
+  if log:
+    print('Running %r in %r (env: %r)' % (argv, cwd, env))
+  process = subprocess.Popen(argv, env=env, cwd=cwd, stderr=subprocess.STDOUT)
+  forward_signals([process])
+  return wait_with_signals(process)
+
+
+def wait_with_signals(process):
+  """A version of process.wait() that works cross-platform.
+
+  This version properly surfaces the SIGBREAK signal.
+
+  From reading the subprocess.py source code, it seems we need to explicitly
+  call time.sleep(). The reason is that subprocess.Popen.wait() on Windows
+  directly calls WaitForSingleObject(), but only time.sleep() properly surface
+  the SIGBREAK signal.
+
+  Refs:
+  https://github.com/python/cpython/blob/v2.7.15/Lib/subprocess.py#L692
+  https://github.com/python/cpython/blob/v2.7.15/Modules/timemodule.c#L1084
+
+  Returns:
+    returncode of the process.
+  """
+  while process.poll() is None:
+    time.sleep(0.1)
+  return process.returncode
+
+
 def forward_signals(procs):
   """Forwards unix's SIGTERM or win's CTRL_BREAK_EVENT to the given processes.
 
@@ -286,15 +332,13 @@
           env=env, stdin=p1.stdout)
       p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
       forward_signals([p1, p2])
-      p1.wait()
-      p2.wait()
+      wait_with_signals(p1)
+      wait_with_signals(p2)
       # Also feed the out-of-band JSON output to the symbolizer script.
       symbolize_snippets_in_json(cmd, env)
       return p1.returncode
     else:
-      p = subprocess.Popen(cmd, env=env)
-      forward_signals([p])
-      return p.wait()
+      return run_command(cmd, env=env, log=False)
   except OSError:
     print >> sys.stderr, 'Failed to start %s' % cmd
     raise
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index dfc6f73..857e314c 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -686,7 +686,7 @@
             ]
         }
     ],
-    "AutofillLocalCardMigrationWithFeedback": [
+    "AutofillLocalCardMigration": [
         {
             "platforms": [
                 "chromeos",
@@ -696,9 +696,26 @@
             ],
             "experiments": [
                 {
-                    "name": "EnableLocalCardMigrationWithFeedback",
+                    "name": "EnableLocalCardMigration",
                     "enable_features": [
-                        "AutofillCreditCardLocalCardMigration",
+                        "AutofillCreditCardLocalCardMigration"
+                    ]
+                }
+            ]
+        }
+    ],
+    "AutofillLocalCardMigrationShowFeedback": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "EnableLocalCardMigrationShowFeedback",
+                    "enable_features": [
                         "AutofillLocalCardMigrationShowFeedback"
                     ]
                 }
@@ -2566,6 +2583,22 @@
             ]
         }
     ],
+    "MediaCapabilitiesParams": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "DBWindow5000Frames_20190211"
+                }
+            ]
+        }
+    ],
     "MediaFoundationH264Encoding": [
         {
             "platforms": [
diff --git a/testing/xvfb.py b/testing/xvfb.py
index a24526da..a6f9cee 100755
--- a/testing/xvfb.py
+++ b/testing/xvfb.py
@@ -89,10 +89,11 @@
       xvfb_script = __file__
       if xvfb_script.endswith('.pyc'):
         xvfb_script = xvfb_script[:-1]
-      return subprocess.call(['xvfb-run', '-a', "--server-args=-screen 0 "
-                              "1280x800x24 -ac -nolisten tcp -dpi 96 "
-                              "+extension RANDR",
-                              xvfb_script] + cmd, env=env)
+      # TODO(crbug.com/932240): Propagate signals properly.
+      return subprocess.call([
+          'xvfb-run', '-a', "--server-args=-screen 0 "
+          "1280x800x24 -ac -nolisten tcp -dpi 96 "
+          "+extension RANDR", xvfb_script] + cmd, env=env)
   else:
     return test_env.run_executable(cmd, env, stdoutfile)
 
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn
index 01171e5..80f1162 100644
--- a/third_party/android_deps/BUILD.gn
+++ b/third_party/android_deps/BUILD.gn
@@ -239,6 +239,35 @@
   ]
 }
 
+android_aar_prebuilt("androidx_test_core_java") {
+  testonly = true
+  aar_path = "libs/androidx_test_core/core-1.0.0.aar"
+  info_path = "libs/androidx_test_core/androidx_test_core.info"
+  deps = [
+    ":androidx_annotation_annotation_java",
+    ":androidx_lifecycle_lifecycle_common_java",
+    ":androidx_test_monitor_java",
+  ]
+}
+
+android_aar_prebuilt("androidx_test_ext_junit_java") {
+  testonly = true
+  aar_path = "libs/androidx_test_ext_junit/junit-1.0.0.aar"
+  info_path = "libs/androidx_test_ext_junit/androidx_test_ext_junit.info"
+  deps = [
+    "//third_party/junit:junit",
+  ]
+}
+
+android_aar_prebuilt("androidx_test_monitor_java") {
+  testonly = true
+  aar_path = "libs/androidx_test_monitor/monitor-1.1.0.aar"
+  info_path = "libs/androidx_test_monitor/androidx_test_monitor.info"
+  deps = [
+    ":androidx_annotation_annotation_java",
+  ]
+}
+
 android_aar_prebuilt("com_android_support_appcompat_v7_java") {
   aar_path = "libs/com_android_support_appcompat_v7/appcompat-v7-27.0.0.aar"
   info_path = "libs/com_android_support_appcompat_v7/com_android_support_appcompat_v7.info"
@@ -593,6 +622,24 @@
   ]
 }
 
+java_prebuilt("androidx_annotation_annotation_java") {
+  jar_path = "libs/androidx_annotation_annotation/annotation-1.0.0.jar"
+  output_name = "androidx_annotation_annotation"
+  supports_android = true
+  visibility = [ ":*" ]
+}
+
+java_prebuilt("androidx_lifecycle_lifecycle_common_java") {
+  jar_path =
+      "libs/androidx_lifecycle_lifecycle_common/lifecycle-common-2.0.0.jar"
+  output_name = "androidx_lifecycle_lifecycle_common"
+  supports_android = true
+  visibility = [ ":*" ]
+  deps = [
+    ":androidx_annotation_annotation_java",
+  ]
+}
+
 android_aar_prebuilt("com_android_support_animated_vector_drawable_java") {
   aar_path = "libs/com_android_support_animated_vector_drawable/animated-vector-drawable-27.0.0.aar"
   info_path = "libs/com_android_support_animated_vector_drawable/com_android_support_animated_vector_drawable.info"
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json
index 3e52c7b..7953c18 100644
--- a/third_party/android_deps/additional_readme_paths.json
+++ b/third_party/android_deps/additional_readme_paths.json
@@ -2,6 +2,11 @@
     "libs/android_arch_core_common",
     "libs/android_arch_lifecycle_common",
     "libs/android_arch_lifecycle_runtime",
+    "libs/androidx_annotation_annotation",
+    "libs/androidx_lifecycle_lifecycle_common",
+    "libs/androidx_test_core",
+    "libs/androidx_test_ext_junit",
+    "libs/androidx_test_monitor",
     "libs/com_android_support_animated_vector_drawable",
     "libs/com_android_support_appcompat_v7",
     "libs/com_android_support_cardview_v7",
diff --git a/third_party/androidx/LICENSE b/third_party/android_deps/libs/androidx_annotation_annotation/LICENSE
similarity index 89%
rename from third_party/androidx/LICENSE
rename to third_party/android_deps/libs/androidx_annotation_annotation/LICENSE
index f433b1a5..d645695 100644
--- a/third_party/androidx/LICENSE
+++ b/third_party/android_deps/libs/androidx_annotation_annotation/LICENSE
@@ -175,3 +175,28 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_annotation_annotation/OWNERS b/third_party/android_deps/libs/androidx_annotation_annotation/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_annotation_annotation/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_annotation_annotation/README.chromium b/third_party/android_deps/libs/androidx_annotation_annotation/README.chromium
new file mode 100644
index 0000000..261cfd37
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_annotation_annotation/README.chromium
@@ -0,0 +1,13 @@
+Name: Android Support Library Annotations
+Short Name: annotation
+URL: http://developer.android.com/tools/extras/support-library.html
+Version: 1.0.0
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/androidx_annotation_annotation/cipd.yaml b/third_party/android_deps/libs/androidx_annotation_annotation/cipd.yaml
new file mode 100644
index 0000000..a70a331
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_annotation_annotation/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.0.0-cr0
+package: chromium/third_party/android_deps/libs/androidx_annotation_annotation
+description: "Android Support Library Annotations"
+data:
+- file: annotation-1.0.0.jar
diff --git a/third_party/androidx/LICENSE b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/LICENSE
similarity index 89%
copy from third_party/androidx/LICENSE
copy to third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/LICENSE
index f433b1a5..d645695 100644
--- a/third_party/androidx/LICENSE
+++ b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/LICENSE
@@ -175,3 +175,28 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/OWNERS b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/README.chromium b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/README.chromium
new file mode 100644
index 0000000..20e4969
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/README.chromium
@@ -0,0 +1,13 @@
+Name: Android Lifecycle-Common
+Short Name: lifecycle-common
+URL: https://developer.android.com/topic/libraries/architecture/index.html
+Version: 2.0.0
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+Android Lifecycle-Common
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/cipd.yaml b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/cipd.yaml
new file mode 100644
index 0000000..3f2cc1fe
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2.0.0-cr0
+package: chromium/third_party/android_deps/libs/androidx_lifecycle_lifecycle_common
+description: "Android Lifecycle-Common"
+data:
+- file: lifecycle-common-2.0.0.jar
diff --git a/third_party/androidx/LICENSE b/third_party/android_deps/libs/androidx_test_core/LICENSE
similarity index 89%
copy from third_party/androidx/LICENSE
copy to third_party/android_deps/libs/androidx_test_core/LICENSE
index f433b1a5..d645695 100644
--- a/third_party/androidx/LICENSE
+++ b/third_party/android_deps/libs/androidx_test_core/LICENSE
@@ -175,3 +175,28 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_test_core/OWNERS b/third_party/android_deps/libs/androidx_test_core/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_core/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_test_core/README.chromium b/third_party/android_deps/libs/androidx_test_core/README.chromium
new file mode 100644
index 0000000..f9cc7f3
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_core/README.chromium
@@ -0,0 +1,13 @@
+Name: AndroidX Test Library
+Short Name: core
+URL: https://developer.android.com/testing
+Version: 1.0.0
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The AndroidX Test Library provides an extensive framework for testing Android apps
+
+Local Modifications:
+No modifications.
diff --git a/third_party/androidx/androidx_core_java.info b/third_party/android_deps/libs/androidx_test_core/androidx_test_core.info
similarity index 100%
rename from third_party/androidx/androidx_core_java.info
rename to third_party/android_deps/libs/androidx_test_core/androidx_test_core.info
diff --git a/third_party/android_deps/libs/androidx_test_core/cipd.yaml b/third_party/android_deps/libs/androidx_test_core/cipd.yaml
new file mode 100644
index 0000000..c6481bfe
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_core/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.0.0-cr0
+package: chromium/third_party/android_deps/libs/androidx_test_core
+description: "AndroidX Test Library"
+data:
+- file: core-1.0.0.aar
diff --git a/third_party/androidx/LICENSE b/third_party/android_deps/libs/androidx_test_ext_junit/LICENSE
similarity index 89%
copy from third_party/androidx/LICENSE
copy to third_party/android_deps/libs/androidx_test_ext_junit/LICENSE
index f433b1a5..d645695 100644
--- a/third_party/androidx/LICENSE
+++ b/third_party/android_deps/libs/androidx_test_ext_junit/LICENSE
@@ -175,3 +175,28 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_test_ext_junit/OWNERS b/third_party/android_deps/libs/androidx_test_ext_junit/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_ext_junit/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_test_ext_junit/README.chromium b/third_party/android_deps/libs/androidx_test_ext_junit/README.chromium
new file mode 100644
index 0000000..a2c488e
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_ext_junit/README.chromium
@@ -0,0 +1,13 @@
+Name: AndroidX Test Library
+Short Name: junit
+URL: https://developer.android.com/testing
+Version: 1.0.0
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The AndroidX Test Library provides an extensive framework for testing Android apps
+
+Local Modifications:
+No modifications.
diff --git a/third_party/androidx/androidx_junit_java.info b/third_party/android_deps/libs/androidx_test_ext_junit/androidx_test_ext_junit.info
similarity index 100%
rename from third_party/androidx/androidx_junit_java.info
rename to third_party/android_deps/libs/androidx_test_ext_junit/androidx_test_ext_junit.info
diff --git a/third_party/android_deps/libs/androidx_test_ext_junit/cipd.yaml b/third_party/android_deps/libs/androidx_test_ext_junit/cipd.yaml
new file mode 100644
index 0000000..1dbe5dc
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_ext_junit/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.0.0-cr0
+package: chromium/third_party/android_deps/libs/androidx_test_ext_junit
+description: "AndroidX Test Library"
+data:
+- file: junit-1.0.0.aar
diff --git a/third_party/androidx/LICENSE b/third_party/android_deps/libs/androidx_test_monitor/LICENSE
similarity index 89%
copy from third_party/androidx/LICENSE
copy to third_party/android_deps/libs/androidx_test_monitor/LICENSE
index f433b1a5..d645695 100644
--- a/third_party/androidx/LICENSE
+++ b/third_party/android_deps/libs/androidx_test_monitor/LICENSE
@@ -175,3 +175,28 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_deps/libs/androidx_test_monitor/OWNERS b/third_party/android_deps/libs/androidx_test_monitor/OWNERS
new file mode 100644
index 0000000..7b571d97
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_monitor/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
\ No newline at end of file
diff --git a/third_party/android_deps/libs/androidx_test_monitor/README.chromium b/third_party/android_deps/libs/androidx_test_monitor/README.chromium
new file mode 100644
index 0000000..cff4adf
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_monitor/README.chromium
@@ -0,0 +1,13 @@
+Name: AndroidX Test Library
+Short Name: monitor
+URL: https://developer.android.com/testing
+Version: 1.1.0
+License: Apache Version 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The AndroidX Test Library provides an extensive framework for testing Android apps
+
+Local Modifications:
+No modifications.
diff --git a/third_party/androidx/androidx_monitor_java.info b/third_party/android_deps/libs/androidx_test_monitor/androidx_test_monitor.info
similarity index 100%
rename from third_party/androidx/androidx_monitor_java.info
rename to third_party/android_deps/libs/androidx_test_monitor/androidx_test_monitor.info
diff --git a/third_party/android_deps/libs/androidx_test_monitor/cipd.yaml b/third_party/android_deps/libs/androidx_test_monitor/cipd.yaml
new file mode 100644
index 0000000..cdbff6f
--- /dev/null
+++ b/third_party/android_deps/libs/androidx_test_monitor/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:1.1.0-cr0
+package: chromium/third_party/android_deps/libs/androidx_test_monitor
+description: "AndroidX Test Library"
+data:
+- file: monitor-1.1.0.aar
diff --git a/third_party/androidx/BUILD.gn b/third_party/androidx/BUILD.gn
deleted file mode 100644
index c4c92f381..0000000
--- a/third_party/androidx/BUILD.gn
+++ /dev/null
@@ -1,46 +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("//build/config/android/rules.gni")
-
-android_aar_prebuilt("androidx_core_java") {
-  # If this is not test only, there are security implications.
-  # Any changes from test only will need a review from security@chromium.org.
-  testonly = true
-  aar_path = "lib/core-1.0.0.aar"
-  deps = [
-    ":androidx_monitor_java",
-    ":lifecycle-common-2.0.0_java",
-  ]
-}
-
-android_aar_prebuilt("androidx_junit_java") {
-  # If this is not test only, there are security implications.
-  # Any changes from test only will need a review from security@chromium.org.
-  testonly = true
-  aar_path = "lib/junit-1.0.0.aar"
-  deps = [
-    "//third_party/junit:junit",
-  ]
-}
-
-android_aar_prebuilt("androidx_monitor_java") {
-  # If this is not test only, there are security implications.
-  # Any changes from test only will need a review from security@chromium.org.
-  testonly = true
-  aar_path = "lib/monitor-1.1.0.aar"
-}
-
-android_java_prebuilt("annotation-1.0.0_java") {
-  testonly = true
-  jar_path = "lib/annotation-1.0.0.jar"
-}
-
-android_java_prebuilt("lifecycle-common-2.0.0_java") {
-  testonly = true
-  jar_path = "lib/lifecycle-common-2.0.0.jar"
-  deps = [
-    ":annotation-1.0.0_java",
-  ]
-}
diff --git a/third_party/androidx/METADATA b/third_party/androidx/METADATA
deleted file mode 100644
index 2cd0745..0000000
--- a/third_party/androidx/METADATA
+++ /dev/null
@@ -1,21 +0,0 @@
-name: "androidx"
-description:
-    "AndroidX is the open-source project that the Android team uses to develop, "
-    "test, package, version and release libraries within Jetpack."
-
-third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://developer.android.com/jetpack/androidx/"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://mvnrepository.com/artifact/androidx.test"
-  }
-  url {
-    type: GIT
-    value: "https://android.googlesource.com/platform/frameworks/support/+/androidx-1.0-dev"
-  }
-  version: "1.0.0"
-  last_upgrade_date { year: 2019 month: 1 day: 23 }
-}
diff --git a/third_party/androidx/OWNERS b/third_party/androidx/OWNERS
deleted file mode 100644
index 6ad440e..0000000
--- a/third_party/androidx/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbudorick@chromium.org
-bjoyce@chromium.org
-yliuyliu@chromium.org
-yzjr@chromium.org
diff --git a/third_party/androidx/README.chromium b/third_party/androidx/README.chromium
deleted file mode 100644
index 18aabf7..0000000
--- a/third_party/androidx/README.chromium
+++ /dev/null
@@ -1,15 +0,0 @@
-Name: Androidx
-URL: https://developer.android.com/jetpack/androidx/
-Version: 1.0.0
-License: Apache 2.0
-License File: NOT_SHIPPED
-Security Critical: no
-License Android Compatible: yes
-Description: AndroidX is used to develop, test, package, version and release
-libraries within Jetpack.
-How To Update:
-- Update file names in our BUILD.gn file.
-- Update DEPS to new Androidx revision.
-- Update CIPD package to include new Androidx libraries.
-- add or update appropriate .info files outlined
-in build/config/android/rules.gni for android_aar_prebuilt.
diff --git a/third_party/androidx/cipd.yaml b/third_party/androidx/cipd.yaml
deleted file mode 100644
index 3d2c3af..0000000
--- a/third_party/androidx/cipd.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# To create CIPD package run the following command.
-# cipd create --pkg-def cipd.yaml -tag version:$(cat version.txt)
-package: chromium/third_party/androidx
-description: Androidx libray files
-data:
-  - file: lib/core-1.0.0.aar
-  - file: lib/junit-1.0.0.aar
-  - file: lib/monitor-1.1.0.aar
-  - file: lib/annotation-1.0.0.jar
-  - file: lib/lifecycle-common-2.0.0.jar
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index e9e0db8..b7b0bf9 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -2231,6 +2231,7 @@
   kClientHintsUAModel = 2792,
   kAnimationFrameCancelledWithinFrame = 2793,
   kSchedulingIsInputPending = 2794,
+  kV8StringNormalize = 2795,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
index f3c5c8d..23eab2b 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/location.h"
+#include "third_party/blink/renderer/core/frame/remote_dom_window.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/html/html_collection.h"
@@ -81,7 +82,7 @@
   // whether or not |window| is cross-origin. If |window| is local, the
   // |location| property must always return the same wrapper, even if the
   // cross-origin status changes by changing properties like |document.domain|.
-  if (window->IsRemoteDOMWindow()) {
+  if (IsA<RemoteDOMWindow>(window)) {
     DOMWrapperWorld& world = DOMWrapperWorld::Current(isolate);
     const auto* location_wrapper_type = location->GetWrapperTypeInfo();
     v8::Local<v8::Object> new_wrapper =
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
index a4171ba..74f2818 100644
--- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
+++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -223,6 +223,9 @@
     case v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp:
       blink_feature = WebFeature::kV8RegExpMatchIsFalseishOnJSRegExp;
       break;
+    case v8::Isolate::kStringNormalize:
+      blink_feature = WebFeature::kV8StringNormalize;
+      break;
     default:
       // This can happen if V8 has added counters that this version of Blink
       // does not know about. It's harmless.
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 31d29fd7..320b24cb 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -997,7 +997,7 @@
     const StyleResolverState& state,
     const CSSValue& value) {
   return UnzoomedLength(ToCSSPrimitiveValue(value).ConvertToLength(
-      state.CssToLengthConversionData().CopyWithAdjustedZoom(1.0f)));
+      state.UnzoomedLengthConversionData()));
 }
 
 Length StyleBuilderConverter::ConvertLengthOrAuto(
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
index 9f64fd7..bd8eadd 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -94,17 +94,29 @@
   return std::move(style_);
 }
 
-CSSToLengthConversionData StyleResolverState::FontSizeConversionData() const {
-  float em = ParentStyle()->SpecifiedFontSize();
+CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData(
+    const ComputedStyle* font_style) const {
+  float em = font_style->SpecifiedFontSize();
   float rem = RootElementStyle() ? RootElementStyle()->SpecifiedFontSize() : 1;
+  // TODO(fs): Since 'ch' and 'ex' are still accessed directly from the font,
+  // they will still have zoom applied.
   CSSToLengthConversionData::FontSizes font_sizes(em, rem,
-                                                  &ParentStyle()->GetFont());
+                                                  &font_style->GetFont());
   CSSToLengthConversionData::ViewportSize viewport_size(
       GetDocument().GetLayoutView());
 
   return CSSToLengthConversionData(Style(), font_sizes, viewport_size, 1);
 }
 
+CSSToLengthConversionData StyleResolverState::FontSizeConversionData() const {
+  return UnzoomedLengthConversionData(ParentStyle());
+}
+
+CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData()
+    const {
+  return UnzoomedLengthConversionData(Style());
+}
+
 void StyleResolverState::SetParentStyle(
     scoped_refptr<const ComputedStyle> parent_style) {
   parent_style_ = std::move(parent_style);
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
index b50afc5..541940e 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
@@ -97,6 +97,7 @@
     return css_to_length_conversion_data_;
   }
   CSSToLengthConversionData FontSizeConversionData() const;
+  CSSToLengthConversionData UnzoomedLengthConversionData() const;
 
   void SetConversionFontSizes(
       const CSSToLengthConversionData::FontSizes& font_sizes) {
@@ -193,6 +194,9 @@
       const CSSPendingSubstitutionValue&) const;
 
  private:
+  CSSToLengthConversionData UnzoomedLengthConversionData(
+      const ComputedStyle* font_style) const;
+
   ElementResolveContext element_context_;
   Member<Document> document_;
 
diff --git a/third_party/blink/renderer/core/frame/remote_dom_window.h b/third_party/blink/renderer/core/frame/remote_dom_window.h
index ccacdd3..cb0507c6 100644
--- a/third_party/blink/renderer/core/frame/remote_dom_window.h
+++ b/third_party/blink/renderer/core/frame/remote_dom_window.h
@@ -7,7 +7,7 @@
 
 #include "third_party/blink/renderer/core/frame/dom_window.h"
 #include "third_party/blink/renderer/core/frame/remote_frame.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -48,11 +48,12 @@
                           bool has_user_gesture);
 };
 
-DEFINE_TYPE_CASTS(RemoteDOMWindow,
-                  DOMWindow,
-                  x,
-                  x->IsRemoteDOMWindow(),
-                  x.IsRemoteDOMWindow());
+template <>
+struct DowncastTraits<RemoteDOMWindow> {
+  static bool AllowFrom(const DOMWindow& window) {
+    return window.IsRemoteDOMWindow();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index 485a93ec..0dd5c97 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -125,7 +125,7 @@
   // That combined with wrappers (owned and kept alive by RemoteFrame) keeping
   // persistent strong references to RemoteDOMWindow will prevent the GCing
   // of all these objects. Break the cycle by notifying of detachment.
-  ToRemoteDOMWindow(dom_window_)->FrameDetached();
+  To<RemoteDOMWindow>(dom_window_.Get())->FrameDetached();
   if (cc_layer_)
     SetCcLayer(nullptr, false, false);
 }
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index b14d85c..fa20398 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -951,6 +951,7 @@
 void DocumentLoader::StopLoading() {
   fetcher_->StopFetching();
   body_loader_.reset();
+  virtual_time_pauser_.UnpauseVirtualTime();
   if (!SentDidFinishLoad())
     LoadFailed(ResourceError::CancelledError(Url()));
 }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 6d29d691..bdc93cbf 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -80,6 +80,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/performance_monitor.h"
+#include "third_party/blink/renderer/core/frame/remote_dom_window.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/geometry/dom_point.h"
@@ -488,7 +489,7 @@
 }
 
 bool Internals::doesWindowHaveUrlFragment(DOMWindow* window) {
-  if (window->IsRemoteDOMWindow())
+  if (IsA<RemoteDOMWindow>(window))
     return false;
   return ToLocalFrame(window->GetFrame())
       ->GetDocument()
diff --git a/third_party/blink/renderer/devtools/scripts/chrome_debug_launcher/launch_chrome.js b/third_party/blink/renderer/devtools/scripts/chrome_debug_launcher/launch_chrome.js
index e7b2625..7c568a3 100644
--- a/third_party/blink/renderer/devtools/scripts/chrome_debug_launcher/launch_chrome.js
+++ b/third_party/blink/renderer/devtools/scripts/chrome_debug_launcher/launch_chrome.js
@@ -48,15 +48,19 @@
 
 function launchChromeWindows() {
   var chromeCanaryPath;
-  var suffix = '\\Google\\Chrome SxS\\Application\\chrome.exe';
-  var prefixes = [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']];
-  for (var i = 0; i < prefixes.length; i++) {
-    var prefix = prefixes[i];
-    try {
-      chromeCanaryPath = path.join(prefix, suffix);
-      fs.accessSync(chromeCanaryPath);
-      break;
-    } catch (e) {
+  if (utils.isFile(process.env.CHROMIUM_PATH)) {
+    chromeCanaryPath = process.env.CHROMIUM_PATH;
+  } else {
+    var suffix = '\\Google\\Chrome SxS\\Application\\chrome.exe';
+    var prefixes = [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']];
+    for (var i = 0; i < prefixes.length; i++) {
+      var prefix = prefixes[i];
+      try {
+        chromeCanaryPath = path.join(prefix, suffix);
+        fs.accessSync(chromeCanaryPath);
+        break;
+      } catch (e) {
+      }
     }
   }
   launchChrome(chromeCanaryPath, chromeArgs);
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
index 5574c68..5380874 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -249,18 +249,27 @@
              : auto_picture_in_picture_elements_.back();
 }
 
-void PictureInPictureControllerImpl::PageVisibilityChanged() {
-  DCHECK(GetSupplementable());
+bool PictureInPictureControllerImpl::IsAutoPictureInPictureAllowed() const {
+  // Chrome extensions are allowed to trigger Auto Picture-in-Picture.
+  if (GetSupplementable()->Url().ProtocolIs("chrome-extension"))
+    return true;
 
-  // Auto Picture-in-Picture is allowed only in a PWA window.
+  // Otherwise, Auto Picture-in-Picture is allowed only in a PWA window.
   if (!GetSupplementable()->GetFrame() ||
       GetSupplementable()->GetFrame()->View()->DisplayMode() ==
           WebDisplayMode::kWebDisplayModeBrowser) {
-    return;
+    return false;
   }
 
-  // Auto Picture-in-Picture is allowed only in the scope of a PWA.
-  if (!GetSupplementable()->IsInWebAppScope())
+  // And if in a PWA window, Auto Picture-in-Picture is allowed only in the
+  // scope of the PWA.
+  return (GetSupplementable()->IsInWebAppScope());
+}
+
+void PictureInPictureControllerImpl::PageVisibilityChanged() {
+  DCHECK(GetSupplementable());
+
+  if (!IsAutoPictureInPictureAllowed())
     return;
 
   // If page becomes visible and Picture-in-Picture element has entered
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
index e5e5dd6..f0df21f 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
@@ -62,6 +62,11 @@
   // recently.
   HTMLVideoElement* AutoPictureInPictureElement() const;
 
+  // Returns whether Auto Picture-in-Picture is allowed. It returns true if
+  // it's a Chrome extension or if is's a PWA window in its web app scope.
+  // Otherwise it returns false.
+  bool IsAutoPictureInPictureAllowed() const;
+
   // Implementation of PictureInPictureController.
   void EnterPictureInPicture(HTMLVideoElement*,
                              ScriptPromiseResolver*) override;
diff --git a/third_party/blink/renderer/platform/fonts/font_platform_data.cc b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
index 77b09a3..ccfc07f 100644
--- a/third_party/blink/renderer/platform/fonts/font_platform_data.cc
+++ b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
@@ -170,7 +170,7 @@
 #if defined(OS_MACOSX)
 CTFontRef FontPlatformData::CtFont() const {
   return SkTypeface_GetCTFontRef(typeface_.get());
-};
+}
 
 CGFontRef FontPlatformData::CgFont() const {
   if (!CtFont())
diff --git a/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc b/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
index 73a48b7..8e0ab9f 100644
--- a/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
+++ b/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
@@ -116,6 +116,12 @@
   SkPath path;
   font.getPath(glyph, &path);
   *bounds = path.getBounds();
+  // For Apple Color Emoji path bounds are returning empty rectangles, see
+  // https://bugs.chromium.org/p/skia/issues/detail?id=8779
+  // OpenTypeVerticalData::GetVerticalTranslationsForGlyphs needs a non-empty
+  // rectangle for vertical origin computation, hence fall back to bounds here.
+  if (UNLIKELY(bounds->isEmpty()))
+    font.getWidths(&glyph, 1, nullptr, bounds);
 #else
   font.getWidths(&glyph, 1, nullptr, bounds);
 #endif
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 298f229..38975370 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3922,8 +3922,8 @@
 crbug.com/626703 external/wpt/encoding/eof-utf-8-two.html [ Failure ]
 crbug.com/626703 external/wpt/html/browsers/the-window-object/window-open-noopener.html [ Timeout ]
 crbug.com/626703 external/wpt/html/browsers/windows/noreferrer-window-name.html [ Timeout ]
-crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-16be.html [ Timeout Crash ]
-crbug.com/626703 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html [ Timeout ]
+crbug.com/626703 crbug.com/930297 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-16be.html [ Timeout Crash ]
+crbug.com/626703 crbug.com/930297 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html [ Timeout Crash ]
 crbug.com/626703 external/wpt/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html [ Failure ]
 crbug.com/626703 external/wpt/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html [ Failure ]
 crbug.com/626703 external/wpt/html/semantics/embedded-content/the-img-element/relevant-mutations.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index 1bb52a4..a748c73 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -109097,6 +109097,18 @@
      {}
     ]
    ],
+   "svg/pservers/reftests/radialgradient-fully-overlapping.svg": [
+    [
+     "/svg/pservers/reftests/radialgradient-fully-overlapping.svg",
+     [
+      [
+       "/svg/pservers/reftests/reference/green-100x100.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "svg/pservers/reftests/stop-color-currentcolor-dynamic-001.svg": [
     [
      "/svg/pservers/reftests/stop-color-currentcolor-dynamic-001.svg",
@@ -175024,6 +175036,11 @@
      {}
     ]
    ],
+   "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [
+    [
+     {}
+    ]
+   ],
    "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [
     [
      {}
@@ -223595,6 +223612,12 @@
      {}
     ]
    ],
+   "custom-elements/reactions/HTMLAreaElement.html": [
+    [
+     "/custom-elements/reactions/HTMLAreaElement.html",
+     {}
+    ]
+   ],
    "custom-elements/reactions/HTMLBaseElement.html": [
     [
      "/custom-elements/reactions/HTMLBaseElement.html",
@@ -223631,6 +223654,24 @@
      {}
     ]
    ],
+   "custom-elements/reactions/HTMLEmbedElement.html": [
+    [
+     "/custom-elements/reactions/HTMLEmbedElement.html",
+     {}
+    ]
+   ],
+   "custom-elements/reactions/HTMLFieldSetElement.html": [
+    [
+     "/custom-elements/reactions/HTMLFieldSetElement.html",
+     {}
+    ]
+   ],
+   "custom-elements/reactions/HTMLImageElement.html": [
+    [
+     "/custom-elements/reactions/HTMLImageElement.html",
+     {}
+    ]
+   ],
    "custom-elements/reactions/HTMLInputElement.html": [
     [
      "/custom-elements/reactions/HTMLInputElement.html",
@@ -251715,6 +251756,14 @@
      {}
     ]
    ],
+   "infrastructure/testdriver/actions/actionsWithKeyPressed.html": [
+    [
+     "/infrastructure/testdriver/actions/actionsWithKeyPressed.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "infrastructure/testdriver/actions/elementPosition.html": [
     [
      "/infrastructure/testdriver/actions/elementPosition.html",
@@ -393580,12 +393629,16 @@
    "c6eeb1dce90b2a3ffe099cba80e64d71f2741f81",
    "testharness"
   ],
+  "custom-elements/reactions/HTMLAreaElement.html": [
+   "95059b7c8d08606c45aa315eba27c30945ad96e5",
+   "testharness"
+  ],
   "custom-elements/reactions/HTMLBaseElement.html": [
    "82ab9228043053d26496c6ec106b812da5a66267",
    "testharness"
   ],
   "custom-elements/reactions/HTMLButtonElement.html": [
-   "b97d479d7c6ddcc4dc05d3a3501fe60b21ff051d",
+   "f97b6daa0b5c23b83ea916e2bf756b49ecf3a51a",
    "testharness"
   ],
   "custom-elements/reactions/HTMLCanvasElement.html": [
@@ -393604,6 +393657,18 @@
    "5fe422cdfc1df56d58e4eeac1be4669ba8fee967",
    "testharness"
   ],
+  "custom-elements/reactions/HTMLEmbedElement.html": [
+   "505d9e3215b1b2f075e396dfba4ed0f14421079a",
+   "testharness"
+  ],
+  "custom-elements/reactions/HTMLFieldSetElement.html": [
+   "4aea2780ba5d279bcd54f9785e364d012b25c079",
+   "testharness"
+  ],
+  "custom-elements/reactions/HTMLImageElement.html": [
+   "b483c3664051e4c5e43f9f9103ea072ba5b97df5",
+   "testharness"
+  ],
   "custom-elements/reactions/HTMLInputElement.html": [
    "dc4b22a22eea3ea841b1380e7db3e75e7f4eb256",
    "testharness"
@@ -393689,7 +393754,7 @@
    "testharness"
   ],
   "custom-elements/reactions/resources/reactions.js": [
-   "84d039bad9fb3674e124f7f852e77b2fcdf21a28",
+   "87510ceee164ffb331808d1c0a026af43fde1fbc",
    "support"
   ],
   "custom-elements/reactions/with-exceptions.html": [
@@ -401161,7 +401226,7 @@
    "testharness"
   ],
   "fetch/data-urls/processing.any-expected.txt": [
-   "1e47de1060e4d825cd7103a81ceb54d807aff130",
+   "175aa9f992e94925bab022d7eca862ec0c9e2f46",
    "support"
   ],
   "fetch/data-urls/processing.any.js": [
@@ -401169,7 +401234,7 @@
    "testharness"
   ],
   "fetch/data-urls/processing.any.worker-expected.txt": [
-   "1e47de1060e4d825cd7103a81ceb54d807aff130",
+   "175aa9f992e94925bab022d7eca862ec0c9e2f46",
    "support"
   ],
   "fetch/data-urls/resources/base64.json": [
@@ -422696,6 +422761,10 @@
    "cbae6b15410e13433c4a9fadd8c2a8cc5fbc4fdc",
    "support"
   ],
+  "infrastructure/metadata/infrastructure/testdriver/actions/actionsWithKeyPressed.html.ini": [
+   "78bfa5f38a1c501c647c142e03a9586e1c2ed7d4",
+   "support"
+  ],
   "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [
    "9ae71a6e73e22a855c69d3269936d71c17d6e9e5",
    "support"
@@ -422864,6 +422933,10 @@
    "ea7973a62e0ee9cdc874879fd844b2309e944e61",
    "testharness"
   ],
+  "infrastructure/testdriver/actions/actionsWithKeyPressed.html": [
+   "74e939f5fde4773aade6ce4f7bbee573e39ae8ec",
+   "testharness"
+  ],
   "infrastructure/testdriver/actions/elementPosition.html": [
    "145852e7b51bd0cdc9e7b4ef5ebddcbf1c0235c5",
    "testharness"
@@ -424149,11 +424222,11 @@
    "testharness"
   ],
   "mathml/META.yml": [
-   "a410f582f0a9b006946e8d9c46e1e0a2b5acea43",
+   "5aea9088d744bfa835ca91217c9a6d9f60253e3e",
    "support"
   ],
   "mathml/README.md": [
-   "bab35474dd5726d8310f22c826da0e6cff86ab7e",
+   "175c1813deeb7b784925cbb87e7990fb3f056fce",
    "support"
   ],
   "mathml/presentation-markup/fractions/frac-1.html": [
@@ -454372,6 +454445,10 @@
    "04d8d3025ee0f039a05bdd439f2dc02c13f49a23",
    "reftest"
   ],
+  "svg/pservers/reftests/radialgradient-fully-overlapping.svg": [
+   "e16bb4ab917178b7a17bcb82b74046a457e9c03f",
+   "reftest"
+  ],
   "svg/pservers/reftests/reference/green-100x100.svg": [
    "120941444a4898197d6b6001f9908a6cd48b62ba",
    "support"
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAreaElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAreaElement.html
new file mode 100644
index 0000000..95059b7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAreaElement.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLAreaElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="alt, coords, shape, target, download, ping, rel,
+  referrerPolicy of HTMLAreaElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-area-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<map name="yellow" id="map">
+</map>
+<img usemap="#yellow" src="/images/yellow.png" alt="yellow pic">
+
+<script>
+
+function getParentElement() {
+  let map = document.getElementById('map');
+  return map;
+}
+
+function setAttributes(instance) {
+  instance.setAttribute('href', '/images/yellow.png');
+}
+
+testReflectAttributeWithDependentAttributes(
+  'alt', 'alt', 'yellow pic',
+  'yellow pic2', 'alt on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+testReflectAttributeWithParentNode(
+  'coords', 'coords', '1, 1, 5, 5',
+  '2, 2, 6, 6', 'coords on HTMLAreaElement', 'area',
+  getParentElement, HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'shape', 'shape', 'rectangle',
+  'default', 'shape on HTMLAreaElement', 'area',
+  getParentElement, instance => instance.setAttribute('coords', '1, 1, 5, 5'),
+  HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'target', 'target', '_blank',
+  '_top', 'target on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'download', 'download', 'pic1',
+  'pic2', 'download on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'ping', 'ping', 'location.href',
+  `${location.protocol}\/\/${location.host}`, 'ping on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'rel', 'rel', 'help',
+  'noreferrer', 'rel on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+testReflectAttributeWithDependentAttributes(
+  'referrerPolicy', 'referrerpolicy', 'same-origin',
+  'origin', 'referrerPolicy on HTMLAreaElement', 'area',
+  getParentElement, instance => setAttributes(instance), HTMLAreaElement
+);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement.html
index b97d479..f97b6daa 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement.html
@@ -1,7 +1,9 @@
 <!DOCTYPE html>
 <title>Custom Elements: CEReactions on HTMLButtonElement interface</title>
 <meta name="author" title="Zhang Xiaoyu" href="xiaoyux.zhang@intel.com">
-<meta name="assert" content=" autofocus, disabled, formAction, formEnctype, formMethod, formNoValidate, formTarget, name, type, value of HTMLButtonElement interface must have CEReactions">
+<meta name="assert" content=" autofocus, disabled, formAction, formEnctype,
+  formMethod, formNoValidate, formTarget, name, type, value
+  of HTMLButtonElement interface must have CEReactions">
 <meta name="help" content="https://html.spec.whatwg.org/#htmlbuttonelement">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -16,60 +18,63 @@
   return parentElement;
 }
 
-testReflectBooleanAttribute('autofocus', 'autofocus', 'autofocus on HTMLButtonElement', 'button', HTMLButtonElement);
-testReflectBooleanAttribute('disabled', 'disabled', 'disabled on HTMLButtonElement', 'button', HTMLButtonElement);
-testReflectAttribute('name', 'name', 'intel', 'intel1', 'name on HTMLButtonElement', 'button', HTMLButtonElement);
-testReflectAttribute('value', 'value', 'HTML', 'CSS', 'value on HTMLButtonElement', 'button', HTMLButtonElement);
-testReflectAttributeWithParentNode('type', 'type', 'submit', 'reset', 'type on HTMLButtonElement', 'button', () => getParentElement('form'), HTMLButtonElement);
-testReflectAttrWithDepAttr('formAction', 'formaction', 'type', 'intel.asp', 'intel1.asp', 'submit', 'formAction on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
-testReflectAttrWithDepAttr('formEnctype', 'formenctype', 'type', 'text/plain', 'multipart/form-data', 'submit', 'formEnctype on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
-testReflectAttrWithDepAttr('formMethod', 'formmethod', 'type', 'get', 'post', 'submit', 'formMethod on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
-testReflectAttrWithContentValuesAndDepAttr('formNoValidate', 'formnovalidate', 'type', true, '', false, null, 'submit', 'formNoValidate on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
-testReflectAttrWithDepAttr('formTarget', 'formtarget', 'type', '_blank', '_self', 'submit', 'formTarget on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
-
-//In parent node, sub node's observeAttribute which depends another attribute can enqueue by changing attribute value
-//Test reflect attribute with content values and dependent attribute 
-function testReflectAttrWithContentValuesAndDepAttr(jsAtName, coAtName, deAtName, jsAtValue1, coAtValue1, jsAtValue2, coAtValue2, deAtValue, name, elementName, pElementName, interfaceName) {
-    var parentElement = document.createElement(pElementName);
-    document.body.appendChild(parentElement);
-
-    test(() => {
-        var element = define_build_in_custom_element([coAtName], interfaceName, elementName);
-        var instance = document.createElement(elementName, { is: element.name });
-
-        assert_array_equals(element.takeLog().types(), ['constructed']);
-        parentElement.appendChild(instance);
-        assert_array_equals(element.takeLog().types(), ['connected']);
-        instance.setAttribute(deAtName, deAtValue);
-        instance[jsAtName] = jsAtValue1;
-        var logEntries = element.takeLog();
-        assert_array_equals(logEntries.types(), ['attributeChanged']);
-        assert_attribute_log_entry(logEntries.last(), { name: coAtName, oldValue: null, newValue: coAtValue1, namespace: null });
-
-    }, name + ' must enqueue an attributeChanged reaction when adding a new attribute');
-
-    test(() => {
-        var element = define_build_in_custom_element([coAtName], interfaceName, elementName);
-        var instance = document.createElement(elementName, { is: element.name });
-        parentElement.appendChild(instance);
-        instance.setAttribute(deAtName, deAtValue);
-        instance[jsAtName] = jsAtValue1;
-
-        assert_array_equals(element.takeLog().types(), ['constructed', 'connected', 'attributeChanged']);
-        instance[jsAtName] = jsAtValue2;
-        var logEntries = element.takeLog();
-        assert_array_equals(logEntries.types(), ['attributeChanged']);
-        assert_attribute_log_entry(logEntries.last(), { name: coAtName, oldValue: coAtValue1, newValue: coAtValue2, namespace: null });
-
-    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
-
-    parentElement.parentNode.removeChild(parentElement);
+function setAttributes(instance) {
+  instance.setAttribute('type', 'submit');
 }
 
-//Package reflect attribute with dependent attribute
-function testReflectAttrWithDepAttr(jsAtName, coAtName, deAtName, jsAtValue1, jsAtValue2, deAtValue, name, elementName, pElementName, interfaceName) {
-    testReflectAttrWithContentValuesAndDepAttr(jsAtName, coAtName, deAtName, jsAtValue1, jsAtValue1, jsAtValue2, jsAtValue2, deAtValue, name, elementName, pElementName, interfaceName);
-}
+testReflectBooleanAttribute(
+  'autofocus', 'autofocus', 'autofocus on HTMLButtonElement',
+  'button', HTMLButtonElement
+);
+testReflectBooleanAttribute(
+  'disabled', 'disabled','disabled on HTMLButtonElement',
+  'button', HTMLButtonElement
+);
+testReflectAttribute(
+  'name', 'name', 'intel',
+  'intel1', 'name on HTMLButtonElement', 'button',
+  HTMLButtonElement
+);
+testReflectAttribute(
+  'value', 'value', 'HTML',
+  'CSS', 'value on HTMLButtonElement', 'button',
+  HTMLButtonElement
+);
+testReflectAttributeWithParentNode(
+  'type', 'type', 'submit',
+  'reset',  'type on HTMLButtonElement', 'button',
+  () => getParentElement('form'), HTMLButtonElement
+);
+testReflectAttributeWithDependentAttributes(
+  'formAction', 'formaction', 'intel.asp',
+  'intel1.asp', 'formAction on HTMLButtonElement', 'button',
+  () => getParentElement('form'), instance => setAttributes(instance),
+  HTMLButtonElement
+);
+testReflectAttributeWithDependentAttributes(
+  'formEnctype', 'formenctype', 'text/plain', 'multipart/form-data',
+  'formEnctype on HTMLButtonElement', 'button', () => getParentElement('form'),
+  instance => setAttributes(instance),
+  HTMLButtonElement
+);
+testReflectAttributeWithDependentAttributes(
+  'formMethod', 'formmethod', 'get',
+  'post', 'formMethod on HTMLButtonElement', 'button',
+  () => getParentElement('form'), instance => setAttributes(instance),
+  HTMLButtonElement
+);
+testReflectBooleanAttributeWithDependentAttributes(
+  'formNoValidate', 'formnovalidate', 'formNoValidate on HTMLButtonElement',
+  'button', () => getParentElement('form'),
+  instance => setAttributes(instance),
+  HTMLButtonElement
+);
+testReflectAttributeWithDependentAttributes(
+  'formTarget', 'formtarget', '_blank',
+  '_self', 'formTarget on HTMLButtonElement', 'button',
+  () => getParentElement('form'), instance => setAttributes(instance),
+  HTMLButtonElement
+);
 
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLEmbedElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLEmbedElement.html
new file mode 100644
index 0000000..505d9e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLEmbedElement.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLEmbedElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="src, type, width, height of
+  HTMLEmbedElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-embed-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<script>
+
+testReflectAttribute(
+  'src', 'src', '/media/movie_5.mp4',
+  '/media/sound_5.mp3', 'src on HTMLEmbedElement', 'embed',
+  HTMLEmbedElement
+);
+testReflectAttribute(
+  'type', 'type', 'video/webm',
+  'video/mp4', 'type on HTMLEmbedElement', 'embed',
+  HTMLEmbedElement
+);
+testReflectAttribute(
+  'width', 'width', '100',
+  '120', 'width on HTMLEmbedElement', 'embed',
+  HTMLEmbedElement
+);
+testReflectAttribute(
+  'height', 'height', '100',
+  '120', 'height on HTMLEmbedElement', 'embed',
+  HTMLEmbedElement
+);
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLFieldSetElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLFieldSetElement.html
new file mode 100644
index 0000000..4aea278
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLFieldSetElement.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLFieldSetElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="disabled, name of
+  HTMLFieldSetElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-fieldset-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<body>
+<script>
+
+function getParentElement() {
+  let form = document.createElement("form");
+  document.body.appendChild(form);
+  return form;
+}
+
+testReflectBooleanAttributeWithParentNode(
+  'disabled', 'disabled', 'disabled on HTMLFieldSetElement',
+  'fieldset', getParentElement, HTMLFieldSetElement
+);
+testReflectAttributeWithParentNode(
+  'name', 'name', 'fieldset1',
+  'fieldset2', 'name on HTMLFieldSetElement', 'fieldset',
+  getParentElement, HTMLFieldSetElement
+);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLImageElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLImageElement.html
new file mode 100644
index 0000000..b483c36
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLImageElement.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<title>Custom Elements: CEReactions on HTMLImageElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<meta name="assert" content="alt, src, srcset, sizes, crossOrigin, useMap,
+  isMap, width, height, referrerPolicy, decoding of
+  HTMLImageElement interface must have CEReactions">
+<meta name="help" content="https://html.spec.whatwg.org/#the-img-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/custom-elements-helpers.js"></script>
+<script src="./resources/reactions.js"></script>
+
+<map name="yellow"></map>
+<map name="green"></map>
+<a href="/" id="a">
+</a>
+<body>
+<script>
+
+function getParentElement() {
+  return document.body;
+}
+
+function setAttributes(instance) {
+  instance.setAttribute('src', '/images/green-1x1.png');
+}
+
+testReflectAttributeWithDependentAttributes(
+  'alt', 'alt', 'image1',
+  'image2', 'alt on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithParentNode(
+  'src', 'src', '/images/green-1x1.png',
+  '/images/green-2x2.png', 'src on HTMLImageElement', 'img',
+  getParentElement, HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'srcset', 'srcset', '/images/green.png',
+  '/images/green-2x2.png', 'srcset on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'sizes', 'sizes', '(max-width: 32px) 28px',
+  '(max-width: 48px) 44px', 'sizes on HTMLImageElement', 'img',
+  getParentElement, instance => {
+    instance.setAttribute('src', '/images/green-1x1.png');
+    instance.setAttribute('srcset', '/images/green-2x2.png 1x');
+  }, HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'crossOrigin', 'crossorigin', 'use-credentials',
+  'anonymous', 'crossOrigin on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'useMap', 'usemap', '#yellow',
+  '#green', 'useMap on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectBooleanAttributeWithDependentAttributes(
+  'isMap', 'ismap', 'isMap on HTMLImageElement',
+  'img', () => { return document.getElementById('a') },
+  instance => setAttributes(instance),
+  HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'width', 'width', '1',
+  '2', 'width on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'height', 'height', '1',
+  '2', 'height on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'referrerPolicy', 'referrerpolicy', 'same-origin',
+  'origin', 'referrerPolicy on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+testReflectAttributeWithDependentAttributes(
+  'decoding', 'decoding', 'async',
+  'sync', 'decoding on HTMLImageElement', 'img',
+  getParentElement, instance => setAttributes(instance), HTMLImageElement
+);
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/resources/reactions.js b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/resources/reactions.js
index 84d039ba..87510ce 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/resources/reactions.js
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/resources/reactions.js
@@ -168,6 +168,48 @@
     testReflectAttributeWithContentValues(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, interfaceName);
 }
 
+function testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, elementName, getParentElement, setAttributes, interfaceName) {
+    let parentElement = getParentElement();
+
+    test(() => {
+        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
+        let instance = document.createElement(elementName, { is: element.name });
+
+        assert_array_equals(element.takeLog().types(), ['constructed']);
+        parentElement.appendChild(instance);
+        assert_array_equals(element.takeLog().types(), ['connected']);
+        setAttributes(instance);
+        instance[jsAttributeName] = validValue1;
+        let logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: null, newValue: contentValue1, namespace: null });
+
+    }, name + ' must enqueue an attributeChanged reaction when adding a new attribute');
+
+    test(() => {
+        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
+        let instance = document.createElement(elementName, { is: element.name });
+        parentElement.appendChild(instance);
+        setAttributes(instance);
+        instance[jsAttributeName] = validValue1;
+
+        assert_array_equals(element.takeLog().types(), ['constructed', 'connected', 'attributeChanged']);
+        instance[jsAttributeName] = validValue2;
+        let logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: contentValue1, newValue: contentValue2, namespace: null });
+
+    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
+}
+
+function testReflectAttributeWithDependentAttributes(jsAttributeName, contentAttributeName, validValue1, validValue2, name, elementName, getParentElement, setAttributes, interfaceName) {
+    testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, validValue1, validValue1, validValue2, validValue2, name, elementName, getParentElement, setAttributes, interfaceName);
+}
+
+function testReflectBooleanAttributeWithDependentAttributes(jsAttributeName, contentAttributeName, name, elementName, getParentElement, setAttributes, interfaceName) {
+    testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, getParentElement, setAttributes, interfaceName);
+}
+
 function testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, elementName, getParentElement, interfaceName) {
     let parentElement = getParentElement();
 
@@ -203,6 +245,10 @@
     testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, validValue1, validValue1, validValue2, validValue2, name, elementName, getParentElement, interfaceName);
 }
 
+function testReflectBooleanAttributeWithParentNode(jsAttributeName, contentAttributeName, name, elementName, getParentElement, interfaceName) {
+    testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, getParentElement, interfaceName);
+}
+
 function testAttributeAdder(testFunction, name) {
     test(function () {
         var element = define_new_custom_element(['id']);
diff --git a/third_party/blink/web_tests/external/wpt/mathml/META.yml b/third_party/blink/web_tests/external/wpt/mathml/META.yml
index a410f58..5aea908 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/META.yml
+++ b/third_party/blink/web_tests/external/wpt/mathml/META.yml
@@ -1,3 +1,3 @@
-spec: http://www.mathml-association.org/MathMLinHTML5/
+spec: https://mathml-refresh.github.io/mathml-core/
 suggested_reviewers:
   - fred-wang
diff --git a/third_party/blink/web_tests/external/wpt/mathml/README.md b/third_party/blink/web_tests/external/wpt/mathml/README.md
index bab3547..175c181 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/README.md
+++ b/third_party/blink/web_tests/external/wpt/mathml/README.md
@@ -1,13 +1,7 @@
-# MathML: Tests for the MathML in HTML5 implementation note
+# MathML: Tests for the MathML Core specification
 
 This directory contains tests for the
-[MathML in HTML5 implementation note](http://www.mathml-association.org/MathMLinHTML5/)
-which is itself based on the
-[HTML5 W3C recommendation](https://www.w3.org/TR/html5/),
-on the [MathML3 W3C recommendation](https://www.w3.org/TR/MathML3/)
-and on the
-[Open Font Format 3](http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=66391) standard.
-
+[MathML Core specification](https://mathml-refresh.github.io/mathml-core/).
 Many of the tests verify OpenType features and require specific Web fonts for
 that purpose. WOFF fonts are generated by scripts in the `tools/` folder using
 the Python API of
diff --git a/third_party/blink/web_tests/fast/text/emoji-vertical-origin-visual.html b/third_party/blink/web_tests/fast/text/emoji-vertical-origin-visual.html
new file mode 100644
index 0000000..d5f03fb
--- /dev/null
+++ b/third_party/blink/web_tests/fast/text/emoji-vertical-origin-visual.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Writing Modes: Emoji in writing-mode: vertical-lr or vertical-rl</title>
+<link rel="author" title="The Chromium Authors">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#block-flow">
+<meta name="assert" content="Emoji must be correctly positioned as part of a vertical run.">
+<meta name="flags" content="">
+<style>
+body {
+font-size: 64px;
+}
+</style>
+</head>
+<!-- The diamond emoji needs to be rendered between the Ahem characters and must
+not cover the top or bottom adjacent character. -->
+<p style="writing-mode: vertical-lr;">あ🔷あ</p>
+<p style="writing-mode: vertical-rl;">あ🔷あ</p>
diff --git a/third_party/blink/web_tests/platform/linux/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/linux/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..d5dab24
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..766e200c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..030e64c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..b50ec93
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/mac/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..0f9d1d12
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/win/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..c04cf0cf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/text/emoji-vertical-origin-visual-expected.png b/third_party/blink/web_tests/platform/win7/fast/text/emoji-vertical-origin-visual-expected.png
new file mode 100644
index 0000000..733eb62
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win7/fast/text/emoji-vertical-origin-visual-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/zoom/zoomed-stroke-width-em.html b/third_party/blink/web_tests/svg/zoom/zoomed-stroke-width-em.html
new file mode 100644
index 0000000..5b1706c
--- /dev/null
+++ b/third_party/blink/web_tests/svg/zoom/zoomed-stroke-width-em.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Zoomed EM resolution for 'stroke-width'</title>
+<script src="../../resources/ahem.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<style>
+  html {
+    font-size: 50px;
+    font-family: Ahem;
+    zoom: 4;
+  }
+  body {
+    font-size: initial;
+    font-family: initial;
+    zoom: 0.25;
+  }
+</style>
+<svg font-size="50" font-family="Ahem" style="zoom: 3">
+  <rect width="100" height="100" stroke-width="1em"/>
+  <rect width="100" height="100" stroke-width="1rem"/>
+</svg>
+<script>
+  const elements = document.querySelectorAll('rect');
+
+  test(function() {
+    let computed_size = getComputedStyle(elements[0]).getPropertyValue('stroke-width');
+    assert_equals(computed_size, '50px', 'em');
+  }, document.title + ', em');
+
+  test(function() {
+    let computed_size = getComputedStyle(elements[1]).getPropertyValue('stroke-width');
+    assert_equals(computed_size, '50px', 'rem');
+  }, document.title + ', rem');
+</script>
diff --git a/third_party/boringssl/ios-arm/crypto/fipsmodule/bsaes-armv7.S b/third_party/boringssl/ios-arm/crypto/fipsmodule/bsaes-armv7.S
index d997c6c..6c25fcc 100644
--- a/third_party/boringssl/ios-arm/crypto/fipsmodule/bsaes-armv7.S
+++ b/third_party/boringssl/ios-arm/crypto/fipsmodule/bsaes-armv7.S
@@ -1589,1001 +1589,5 @@
 
 	ldmia	sp!, {r4,r5,r6,r7,r8, pc}
 
-.globl	_bsaes_xts_encrypt
-.private_extern	_bsaes_xts_encrypt
-#ifdef __thumb2__
-.thumb_func	_bsaes_xts_encrypt
-#endif
-.align	4
-_bsaes_xts_encrypt:
-	mov	ip, sp
-	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
-	VFP_ABI_PUSH
-	mov	r6, sp				@ future r3
-
-	mov	r7, r0
-	mov	r8, r1
-	mov	r9, r2
-	mov	r10, r3
-
-	sub	r0, sp, #0x10			@ 0x10
-	bic	r0, #0xf			@ align at 16 bytes
-	mov	sp, r0
-
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r0, [ip]			@ pointer to input tweak
-#else
-	@ generate initial tweak
-	ldr	r0, [ip, #4]			@ iv[]
-	mov	r1, sp
-	ldr	r2, [ip, #0]			@ key2
-	bl	_AES_encrypt
-	mov	r0,sp				@ pointer to initial tweak
-#endif
-
-	ldr	r1, [r10, #240]		@ get # of rounds
-	mov	r3, r6
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	@ allocate the key schedule on the stack
-	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
-	@ add	r12, #96			@ size of bit-sliced key schedule
-	sub	r12, #48			@ place for tweak[9]
-
-	@ populate the key schedule
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	mov	sp, r12
-	add	r12, #0x90			@ pass key schedule
-	bl	_bsaes_key_convert
-	veor	q7, q7, q15	@ fix up last round key
-	vstmia	r12, {q7}			@ save last round key
-#else
-	ldr	r12, [r10, #244]
-	eors	r12, #1
-	beq	0f
-
-	str	r12, [r10, #244]
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	add	r12, r10, #248			@ pass key schedule
-	bl	_bsaes_key_convert
-	veor	q7, q7, q15	@ fix up last round key
-	vstmia	r12, {q7}
-
-.align	2
-	sub	sp, #0x90			@ place for tweak[9]
-#endif
-
-	vld1.8	{q8}, [r0]			@ initial tweak
-	adr	r2, Lxts_magic
-
-	subs	r9, #0x80
-	blo	Lxts_enc_short
-	b	Lxts_enc_loop
-
-.align	4
-Lxts_enc_loop:
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q6, q8, #63
-	mov	r0, sp
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q9, #63
-	veor	q9, q9, q6
-	vand	q7, q7, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q10, #63
-	veor	q10, q10, q7
-	vand	q6, q6, q5
-	vld1.8	{q0}, [r7]!
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q11, #63
-	veor	q11, q11, q6
-	vand	q7, q7, q5
-	vld1.8	{q1}, [r7]!
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q12, #63
-	veor	q12, q12, q7
-	vand	q6, q6, q5
-	vld1.8	{q2}, [r7]!
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q13, #63
-	veor	q13, q13, q6
-	vand	q7, q7, q5
-	vld1.8	{q3}, [r7]!
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q14, #63
-	veor	q14, q14, q7
-	vand	q6, q6, q5
-	vld1.8	{q4}, [r7]!
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q15, #63
-	veor	q15, q15, q6
-	vand	q7, q7, q5
-	vld1.8	{q5}, [r7]!
-	veor	q4, q4, q12
-	vadd.u64	q8, q15, q15
-	vst1.64	{q15}, [r0,:128]!
-	vswp	d15,d14
-	veor	q8, q8, q7
-	vst1.64	{q8}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6,q7}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	veor	q7, q7, q15
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vld1.64	{q14,q15}, [r0,:128]!
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q2, q14
-	vst1.8	{q10,q11}, [r8]!
-	veor	q13, q5, q15
-	vst1.8	{q12,q13}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-
-	subs	r9, #0x80
-	bpl	Lxts_enc_loop
-
-Lxts_enc_short:
-	adds	r9, #0x70
-	bmi	Lxts_enc_done
-
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q7, q8, #63
-	mov	r0, sp
-	vand	q7, q7, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q9, #63
-	veor	q9, q9, q7
-	vand	q6, q6, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q10, #63
-	veor	q10, q10, q6
-	vand	q7, q7, q5
-	vld1.8	{q0}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_1
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q11, #63
-	veor	q11, q11, q7
-	vand	q6, q6, q5
-	vld1.8	{q1}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_2
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q12, #63
-	veor	q12, q12, q6
-	vand	q7, q7, q5
-	vld1.8	{q2}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_3
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q13, #63
-	veor	q13, q13, q7
-	vand	q6, q6, q5
-	vld1.8	{q3}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_4
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q14, #63
-	veor	q14, q14, q6
-	vand	q7, q7, q5
-	vld1.8	{q4}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_5
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q15, #63
-	veor	q15, q15, q7
-	vand	q6, q6, q5
-	vld1.8	{q5}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_enc_6
-	veor	q4, q4, q12
-	sub	r9, #0x10
-	vst1.64	{q15}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vld1.64	{q14}, [r0,:128]!
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q2, q14
-	vst1.8	{q10,q11}, [r8]!
-	vst1.8	{q12}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-.align	4
-Lxts_enc_6:
-	veor	q4, q4, q12
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q5, q5, q13
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	vst1.8	{q10,q11}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-
-@ put this in range for both ARM and Thumb mode adr instructions
-.align	5
-Lxts_magic:
-.quad	1, 0x87
-
-.align	5
-Lxts_enc_5:
-	veor	q3, q3, q11
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q4, q4, q12
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	vst1.8	{q10}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-.align	4
-Lxts_enc_4:
-	veor	q2, q2, q10
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q3, q3, q11
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vst1.8	{q8,q9}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-.align	4
-Lxts_enc_3:
-	veor	q1, q1, q9
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q2, q2, q10
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	vst1.8	{q8}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-.align	4
-Lxts_enc_2:
-	veor	q0, q0, q8
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q1, q1, q9
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	vst1.8	{q0,q1}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_enc_done
-.align	4
-Lxts_enc_1:
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3				@ preserve fp
-
-	bl	_AES_encrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r8]!
-	mov	r3, r4
-
-	vmov	q8, q9		@ next round tweak
-
-Lxts_enc_done:
-#ifndef	XTS_CHAIN_TWEAK
-	adds	r9, #0x10
-	beq	Lxts_enc_ret
-	sub	r6, r8, #0x10
-
-Lxts_enc_steal:
-	ldrb	r0, [r7], #1
-	ldrb	r1, [r8, #-0x10]
-	strb	r0, [r8, #-0x10]
-	strb	r1, [r8], #1
-
-	subs	r9, #1
-	bhi	Lxts_enc_steal
-
-	vld1.8	{q0}, [r6]
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3			@ preserve fp
-
-	bl	_AES_encrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r6]
-	mov	r3, r4
-#endif
-
-Lxts_enc_ret:
-	bic	r0, r3, #0xf
-	vmov.i32	q0, #0
-	vmov.i32	q1, #0
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
-#endif
-Lxts_enc_bzero:@ wipe key schedule [if any]
-	vstmia	sp!, {q0,q1}
-	cmp	sp, r0
-	bne	Lxts_enc_bzero
-
-	mov	sp, r3
-#ifdef	XTS_CHAIN_TWEAK
-	vst1.8	{q8}, [r1]
-#endif
-	VFP_ABI_POP
-	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
-
-
-
-.globl	_bsaes_xts_decrypt
-.private_extern	_bsaes_xts_decrypt
-#ifdef __thumb2__
-.thumb_func	_bsaes_xts_decrypt
-#endif
-.align	4
-_bsaes_xts_decrypt:
-	mov	ip, sp
-	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
-	VFP_ABI_PUSH
-	mov	r6, sp				@ future r3
-
-	mov	r7, r0
-	mov	r8, r1
-	mov	r9, r2
-	mov	r10, r3
-
-	sub	r0, sp, #0x10			@ 0x10
-	bic	r0, #0xf			@ align at 16 bytes
-	mov	sp, r0
-
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r0, [ip]			@ pointer to input tweak
-#else
-	@ generate initial tweak
-	ldr	r0, [ip, #4]			@ iv[]
-	mov	r1, sp
-	ldr	r2, [ip, #0]			@ key2
-	bl	_AES_encrypt
-	mov	r0, sp				@ pointer to initial tweak
-#endif
-
-	ldr	r1, [r10, #240]		@ get # of rounds
-	mov	r3, r6
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	@ allocate the key schedule on the stack
-	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
-	@ add	r12, #96			@ size of bit-sliced key schedule
-	sub	r12, #48			@ place for tweak[9]
-
-	@ populate the key schedule
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	mov	sp, r12
-	add	r12, #0x90			@ pass key schedule
-	bl	_bsaes_key_convert
-	add	r4, sp, #0x90
-	vldmia	r4, {q6}
-	vstmia	r12,  {q15}		@ save last round key
-	veor	q7, q7, q6	@ fix up round 0 key
-	vstmia	r4, {q7}
-#else
-	ldr	r12, [r10, #244]
-	eors	r12, #1
-	beq	0f
-
-	str	r12, [r10, #244]
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	add	r12, r10, #248			@ pass key schedule
-	bl	_bsaes_key_convert
-	add	r4, r10, #248
-	vldmia	r4, {q6}
-	vstmia	r12,  {q15}		@ save last round key
-	veor	q7, q7, q6	@ fix up round 0 key
-	vstmia	r4, {q7}
-
-.align	2
-	sub	sp, #0x90			@ place for tweak[9]
-#endif
-	vld1.8	{q8}, [r0]			@ initial tweak
-	adr	r2, Lxts_magic
-
-#ifndef	XTS_CHAIN_TWEAK
-	tst	r9, #0xf			@ if not multiple of 16
-	it	ne				@ Thumb2 thing, sanity check in ARM
-	subne	r9, #0x10			@ subtract another 16 bytes
-#endif
-	subs	r9, #0x80
-
-	blo	Lxts_dec_short
-	b	Lxts_dec_loop
-
-.align	4
-Lxts_dec_loop:
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q6, q8, #63
-	mov	r0, sp
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q9, #63
-	veor	q9, q9, q6
-	vand	q7, q7, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q10, #63
-	veor	q10, q10, q7
-	vand	q6, q6, q5
-	vld1.8	{q0}, [r7]!
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q11, #63
-	veor	q11, q11, q6
-	vand	q7, q7, q5
-	vld1.8	{q1}, [r7]!
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q12, #63
-	veor	q12, q12, q7
-	vand	q6, q6, q5
-	vld1.8	{q2}, [r7]!
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q13, #63
-	veor	q13, q13, q6
-	vand	q7, q7, q5
-	vld1.8	{q3}, [r7]!
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q14, #63
-	veor	q14, q14, q7
-	vand	q6, q6, q5
-	vld1.8	{q4}, [r7]!
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q15, #63
-	veor	q15, q15, q6
-	vand	q7, q7, q5
-	vld1.8	{q5}, [r7]!
-	veor	q4, q4, q12
-	vadd.u64	q8, q15, q15
-	vst1.64	{q15}, [r0,:128]!
-	vswp	d15,d14
-	veor	q8, q8, q7
-	vst1.64	{q8}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6,q7}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	veor	q7, q7, q15
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vld1.64	{q14,q15}, [r0,:128]!
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q3, q14
-	vst1.8	{q10,q11}, [r8]!
-	veor	q13, q5, q15
-	vst1.8	{q12,q13}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-
-	subs	r9, #0x80
-	bpl	Lxts_dec_loop
-
-Lxts_dec_short:
-	adds	r9, #0x70
-	bmi	Lxts_dec_done
-
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q7, q8, #63
-	mov	r0, sp
-	vand	q7, q7, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q9, #63
-	veor	q9, q9, q7
-	vand	q6, q6, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q10, #63
-	veor	q10, q10, q6
-	vand	q7, q7, q5
-	vld1.8	{q0}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_1
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q11, #63
-	veor	q11, q11, q7
-	vand	q6, q6, q5
-	vld1.8	{q1}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_2
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q12, #63
-	veor	q12, q12, q6
-	vand	q7, q7, q5
-	vld1.8	{q2}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_3
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q13, #63
-	veor	q13, q13, q7
-	vand	q6, q6, q5
-	vld1.8	{q3}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_4
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q14, #63
-	veor	q14, q14, q6
-	vand	q7, q7, q5
-	vld1.8	{q4}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_5
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q15, #63
-	veor	q15, q15, q7
-	vand	q6, q6, q5
-	vld1.8	{q5}, [r7]!
-	subs	r9, #0x10
-	bmi	Lxts_dec_6
-	veor	q4, q4, q12
-	sub	r9, #0x10
-	vst1.64	{q15}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vld1.64	{q14}, [r0,:128]!
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q3, q14
-	vst1.8	{q10,q11}, [r8]!
-	vst1.8	{q12}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_6:
-	vst1.64	{q14}, [r0,:128]		@ next round tweak
-
-	veor	q4, q4, q12
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q5, q5, q13
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	vst1.8	{q10,q11}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_5:
-	veor	q3, q3, q11
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q4, q4, q12
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	vst1.8	{q10}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_4:
-	veor	q2, q2, q10
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q3, q3, q11
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vst1.8	{q8,q9}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_3:
-	veor	q1, q1, q9
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q2, q2, q10
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	vst1.8	{q8}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_2:
-	veor	q0, q0, q8
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q1, q1, q9
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	vst1.8	{q0,q1}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	Lxts_dec_done
-.align	4
-Lxts_dec_1:
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r5, r2			@ preserve magic
-	mov	r2, r10
-	mov	r4, r3				@ preserve fp
-
-	bl	_AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r8]!
-	mov	r3, r4
-	mov	r2, r5
-
-	vmov	q8, q9		@ next round tweak
-
-Lxts_dec_done:
-#ifndef	XTS_CHAIN_TWEAK
-	adds	r9, #0x10
-	beq	Lxts_dec_ret
-
-	@ calculate one round of extra tweak for the stolen ciphertext
-	vldmia	r2, {q5}
-	vshr.s64	q6, q8, #63
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vswp	d13,d12
-	veor	q9, q9, q6
-
-	@ perform the final decryption with the last tweak value
-	vld1.8	{q0}, [r7]!
-	mov	r0, sp
-	veor	q0, q0, q9
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3			@ preserve fp
-
-	bl	_AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q9
-	vst1.8	{q0}, [r8]
-
-	mov	r6, r8
-Lxts_dec_steal:
-	ldrb	r1, [r8]
-	ldrb	r0, [r7], #1
-	strb	r1, [r8, #0x10]
-	strb	r0, [r8], #1
-
-	subs	r9, #1
-	bhi	Lxts_dec_steal
-
-	vld1.8	{q0}, [r6]
-	mov	r0, sp
-	veor	q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-
-	bl	_AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r6]
-	mov	r3, r4
-#endif
-
-Lxts_dec_ret:
-	bic	r0, r3, #0xf
-	vmov.i32	q0, #0
-	vmov.i32	q1, #0
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
-#endif
-Lxts_dec_bzero:@ wipe key schedule [if any]
-	vstmia	sp!, {q0,q1}
-	cmp	sp, r0
-	bne	Lxts_dec_bzero
-
-	mov	sp, r3
-#ifdef	XTS_CHAIN_TWEAK
-	vst1.8	{q8}, [r1]
-#endif
-	VFP_ABI_POP
-	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
-
-
 #endif
 #endif  // !OPENSSL_NO_ASM
diff --git a/third_party/boringssl/linux-arm/crypto/fipsmodule/bsaes-armv7.S b/third_party/boringssl/linux-arm/crypto/fipsmodule/bsaes-armv7.S
index 38a0290..ef3ee85 100644
--- a/third_party/boringssl/linux-arm/crypto/fipsmodule/bsaes-armv7.S
+++ b/third_party/boringssl/linux-arm/crypto/fipsmodule/bsaes-armv7.S
@@ -1580,998 +1580,6 @@
 
 	ldmia	sp!, {r4,r5,r6,r7,r8, pc}
 .size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-.globl	bsaes_xts_encrypt
-.hidden	bsaes_xts_encrypt
-.type	bsaes_xts_encrypt,%function
-.align	4
-bsaes_xts_encrypt:
-	mov	ip, sp
-	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
-	VFP_ABI_PUSH
-	mov	r6, sp				@ future r3
-
-	mov	r7, r0
-	mov	r8, r1
-	mov	r9, r2
-	mov	r10, r3
-
-	sub	r0, sp, #0x10			@ 0x10
-	bic	r0, #0xf			@ align at 16 bytes
-	mov	sp, r0
-
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r0, [ip]			@ pointer to input tweak
-#else
-	@ generate initial tweak
-	ldr	r0, [ip, #4]			@ iv[]
-	mov	r1, sp
-	ldr	r2, [ip, #0]			@ key2
-	bl	AES_encrypt
-	mov	r0,sp				@ pointer to initial tweak
-#endif
-
-	ldr	r1, [r10, #240]		@ get # of rounds
-	mov	r3, r6
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	@ allocate the key schedule on the stack
-	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
-	@ add	r12, #96			@ size of bit-sliced key schedule
-	sub	r12, #48			@ place for tweak[9]
-
-	@ populate the key schedule
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	mov	sp, r12
-	add	r12, #0x90			@ pass key schedule
-	bl	_bsaes_key_convert
-	veor	q7, q7, q15	@ fix up last round key
-	vstmia	r12, {q7}			@ save last round key
-#else
-	ldr	r12, [r10, #244]
-	eors	r12, #1
-	beq	0f
-
-	str	r12, [r10, #244]
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	add	r12, r10, #248			@ pass key schedule
-	bl	_bsaes_key_convert
-	veor	q7, q7, q15	@ fix up last round key
-	vstmia	r12, {q7}
-
-.align	2
-	sub	sp, #0x90			@ place for tweak[9]
-#endif
-
-	vld1.8	{q8}, [r0]			@ initial tweak
-	adr	r2, .Lxts_magic
-
-	subs	r9, #0x80
-	blo	.Lxts_enc_short
-	b	.Lxts_enc_loop
-
-.align	4
-.Lxts_enc_loop:
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q6, q8, #63
-	mov	r0, sp
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q9, #63
-	veor	q9, q9, q6
-	vand	q7, q7, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q10, #63
-	veor	q10, q10, q7
-	vand	q6, q6, q5
-	vld1.8	{q0}, [r7]!
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q11, #63
-	veor	q11, q11, q6
-	vand	q7, q7, q5
-	vld1.8	{q1}, [r7]!
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q12, #63
-	veor	q12, q12, q7
-	vand	q6, q6, q5
-	vld1.8	{q2}, [r7]!
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q13, #63
-	veor	q13, q13, q6
-	vand	q7, q7, q5
-	vld1.8	{q3}, [r7]!
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q14, #63
-	veor	q14, q14, q7
-	vand	q6, q6, q5
-	vld1.8	{q4}, [r7]!
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q15, #63
-	veor	q15, q15, q6
-	vand	q7, q7, q5
-	vld1.8	{q5}, [r7]!
-	veor	q4, q4, q12
-	vadd.u64	q8, q15, q15
-	vst1.64	{q15}, [r0,:128]!
-	vswp	d15,d14
-	veor	q8, q8, q7
-	vst1.64	{q8}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6,q7}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	veor	q7, q7, q15
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vld1.64	{q14,q15}, [r0,:128]!
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q2, q14
-	vst1.8	{q10,q11}, [r8]!
-	veor	q13, q5, q15
-	vst1.8	{q12,q13}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-
-	subs	r9, #0x80
-	bpl	.Lxts_enc_loop
-
-.Lxts_enc_short:
-	adds	r9, #0x70
-	bmi	.Lxts_enc_done
-
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q7, q8, #63
-	mov	r0, sp
-	vand	q7, q7, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q9, #63
-	veor	q9, q9, q7
-	vand	q6, q6, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q10, #63
-	veor	q10, q10, q6
-	vand	q7, q7, q5
-	vld1.8	{q0}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_1
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q11, #63
-	veor	q11, q11, q7
-	vand	q6, q6, q5
-	vld1.8	{q1}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_2
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q12, #63
-	veor	q12, q12, q6
-	vand	q7, q7, q5
-	vld1.8	{q2}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_3
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q13, #63
-	veor	q13, q13, q7
-	vand	q6, q6, q5
-	vld1.8	{q3}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_4
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q14, #63
-	veor	q14, q14, q6
-	vand	q7, q7, q5
-	vld1.8	{q4}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_5
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q15, #63
-	veor	q15, q15, q7
-	vand	q6, q6, q5
-	vld1.8	{q5}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_enc_6
-	veor	q4, q4, q12
-	sub	r9, #0x10
-	vst1.64	{q15}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vld1.64	{q14}, [r0,:128]!
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q2, q14
-	vst1.8	{q10,q11}, [r8]!
-	vst1.8	{q12}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-.align	4
-.Lxts_enc_6:
-	veor	q4, q4, q12
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q5, q5, q13
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	vst1.8	{q10,q11}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-
-@ put this in range for both ARM and Thumb mode adr instructions
-.align	5
-.Lxts_magic:
-.quad	1, 0x87
-
-.align	5
-.Lxts_enc_5:
-	veor	q3, q3, q11
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q4, q4, q12
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	veor	q10, q3, q12
-	vst1.8	{q8,q9}, [r8]!
-	vst1.8	{q10}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-.align	4
-.Lxts_enc_4:
-	veor	q2, q2, q10
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q3, q3, q11
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q6, q11
-	vst1.8	{q8,q9}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-.align	4
-.Lxts_enc_3:
-	veor	q1, q1, q9
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q2, q2, q10
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q4, q10
-	vst1.8	{q0,q1}, [r8]!
-	vst1.8	{q8}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-.align	4
-.Lxts_enc_2:
-	veor	q0, q0, q8
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q1, q1, q9
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_encrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	vst1.8	{q0,q1}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_enc_done
-.align	4
-.Lxts_enc_1:
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3				@ preserve fp
-
-	bl	AES_encrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r8]!
-	mov	r3, r4
-
-	vmov	q8, q9		@ next round tweak
-
-.Lxts_enc_done:
-#ifndef	XTS_CHAIN_TWEAK
-	adds	r9, #0x10
-	beq	.Lxts_enc_ret
-	sub	r6, r8, #0x10
-
-.Lxts_enc_steal:
-	ldrb	r0, [r7], #1
-	ldrb	r1, [r8, #-0x10]
-	strb	r0, [r8, #-0x10]
-	strb	r1, [r8], #1
-
-	subs	r9, #1
-	bhi	.Lxts_enc_steal
-
-	vld1.8	{q0}, [r6]
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3			@ preserve fp
-
-	bl	AES_encrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r6]
-	mov	r3, r4
-#endif
-
-.Lxts_enc_ret:
-	bic	r0, r3, #0xf
-	vmov.i32	q0, #0
-	vmov.i32	q1, #0
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
-#endif
-.Lxts_enc_bzero:@ wipe key schedule [if any]
-	vstmia	sp!, {q0,q1}
-	cmp	sp, r0
-	bne	.Lxts_enc_bzero
-
-	mov	sp, r3
-#ifdef	XTS_CHAIN_TWEAK
-	vst1.8	{q8}, [r1]
-#endif
-	VFP_ABI_POP
-	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
-
-.size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
-
-.globl	bsaes_xts_decrypt
-.hidden	bsaes_xts_decrypt
-.type	bsaes_xts_decrypt,%function
-.align	4
-bsaes_xts_decrypt:
-	mov	ip, sp
-	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
-	VFP_ABI_PUSH
-	mov	r6, sp				@ future r3
-
-	mov	r7, r0
-	mov	r8, r1
-	mov	r9, r2
-	mov	r10, r3
-
-	sub	r0, sp, #0x10			@ 0x10
-	bic	r0, #0xf			@ align at 16 bytes
-	mov	sp, r0
-
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r0, [ip]			@ pointer to input tweak
-#else
-	@ generate initial tweak
-	ldr	r0, [ip, #4]			@ iv[]
-	mov	r1, sp
-	ldr	r2, [ip, #0]			@ key2
-	bl	AES_encrypt
-	mov	r0, sp				@ pointer to initial tweak
-#endif
-
-	ldr	r1, [r10, #240]		@ get # of rounds
-	mov	r3, r6
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	@ allocate the key schedule on the stack
-	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
-	@ add	r12, #96			@ size of bit-sliced key schedule
-	sub	r12, #48			@ place for tweak[9]
-
-	@ populate the key schedule
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	mov	sp, r12
-	add	r12, #0x90			@ pass key schedule
-	bl	_bsaes_key_convert
-	add	r4, sp, #0x90
-	vldmia	r4, {q6}
-	vstmia	r12,  {q15}		@ save last round key
-	veor	q7, q7, q6	@ fix up round 0 key
-	vstmia	r4, {q7}
-#else
-	ldr	r12, [r10, #244]
-	eors	r12, #1
-	beq	0f
-
-	str	r12, [r10, #244]
-	mov	r4, r10			@ pass key
-	mov	r5, r1			@ pass # of rounds
-	add	r12, r10, #248			@ pass key schedule
-	bl	_bsaes_key_convert
-	add	r4, r10, #248
-	vldmia	r4, {q6}
-	vstmia	r12,  {q15}		@ save last round key
-	veor	q7, q7, q6	@ fix up round 0 key
-	vstmia	r4, {q7}
-
-.align	2
-	sub	sp, #0x90			@ place for tweak[9]
-#endif
-	vld1.8	{q8}, [r0]			@ initial tweak
-	adr	r2, .Lxts_magic
-
-#ifndef	XTS_CHAIN_TWEAK
-	tst	r9, #0xf			@ if not multiple of 16
-	it	ne				@ Thumb2 thing, sanity check in ARM
-	subne	r9, #0x10			@ subtract another 16 bytes
-#endif
-	subs	r9, #0x80
-
-	blo	.Lxts_dec_short
-	b	.Lxts_dec_loop
-
-.align	4
-.Lxts_dec_loop:
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q6, q8, #63
-	mov	r0, sp
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q9, #63
-	veor	q9, q9, q6
-	vand	q7, q7, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q10, #63
-	veor	q10, q10, q7
-	vand	q6, q6, q5
-	vld1.8	{q0}, [r7]!
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q11, #63
-	veor	q11, q11, q6
-	vand	q7, q7, q5
-	vld1.8	{q1}, [r7]!
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q12, #63
-	veor	q12, q12, q7
-	vand	q6, q6, q5
-	vld1.8	{q2}, [r7]!
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q13, #63
-	veor	q13, q13, q6
-	vand	q7, q7, q5
-	vld1.8	{q3}, [r7]!
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q14, #63
-	veor	q14, q14, q7
-	vand	q6, q6, q5
-	vld1.8	{q4}, [r7]!
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q15, #63
-	veor	q15, q15, q6
-	vand	q7, q7, q5
-	vld1.8	{q5}, [r7]!
-	veor	q4, q4, q12
-	vadd.u64	q8, q15, q15
-	vst1.64	{q15}, [r0,:128]!
-	vswp	d15,d14
-	veor	q8, q8, q7
-	vst1.64	{q8}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6,q7}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	veor	q7, q7, q15
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vld1.64	{q14,q15}, [r0,:128]!
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q3, q14
-	vst1.8	{q10,q11}, [r8]!
-	veor	q13, q5, q15
-	vst1.8	{q12,q13}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-
-	subs	r9, #0x80
-	bpl	.Lxts_dec_loop
-
-.Lxts_dec_short:
-	adds	r9, #0x70
-	bmi	.Lxts_dec_done
-
-	vldmia	r2, {q5}	@ load XTS magic
-	vshr.s64	q7, q8, #63
-	mov	r0, sp
-	vand	q7, q7, q5
-	vadd.u64	q9, q8, q8
-	vst1.64	{q8}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q9, #63
-	veor	q9, q9, q7
-	vand	q6, q6, q5
-	vadd.u64	q10, q9, q9
-	vst1.64	{q9}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q10, #63
-	veor	q10, q10, q6
-	vand	q7, q7, q5
-	vld1.8	{q0}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_1
-	vadd.u64	q11, q10, q10
-	vst1.64	{q10}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q11, #63
-	veor	q11, q11, q7
-	vand	q6, q6, q5
-	vld1.8	{q1}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_2
-	veor	q0, q0, q8
-	vadd.u64	q12, q11, q11
-	vst1.64	{q11}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q12, #63
-	veor	q12, q12, q6
-	vand	q7, q7, q5
-	vld1.8	{q2}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_3
-	veor	q1, q1, q9
-	vadd.u64	q13, q12, q12
-	vst1.64	{q12}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q13, #63
-	veor	q13, q13, q7
-	vand	q6, q6, q5
-	vld1.8	{q3}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_4
-	veor	q2, q2, q10
-	vadd.u64	q14, q13, q13
-	vst1.64	{q13}, [r0,:128]!
-	vswp	d13,d12
-	vshr.s64	q7, q14, #63
-	veor	q14, q14, q6
-	vand	q7, q7, q5
-	vld1.8	{q4}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_5
-	veor	q3, q3, q11
-	vadd.u64	q15, q14, q14
-	vst1.64	{q14}, [r0,:128]!
-	vswp	d15,d14
-	vshr.s64	q6, q15, #63
-	veor	q15, q15, q7
-	vand	q6, q6, q5
-	vld1.8	{q5}, [r7]!
-	subs	r9, #0x10
-	bmi	.Lxts_dec_6
-	veor	q4, q4, q12
-	sub	r9, #0x10
-	vst1.64	{q15}, [r0,:128]		@ next round tweak
-
-	vld1.8	{q6}, [r7]!
-	veor	q5, q5, q13
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q6, q6, q14
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vld1.64	{q14}, [r0,:128]!
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	veor	q12, q3, q14
-	vst1.8	{q10,q11}, [r8]!
-	vst1.8	{q12}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_6:
-	vst1.64	{q14}, [r0,:128]		@ next round tweak
-
-	veor	q4, q4, q12
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q5, q5, q13
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12,q13}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	veor	q11, q7, q13
-	vst1.8	{q10,q11}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_5:
-	veor	q3, q3, q11
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q4, q4, q12
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	vld1.64	{q12}, [r0,:128]!
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	veor	q10, q2, q12
-	vst1.8	{q8,q9}, [r8]!
-	vst1.8	{q10}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_4:
-	veor	q2, q2, q10
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q3, q3, q11
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10,q11}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	veor	q9, q4, q11
-	vst1.8	{q8,q9}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_3:
-	veor	q1, q1, q9
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q2, q2, q10
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	vld1.64	{q10}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	veor	q8, q6, q10
-	vst1.8	{q0,q1}, [r8]!
-	vst1.8	{q8}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_2:
-	veor	q0, q0, q8
-#ifndef	BSAES_ASM_EXTENDED_KEY
-	add	r4, sp, #0x90			@ pass key schedule
-#else
-	add	r4, r10, #248			@ pass key schedule
-#endif
-	veor	q1, q1, q9
-	mov	r5, r1			@ pass rounds
-	mov	r0, sp
-
-	bl	_bsaes_decrypt8
-
-	vld1.64	{q8,q9}, [r0,:128]!
-	veor	q0, q0, q8
-	veor	q1, q1, q9
-	vst1.8	{q0,q1}, [r8]!
-
-	vld1.64	{q8}, [r0,:128]		@ next round tweak
-	b	.Lxts_dec_done
-.align	4
-.Lxts_dec_1:
-	mov	r0, sp
-	veor	q0, q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r5, r2			@ preserve magic
-	mov	r2, r10
-	mov	r4, r3				@ preserve fp
-
-	bl	AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r8]!
-	mov	r3, r4
-	mov	r2, r5
-
-	vmov	q8, q9		@ next round tweak
-
-.Lxts_dec_done:
-#ifndef	XTS_CHAIN_TWEAK
-	adds	r9, #0x10
-	beq	.Lxts_dec_ret
-
-	@ calculate one round of extra tweak for the stolen ciphertext
-	vldmia	r2, {q5}
-	vshr.s64	q6, q8, #63
-	vand	q6, q6, q5
-	vadd.u64	q9, q8, q8
-	vswp	d13,d12
-	veor	q9, q9, q6
-
-	@ perform the final decryption with the last tweak value
-	vld1.8	{q0}, [r7]!
-	mov	r0, sp
-	veor	q0, q0, q9
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-	mov	r4, r3			@ preserve fp
-
-	bl	AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q9
-	vst1.8	{q0}, [r8]
-
-	mov	r6, r8
-.Lxts_dec_steal:
-	ldrb	r1, [r8]
-	ldrb	r0, [r7], #1
-	strb	r1, [r8, #0x10]
-	strb	r0, [r8], #1
-
-	subs	r9, #1
-	bhi	.Lxts_dec_steal
-
-	vld1.8	{q0}, [r6]
-	mov	r0, sp
-	veor	q0, q8
-	mov	r1, sp
-	vst1.8	{q0}, [sp,:128]
-	mov	r2, r10
-
-	bl	AES_decrypt
-
-	vld1.8	{q0}, [sp,:128]
-	veor	q0, q0, q8
-	vst1.8	{q0}, [r6]
-	mov	r3, r4
-#endif
-
-.Lxts_dec_ret:
-	bic	r0, r3, #0xf
-	vmov.i32	q0, #0
-	vmov.i32	q1, #0
-#ifdef	XTS_CHAIN_TWEAK
-	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
-#endif
-.Lxts_dec_bzero:@ wipe key schedule [if any]
-	vstmia	sp!, {q0,q1}
-	cmp	sp, r0
-	bne	.Lxts_dec_bzero
-
-	mov	sp, r3
-#ifdef	XTS_CHAIN_TWEAK
-	vst1.8	{q8}, [r1]
-#endif
-	VFP_ABI_POP
-	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
-
-.size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
 #endif
 #endif
 #endif  // !OPENSSL_NO_ASM
diff --git a/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S
index 423c697..4e2267b 100644
--- a/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S
@@ -79,13 +79,13 @@
 .cfi_adjust_cfa_offset	88
 .Lctr32_body:
 
-#movdqa	.Lsigma(%rip),%xmm0
+
 	movdqu	(%rcx),%xmm1
 	movdqu	16(%rcx),%xmm2
 	movdqu	(%r8),%xmm3
 	movdqa	.Lone(%rip),%xmm4
 
-#movdqa	%xmm0,4*0(%rsp)
+
 	movdqa	%xmm1,16(%rsp)
 	movdqa	%xmm2,32(%rsp)
 	movdqa	%xmm3,48(%rsp)
@@ -878,9 +878,9 @@
 	cmpq	$64,%rdx
 	jae	.L64_or_more4x
 
-#movdqa		0x00(%rsp),%xmm6
+
 	xorq	%r10,%r10
-#movdqa		%xmm6,0x00(%rsp)
+
 	movdqa	%xmm12,16(%rsp)
 	movdqa	%xmm4,32(%rsp)
 	movdqa	%xmm0,48(%rsp)
@@ -1034,7 +1034,7 @@
 	andq	$-32,%rsp
 	vzeroupper
 
-###############
+
 
 
 
diff --git a/third_party/boringssl/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
index 32c3151..3eb1688 100644
--- a/third_party/boringssl/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
@@ -213,7 +213,7 @@
 	vpclmulqdq	$0x10,(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	96(%rsi),%xmm0
 	vpclmulqdq	$0x01,16(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
@@ -225,7 +225,7 @@
 	vpxor	%xmm6,%xmm5,%xmm5
 
 
-#########################################################
+
 	vmovdqu	80(%rsi),%xmm0
 
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm7
@@ -242,7 +242,7 @@
 
 
 	vpxor	%xmm7,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	64(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,48(%rdi),%xmm0,%xmm6
@@ -254,7 +254,7 @@
 	vpclmulqdq	$0x10,48(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	48(%rsi),%xmm0
 
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm7
@@ -271,7 +271,7 @@
 
 
 	vpxor	%xmm7,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	32(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,80(%rdi),%xmm0,%xmm6
@@ -285,7 +285,7 @@
 
 
 	vpxor	%xmm9,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	16(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,96(%rdi),%xmm0,%xmm6
@@ -297,7 +297,7 @@
 	vpclmulqdq	$0x10,96(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	0(%rsi),%xmm0
 	vpxor	%xmm1,%xmm0,%xmm0
 
@@ -310,7 +310,7 @@
 	vpclmulqdq	$0x10,112(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vpsrldq	$8,%xmm5,%xmm6
 	vpslldq	$8,%xmm5,%xmm5
 
@@ -320,7 +320,7 @@
 	leaq	128(%rsi),%rsi
 	jmp	.Lhtable_polyval_main_loop
 
-#########################################################
+
 
 .Lhtable_polyval_out:
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm6
@@ -488,10 +488,10 @@
 	vmovdqa	con1(%rip),%xmm0
 	vmovdqa	mask(%rip),%xmm15
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -500,10 +500,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,16(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -512,10 +512,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,32(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -524,10 +524,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,48(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -536,10 +536,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,64(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -548,10 +548,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,80(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -560,10 +560,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,96(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -572,10 +572,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,112(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -587,10 +587,10 @@
 
 	vmovdqa	con2(%rip),%xmm0
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -599,9 +599,9 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,144(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -733,7 +733,7 @@
 
 
 	vmovdqa	(%rdx),%xmm15
-	vpor	OR_MASK(%rip),%xmm15,%xmm15#IV = [1]TAG[126...32][00..00]
+	vpor	OR_MASK(%rip),%xmm15,%xmm15
 
 	vmovdqu	four(%rip),%xmm4
 	vmovdqa	%xmm15,%xmm0
diff --git a/third_party/boringssl/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S b/third_party/boringssl/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
index ef4462d..677335b 100644
--- a/third_party/boringssl/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
@@ -1343,7 +1343,7 @@
 	leaq	128(%rdi),%rdi
 	jmp	open_sse_tail_64_dec_loop
 3:
-###############################################################################
+
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
 	movdqa	64(%rbp),%xmm8
@@ -1698,7 +1698,7 @@
 	subq	$192,%rbx
 	leaq	192(%rsi),%rsi
 	leaq	192(%rdi),%rdi
-###############################################################################
+
 
 open_sse_tail_64_dec_loop:
 	cmpq	$16,%rbx
@@ -1868,7 +1868,7 @@
 .cfi_adjust_cfa_offset	-8
 	.byte	0xf3,0xc3
 .cfi_adjust_cfa_offset	(8 * 6) + 288 + 32
-###############################################################################
+
 open_sse_128:
 	movdqu	.chacha20_consts(%rip),%xmm0
 	movdqa	%xmm0,%xmm1
@@ -2102,8 +2102,8 @@
 .size	chacha20_poly1305_open, .-chacha20_poly1305_open
 .cfi_endproc	
 
-################################################################################
-################################################################################
+
+
 
 .globl	chacha20_poly1305_seal
 .hidden chacha20_poly1305_seal
@@ -2839,7 +2839,7 @@
 	movq	$6,%rcx
 	cmpq	$64,%rbx
 	jg	3f
-###############################################################################
+
 seal_sse_tail_64:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -2991,7 +2991,7 @@
 3:
 	cmpq	$128,%rbx
 	jg	3f
-###############################################################################
+
 seal_sse_tail_128:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -3208,7 +3208,7 @@
 	leaq	64(%rsi),%rsi
 	jmp	seal_sse_128_seal_hash
 3:
-###############################################################################
+
 seal_sse_tail_192:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -3487,7 +3487,7 @@
 	movq	$128,%rcx
 	subq	$128,%rbx
 	leaq	128(%rsi),%rsi
-###############################################################################
+
 seal_sse_128_seal_hash:
 	cmpq	$16,%rcx
 	jb	seal_sse_128_seal
@@ -3632,7 +3632,7 @@
 
 
 
-#
+
 
 
 	movq	288+32(%rsp),%r9
@@ -3936,7 +3936,7 @@
 .cfi_adjust_cfa_offset	-8
 	.byte	0xf3,0xc3
 .cfi_adjust_cfa_offset	(8 * 6) + 288 + 32
-################################################################################
+
 seal_sse_128:
 	movdqu	.chacha20_consts(%rip),%xmm0
 	movdqa	%xmm0,%xmm1
@@ -4107,7 +4107,7 @@
 	jmp	seal_sse_128_seal
 .size	chacha20_poly1305_seal, .-chacha20_poly1305_seal
 
-###############################################################################
+
 .type	chacha20_poly1305_open_avx2,@function
 .align	64
 chacha20_poly1305_open_avx2:
@@ -5819,7 +5819,7 @@
 	vmovdqa	%xmm0,%xmm1
 	jb	1f
 	subq	$16,%rbx
-#load for decryption
+
 	vpxor	(%rsi),%xmm0,%xmm1
 	vmovdqu	%xmm1,(%rdi)
 	leaq	16(%rsi),%rsi
@@ -5829,7 +5829,7 @@
 1:
 	vzeroupper
 	jmp	open_sse_tail_16
-###############################################################################
+
 open_avx2_192:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -6101,7 +6101,7 @@
 1:
 	vzeroupper
 	jmp	open_sse_tail_16
-###############################################################################
+
 open_avx2_320:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -6264,8 +6264,8 @@
 	vperm2i128	$0x13,%ymm10,%ymm14,%ymm6
 	jmp	open_avx2_short
 .size	chacha20_poly1305_open_avx2, .-chacha20_poly1305_open_avx2
-###############################################################################
-###############################################################################
+
+
 .type	chacha20_poly1305_seal_avx2,@function
 .align	64
 chacha20_poly1305_seal_avx2:
@@ -7335,7 +7335,7 @@
 	xorq	%r8,%r8
 	cmpq	$128,%rbx
 	ja	3f
-###############################################################################
+
 seal_avx2_tail_128:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -7529,7 +7529,7 @@
 3:
 	cmpq	$256,%rbx
 	ja	3f
-###############################################################################
+
 seal_avx2_tail_256:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -7785,7 +7785,7 @@
 3:
 	cmpq	$384,%rbx
 	ja	seal_avx2_tail_512
-###############################################################################
+
 seal_avx2_tail_384:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -8097,7 +8097,7 @@
 	leaq	256(%rsi),%rsi
 	subq	$256,%rbx
 	jmp	seal_avx2_hash
-###############################################################################
+
 seal_avx2_tail_512:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -8499,7 +8499,7 @@
 	leaq	384(%rsi),%rsi
 	subq	$384,%rbx
 	jmp	seal_avx2_hash
-################################################################################
+
 seal_avx2_320:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -8661,7 +8661,7 @@
 	vperm2i128	$0x13,%ymm2,%ymm6,%ymm2
 	vperm2i128	$0x13,%ymm10,%ymm14,%ymm6
 	jmp	seal_avx2_short
-################################################################################
+
 seal_avx2_192:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
index 53875e30..f45e010 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
@@ -91,8 +91,8 @@
 	movzbl	%bh,%edi
 	movzbl	%ch,%ebp
 	movzbl	2(%r14,%rsi,8),%r8d
-	movl	0(%r14,%rdi,8),%edi#%r10d
-	movl	0(%r14,%rbp,8),%ebp#%r11d
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
 
 	andl	$0x0000ff00,%edi
 	andl	$0x0000ff00,%ebp
@@ -104,8 +104,8 @@
 	movzbl	%dh,%esi
 	movzbl	%ah,%edi
 	shrl	$16,%edx
-	movl	0(%r14,%rsi,8),%esi#%r12d
-	movl	0(%r14,%rdi,8),%edi#%r8d
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
 
 	andl	$0x0000ff00,%esi
 	andl	$0x0000ff00,%edi
@@ -117,9 +117,9 @@
 	movzbl	%cl,%esi
 	movzbl	%dl,%edi
 	movzbl	%al,%ebp
-	movl	0(%r14,%rsi,8),%esi#%r10d
-	movl	0(%r14,%rdi,8),%edi#%r11d
-	movl	0(%r14,%rbp,8),%ebp#%r12d
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
 
 	andl	$0x00ff0000,%esi
 	andl	$0x00ff0000,%edi
@@ -132,9 +132,9 @@
 	movzbl	%bl,%esi
 	movzbl	%dh,%edi
 	movzbl	%ah,%ebp
-	movl	0(%r14,%rsi,8),%esi#%r8d
-	movl	2(%r14,%rdi,8),%edi#%r10d
-	movl	2(%r14,%rbp,8),%ebp#%r11d
+	movl	0(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	2(%r14,%rbp,8),%ebp
 
 	andl	$0x00ff0000,%esi
 	andl	$0xff000000,%edi
@@ -147,8 +147,8 @@
 	movzbl	%bh,%esi
 	movzbl	%ch,%edi
 	movl	16+12(%r15),%edx
-	movl	2(%r14,%rsi,8),%esi#%r12d
-	movl	2(%r14,%rdi,8),%edi#%r8d
+	movl	2(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
 	andl	$0xff000000,%esi
@@ -199,12 +199,12 @@
 	movzbl	(%r14,%r12,1),%r12d
 	movzbl	(%r14,%r8,1),%r8d
 
-	movzbl	(%r14,%rsi,1),%r9d#%r10d
+	movzbl	(%r14,%rsi,1),%r9d
 	movzbl	%ah,%esi
-	movzbl	(%r14,%rdi,1),%r13d#%r11d
+	movzbl	(%r14,%rdi,1),%r13d
 	movzbl	%cl,%edi
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
-	movzbl	(%r14,%rsi,1),%esi#%r8d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
 
 	shll	$8,%r9d
 	shrl	$16,%edx
@@ -216,16 +216,16 @@
 	xorl	%r13d,%r11d
 	shll	$8,%ebp
 	movzbl	%al,%r13d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
+	movzbl	(%r14,%rdi,1),%edi
 	xorl	%ebp,%r12d
 
 	shll	$8,%esi
 	movzbl	%bl,%ebp
 	shll	$16,%edi
 	xorl	%esi,%r8d
-	movzbl	(%r14,%r9,1),%r9d#%r11d
+	movzbl	(%r14,%r9,1),%r9d
 	movzbl	%dh,%esi
-	movzbl	(%r14,%r13,1),%r13d#%r12d
+	movzbl	(%r14,%r13,1),%r13d
 	xorl	%edi,%r10d
 
 	shrl	$8,%ecx
@@ -234,11 +234,11 @@
 	shrl	$8,%ebx
 	shll	$16,%r13d
 	xorl	%r9d,%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r8d
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%edi#%r11d
-	movzbl	(%r14,%rcx,1),%edx#%r8d
-	movzbl	(%r14,%rbx,1),%ecx#%r12d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rcx,1),%edx
+	movzbl	(%r14,%rbx,1),%ecx
 
 	shll	$16,%ebp
 	xorl	%r13d,%r12d
@@ -504,8 +504,8 @@
 	movzbl	%dh,%edi
 	movzbl	%ah,%ebp
 	movzbl	(%r14,%rsi,1),%r8d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
-	movzbl	(%r14,%rbp,1),%ebp#%r11d
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$8,%edi
 	shll	$8,%ebp
@@ -517,8 +517,8 @@
 	movzbl	%bh,%esi
 	movzbl	%ch,%edi
 	shrl	$16,%eax
-	movzbl	(%r14,%rsi,1),%esi#%r12d
-	movzbl	(%r14,%rdi,1),%edi#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
 
 	shll	$8,%esi
 	shll	$8,%edi
@@ -530,9 +530,9 @@
 	movzbl	%cl,%esi
 	movzbl	%dl,%edi
 	movzbl	%al,%ebp
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%edi#%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$16,%esi
 	shll	$16,%edi
@@ -545,9 +545,9 @@
 	movzbl	%bl,%esi
 	movzbl	%bh,%edi
 	movzbl	%ch,%ebp
-	movzbl	(%r14,%rsi,1),%esi#%r8d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
-	movzbl	(%r14,%rbp,1),%ebp#%r11d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$16,%esi
 	shll	$24,%edi
@@ -560,8 +560,8 @@
 	movzbl	%dh,%esi
 	movzbl	%ah,%edi
 	movl	16+12(%r15),%edx
-	movzbl	(%r14,%rsi,1),%esi#%r12d
-	movzbl	(%r14,%rdi,1),%edi#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
 	movl	16+0(%r15),%eax
 
 	shll	$24,%esi
@@ -614,11 +614,11 @@
 	movzbl	(%r14,%r12,1),%r12d
 	movzbl	(%r14,%r8,1),%r8d
 
-	movzbl	(%r14,%rsi,1),%r9d#%r10d
+	movzbl	(%r14,%rsi,1),%r9d
 	movzbl	%ch,%esi
-	movzbl	(%r14,%rdi,1),%r13d#%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
-	movzbl	(%r14,%rsi,1),%esi#%r8d
+	movzbl	(%r14,%rdi,1),%r13d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
 
 	shrl	$16,%ecx
 	shll	$8,%r13d
@@ -633,17 +633,17 @@
 	xorl	%r13d,%r11d
 	shll	$8,%esi
 	movzbl	%al,%r13d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
+	movzbl	(%r14,%rdi,1),%edi
 	xorl	%ebp,%r12d
 	movzbl	%bl,%ebp
 
 	shll	$16,%edi
 	xorl	%esi,%r8d
-	movzbl	(%r14,%r9,1),%r9d#%r11d
+	movzbl	(%r14,%r9,1),%r9d
 	movzbl	%bh,%esi
-	movzbl	(%r14,%rbp,1),%ebp#%r8d
+	movzbl	(%r14,%rbp,1),%ebp
 	xorl	%edi,%r10d
-	movzbl	(%r14,%r13,1),%r13d#%r12d
+	movzbl	(%r14,%r13,1),%r13d
 	movzbl	%ch,%edi
 
 	shll	$16,%ebp
@@ -655,10 +655,10 @@
 	shrl	$8,%eax
 	xorl	%r13d,%r12d
 
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%ebx#%r11d
-	movzbl	(%r14,%rbp,1),%ecx#%r12d
-	movzbl	(%r14,%rax,1),%edx#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%ebx
+	movzbl	(%r14,%rbp,1),%ecx
+	movzbl	(%r14,%rax,1),%edx
 
 	movl	%r10d,%eax
 	shll	$24,%esi
@@ -1464,7 +1464,7 @@
 
 	xchgq	%rsp,%r15
 .cfi_def_cfa_register	%r15
-#add	$8,%rsp
+
 	movq	%r15,16(%rsp)
 .cfi_escape	0x0f,0x05,0x77,0x10,0x06,0x23,0x40
 .Lcbc_fast_body:
@@ -1515,7 +1515,7 @@
 	cmpq	$0,%rbx
 	je	.LFAST_DECRYPT
 
-#----------------------------- ENCRYPT -----------------------------#
+
 	movl	0(%rbp),%eax
 	movl	4(%rbp),%ebx
 	movl	8(%rbp),%ecx
@@ -1553,7 +1553,7 @@
 
 	jmp	.Lcbc_fast_cleanup
 
-#----------------------------- DECRYPT -----------------------------#
+
 .align	16
 .LFAST_DECRYPT:
 	cmpq	%r8,%r9
@@ -1661,7 +1661,7 @@
 
 	jmp	.Lcbc_exit
 
-#--------------------------- SLOW ROUTINE ---------------------------#
+
 .align	16
 .Lcbc_slow_prologue:
 .cfi_restore_state	
@@ -1677,14 +1677,14 @@
 
 	xchgq	%rsp,%rbp
 .cfi_def_cfa_register	%rbp
-#add	$8,%rsp
+
 	movq	%rbp,16(%rsp)
 .cfi_escape	0x0f,0x05,0x77,0x10,0x06,0x23,0x40
 .Lcbc_slow_body:
-#mov	%rdi,24(%rsp)
-#mov	%rsi,32(%rsp)
-#mov	%rdx,40(%rsp)
-#mov	%rcx,48(%rsp)
+
+
+
+
 	movq	%r8,56(%rsp)
 	movq	%r8,%rbp
 	movq	%r9,%rbx
@@ -1709,7 +1709,7 @@
 	cmpq	$0,%rbx
 	je	.LSLOW_DECRYPT
 
-#--------------------------- SLOW ENCRYPT ---------------------------#
+
 	testq	$-16,%r10
 	movl	0(%rbp),%eax
 	movl	4(%rbp),%ebx
@@ -1770,7 +1770,7 @@
 	movq	%r11,%rax
 	movq	%r12,%rcx
 	jmp	.Lcbc_slow_enc_loop
-#--------------------------- SLOW DECRYPT ---------------------------#
+
 .align	16
 .LSLOW_DECRYPT:
 	shrq	$3,%rax
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
index 038a9d5..240cb5d47 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
@@ -57,7 +57,7 @@
 
 
 
-#
+
 
 
 
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
index 0db3f55..42e55307 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
@@ -551,7 +551,7 @@
 	movl	%eax,%r10d
 	testl	%r8d,%r8d
 	jz	.Lecb_decrypt
-#--------------------------- ECB ENCRYPT ------------------------------#
+
 	cmpq	$0x80,%rdx
 	jb	.Lecb_enc_tail
 
@@ -692,7 +692,7 @@
 	movups	%xmm6,64(%rsi)
 	movups	%xmm7,80(%rsi)
 	jmp	.Lecb_ret
-#--------------------------- ECB DECRYPT ------------------------------#
+
 .align	16
 .Lecb_decrypt:
 	cmpq	$0x80,%rdx
@@ -881,168 +881,6 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	aes_hw_ecb_encrypt,.-aes_hw_ecb_encrypt
-.globl	aes_hw_ccm64_encrypt_blocks
-.hidden aes_hw_ccm64_encrypt_blocks
-.type	aes_hw_ccm64_encrypt_blocks,@function
-.align	16
-aes_hw_ccm64_encrypt_blocks:
-	movl	240(%rcx),%eax
-	movdqu	(%r8),%xmm6
-	movdqa	.Lincrement64(%rip),%xmm9
-	movdqa	.Lbswap_mask(%rip),%xmm7
-
-	shll	$4,%eax
-	movl	$16,%r10d
-	leaq	0(%rcx),%r11
-	movdqu	(%r9),%xmm3
-	movdqa	%xmm6,%xmm2
-	leaq	32(%rcx,%rax,1),%rcx
-.byte	102,15,56,0,247
-	subq	%rax,%r10
-	jmp	.Lccm64_enc_outer
-.align	16
-.Lccm64_enc_outer:
-	movups	(%r11),%xmm0
-	movq	%r10,%rax
-	movups	(%rdi),%xmm8
-
-	xorps	%xmm0,%xmm2
-	movups	16(%r11),%xmm1
-	xorps	%xmm8,%xmm0
-	xorps	%xmm0,%xmm3
-	movups	32(%r11),%xmm0
-
-.Lccm64_enc2_loop:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Lccm64_enc2_loop
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	paddq	%xmm9,%xmm6
-	decq	%rdx
-.byte	102,15,56,221,208
-.byte	102,15,56,221,216
-
-	leaq	16(%rdi),%rdi
-	xorps	%xmm2,%xmm8
-	movdqa	%xmm6,%xmm2
-	movups	%xmm8,(%rsi)
-.byte	102,15,56,0,215
-	leaq	16(%rsi),%rsi
-	jnz	.Lccm64_enc_outer
-
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	movups	%xmm3,(%r9)
-	pxor	%xmm3,%xmm3
-	pxor	%xmm8,%xmm8
-	pxor	%xmm6,%xmm6
-	.byte	0xf3,0xc3
-.size	aes_hw_ccm64_encrypt_blocks,.-aes_hw_ccm64_encrypt_blocks
-.globl	aes_hw_ccm64_decrypt_blocks
-.hidden aes_hw_ccm64_decrypt_blocks
-.type	aes_hw_ccm64_decrypt_blocks,@function
-.align	16
-aes_hw_ccm64_decrypt_blocks:
-	movl	240(%rcx),%eax
-	movups	(%r8),%xmm6
-	movdqu	(%r9),%xmm3
-	movdqa	.Lincrement64(%rip),%xmm9
-	movdqa	.Lbswap_mask(%rip),%xmm7
-
-	movaps	%xmm6,%xmm2
-	movl	%eax,%r10d
-	movq	%rcx,%r11
-.byte	102,15,56,0,247
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_enc1_5:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_enc1_5
-.byte	102,15,56,221,209
-	shll	$4,%r10d
-	movl	$16,%eax
-	movups	(%rdi),%xmm8
-	paddq	%xmm9,%xmm6
-	leaq	16(%rdi),%rdi
-	subq	%r10,%rax
-	leaq	32(%r11,%r10,1),%rcx
-	movq	%rax,%r10
-	jmp	.Lccm64_dec_outer
-.align	16
-.Lccm64_dec_outer:
-	xorps	%xmm2,%xmm8
-	movdqa	%xmm6,%xmm2
-	movups	%xmm8,(%rsi)
-	leaq	16(%rsi),%rsi
-.byte	102,15,56,0,215
-
-	subq	$1,%rdx
-	jz	.Lccm64_dec_break
-
-	movups	(%r11),%xmm0
-	movq	%r10,%rax
-	movups	16(%r11),%xmm1
-	xorps	%xmm0,%xmm8
-	xorps	%xmm0,%xmm2
-	xorps	%xmm8,%xmm3
-	movups	32(%r11),%xmm0
-	jmp	.Lccm64_dec2_loop
-.align	16
-.Lccm64_dec2_loop:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Lccm64_dec2_loop
-	movups	(%rdi),%xmm8
-	paddq	%xmm9,%xmm6
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,221,208
-.byte	102,15,56,221,216
-	leaq	16(%rdi),%rdi
-	jmp	.Lccm64_dec_outer
-
-.align	16
-.Lccm64_dec_break:
-#xorps	%xmm8,%xmm3
-	movl	240(%r11),%eax
-	movups	(%r11),%xmm0
-	movups	16(%r11),%xmm1
-	xorps	%xmm0,%xmm8
-	leaq	32(%r11),%r11
-	xorps	%xmm8,%xmm3
-.Loop_enc1_6:
-.byte	102,15,56,220,217
-	decl	%eax
-	movups	(%r11),%xmm1
-	leaq	16(%r11),%r11
-	jnz	.Loop_enc1_6
-.byte	102,15,56,221,217
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	movups	%xmm3,(%r9)
-	pxor	%xmm3,%xmm3
-	pxor	%xmm8,%xmm8
-	pxor	%xmm6,%xmm6
-	.byte	0xf3,0xc3
-.size	aes_hw_ccm64_decrypt_blocks,.-aes_hw_ccm64_decrypt_blocks
 .globl	aes_hw_ctr32_encrypt_blocks
 .hidden aes_hw_ctr32_encrypt_blocks
 .type	aes_hw_ctr32_encrypt_blocks,@function
@@ -1066,12 +904,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-.Loop_enc1_7:
+.Loop_enc1_5:
 .byte	102,15,56,220,209
 	decl	%edx
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	.Loop_enc1_7
+	jnz	.Loop_enc1_5
 .byte	102,15,56,221,209
 	pxor	%xmm0,%xmm0
 	pxor	%xmm1,%xmm1
@@ -1456,7 +1294,7 @@
 	movdqa	64(%rsp),%xmm15
 .byte	102,68,15,56,221,193
 	movdqa	80(%rsp),%xmm0
-	movups	16-128(%rcx),%xmm1#real 1st-round key
+	movups	16-128(%rcx),%xmm1
 .byte	102,69,15,56,221,202
 
 	movups	%xmm2,(%rsi)
@@ -1628,1839 +1466,6 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks
-.globl	aes_hw_xts_encrypt
-.hidden aes_hw_xts_encrypt
-.type	aes_hw_xts_encrypt,@function
-.align	16
-aes_hw_xts_encrypt:
-.cfi_startproc	
-	leaq	(%rsp),%r11
-.cfi_def_cfa_register	%r11
-	pushq	%rbp
-.cfi_offset	%rbp,-16
-	subq	$112,%rsp
-	andq	$-16,%rsp
-	movups	(%r9),%xmm2
-	movl	240(%r8),%eax
-	movl	240(%rcx),%r10d
-	movups	(%r8),%xmm0
-	movups	16(%r8),%xmm1
-	leaq	32(%r8),%r8
-	xorps	%xmm0,%xmm2
-.Loop_enc1_8:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%r8),%xmm1
-	leaq	16(%r8),%r8
-	jnz	.Loop_enc1_8
-.byte	102,15,56,221,209
-	movups	(%rcx),%xmm0
-	movq	%rcx,%rbp
-	movl	%r10d,%eax
-	shll	$4,%r10d
-	movq	%rdx,%r9
-	andq	$-16,%rdx
-
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqa	.Lxts_magic(%rip),%xmm8
-	movdqa	%xmm2,%xmm15
-	pshufd	$0x5f,%xmm2,%xmm9
-	pxor	%xmm0,%xmm1
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm10
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm10
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm11
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm11
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm12
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm12
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm13
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm13
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm15,%xmm14
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm9
-	pxor	%xmm0,%xmm14
-	pxor	%xmm9,%xmm15
-	movaps	%xmm1,96(%rsp)
-
-	subq	$96,%rdx
-	jc	.Lxts_enc_short
-
-	movl	$16+96,%eax
-	leaq	32(%rbp,%r10,1),%rcx
-	subq	%r10,%rax
-	movups	16(%rbp),%xmm1
-	movq	%rax,%r10
-	leaq	.Lxts_magic(%rip),%r8
-	jmp	.Lxts_enc_grandloop
-
-.align	32
-.Lxts_enc_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqa	%xmm0,%xmm8
-	movdqu	16(%rdi),%xmm3
-	pxor	%xmm10,%xmm2
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm11,%xmm3
-.byte	102,15,56,220,209
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm12,%xmm4
-.byte	102,15,56,220,217
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm13,%xmm5
-.byte	102,15,56,220,225
-	movdqu	80(%rdi),%xmm7
-	pxor	%xmm15,%xmm8
-	movdqa	96(%rsp),%xmm9
-	pxor	%xmm14,%xmm6
-.byte	102,15,56,220,233
-	movups	32(%rbp),%xmm0
-	leaq	96(%rdi),%rdi
-	pxor	%xmm8,%xmm7
-
-	pxor	%xmm9,%xmm10
-.byte	102,15,56,220,241
-	pxor	%xmm9,%xmm11
-	movdqa	%xmm10,0(%rsp)
-.byte	102,15,56,220,249
-	movups	48(%rbp),%xmm1
-	pxor	%xmm9,%xmm12
-
-.byte	102,15,56,220,208
-	pxor	%xmm9,%xmm13
-	movdqa	%xmm11,16(%rsp)
-.byte	102,15,56,220,216
-	pxor	%xmm9,%xmm14
-	movdqa	%xmm12,32(%rsp)
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	pxor	%xmm9,%xmm8
-	movdqa	%xmm14,64(%rsp)
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	64(%rbp),%xmm0
-	movdqa	%xmm8,80(%rsp)
-	pshufd	$0x5f,%xmm15,%xmm9
-	jmp	.Lxts_enc_loop6
-.align	32
-.Lxts_enc_loop6:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	-64(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	-80(%rcx,%rax,1),%xmm0
-	jnz	.Lxts_enc_loop6
-
-	movdqa	(%r8),%xmm8
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	paddq	%xmm15,%xmm15
-	psrad	$31,%xmm14
-.byte	102,15,56,220,217
-	pand	%xmm8,%xmm14
-	movups	(%rbp),%xmm10
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-	pxor	%xmm14,%xmm15
-	movaps	%xmm10,%xmm11
-.byte	102,15,56,220,249
-	movups	-64(%rcx),%xmm1
-
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,208
-	paddd	%xmm9,%xmm9
-	pxor	%xmm15,%xmm10
-.byte	102,15,56,220,216
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	pand	%xmm8,%xmm14
-	movaps	%xmm11,%xmm12
-.byte	102,15,56,220,240
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,248
-	movups	-48(%rcx),%xmm0
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	pxor	%xmm15,%xmm11
-	psrad	$31,%xmm14
-.byte	102,15,56,220,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movdqa	%xmm13,48(%rsp)
-	pxor	%xmm14,%xmm15
-.byte	102,15,56,220,241
-	movaps	%xmm12,%xmm13
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,249
-	movups	-32(%rcx),%xmm1
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,208
-	pxor	%xmm15,%xmm12
-	psrad	$31,%xmm14
-.byte	102,15,56,220,216
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-	pxor	%xmm14,%xmm15
-	movaps	%xmm13,%xmm14
-.byte	102,15,56,220,248
-
-	movdqa	%xmm9,%xmm0
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	pxor	%xmm15,%xmm13
-	psrad	$31,%xmm0
-.byte	102,15,56,220,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm0
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	pxor	%xmm0,%xmm15
-	movups	(%rbp),%xmm0
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	16(%rbp),%xmm1
-
-	pxor	%xmm15,%xmm14
-.byte	102,15,56,221,84,36,0
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,221,92,36,16
-.byte	102,15,56,221,100,36,32
-	pand	%xmm8,%xmm9
-	movq	%r10,%rax
-.byte	102,15,56,221,108,36,48
-.byte	102,15,56,221,116,36,64
-.byte	102,15,56,221,124,36,80
-	pxor	%xmm9,%xmm15
-
-	leaq	96(%rsi),%rsi
-	movups	%xmm2,-96(%rsi)
-	movups	%xmm3,-80(%rsi)
-	movups	%xmm4,-64(%rsi)
-	movups	%xmm5,-48(%rsi)
-	movups	%xmm6,-32(%rsi)
-	movups	%xmm7,-16(%rsi)
-	subq	$96,%rdx
-	jnc	.Lxts_enc_grandloop
-
-	movl	$16+96,%eax
-	subl	%r10d,%eax
-	movq	%rbp,%rcx
-	shrl	$4,%eax
-
-.Lxts_enc_short:
-
-	movl	%eax,%r10d
-	pxor	%xmm0,%xmm10
-	addq	$96,%rdx
-	jz	.Lxts_enc_done
-
-	pxor	%xmm0,%xmm11
-	cmpq	$0x20,%rdx
-	jb	.Lxts_enc_one
-	pxor	%xmm0,%xmm12
-	je	.Lxts_enc_two
-
-	pxor	%xmm0,%xmm13
-	cmpq	$0x40,%rdx
-	jb	.Lxts_enc_three
-	pxor	%xmm0,%xmm14
-	je	.Lxts_enc_four
-
-	movdqu	(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm10,%xmm2
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm11,%xmm3
-	movdqu	64(%rdi),%xmm6
-	leaq	80(%rdi),%rdi
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	_aesni_encrypt6
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm15,%xmm10
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	xorps	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	xorps	%xmm14,%xmm6
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	movdqu	%xmm6,64(%rsi)
-	leaq	80(%rsi),%rsi
-	jmp	.Lxts_enc_done
-
-.align	16
-.Lxts_enc_one:
-	movups	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_enc1_9:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_enc1_9
-.byte	102,15,56,221,209
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm11,%xmm10
-	movups	%xmm2,(%rsi)
-	leaq	16(%rsi),%rsi
-	jmp	.Lxts_enc_done
-
-.align	16
-.Lxts_enc_two:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	leaq	32(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-
-	call	_aesni_encrypt2
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm12,%xmm10
-	xorps	%xmm11,%xmm3
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	leaq	32(%rsi),%rsi
-	jmp	.Lxts_enc_done
-
-.align	16
-.Lxts_enc_three:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	leaq	48(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-
-	call	_aesni_encrypt3
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm13,%xmm10
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	leaq	48(%rsi),%rsi
-	jmp	.Lxts_enc_done
-
-.align	16
-.Lxts_enc_four:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	xorps	%xmm10,%xmm2
-	movups	48(%rdi),%xmm5
-	leaq	64(%rdi),%rdi
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	xorps	%xmm13,%xmm5
-
-	call	_aesni_encrypt4
-
-	pxor	%xmm10,%xmm2
-	movdqa	%xmm14,%xmm10
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	pxor	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	leaq	64(%rsi),%rsi
-	jmp	.Lxts_enc_done
-
-.align	16
-.Lxts_enc_done:
-	andq	$15,%r9
-	jz	.Lxts_enc_ret
-	movq	%r9,%rdx
-
-.Lxts_enc_steal:
-	movzbl	(%rdi),%eax
-	movzbl	-16(%rsi),%ecx
-	leaq	1(%rdi),%rdi
-	movb	%al,-16(%rsi)
-	movb	%cl,0(%rsi)
-	leaq	1(%rsi),%rsi
-	subq	$1,%rdx
-	jnz	.Lxts_enc_steal
-
-	subq	%r9,%rsi
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	-16(%rsi),%xmm2
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_enc1_10:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_enc1_10
-.byte	102,15,56,221,209
-	xorps	%xmm10,%xmm2
-	movups	%xmm2,-16(%rsi)
-
-.Lxts_enc_ret:
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	movaps	%xmm0,0(%rsp)
-	pxor	%xmm8,%xmm8
-	movaps	%xmm0,16(%rsp)
-	pxor	%xmm9,%xmm9
-	movaps	%xmm0,32(%rsp)
-	pxor	%xmm10,%xmm10
-	movaps	%xmm0,48(%rsp)
-	pxor	%xmm11,%xmm11
-	movaps	%xmm0,64(%rsp)
-	pxor	%xmm12,%xmm12
-	movaps	%xmm0,80(%rsp)
-	pxor	%xmm13,%xmm13
-	movaps	%xmm0,96(%rsp)
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	movq	-8(%r11),%rbp
-.cfi_restore	%rbp
-	leaq	(%r11),%rsp
-.cfi_def_cfa_register	%rsp
-.Lxts_enc_epilogue:
-	.byte	0xf3,0xc3
-.cfi_endproc	
-.size	aes_hw_xts_encrypt,.-aes_hw_xts_encrypt
-.globl	aes_hw_xts_decrypt
-.hidden aes_hw_xts_decrypt
-.type	aes_hw_xts_decrypt,@function
-.align	16
-aes_hw_xts_decrypt:
-.cfi_startproc	
-	leaq	(%rsp),%r11
-.cfi_def_cfa_register	%r11
-	pushq	%rbp
-.cfi_offset	%rbp,-16
-	subq	$112,%rsp
-	andq	$-16,%rsp
-	movups	(%r9),%xmm2
-	movl	240(%r8),%eax
-	movl	240(%rcx),%r10d
-	movups	(%r8),%xmm0
-	movups	16(%r8),%xmm1
-	leaq	32(%r8),%r8
-	xorps	%xmm0,%xmm2
-.Loop_enc1_11:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%r8),%xmm1
-	leaq	16(%r8),%r8
-	jnz	.Loop_enc1_11
-.byte	102,15,56,221,209
-	xorl	%eax,%eax
-	testq	$15,%rdx
-	setnz	%al
-	shlq	$4,%rax
-	subq	%rax,%rdx
-
-	movups	(%rcx),%xmm0
-	movq	%rcx,%rbp
-	movl	%r10d,%eax
-	shll	$4,%r10d
-	movq	%rdx,%r9
-	andq	$-16,%rdx
-
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqa	.Lxts_magic(%rip),%xmm8
-	movdqa	%xmm2,%xmm15
-	pshufd	$0x5f,%xmm2,%xmm9
-	pxor	%xmm0,%xmm1
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm10
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm10
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm11
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm11
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm12
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm12
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm13
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm13
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm15,%xmm14
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm9
-	pxor	%xmm0,%xmm14
-	pxor	%xmm9,%xmm15
-	movaps	%xmm1,96(%rsp)
-
-	subq	$96,%rdx
-	jc	.Lxts_dec_short
-
-	movl	$16+96,%eax
-	leaq	32(%rbp,%r10,1),%rcx
-	subq	%r10,%rax
-	movups	16(%rbp),%xmm1
-	movq	%rax,%r10
-	leaq	.Lxts_magic(%rip),%r8
-	jmp	.Lxts_dec_grandloop
-
-.align	32
-.Lxts_dec_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqa	%xmm0,%xmm8
-	movdqu	16(%rdi),%xmm3
-	pxor	%xmm10,%xmm2
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm11,%xmm3
-.byte	102,15,56,222,209
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm12,%xmm4
-.byte	102,15,56,222,217
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm13,%xmm5
-.byte	102,15,56,222,225
-	movdqu	80(%rdi),%xmm7
-	pxor	%xmm15,%xmm8
-	movdqa	96(%rsp),%xmm9
-	pxor	%xmm14,%xmm6
-.byte	102,15,56,222,233
-	movups	32(%rbp),%xmm0
-	leaq	96(%rdi),%rdi
-	pxor	%xmm8,%xmm7
-
-	pxor	%xmm9,%xmm10
-.byte	102,15,56,222,241
-	pxor	%xmm9,%xmm11
-	movdqa	%xmm10,0(%rsp)
-.byte	102,15,56,222,249
-	movups	48(%rbp),%xmm1
-	pxor	%xmm9,%xmm12
-
-.byte	102,15,56,222,208
-	pxor	%xmm9,%xmm13
-	movdqa	%xmm11,16(%rsp)
-.byte	102,15,56,222,216
-	pxor	%xmm9,%xmm14
-	movdqa	%xmm12,32(%rsp)
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	pxor	%xmm9,%xmm8
-	movdqa	%xmm14,64(%rsp)
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	64(%rbp),%xmm0
-	movdqa	%xmm8,80(%rsp)
-	pshufd	$0x5f,%xmm15,%xmm9
-	jmp	.Lxts_dec_loop6
-.align	32
-.Lxts_dec_loop6:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	-64(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	-80(%rcx,%rax,1),%xmm0
-	jnz	.Lxts_dec_loop6
-
-	movdqa	(%r8),%xmm8
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	paddq	%xmm15,%xmm15
-	psrad	$31,%xmm14
-.byte	102,15,56,222,217
-	pand	%xmm8,%xmm14
-	movups	(%rbp),%xmm10
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-	pxor	%xmm14,%xmm15
-	movaps	%xmm10,%xmm11
-.byte	102,15,56,222,249
-	movups	-64(%rcx),%xmm1
-
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,208
-	paddd	%xmm9,%xmm9
-	pxor	%xmm15,%xmm10
-.byte	102,15,56,222,216
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	pand	%xmm8,%xmm14
-	movaps	%xmm11,%xmm12
-.byte	102,15,56,222,240
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,248
-	movups	-48(%rcx),%xmm0
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	pxor	%xmm15,%xmm11
-	psrad	$31,%xmm14
-.byte	102,15,56,222,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movdqa	%xmm13,48(%rsp)
-	pxor	%xmm14,%xmm15
-.byte	102,15,56,222,241
-	movaps	%xmm12,%xmm13
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,249
-	movups	-32(%rcx),%xmm1
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,208
-	pxor	%xmm15,%xmm12
-	psrad	$31,%xmm14
-.byte	102,15,56,222,216
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-	pxor	%xmm14,%xmm15
-	movaps	%xmm13,%xmm14
-.byte	102,15,56,222,248
-
-	movdqa	%xmm9,%xmm0
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	pxor	%xmm15,%xmm13
-	psrad	$31,%xmm0
-.byte	102,15,56,222,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm0
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	pxor	%xmm0,%xmm15
-	movups	(%rbp),%xmm0
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	16(%rbp),%xmm1
-
-	pxor	%xmm15,%xmm14
-.byte	102,15,56,223,84,36,0
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,223,92,36,16
-.byte	102,15,56,223,100,36,32
-	pand	%xmm8,%xmm9
-	movq	%r10,%rax
-.byte	102,15,56,223,108,36,48
-.byte	102,15,56,223,116,36,64
-.byte	102,15,56,223,124,36,80
-	pxor	%xmm9,%xmm15
-
-	leaq	96(%rsi),%rsi
-	movups	%xmm2,-96(%rsi)
-	movups	%xmm3,-80(%rsi)
-	movups	%xmm4,-64(%rsi)
-	movups	%xmm5,-48(%rsi)
-	movups	%xmm6,-32(%rsi)
-	movups	%xmm7,-16(%rsi)
-	subq	$96,%rdx
-	jnc	.Lxts_dec_grandloop
-
-	movl	$16+96,%eax
-	subl	%r10d,%eax
-	movq	%rbp,%rcx
-	shrl	$4,%eax
-
-.Lxts_dec_short:
-
-	movl	%eax,%r10d
-	pxor	%xmm0,%xmm10
-	pxor	%xmm0,%xmm11
-	addq	$96,%rdx
-	jz	.Lxts_dec_done
-
-	pxor	%xmm0,%xmm12
-	cmpq	$0x20,%rdx
-	jb	.Lxts_dec_one
-	pxor	%xmm0,%xmm13
-	je	.Lxts_dec_two
-
-	pxor	%xmm0,%xmm14
-	cmpq	$0x40,%rdx
-	jb	.Lxts_dec_three
-	je	.Lxts_dec_four
-
-	movdqu	(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm10,%xmm2
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm11,%xmm3
-	movdqu	64(%rdi),%xmm6
-	leaq	80(%rdi),%rdi
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm6
-
-	call	_aesni_decrypt6
-
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	xorps	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	xorps	%xmm14,%xmm6
-	movdqu	%xmm4,32(%rsi)
-	pxor	%xmm14,%xmm14
-	movdqu	%xmm5,48(%rsi)
-	pcmpgtd	%xmm15,%xmm14
-	movdqu	%xmm6,64(%rsi)
-	leaq	80(%rsi),%rsi
-	pshufd	$0x13,%xmm14,%xmm11
-	andq	$15,%r9
-	jz	.Lxts_dec_ret
-
-	movdqa	%xmm15,%xmm10
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm11
-	pxor	%xmm15,%xmm11
-	jmp	.Lxts_dec_done2
-
-.align	16
-.Lxts_dec_one:
-	movups	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_dec1_12:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_dec1_12
-.byte	102,15,56,223,209
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm11,%xmm10
-	movups	%xmm2,(%rsi)
-	movdqa	%xmm12,%xmm11
-	leaq	16(%rsi),%rsi
-	jmp	.Lxts_dec_done
-
-.align	16
-.Lxts_dec_two:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	leaq	32(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-
-	call	_aesni_decrypt2
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm12,%xmm10
-	xorps	%xmm11,%xmm3
-	movdqa	%xmm13,%xmm11
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	leaq	32(%rsi),%rsi
-	jmp	.Lxts_dec_done
-
-.align	16
-.Lxts_dec_three:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	leaq	48(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-
-	call	_aesni_decrypt3
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm13,%xmm10
-	xorps	%xmm11,%xmm3
-	movdqa	%xmm14,%xmm11
-	xorps	%xmm12,%xmm4
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	leaq	48(%rsi),%rsi
-	jmp	.Lxts_dec_done
-
-.align	16
-.Lxts_dec_four:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	xorps	%xmm10,%xmm2
-	movups	48(%rdi),%xmm5
-	leaq	64(%rdi),%rdi
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	xorps	%xmm13,%xmm5
-
-	call	_aesni_decrypt4
-
-	pxor	%xmm10,%xmm2
-	movdqa	%xmm14,%xmm10
-	pxor	%xmm11,%xmm3
-	movdqa	%xmm15,%xmm11
-	pxor	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	pxor	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	leaq	64(%rsi),%rsi
-	jmp	.Lxts_dec_done
-
-.align	16
-.Lxts_dec_done:
-	andq	$15,%r9
-	jz	.Lxts_dec_ret
-.Lxts_dec_done2:
-	movq	%r9,%rdx
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	(%rdi),%xmm2
-	xorps	%xmm11,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_dec1_13:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_dec1_13
-.byte	102,15,56,223,209
-	xorps	%xmm11,%xmm2
-	movups	%xmm2,(%rsi)
-
-.Lxts_dec_steal:
-	movzbl	16(%rdi),%eax
-	movzbl	(%rsi),%ecx
-	leaq	1(%rdi),%rdi
-	movb	%al,(%rsi)
-	movb	%cl,16(%rsi)
-	leaq	1(%rsi),%rsi
-	subq	$1,%rdx
-	jnz	.Lxts_dec_steal
-
-	subq	%r9,%rsi
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	(%rsi),%xmm2
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-.Loop_dec1_14:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	.Loop_dec1_14
-.byte	102,15,56,223,209
-	xorps	%xmm10,%xmm2
-	movups	%xmm2,(%rsi)
-
-.Lxts_dec_ret:
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	movaps	%xmm0,0(%rsp)
-	pxor	%xmm8,%xmm8
-	movaps	%xmm0,16(%rsp)
-	pxor	%xmm9,%xmm9
-	movaps	%xmm0,32(%rsp)
-	pxor	%xmm10,%xmm10
-	movaps	%xmm0,48(%rsp)
-	pxor	%xmm11,%xmm11
-	movaps	%xmm0,64(%rsp)
-	pxor	%xmm12,%xmm12
-	movaps	%xmm0,80(%rsp)
-	pxor	%xmm13,%xmm13
-	movaps	%xmm0,96(%rsp)
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	movq	-8(%r11),%rbp
-.cfi_restore	%rbp
-	leaq	(%r11),%rsp
-.cfi_def_cfa_register	%rsp
-.Lxts_dec_epilogue:
-	.byte	0xf3,0xc3
-.cfi_endproc	
-.size	aes_hw_xts_decrypt,.-aes_hw_xts_decrypt
-.globl	aes_hw_ocb_encrypt
-.hidden aes_hw_ocb_encrypt
-.type	aes_hw_ocb_encrypt,@function
-.align	32
-aes_hw_ocb_encrypt:
-.cfi_startproc	
-	leaq	(%rsp),%rax
-	pushq	%rbx
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%rbx,-16
-	pushq	%rbp
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%rbp,-24
-	pushq	%r12
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r12,-32
-	pushq	%r13
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r13,-40
-	pushq	%r14
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r14,-48
-	movq	8(%rax),%rbx
-	movq	8+8(%rax),%rbp
-
-	movl	240(%rcx),%r10d
-	movq	%rcx,%r11
-	shll	$4,%r10d
-	movups	(%rcx),%xmm9
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqu	(%r9),%xmm15
-	pxor	%xmm1,%xmm9
-	pxor	%xmm1,%xmm15
-
-	movl	$16+32,%eax
-	leaq	32(%r11,%r10,1),%rcx
-	movups	16(%r11),%xmm1
-	subq	%r10,%rax
-	movq	%rax,%r10
-
-	movdqu	(%rbx),%xmm10
-	movdqu	(%rbp),%xmm8
-
-	testq	$1,%r8
-	jnz	.Locb_enc_odd
-
-	bsfq	%r8,%r12
-	addq	$1,%r8
-	shlq	$4,%r12
-	movdqu	(%rbx,%r12,1),%xmm7
-	movdqu	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-
-	call	__ocb_encrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,(%rsi)
-	leaq	16(%rsi),%rsi
-	subq	$1,%rdx
-	jz	.Locb_enc_done
-
-.Locb_enc_odd:
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	leaq	6(%r8),%r8
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-	shlq	$4,%r12
-	shlq	$4,%r13
-	shlq	$4,%r14
-
-	subq	$6,%rdx
-	jc	.Locb_enc_short
-	jmp	.Locb_enc_grandloop
-
-.align	32
-.Locb_enc_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	movdqu	48(%rdi),%xmm5
-	movdqu	64(%rdi),%xmm6
-	movdqu	80(%rdi),%xmm7
-	leaq	96(%rdi),%rdi
-
-	call	__ocb_encrypt6
-
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-	movups	%xmm6,64(%rsi)
-	movups	%xmm7,80(%rsi)
-	leaq	96(%rsi),%rsi
-	subq	$6,%rdx
-	jnc	.Locb_enc_grandloop
-
-.Locb_enc_short:
-	addq	$6,%rdx
-	jz	.Locb_enc_done
-
-	movdqu	0(%rdi),%xmm2
-	cmpq	$2,%rdx
-	jb	.Locb_enc_one
-	movdqu	16(%rdi),%xmm3
-	je	.Locb_enc_two
-
-	movdqu	32(%rdi),%xmm4
-	cmpq	$4,%rdx
-	jb	.Locb_enc_three
-	movdqu	48(%rdi),%xmm5
-	je	.Locb_enc_four
-
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	__ocb_encrypt6
-
-	movdqa	%xmm14,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-	movups	%xmm6,64(%rsi)
-
-	jmp	.Locb_enc_done
-
-.align	16
-.Locb_enc_one:
-	movdqa	%xmm10,%xmm7
-
-	call	__ocb_encrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,0(%rsi)
-	jmp	.Locb_enc_done
-
-.align	16
-.Locb_enc_two:
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	%xmm11,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-
-	jmp	.Locb_enc_done
-
-.align	16
-.Locb_enc_three:
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	%xmm12,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-
-	jmp	.Locb_enc_done
-
-.align	16
-.Locb_enc_four:
-	call	__ocb_encrypt4
-
-	movdqa	%xmm13,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-
-.Locb_enc_done:
-	pxor	%xmm0,%xmm15
-	movdqu	%xmm8,(%rbp)
-	movdqu	%xmm15,(%r9)
-
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	pxor	%xmm8,%xmm8
-	pxor	%xmm9,%xmm9
-	pxor	%xmm10,%xmm10
-	pxor	%xmm11,%xmm11
-	pxor	%xmm12,%xmm12
-	pxor	%xmm13,%xmm13
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	leaq	40(%rsp),%rax
-.cfi_def_cfa	%rax,8
-	movq	-40(%rax),%r14
-.cfi_restore	%r14
-	movq	-32(%rax),%r13
-.cfi_restore	%r13
-	movq	-24(%rax),%r12
-.cfi_restore	%r12
-	movq	-16(%rax),%rbp
-.cfi_restore	%rbp
-	movq	-8(%rax),%rbx
-.cfi_restore	%rbx
-	leaq	(%rax),%rsp
-.cfi_def_cfa_register	%rsp
-.Locb_enc_epilogue:
-	.byte	0xf3,0xc3
-.cfi_endproc	
-.size	aes_hw_ocb_encrypt,.-aes_hw_ocb_encrypt
-
-.type	__ocb_encrypt6,@function
-.align	32
-__ocb_encrypt6:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	movdqa	%xmm10,%xmm14
-	pxor	%xmm15,%xmm10
-	movdqu	(%rbx,%r14,1),%xmm15
-	pxor	%xmm10,%xmm11
-	pxor	%xmm2,%xmm8
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm3,%xmm8
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm4,%xmm8
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm14
-	pxor	%xmm5,%xmm8
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm15
-	pxor	%xmm6,%xmm8
-	pxor	%xmm14,%xmm6
-	pxor	%xmm7,%xmm8
-	pxor	%xmm15,%xmm7
-	movups	32(%r11),%xmm0
-
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	addq	$6,%r8
-	pxor	%xmm9,%xmm10
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-.byte	102,15,56,220,241
-	pxor	%xmm9,%xmm13
-	pxor	%xmm9,%xmm14
-.byte	102,15,56,220,249
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm15
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	64(%r11),%xmm0
-	shlq	$4,%r12
-	shlq	$4,%r13
-	jmp	.Locb_enc_loop6
-
-.align	32
-.Locb_enc_loop6:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_enc_loop6
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	16(%r11),%xmm1
-	shlq	$4,%r14
-
-.byte	102,65,15,56,221,210
-	movdqu	(%rbx),%xmm10
-	movq	%r10,%rax
-.byte	102,65,15,56,221,219
-.byte	102,65,15,56,221,228
-.byte	102,65,15,56,221,237
-.byte	102,65,15,56,221,246
-.byte	102,65,15,56,221,255
-	.byte	0xf3,0xc3
-.size	__ocb_encrypt6,.-__ocb_encrypt6
-
-.type	__ocb_encrypt4,@function
-.align	32
-__ocb_encrypt4:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	pxor	%xmm15,%xmm10
-	pxor	%xmm10,%xmm11
-	pxor	%xmm2,%xmm8
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm3,%xmm8
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm4,%xmm8
-	pxor	%xmm12,%xmm4
-	pxor	%xmm5,%xmm8
-	pxor	%xmm13,%xmm5
-	movups	32(%r11),%xmm0
-
-	pxor	%xmm9,%xmm10
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-	pxor	%xmm9,%xmm13
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	48(%r11),%xmm1
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	movups	64(%r11),%xmm0
-	jmp	.Locb_enc_loop4
-
-.align	32
-.Locb_enc_loop4:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_enc_loop4
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,65,15,56,221,210
-.byte	102,65,15,56,221,219
-.byte	102,65,15,56,221,228
-.byte	102,65,15,56,221,237
-	.byte	0xf3,0xc3
-.size	__ocb_encrypt4,.-__ocb_encrypt4
-
-.type	__ocb_encrypt1,@function
-.align	32
-__ocb_encrypt1:
-	pxor	%xmm15,%xmm7
-	pxor	%xmm9,%xmm7
-	pxor	%xmm2,%xmm8
-	pxor	%xmm7,%xmm2
-	movups	32(%r11),%xmm0
-
-.byte	102,15,56,220,209
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm7
-
-.byte	102,15,56,220,208
-	movups	64(%r11),%xmm0
-	jmp	.Locb_enc_loop1
-
-.align	32
-.Locb_enc_loop1:
-.byte	102,15,56,220,209
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_enc_loop1
-
-.byte	102,15,56,220,209
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,15,56,221,215
-	.byte	0xf3,0xc3
-.size	__ocb_encrypt1,.-__ocb_encrypt1
-
-.globl	aes_hw_ocb_decrypt
-.hidden aes_hw_ocb_decrypt
-.type	aes_hw_ocb_decrypt,@function
-.align	32
-aes_hw_ocb_decrypt:
-.cfi_startproc	
-	leaq	(%rsp),%rax
-	pushq	%rbx
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%rbx,-16
-	pushq	%rbp
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%rbp,-24
-	pushq	%r12
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r12,-32
-	pushq	%r13
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r13,-40
-	pushq	%r14
-.cfi_adjust_cfa_offset	8
-.cfi_offset	%r14,-48
-	movq	8(%rax),%rbx
-	movq	8+8(%rax),%rbp
-
-	movl	240(%rcx),%r10d
-	movq	%rcx,%r11
-	shll	$4,%r10d
-	movups	(%rcx),%xmm9
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqu	(%r9),%xmm15
-	pxor	%xmm1,%xmm9
-	pxor	%xmm1,%xmm15
-
-	movl	$16+32,%eax
-	leaq	32(%r11,%r10,1),%rcx
-	movups	16(%r11),%xmm1
-	subq	%r10,%rax
-	movq	%rax,%r10
-
-	movdqu	(%rbx),%xmm10
-	movdqu	(%rbp),%xmm8
-
-	testq	$1,%r8
-	jnz	.Locb_dec_odd
-
-	bsfq	%r8,%r12
-	addq	$1,%r8
-	shlq	$4,%r12
-	movdqu	(%rbx,%r12,1),%xmm7
-	movdqu	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-
-	call	__ocb_decrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,(%rsi)
-	xorps	%xmm2,%xmm8
-	leaq	16(%rsi),%rsi
-	subq	$1,%rdx
-	jz	.Locb_dec_done
-
-.Locb_dec_odd:
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	leaq	6(%r8),%r8
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-	shlq	$4,%r12
-	shlq	$4,%r13
-	shlq	$4,%r14
-
-	subq	$6,%rdx
-	jc	.Locb_dec_short
-	jmp	.Locb_dec_grandloop
-
-.align	32
-.Locb_dec_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	movdqu	48(%rdi),%xmm5
-	movdqu	64(%rdi),%xmm6
-	movdqu	80(%rdi),%xmm7
-	leaq	96(%rdi),%rdi
-
-	call	__ocb_decrypt6
-
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-	movups	%xmm6,64(%rsi)
-	pxor	%xmm6,%xmm8
-	movups	%xmm7,80(%rsi)
-	pxor	%xmm7,%xmm8
-	leaq	96(%rsi),%rsi
-	subq	$6,%rdx
-	jnc	.Locb_dec_grandloop
-
-.Locb_dec_short:
-	addq	$6,%rdx
-	jz	.Locb_dec_done
-
-	movdqu	0(%rdi),%xmm2
-	cmpq	$2,%rdx
-	jb	.Locb_dec_one
-	movdqu	16(%rdi),%xmm3
-	je	.Locb_dec_two
-
-	movdqu	32(%rdi),%xmm4
-	cmpq	$4,%rdx
-	jb	.Locb_dec_three
-	movdqu	48(%rdi),%xmm5
-	je	.Locb_dec_four
-
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	__ocb_decrypt6
-
-	movdqa	%xmm14,%xmm15
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-	movups	%xmm6,64(%rsi)
-	pxor	%xmm6,%xmm8
-
-	jmp	.Locb_dec_done
-
-.align	16
-.Locb_dec_one:
-	movdqa	%xmm10,%xmm7
-
-	call	__ocb_decrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	jmp	.Locb_dec_done
-
-.align	16
-.Locb_dec_two:
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	%xmm11,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	xorps	%xmm3,%xmm8
-
-	jmp	.Locb_dec_done
-
-.align	16
-.Locb_dec_three:
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	%xmm12,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	xorps	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	xorps	%xmm4,%xmm8
-
-	jmp	.Locb_dec_done
-
-.align	16
-.Locb_dec_four:
-	call	__ocb_decrypt4
-
-	movdqa	%xmm13,%xmm15
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-
-.Locb_dec_done:
-	pxor	%xmm0,%xmm15
-	movdqu	%xmm8,(%rbp)
-	movdqu	%xmm15,(%r9)
-
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	pxor	%xmm8,%xmm8
-	pxor	%xmm9,%xmm9
-	pxor	%xmm10,%xmm10
-	pxor	%xmm11,%xmm11
-	pxor	%xmm12,%xmm12
-	pxor	%xmm13,%xmm13
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	leaq	40(%rsp),%rax
-.cfi_def_cfa	%rax,8
-	movq	-40(%rax),%r14
-.cfi_restore	%r14
-	movq	-32(%rax),%r13
-.cfi_restore	%r13
-	movq	-24(%rax),%r12
-.cfi_restore	%r12
-	movq	-16(%rax),%rbp
-.cfi_restore	%rbp
-	movq	-8(%rax),%rbx
-.cfi_restore	%rbx
-	leaq	(%rax),%rsp
-.cfi_def_cfa_register	%rsp
-.Locb_dec_epilogue:
-	.byte	0xf3,0xc3
-.cfi_endproc	
-.size	aes_hw_ocb_decrypt,.-aes_hw_ocb_decrypt
-
-.type	__ocb_decrypt6,@function
-.align	32
-__ocb_decrypt6:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	movdqa	%xmm10,%xmm14
-	pxor	%xmm15,%xmm10
-	movdqu	(%rbx,%r14,1),%xmm15
-	pxor	%xmm10,%xmm11
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm14
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm15
-	pxor	%xmm14,%xmm6
-	pxor	%xmm15,%xmm7
-	movups	32(%r11),%xmm0
-
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	addq	$6,%r8
-	pxor	%xmm9,%xmm10
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-.byte	102,15,56,222,241
-	pxor	%xmm9,%xmm13
-	pxor	%xmm9,%xmm14
-.byte	102,15,56,222,249
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm15
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	64(%r11),%xmm0
-	shlq	$4,%r12
-	shlq	$4,%r13
-	jmp	.Locb_dec_loop6
-
-.align	32
-.Locb_dec_loop6:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_dec_loop6
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	16(%r11),%xmm1
-	shlq	$4,%r14
-
-.byte	102,65,15,56,223,210
-	movdqu	(%rbx),%xmm10
-	movq	%r10,%rax
-.byte	102,65,15,56,223,219
-.byte	102,65,15,56,223,228
-.byte	102,65,15,56,223,237
-.byte	102,65,15,56,223,246
-.byte	102,65,15,56,223,255
-	.byte	0xf3,0xc3
-.size	__ocb_decrypt6,.-__ocb_decrypt6
-
-.type	__ocb_decrypt4,@function
-.align	32
-__ocb_decrypt4:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	pxor	%xmm15,%xmm10
-	pxor	%xmm10,%xmm11
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	movups	32(%r11),%xmm0
-
-	pxor	%xmm9,%xmm10
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-	pxor	%xmm9,%xmm13
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	48(%r11),%xmm1
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	movups	64(%r11),%xmm0
-	jmp	.Locb_dec_loop4
-
-.align	32
-.Locb_dec_loop4:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_dec_loop4
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,65,15,56,223,210
-.byte	102,65,15,56,223,219
-.byte	102,65,15,56,223,228
-.byte	102,65,15,56,223,237
-	.byte	0xf3,0xc3
-.size	__ocb_decrypt4,.-__ocb_decrypt4
-
-.type	__ocb_decrypt1,@function
-.align	32
-__ocb_decrypt1:
-	pxor	%xmm15,%xmm7
-	pxor	%xmm9,%xmm7
-	pxor	%xmm7,%xmm2
-	movups	32(%r11),%xmm0
-
-.byte	102,15,56,222,209
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm7
-
-.byte	102,15,56,222,208
-	movups	64(%r11),%xmm0
-	jmp	.Locb_dec_loop1
-
-.align	32
-.Locb_dec_loop1:
-.byte	102,15,56,222,209
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	.Locb_dec_loop1
-
-.byte	102,15,56,222,209
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,15,56,223,215
-	.byte	0xf3,0xc3
-.size	__ocb_decrypt1,.-__ocb_decrypt1
 .globl	aes_hw_cbc_encrypt
 .hidden aes_hw_cbc_encrypt
 .type	aes_hw_cbc_encrypt,@function
@@ -3474,7 +1479,7 @@
 	movq	%rcx,%r11
 	testl	%r9d,%r9d
 	jz	.Lcbc_decrypt
-#--------------------------- CBC ENCRYPT ------------------------------#
+
 	movups	(%r8),%xmm2
 	movl	%r10d,%eax
 	cmpq	$16,%rdx
@@ -3485,18 +1490,18 @@
 .Lcbc_enc_loop:
 	movups	(%rdi),%xmm3
 	leaq	16(%rdi),%rdi
-#xorps	%xmm3,%xmm2
+
 	movups	(%rcx),%xmm0
 	movups	16(%rcx),%xmm1
 	xorps	%xmm0,%xmm3
 	leaq	32(%rcx),%rcx
 	xorps	%xmm3,%xmm2
-.Loop_enc1_15:
+.Loop_enc1_6:
 .byte	102,15,56,220,209
 	decl	%eax
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	.Loop_enc1_15
+	jnz	.Loop_enc1_6
 .byte	102,15,56,221,209
 	movl	%r10d,%eax
 	movq	%r11,%rcx
@@ -3527,7 +1532,7 @@
 	movq	%r11,%rcx
 	xorq	%rdx,%rdx
 	jmp	.Lcbc_enc_loop
-#--------------------------- CBC DECRYPT ------------------------------#
+
 .align	16
 .Lcbc_decrypt:
 	cmpq	$16,%rdx
@@ -3542,12 +1547,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-.Loop_dec1_16:
+.Loop_dec1_7:
 .byte	102,15,56,222,209
 	decl	%r10d
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	.Loop_dec1_16
+	jnz	.Loop_dec1_7
 .byte	102,15,56,223,209
 	pxor	%xmm0,%xmm0
 	pxor	%xmm1,%xmm1
@@ -3960,12 +1965,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-.Loop_dec1_17:
+.Loop_dec1_8:
 .byte	102,15,56,222,209
 	decl	%eax
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	.Loop_dec1_17
+	jnz	.Loop_dec1_8
 .byte	102,15,56,223,209
 	xorps	%xmm10,%xmm2
 	movaps	%xmm11,%xmm10
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S
index 7b2038899..5236aa66f 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S
@@ -221,7 +221,7 @@
 	pxor	%xmm13,%xmm8
 	pxor	%xmm14,%xmm7
 
-#Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
+
 
 
 
@@ -692,7 +692,7 @@
 	pxor	%xmm13,%xmm8
 	pxor	%xmm14,%xmm7
 
-#Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
+
 
 
 
@@ -1079,7 +1079,7 @@
 	jnz	.Lkey_loop
 
 	movdqa	80(%r11),%xmm7
-#movdqa	%xmm6, (%rax)
+
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	_bsaes_key_convert,.-_bsaes_key_convert
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
index 9543246..0b36afa 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -731,7 +731,7 @@
 	pshufd	$255,%xmm2,%xmm4
 	movdqa	%xmm2,%xmm3
 	psllq	$1,%xmm2
-	pxor	%xmm5,%xmm5#
+	pxor	%xmm5,%xmm5
 	psrlq	$63,%xmm3
 	pcmpgtd	%xmm4,%xmm5
 	pslldq	$8,%xmm3
@@ -745,43 +745,43 @@
 	pshufd	$78,%xmm2,%xmm6
 	movdqa	%xmm2,%xmm0
 	pxor	%xmm2,%xmm6
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	pshufd	$78,%xmm2,%xmm3
 	pshufd	$78,%xmm0,%xmm4
 	pxor	%xmm2,%xmm3
@@ -790,81 +790,81 @@
 	movdqu	%xmm0,16(%rdi)
 .byte	102,15,58,15,227,8
 	movdqu	%xmm4,32(%rdi)
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	movdqa	%xmm0,%xmm5
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	pshufd	$78,%xmm5,%xmm3
 	pshufd	$78,%xmm0,%xmm4
 	pxor	%xmm5,%xmm3
@@ -888,43 +888,43 @@
 	movdqu	(%rsi),%xmm2
 	movdqu	32(%rsi),%xmm4
 .byte	102,15,56,0,197
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,220,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 .byte	102,15,56,0,197
 	movdqu	%xmm0,(%rdi)
 	.byte	0xf3,0xc3
@@ -962,9 +962,9 @@
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
-#######
 
-#
+
+
 	movdqu	48(%rdx),%xmm3
 	movdqu	32(%rdx),%xmm11
 .byte	102,65,15,56,0,218
@@ -1031,28 +1031,28 @@
 
 	pxor	%xmm0,%xmm8
 	movdqa	%xmm3,%xmm5
-	pxor	%xmm1,%xmm8#
+	pxor	%xmm1,%xmm8
 	pxor	%xmm3,%xmm4
-	movdqa	%xmm8,%xmm9#
+	movdqa	%xmm8,%xmm9
 .byte	102,68,15,58,68,234,17
 	pslldq	$8,%xmm8
-	psrldq	$8,%xmm9#
+	psrldq	$8,%xmm9
 	pxor	%xmm8,%xmm0
 	movdqa	.L7_mask(%rip),%xmm8
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 .byte	102,76,15,110,200
 
 	pand	%xmm0,%xmm8
 .byte	102,69,15,56,0,200
-	pxor	%xmm0,%xmm9#
+	pxor	%xmm0,%xmm9
 .byte	102,68,15,58,68,231,0
-	psllq	$57,%xmm9#
-	movdqa	%xmm9,%xmm8#
+	psllq	$57,%xmm9
+	movdqa	%xmm9,%xmm8
 	pslldq	$8,%xmm9
 .byte	102,15,58,68,222,0
-	psrldq	$8,%xmm8#
+	psrldq	$8,%xmm8
 	pxor	%xmm9,%xmm0
-	pxor	%xmm8,%xmm1#
+	pxor	%xmm8,%xmm1
 	movdqu	0(%rdx),%xmm8
 
 	movdqa	%xmm0,%xmm9
@@ -1065,19 +1065,19 @@
 	xorps	%xmm13,%xmm5
 	movups	80(%rsi),%xmm7
 .byte	102,69,15,56,0,194
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 	pxor	%xmm0,%xmm9
 	psrlq	$5,%xmm0
 
 	movdqa	%xmm11,%xmm13
 	pxor	%xmm12,%xmm4
 	pshufd	$78,%xmm11,%xmm12
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 	pxor	%xmm8,%xmm1
 	pxor	%xmm11,%xmm12
 .byte	102,69,15,58,68,222,0
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	movdqa	%xmm0,%xmm1
 .byte	102,69,15,58,68,238,17
 	xorps	%xmm11,%xmm3
@@ -1101,48 +1101,48 @@
 	pxor	%xmm0,%xmm1
 	pxor	%xmm4,%xmm8
 
-	pxor	%xmm1,%xmm8#
+	pxor	%xmm1,%xmm8
 	pxor	%xmm0,%xmm1
 
-	movdqa	%xmm8,%xmm9#
+	movdqa	%xmm8,%xmm9
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm9#
+	pslldq	$8,%xmm9
 	pxor	%xmm8,%xmm1
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	addq	$0x40,%rcx
 	jz	.Ldone
 	movdqu	32(%rsi),%xmm7
 	subq	$0x10,%rcx
 	jz	.Lodd_tail
 .Lskip4x:
-#######
 
-#	[(H*Ii+1) + (H*Xi+1)] mod P =
-#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-#
+
+
+
+
 	movdqu	(%rdx),%xmm8
 	movdqu	16(%rdx),%xmm3
 .byte	102,69,15,56,0,194
@@ -1167,8 +1167,8 @@
 .Lmod_loop:
 	movdqa	%xmm0,%xmm1
 	movdqa	%xmm4,%xmm8
-	pshufd	$78,%xmm0,%xmm4#
-	pxor	%xmm0,%xmm4#
+	pshufd	$78,%xmm0,%xmm4
+	pxor	%xmm0,%xmm4
 
 .byte	102,15,58,68,198,0
 .byte	102,15,58,68,206,17
@@ -1185,41 +1185,41 @@
 	pxor	%xmm9,%xmm1
 	pxor	%xmm8,%xmm4
 .byte	102,65,15,56,0,218
-	movdqa	%xmm4,%xmm8#
+	movdqa	%xmm4,%xmm8
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm8,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm3,%xmm5#
+	movdqa	%xmm3,%xmm5
 
 	movdqa	%xmm0,%xmm9
 	movdqa	%xmm0,%xmm8
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm8#
+	pxor	%xmm0,%xmm8
 .byte	102,15,58,68,218,0
 	psllq	$1,%xmm0
-	pxor	%xmm8,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm8#
+	pxor	%xmm8,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm8
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm8#
+	psrldq	$8,%xmm8
 	pxor	%xmm9,%xmm0
 	pshufd	$78,%xmm5,%xmm4
-	pxor	%xmm8,%xmm1#
-	pxor	%xmm5,%xmm4#
+	pxor	%xmm8,%xmm1
+	pxor	%xmm5,%xmm4
 
 	movdqa	%xmm0,%xmm9
 	psrlq	$1,%xmm0
 .byte	102,15,58,68,234,17
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 	pxor	%xmm0,%xmm9
 	psrlq	$5,%xmm0
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 	leaq	32(%rdx),%rdx
-	psrlq	$1,%xmm0#
+	psrlq	$1,%xmm0
 .byte	102,15,58,68,231,0
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm1,%xmm0
 
 	subq	$0x20,%rcx
 	ja	.Lmod_loop
@@ -1227,8 +1227,8 @@
 .Leven_tail:
 	movdqa	%xmm0,%xmm1
 	movdqa	%xmm4,%xmm8
-	pshufd	$78,%xmm0,%xmm4#
-	pxor	%xmm0,%xmm4#
+	pshufd	$78,%xmm0,%xmm4
+	pxor	%xmm0,%xmm4
 
 .byte	102,15,58,68,198,0
 .byte	102,15,58,68,206,17
@@ -1239,34 +1239,34 @@
 	pxor	%xmm0,%xmm8
 	pxor	%xmm1,%xmm8
 	pxor	%xmm8,%xmm4
-	movdqa	%xmm4,%xmm8#
+	movdqa	%xmm4,%xmm8
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm8,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	testq	%rcx,%rcx
 	jnz	.Ldone
 
@@ -1274,43 +1274,43 @@
 	movdqu	(%rdx),%xmm8
 .byte	102,69,15,56,0,194
 	pxor	%xmm8,%xmm0
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,223,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 .Ldone:
 .byte	102,65,15,56,0,194
 	movdqu	%xmm0,(%rdi)
@@ -1332,7 +1332,7 @@
 	vpshufd	$255,%xmm2,%xmm4
 	vpsrlq	$63,%xmm2,%xmm3
 	vpsllq	$1,%xmm2,%xmm2
-	vpxor	%xmm5,%xmm5,%xmm5#
+	vpxor	%xmm5,%xmm5,%xmm5
 	vpcmpgtd	%xmm4,%xmm5,%xmm5
 	vpslldq	$8,%xmm3,%xmm3
 	vpor	%xmm3,%xmm2,%xmm2
@@ -1351,65 +1351,65 @@
 	vpalignr	$8,%xmm3,%xmm4,%xmm5
 	vmovdqu	%xmm5,-16(%rdi)
 	vpunpckhqdq	%xmm0,%xmm0,%xmm3
-	vpxor	%xmm0,%xmm3,%xmm3#
-	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1#######
-	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0#######
-	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3#######
-	vpxor	%xmm0,%xmm1,%xmm4#
-	vpxor	%xmm4,%xmm3,%xmm3#
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
 
-	vpslldq	$8,%xmm3,%xmm4#
+	vpslldq	$8,%xmm3,%xmm4
 	vpsrldq	$8,%xmm3,%xmm3
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpsllq	$57,%xmm0,%xmm3
 	vpsllq	$62,%xmm0,%xmm4
-	vpxor	%xmm3,%xmm4,%xmm4#
+	vpxor	%xmm3,%xmm4,%xmm4
 	vpsllq	$63,%xmm0,%xmm3
-	vpxor	%xmm3,%xmm4,%xmm4#
-	vpslldq	$8,%xmm4,%xmm3#
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
 	vpsrldq	$8,%xmm4,%xmm4
-	vpxor	%xmm3,%xmm0,%xmm0#
+	vpxor	%xmm3,%xmm0,%xmm0
 	vpxor	%xmm4,%xmm1,%xmm1
 
 	vpsrlq	$1,%xmm0,%xmm4
 	vpxor	%xmm0,%xmm1,%xmm1
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpsrlq	$5,%xmm4,%xmm4
-	vpxor	%xmm4,%xmm0,%xmm0#
-	vpsrlq	$1,%xmm0,%xmm0#
-	vpxor	%xmm1,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
 .Linit_start_avx:
 	vmovdqa	%xmm0,%xmm5
 	vpunpckhqdq	%xmm0,%xmm0,%xmm3
-	vpxor	%xmm0,%xmm3,%xmm3#
-	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1#######
-	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0#######
-	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3#######
-	vpxor	%xmm0,%xmm1,%xmm4#
-	vpxor	%xmm4,%xmm3,%xmm3#
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
 
-	vpslldq	$8,%xmm3,%xmm4#
+	vpslldq	$8,%xmm3,%xmm4
 	vpsrldq	$8,%xmm3,%xmm3
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpsllq	$57,%xmm0,%xmm3
 	vpsllq	$62,%xmm0,%xmm4
-	vpxor	%xmm3,%xmm4,%xmm4#
+	vpxor	%xmm3,%xmm4,%xmm4
 	vpsllq	$63,%xmm0,%xmm3
-	vpxor	%xmm3,%xmm4,%xmm4#
-	vpslldq	$8,%xmm4,%xmm3#
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
 	vpsrldq	$8,%xmm4,%xmm4
-	vpxor	%xmm3,%xmm0,%xmm0#
+	vpxor	%xmm3,%xmm0,%xmm0
 	vpxor	%xmm4,%xmm1,%xmm1
 
 	vpsrlq	$1,%xmm0,%xmm4
 	vpxor	%xmm0,%xmm1,%xmm1
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpsrlq	$5,%xmm4,%xmm4
-	vpxor	%xmm4,%xmm0,%xmm0#
-	vpsrlq	$1,%xmm0,%xmm0#
-	vpxor	%xmm1,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
 	vpshufd	$78,%xmm5,%xmm3
 	vpshufd	$78,%xmm0,%xmm4
 	vpxor	%xmm5,%xmm3,%xmm3
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
index 635282b..3a57522 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
@@ -35,7 +35,7 @@
 .LordK:
 .quad	0xccd1c8aaee00bc4f
 
-################################################################################
+
 
 .globl	ecp_nistz256_neg
 .hidden ecp_nistz256_neg
@@ -93,7 +93,7 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	ecp_nistz256_neg,.-ecp_nistz256_neg
-################################################################################
+
 
 
 
@@ -135,7 +135,7 @@
 	leaq	.Lord(%rip),%r14
 	movq	.LordK(%rip),%r15
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	movq	%rax,%r8
@@ -163,7 +163,7 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-################################
+
 	mulq	0(%r14)
 	movq	%r8,%rbp
 	addq	%rax,%r13
@@ -193,7 +193,7 @@
 	adcq	%rbp,%r12
 	adcq	$0,%r13
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r9
@@ -229,7 +229,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r8
 
-################################
+
 	mulq	0(%r14)
 	movq	%r9,%rbp
 	addq	%rax,%rcx
@@ -258,7 +258,7 @@
 	adcq	%rbp,%r13
 	adcq	$0,%r8
 
-#################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r10
@@ -294,7 +294,7 @@
 	adcq	%rdx,%r8
 	adcq	$0,%r9
 
-################################
+
 	mulq	0(%r14)
 	movq	%r10,%rbp
 	addq	%rax,%rcx
@@ -323,7 +323,7 @@
 	adcq	%rbp,%r8
 	adcq	$0,%r9
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r11
@@ -359,7 +359,7 @@
 	adcq	%rdx,%r9
 	adcq	$0,%r10
 
-################################
+
 	mulq	0(%r14)
 	movq	%r11,%rbp
 	addq	%rax,%rcx
@@ -387,7 +387,7 @@
 	adcq	%rbp,%r9
 	adcq	$0,%r10
 
-################################
+
 	movq	%r12,%rsi
 	subq	0(%r14),%r12
 	movq	%r13,%r11
@@ -427,7 +427,7 @@
 .cfi_endproc	
 .size	ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont
 
-################################################################################
+
 
 
 
@@ -474,7 +474,7 @@
 
 .align	32
 .Loop_ord_sqr:
-################################
+
 	movq	%rax,%rbp
 	mulq	%r8
 	movq	%rax,%r9
@@ -496,13 +496,13 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-################################
+
 	mulq	%r14
 	movq	%rax,%r13
 	movq	%r14,%rax
 	movq	%rdx,%r14
 
-################################
+
 	mulq	%rbp
 	addq	%rax,%r11
 	movq	%r15,%rax
@@ -517,7 +517,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r14
 
-################################
+
 	xorq	%r15,%r15
 	movq	%r8,%rax
 	addq	%r9,%r9
@@ -528,7 +528,7 @@
 	adcq	%r14,%r14
 	adcq	$0,%r15
 
-################################
+
 	mulq	%rax
 	movq	%rax,%r8
 .byte	102,72,15,126,200
@@ -557,7 +557,7 @@
 	movq	0(%rsi),%rax
 	adcq	%rdx,%r15
 
-################################
+
 	mulq	%r8
 	movq	%r8,%rbp
 	addq	%rax,%rcx
@@ -588,7 +588,7 @@
 	addq	%rbp,%r11
 	adcq	$0,%r8
 
-################################
+
 	mulq	%r9
 	movq	%r9,%rbp
 	addq	%rax,%rcx
@@ -619,7 +619,7 @@
 	addq	%rbp,%r8
 	adcq	$0,%r9
 
-################################
+
 	mulq	%r10
 	movq	%r10,%rbp
 	addq	%rax,%rcx
@@ -650,7 +650,7 @@
 	addq	%rbp,%r9
 	adcq	$0,%r10
 
-################################
+
 	mulq	%r11
 	movq	%r11,%rbp
 	addq	%rax,%rcx
@@ -677,7 +677,7 @@
 	addq	%rbp,%r10
 	adcq	$0,%r11
 
-################################
+
 	xorq	%rdx,%rdx
 	addq	%r12,%r8
 	adcq	%r13,%r9
@@ -687,7 +687,7 @@
 	movq	%r9,%rax
 	adcq	$0,%rdx
 
-################################
+
 	subq	0(%rsi),%r8
 	movq	%r10,%r14
 	sbbq	8(%rsi),%r9
@@ -730,7 +730,7 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
-################################################################################
+
 .type	ecp_nistz256_ord_mul_montx,@function
 .align	32
 ecp_nistz256_ord_mul_montx:
@@ -766,7 +766,7 @@
 	leaq	.Lord-128(%rip),%r14
 	movq	.LordK(%rip),%r15
 
-################################
+
 	mulxq	%r9,%r8,%r9
 	mulxq	%r10,%rcx,%r10
 	mulxq	%r11,%rbp,%r11
@@ -778,7 +778,7 @@
 	adcq	%rcx,%r11
 	adcq	$0,%r12
 
-################################
+
 	xorq	%r13,%r13
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r8
@@ -800,7 +800,7 @@
 	adoxq	%r8,%r13
 	adcq	$0,%r13
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r9
 	adoxq	%rbp,%r10
@@ -823,7 +823,7 @@
 	adoxq	%r8,%r8
 	adcq	$0,%r8
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r9
 	adoxq	%rbp,%r10
@@ -844,7 +844,7 @@
 	adoxq	%r9,%r8
 	adcq	$0,%r8
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r10
 	adoxq	%rbp,%r11
@@ -867,7 +867,7 @@
 	adoxq	%r9,%r9
 	adcq	$0,%r9
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r10
 	adoxq	%rbp,%r11
@@ -888,7 +888,7 @@
 	adoxq	%r10,%r9
 	adcq	$0,%r9
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -911,7 +911,7 @@
 	adoxq	%r10,%r10
 	adcq	$0,%r10
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -934,7 +934,7 @@
 	adoxq	%r11,%r10
 	adcq	$0,%r10
 
-#################################
+
 
 	movq	%r8,%rcx
 	subq	0(%r14),%r12
@@ -1019,7 +1019,7 @@
 	adcq	%rbp,%r11
 	adcq	$0,%r12
 	xorq	%r13,%r13
-#################################
+
 	mulxq	%r15,%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -1029,7 +1029,7 @@
 	adcxq	%rcx,%r12
 	adoxq	%rbp,%r13
 	adcq	$0,%r13
-#################################
+
 	mulxq	%r8,%rcx,%r14
 	movq	%rax,%rdx
 .byte	102,73,15,110,216
@@ -1039,7 +1039,7 @@
 	adcxq	%r10,%r10
 	adoxq	%r15,%r14
 
-################################
+
 	mulxq	%rdx,%r8,%rbp
 .byte	102,72,15,126,202
 	adcxq	%r11,%r11
@@ -1061,7 +1061,7 @@
 	adoxq	%rcx,%r14
 	adoxq	%rax,%r15
 
-################################
+
 	movq	%r8,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1080,7 +1080,7 @@
 	adoxq	%rbp,%r8
 	adcxq	%rax,%r8
 
-#################################
+
 	movq	%r9,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1098,7 +1098,7 @@
 	adcxq	%rbp,%r9
 	adoxq	%rax,%r9
 
-#################################
+
 	movq	%r10,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1116,7 +1116,7 @@
 	adoxq	%rbp,%r10
 	adcxq	%rax,%r10
 
-#################################
+
 	movq	%r11,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1134,7 +1134,7 @@
 	adcxq	%rbp,%r11
 	adoxq	%rax,%r11
 
-################################
+
 	addq	%r8,%r12
 	adcq	%r13,%r9
 	movq	%r12,%rdx
@@ -1143,7 +1143,7 @@
 	movq	%r9,%r14
 	adcq	$0,%rax
 
-################################
+
 	subq	0(%rsi),%r12
 	movq	%r10,%r15
 	sbbq	8(%rsi),%r9
@@ -1186,7 +1186,7 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	ecp_nistz256_ord_sqr_montx,.-ecp_nistz256_ord_sqr_montx
-################################################################################
+
 
 
 
@@ -1268,7 +1268,7 @@
 .align	32
 __ecp_nistz256_mul_montq:
 .cfi_startproc	
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	%r9
@@ -1297,12 +1297,12 @@
 	xorq	%r13,%r13
 	movq	%rdx,%r12
 
-########################################################################
 
 
 
 
-#
+
+
 
 
 
@@ -1318,7 +1318,7 @@
 	adcq	$0,%r13
 	xorq	%r8,%r8
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1351,7 +1351,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r8
 
-########################################################################
+
 
 	movq	%r9,%rbp
 	shlq	$32,%r9
@@ -1365,7 +1365,7 @@
 	adcq	$0,%r8
 	xorq	%r9,%r9
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1398,7 +1398,7 @@
 	adcq	%rdx,%r8
 	adcq	$0,%r9
 
-########################################################################
+
 
 	movq	%r10,%rbp
 	shlq	$32,%r10
@@ -1412,7 +1412,7 @@
 	adcq	$0,%r9
 	xorq	%r10,%r10
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1445,7 +1445,7 @@
 	adcq	%rdx,%r9
 	adcq	$0,%r10
 
-########################################################################
+
 
 	movq	%r11,%rbp
 	shlq	$32,%r11
@@ -1459,7 +1459,7 @@
 	movq	%r13,%rbp
 	adcq	$0,%r10
 
-########################################################################
+
 
 	subq	$-1,%r12
 	movq	%r8,%rbx
@@ -1482,7 +1482,7 @@
 .cfi_endproc	
 .size	__ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
 
-################################################################################
+
 
 
 
@@ -1578,7 +1578,7 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-#################################
+
 	mulq	%r14
 	addq	%rax,%r11
 	movq	%r8,%rax
@@ -1593,7 +1593,7 @@
 	movq	%rdx,%r13
 	adcq	$0,%r13
 
-#################################
+
 	mulq	%r15
 	xorq	%r15,%r15
 	addq	%rax,%r13
@@ -1637,7 +1637,7 @@
 	movq	.Lpoly+8(%rip),%rsi
 	movq	.Lpoly+24(%rip),%rbp
 
-##########################################
+
 
 
 	movq	%r8,%rcx
@@ -1650,7 +1650,7 @@
 	movq	%r9,%rax
 	adcq	$0,%rdx
 
-##########################################
+
 
 	movq	%r9,%rcx
 	shlq	$32,%r9
@@ -1663,7 +1663,7 @@
 	movq	%r10,%rax
 	adcq	$0,%rdx
 
-##########################################
+
 
 	movq	%r10,%rcx
 	shlq	$32,%r10
@@ -1676,7 +1676,7 @@
 	movq	%r11,%rax
 	adcq	$0,%rdx
 
-###########################################
+
 
 	movq	%r11,%rcx
 	shlq	$32,%r11
@@ -1689,7 +1689,7 @@
 	adcq	$0,%rdx
 	xorq	%r11,%r11
 
-############################################
+
 
 	addq	%r8,%r12
 	adcq	%r9,%r13
@@ -1723,7 +1723,7 @@
 .align	32
 __ecp_nistz256_mul_montx:
 .cfi_startproc	
-########################################################################
+
 
 	mulxq	%r9,%r8,%r9
 	mulxq	%r10,%rcx,%r10
@@ -1740,7 +1740,7 @@
 	shrxq	%r14,%r8,%rcx
 	adcq	$0,%r12
 
-########################################################################
+
 
 	addq	%rbp,%r9
 	adcq	%rcx,%r10
@@ -1752,7 +1752,7 @@
 	adcq	$0,%r13
 	xorq	%r8,%r8
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r9
@@ -1777,7 +1777,7 @@
 	adoxq	%r8,%r8
 	adcq	$0,%r8
 
-########################################################################
+
 
 	addq	%rcx,%r10
 	adcq	%rbp,%r11
@@ -1789,7 +1789,7 @@
 	adcq	$0,%r8
 	xorq	%r9,%r9
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r10
@@ -1814,7 +1814,7 @@
 	adoxq	%r9,%r9
 	adcq	$0,%r9
 
-########################################################################
+
 
 	addq	%rcx,%r11
 	adcq	%rbp,%r12
@@ -1826,7 +1826,7 @@
 	adcq	$0,%r9
 	xorq	%r10,%r10
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r11
@@ -1851,7 +1851,7 @@
 	adoxq	%r10,%r10
 	adcq	$0,%r10
 
-########################################################################
+
 
 	addq	%rcx,%r12
 	adcq	%rbp,%r13
@@ -1864,7 +1864,7 @@
 	adcq	%rbp,%r9
 	adcq	$0,%r10
 
-########################################################################
+
 
 	xorl	%eax,%eax
 	movq	%r8,%rcx
@@ -1902,7 +1902,7 @@
 	adcq	$0,%r12
 	xorq	%r13,%r13
 
-#################################
+
 	mulxq	%r15,%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -1913,7 +1913,7 @@
 	adoxq	%rbp,%r13
 	adcq	$0,%r13
 
-#################################
+
 	mulxq	%r8,%rcx,%r14
 	movq	0+128(%rsi),%rdx
 	xorq	%r15,%r15
@@ -2017,7 +2017,7 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	__ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
-################################################################################
+
 
 .globl	ecp_nistz256_select_w5
 .hidden ecp_nistz256_select_w5
@@ -2084,7 +2084,7 @@
 .LSEH_end_ecp_nistz256_select_w5:
 .size	ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
 
-################################################################################
+
 
 .globl	ecp_nistz256_select_w7
 .hidden ecp_nistz256_select_w7
@@ -2139,7 +2139,7 @@
 .cfi_endproc	
 .LSEH_end_ecp_nistz256_select_w7:
 .size	ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
-################################################################################
+
 
 .type	ecp_nistz256_avx2_select_w5,@function
 .align	32
@@ -2203,7 +2203,7 @@
 .LSEH_end_ecp_nistz256_avx2_select_w5:
 .size	ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5
 
-################################################################################
+
 
 .globl	ecp_nistz256_avx2_select_w7
 .hidden ecp_nistz256_avx2_select_w7
@@ -2908,9 +2908,9 @@
 	movq	24+32(%rsp),%r12
 	leaq	192(%rsp),%rdi
 	call	__ecp_nistz256_mul_montq
-#lea	192(%rsp), %rsi
-#lea	32(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -3153,7 +3153,7 @@
 	pcmpeqd	%xmm4,%xmm5
 	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rax
-#lea	0x00(%rbx), %rbx
+
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
@@ -3243,9 +3243,9 @@
 	movq	24+128(%rsp),%r12
 	leaq	0(%rsp),%rdi
 	call	__ecp_nistz256_mul_montq
-#lea	0(%rsp), %rsi
-#lea	128(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -4029,9 +4029,9 @@
 	movq	24+32(%rsp),%r12
 	leaq	192(%rsp),%rdi
 	call	__ecp_nistz256_mul_montx
-#lea	192(%rsp), %rsi
-#lea	32(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -4268,7 +4268,7 @@
 	pcmpeqd	%xmm4,%xmm5
 	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rdx
-#lea	0x00(%rbx), %rbx
+
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
@@ -4358,9 +4358,9 @@
 	movq	24+128(%rsp),%r12
 	leaq	0(%rsp),%rdi
 	call	__ecp_nistz256_mul_montx
-#lea	0(%rsp), %rsi
-#lea	128(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S
index d7b0cb4..fefccd6f 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S
@@ -23,14 +23,13 @@
 CRYPTO_rdrand:
 .cfi_startproc	
 	xorq	%rax,%rax
-
-
-.byte	0x48, 0x0f, 0xc7, 0xf1
+.byte	72,15,199,242
 
 	adcq	%rax,%rax
-	movq	%rcx,0(%rdi)
+	movq	%rdx,0(%rdi)
 	.byte	0xf3,0xc3
 .cfi_endproc	
+.size	CRYPTO_rdrand,.-CRYPTO_rdrand
 
 
 
@@ -46,9 +45,7 @@
 	jz	.Lout
 	movq	$8,%rdx
 .Lloop:
-
-
-.byte	0x48, 0x0f, 0xc7, 0xf1
+.byte	72,15,199,241
 	jnc	.Lerr
 	movq	%rcx,0(%rdi)
 	addq	%rdx,%rdi
@@ -61,4 +58,5 @@
 	xorq	%rax,%rax
 	.byte	0xf3,0xc3
 .cfi_endproc	
+.size	CRYPTO_rdrand_multiple8_buf,.-CRYPTO_rdrand_multiple8_buf
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
index bfdc965f..579c7055 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -382,9 +382,9 @@
 	vpaddq	%ymm10,%ymm7,%ymm7
 	vpmuludq	256-128(%r13),%ymm12,%ymm14
 	vmovd	%eax,%xmm12
-#vmovdqu	32*1-8-128(%r13), %ymm11
+
 	vpaddq	%ymm14,%ymm8,%ymm8
-#vmovdqu	32*2-8-128(%r13), %ymm10
+
 	vpbroadcastq	%xmm12,%ymm12
 
 	vpmuludq	32-8-128(%r13),%ymm13,%ymm11
@@ -460,7 +460,7 @@
 	addq	%r12,%rax
 	vpaddq	%ymm14,%ymm7,%ymm7
 	vpmuludq	%ymm12,%ymm11,%ymm11
-#vmovdqu	32*2-24-128(%r13), %ymm14
+
 	movq	%rax,%r9
 	imull	%ecx,%eax
 	vpaddq	%ymm11,%ymm8,%ymm8
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
index 0ce95669..55b540f 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
@@ -1819,8 +1819,8 @@
 	movl	20(%rdi),%r9d
 	movl	24(%rdi),%r10d
 	movl	28(%rdi),%r11d
-#movdqa	K256+512+32(%rip),%xmm8
-#movdqa	K256+512+64(%rip),%xmm9
+
+
 	jmp	.Lloop_ssse3
 .align	16
 .Lloop_ssse3:
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S
index 8cdda6c..232ddf99 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S
@@ -13,21 +13,21 @@
 #endif
 .text	
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-##
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .type	_vpaes_encrypt_core,@function
 .align	16
 _vpaes_encrypt_core:
@@ -115,11 +115,11 @@
 .cfi_endproc	
 .size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
 
-##
-#
-##
-#
-##
+
+
+
+
+
 .type	_vpaes_decrypt_core,@function
 .align	16
 _vpaes_decrypt_core:
@@ -149,9 +149,9 @@
 
 .align	16
 .Ldec_loop:
-##
-#
-##
+
+
+
 	movdqa	-32(%r10),%xmm4
 	movdqa	-16(%r10),%xmm1
 .byte	102,15,56,0,226
@@ -223,11 +223,11 @@
 .cfi_endproc	
 .size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
 
-########################################################
-#
-#
-#
-########################################################
+
+
+
+
+
 .type	_vpaes_schedule_core,@function
 .align	16
 _vpaes_schedule_core:
@@ -268,14 +268,14 @@
 	je	.Lschedule_192
 
 
-##
-#
-##
-#
-##
-#
-#
-##
+
+
+
+
+
+
+
+
 .Lschedule_128:
 	movl	$10,%esi
 
@@ -286,21 +286,21 @@
 	call	_vpaes_schedule_mangle
 	jmp	.Loop_schedule_128
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .align	16
 .Lschedule_192:
 	movdqu	8(%rdi),%xmm0
@@ -323,16 +323,16 @@
 	call	_vpaes_schedule_192_smear
 	jmp	.Loop_schedule_192
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
 .align	16
 .Lschedule_256:
 	movdqu	16(%rdi),%xmm0
@@ -359,16 +359,16 @@
 	jmp	.Loop_schedule_256
 
 
-##
-#
-##
-#
-#
-#
-#
-##
-#
-##
+
+
+
+
+
+
+
+
+
+
 .align	16
 .Lschedule_mangle_last:
 
@@ -401,20 +401,20 @@
 .cfi_endproc	
 .size	_vpaes_schedule_core,.-_vpaes_schedule_core
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .type	_vpaes_schedule_192_smear,@function
 .align	16
 _vpaes_schedule_192_smear:
@@ -430,24 +430,24 @@
 .cfi_endproc	
 .size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
 
-##
-#
-##
-#
-##
-#
-#
-#
-##
-#
-#
-##
-#
-#
-##
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .type	_vpaes_schedule_round,@function
 .align	16
 _vpaes_schedule_round:
@@ -508,15 +508,15 @@
 .cfi_endproc	
 .size	_vpaes_schedule_round,.-_vpaes_schedule_round
 
-##
-#
-##
-#
-##
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
 .type	_vpaes_schedule_transform,@function
 .align	16
 _vpaes_schedule_transform:
@@ -534,29 +534,29 @@
 .cfi_endproc	
 .size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
 
-##
-#
-##
-#
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-#
-#
-##
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .type	_vpaes_schedule_mangle,@function
 .align	16
 _vpaes_schedule_mangle:
@@ -628,9 +628,9 @@
 .cfi_endproc	
 .size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
 
-#
 
-#
+
+
 .globl	vpaes_set_encrypt_key
 .hidden vpaes_set_encrypt_key
 .type	vpaes_set_encrypt_key,@function
@@ -744,12 +744,12 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
-##
-#
-##
-#
-#
-##
+
+
+
+
+
+
 .type	_vpaes_preheat,@function
 .align	16
 _vpaes_preheat:
@@ -765,11 +765,11 @@
 	.byte	0xf3,0xc3
 .cfi_endproc	
 .size	_vpaes_preheat,.-_vpaes_preheat
-########################################################
-#
-#
-#
-########################################################
+
+
+
+
+
 .type	_vpaes_consts,@object
 .align	64
 _vpaes_consts:
@@ -826,10 +826,10 @@
 .quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
 .quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
 
-##
-#
-#
-##
+
+
+
+
 .Lk_dksd:
 .quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
 .quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
@@ -843,10 +843,10 @@
 .quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
 .quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
 
-##
-#
-#
-##
+
+
+
+
 .Lk_dipt:
 .quad	0x0F505B040B545F00, 0x154A411E114E451A
 .quad	0x86E383E660056500, 0x12771772F491F194
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
index 95d5e1d..f3637f0 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
@@ -59,7 +59,7 @@
 	andq	$-1024,%r10
 
 
-#
+
 
 
 
@@ -736,11 +736,11 @@
 	shlq	$3+2,%r10
 	negq	%r9
 
-##############################################################
 
 
 
-#
+
+
 	leaq	-64(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	movq	(%r8),%r8
@@ -943,7 +943,6 @@
 .Lmulx4x_page_walk_done:
 
 	leaq	(%rdx,%r9,1),%r10
-##############################################################
 
 
 
@@ -954,7 +953,8 @@
 
 
 
-#
+
+
 	movq	%r9,0(%rsp)
 	shrq	$5,%r9
 	movq	%r10,16(%rsp)
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
index 71d5e9fe..b12393e 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
@@ -54,7 +54,7 @@
 	andq	$-1024,%r10
 
 
-#
+
 
 
 
@@ -487,7 +487,6 @@
 	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
-##############################################################
 
 
 
@@ -495,7 +494,8 @@
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -566,6 +566,7 @@
 .type	mul4x_internal,@function
 .align	32
 mul4x_internal:
+.cfi_startproc	
 	shlq	$5,%r9
 	movd	8(%rax),%xmm5
 	leaq	.Linc(%rip),%rax
@@ -1087,6 +1088,7 @@
 	movq	16(%rbp),%r14
 	movq	24(%rbp),%r15
 	jmp	.Lsqr4x_sub_entry
+.cfi_endproc	
 .size	mul4x_internal,.-mul4x_internal
 .globl	bn_power5
 .hidden bn_power5
@@ -1120,13 +1122,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -1166,15 +1168,15 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
 
 
-#
+
+
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 .cfi_escape	0x0f,0x05,0x77,0x28,0x06,0x23,0x08
@@ -1232,14 +1234,15 @@
 .align	32
 bn_sqr8x_internal:
 __bn_sqr8x_internal:
-##############################################################
-
-#
+.cfi_startproc	
 
 
 
-#
-##############################################################
+
+
+
+
+
 
 
 
@@ -2006,10 +2009,12 @@
 	cmpq	%rdx,%rdi
 	jb	.L8x_reduction_loop
 	.byte	0xf3,0xc3
+.cfi_endproc	
 .size	bn_sqr8x_internal,.-bn_sqr8x_internal
 .type	__bn_post4x_internal,@function
 .align	32
 __bn_post4x_internal:
+.cfi_startproc	
 	movq	0(%rbp),%r12
 	leaq	(%rdi,%r9,1),%rbx
 	movq	%r9,%rcx
@@ -2060,16 +2065,19 @@
 	movq	%r9,%r10
 	negq	%r9
 	.byte	0xf3,0xc3
+.cfi_endproc	
 .size	__bn_post4x_internal,.-__bn_post4x_internal
 .globl	bn_from_montgomery
 .hidden bn_from_montgomery
 .type	bn_from_montgomery,@function
 .align	32
 bn_from_montgomery:
+.cfi_startproc	
 	testl	$7,%r9d
 	jz	bn_from_mont8x
 	xorl	%eax,%eax
 	.byte	0xf3,0xc3
+.cfi_endproc	
 .size	bn_from_montgomery,.-bn_from_montgomery
 
 .type	bn_from_mont8x,@function
@@ -2098,13 +2106,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2144,15 +2152,15 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
 
 
-#
+
+
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 .cfi_escape	0x0f,0x05,0x77,0x28,0x06,0x23,0x08
@@ -2266,7 +2274,6 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
@@ -2274,7 +2281,8 @@
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2310,7 +2318,6 @@
 	ja	.Lmulx4x_page_walk
 .Lmulx4x_page_walk_done:
 
-##############################################################
 
 
 
@@ -2321,7 +2328,8 @@
 
 
 
-#
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 .cfi_escape	0x0f,0x05,0x77,0x28,0x06,0x23,0x08
@@ -2354,6 +2362,7 @@
 .type	mulx4x_internal,@function
 .align	32
 mulx4x_internal:
+.cfi_startproc	
 	movq	%r9,8(%rsp)
 	movq	%r9,%r10
 	negq	%r9
@@ -2772,6 +2781,7 @@
 	movq	16(%rbp),%r14
 	movq	24(%rbp),%r15
 	jmp	.Lsqrx4x_sub_entry
+.cfi_endproc	
 .size	mulx4x_internal,.-mulx4x_internal
 .type	bn_powerx5,@function
 .align	32
@@ -2799,13 +2809,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2845,9 +2855,6 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
@@ -2855,7 +2862,10 @@
 
 
 
-#
+
+
+
+
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,72,15,110,209
@@ -2916,22 +2926,6 @@
 bn_sqrx8x_internal:
 __bn_sqrx8x_internal:
 .cfi_startproc	
-##################################################################
-
-#
-
-
-
-#
-##################################################################
-
-
-
-
-
-
-
-#
 
 
 
@@ -2948,7 +2942,23 @@
 
 
 
-#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -2980,7 +2990,7 @@
 	jnz	.Lsqrx8x_zero
 
 	movq	0(%rsi),%rdx
-#xor	%r9,%r9
+
 	xorq	%r10,%r10
 	xorq	%r11,%r11
 	xorq	%r12,%r12
@@ -3097,7 +3107,7 @@
 	movq	%r14,%rdx
 	adoxq	%rbx,%r11
 	adcxq	%r12,%r11
-#adox	%rbp,%rax
+
 	adcxq	%rbp,%rax
 
 	mulxq	%r15,%r14,%rbx
@@ -3136,7 +3146,7 @@
 	movq	%rax,16+8(%rsp)
 	movq	%rdi,24+8(%rsp)
 
-#lea	8*8(%rdi),%rdi
+
 	xorl	%eax,%eax
 	jmp	.Lsqrx8x_loop
 
@@ -3259,7 +3269,7 @@
 	adoxq	%r11,%r11
 	movq	16(%rdi),%r12
 	movq	24(%rdi),%r13
-#jmp	.Lsqrx4x_shift_n_add
+
 
 .align	32
 .Lsqrx4x_shift_n_add:
@@ -3324,7 +3334,7 @@
 	movq	32+8(%rsp),%rbx
 	movq	48+8(%rsp),%rdx
 	leaq	-64(%rbp,%r9,1),%rcx
-#lea	48+8(%rsp,%r9,2),%rdi
+
 	movq	%rcx,0+8(%rsp)
 	movq	%rdi,8+8(%rsp)
 
@@ -3530,13 +3540,15 @@
 .cfi_endproc	
 .size	bn_sqrx8x_internal,.-bn_sqrx8x_internal
 .align	32
+.type	__bn_postx4x_internal,@function
 __bn_postx4x_internal:
+.cfi_startproc	
 	movq	0(%rbp),%r12
 	movq	%rcx,%r10
 	movq	%rcx,%r9
 	negq	%rax
 	sarq	$3+2,%rcx
-#lea	48+8(%rsp,%r9),%rdi
+
 .byte	102,72,15,126,202
 .byte	102,72,15,126,206
 	decq	%r12
@@ -3578,12 +3590,14 @@
 	negq	%r9
 
 	.byte	0xf3,0xc3
+.cfi_endproc	
 .size	__bn_postx4x_internal,.-__bn_postx4x_internal
 .globl	bn_scatter5
 .hidden bn_scatter5
 .type	bn_scatter5,@function
 .align	16
 bn_scatter5:
+.cfi_startproc	
 	cmpl	$0,%esi
 	jz	.Lscatter_epilogue
 	leaq	(%rdx,%rcx,8),%rdx
@@ -3596,6 +3610,7 @@
 	jnz	.Lscatter
 .Lscatter_epilogue:
 	.byte	0xf3,0xc3
+.cfi_endproc	
 .size	bn_scatter5,.-bn_scatter5
 
 .globl	bn_gather5
@@ -3603,10 +3618,12 @@
 .type	bn_gather5,@function
 .align	32
 bn_gather5:
+.cfi_startproc	
 .LSEH_begin_bn_gather5:
 
-.byte	0x4c,0x8d,0x14,0x24			#lea    (%rsp),%r10
-.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00	#sub	src/crypto/fipsmodule/bn/asm/x86_64-mont5.plx108,%rsp
+.byte	0x4c,0x8d,0x14,0x24
+.cfi_def_cfa_register	%r10
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
 	leaq	.Linc(%rip),%rax
 	andq	$-16,%rsp
 
@@ -3759,8 +3776,10 @@
 	jnz	.Lgather
 
 	leaq	(%r10),%rsp
+.cfi_def_cfa_register	%rsp
 	.byte	0xf3,0xc3
 .LSEH_end_bn_gather5:
+.cfi_endproc	
 .size	bn_gather5,.-bn_gather5
 .align	64
 .Linc:
diff --git a/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S
index 0bbbf0a..10b1ad95 100644
--- a/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S
@@ -72,13 +72,13 @@
 
 L$ctr32_body:
 
-#movdqa	.Lsigma(%rip),%xmm0
+
 	movdqu	(%rcx),%xmm1
 	movdqu	16(%rcx),%xmm2
 	movdqu	(%r8),%xmm3
 	movdqa	L$one(%rip),%xmm4
 
-#movdqa	%xmm0,4*0(%rsp)
+
 	movdqa	%xmm1,16(%rsp)
 	movdqa	%xmm2,32(%rsp)
 	movdqa	%xmm3,48(%rsp)
@@ -871,9 +871,9 @@
 	cmpq	$64,%rdx
 	jae	L$64_or_more4x
 
-#movdqa		0x00(%rsp),%xmm6
+
 	xorq	%r10,%r10
-#movdqa		%xmm6,0x00(%rsp)
+
 	movdqa	%xmm12,16(%rsp)
 	movdqa	%xmm4,32(%rsp)
 	movdqa	%xmm0,48(%rsp)
@@ -1027,7 +1027,7 @@
 	andq	$-32,%rsp
 	vzeroupper
 
-###############
+
 
 
 
diff --git a/third_party/boringssl/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
index 7aa437c7..0c921b3 100644
--- a/third_party/boringssl/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S
@@ -213,7 +213,7 @@
 	vpclmulqdq	$0x10,(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	96(%rsi),%xmm0
 	vpclmulqdq	$0x01,16(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
@@ -225,7 +225,7 @@
 	vpxor	%xmm6,%xmm5,%xmm5
 
 
-#########################################################
+
 	vmovdqu	80(%rsi),%xmm0
 
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm7
@@ -242,7 +242,7 @@
 
 
 	vpxor	%xmm7,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	64(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,48(%rdi),%xmm0,%xmm6
@@ -254,7 +254,7 @@
 	vpclmulqdq	$0x10,48(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	48(%rsi),%xmm0
 
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm7
@@ -271,7 +271,7 @@
 
 
 	vpxor	%xmm7,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	32(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,80(%rdi),%xmm0,%xmm6
@@ -285,7 +285,7 @@
 
 
 	vpxor	%xmm9,%xmm1,%xmm1
-#########################################################
+
 	vmovdqu	16(%rsi),%xmm0
 
 	vpclmulqdq	$0x01,96(%rdi),%xmm0,%xmm6
@@ -297,7 +297,7 @@
 	vpclmulqdq	$0x10,96(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vmovdqu	0(%rsi),%xmm0
 	vpxor	%xmm1,%xmm0,%xmm0
 
@@ -310,7 +310,7 @@
 	vpclmulqdq	$0x10,112(%rdi),%xmm0,%xmm6
 	vpxor	%xmm6,%xmm5,%xmm5
 
-#########################################################
+
 	vpsrldq	$8,%xmm5,%xmm6
 	vpslldq	$8,%xmm5,%xmm5
 
@@ -320,7 +320,7 @@
 	leaq	128(%rsi),%rsi
 	jmp	L$htable_polyval_main_loop
 
-#########################################################
+
 
 L$htable_polyval_out:
 	vpclmulqdq	$0x10,poly(%rip),%xmm1,%xmm6
@@ -488,10 +488,10 @@
 	vmovdqa	con1(%rip),%xmm0
 	vmovdqa	mask(%rip),%xmm15
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -500,10 +500,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,16(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -512,10 +512,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,32(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -524,10 +524,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,48(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -536,10 +536,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,64(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -548,10 +548,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,80(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -560,10 +560,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,96(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -572,10 +572,10 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,112(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -587,10 +587,10 @@
 
 	vmovdqa	con2(%rip),%xmm0
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
 	vpslld	$1,%xmm0,%xmm0
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -599,9 +599,9 @@
 	vaesenc	%xmm1,%xmm4,%xmm4
 	vmovdqa	%xmm1,144(%rdx)
 
-	vpshufb	%xmm15,%xmm1,%xmm2#!!saving mov instruction to xmm2
+	vpshufb	%xmm15,%xmm1,%xmm2
 	vaesenclast	%xmm0,%xmm2,%xmm2
-	vpsllq	$32,%xmm1,%xmm3#!!saving mov instruction to xmm3
+	vpsllq	$32,%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpshufb	con3(%rip),%xmm1,%xmm3
 	vpxor	%xmm3,%xmm1,%xmm1
@@ -731,7 +731,7 @@
 
 
 	vmovdqa	(%rdx),%xmm15
-	vpor	OR_MASK(%rip),%xmm15,%xmm15#IV = [1]TAG[126...32][00..00]
+	vpor	OR_MASK(%rip),%xmm15,%xmm15
 
 	vmovdqu	four(%rip),%xmm4
 	vmovdqa	%xmm15,%xmm0
diff --git a/third_party/boringssl/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S b/third_party/boringssl/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
index 42476a9..e50227a 100644
--- a/third_party/boringssl/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S
@@ -1342,7 +1342,7 @@
 	leaq	128(%rdi),%rdi
 	jmp	open_sse_tail_64_dec_loop
 3:
-###############################################################################
+
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
 	movdqa	64(%rbp),%xmm8
@@ -1697,7 +1697,7 @@
 	subq	$192,%rbx
 	leaq	192(%rsi),%rsi
 	leaq	192(%rdi),%rdi
-###############################################################################
+
 
 open_sse_tail_64_dec_loop:
 	cmpq	$16,%rbx
@@ -1867,7 +1867,7 @@
 
 	.byte	0xf3,0xc3
 
-###############################################################################
+
 open_sse_128:
 	movdqu	.chacha20_consts(%rip),%xmm0
 	movdqa	%xmm0,%xmm1
@@ -2101,8 +2101,8 @@
 
 
 
-################################################################################
-################################################################################
+
+
 
 .globl	_chacha20_poly1305_seal
 .private_extern _chacha20_poly1305_seal
@@ -2838,7 +2838,7 @@
 	movq	$6,%rcx
 	cmpq	$64,%rbx
 	jg	3f
-###############################################################################
+
 seal_sse_tail_64:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -2990,7 +2990,7 @@
 3:
 	cmpq	$128,%rbx
 	jg	3f
-###############################################################################
+
 seal_sse_tail_128:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -3207,7 +3207,7 @@
 	leaq	64(%rsi),%rsi
 	jmp	seal_sse_128_seal_hash
 3:
-###############################################################################
+
 seal_sse_tail_192:
 	movdqa	.chacha20_consts(%rip),%xmm0
 	movdqa	48(%rbp),%xmm4
@@ -3486,7 +3486,7 @@
 	movq	$128,%rcx
 	subq	$128,%rbx
 	leaq	128(%rsi),%rsi
-###############################################################################
+
 seal_sse_128_seal_hash:
 	cmpq	$16,%rcx
 	jb	seal_sse_128_seal
@@ -3631,7 +3631,7 @@
 
 
 
-#
+
 
 
 	movq	288+32(%rsp),%r9
@@ -3935,7 +3935,7 @@
 
 	.byte	0xf3,0xc3
 
-################################################################################
+
 seal_sse_128:
 	movdqu	.chacha20_consts(%rip),%xmm0
 	movdqa	%xmm0,%xmm1
@@ -4106,7 +4106,7 @@
 	jmp	seal_sse_128_seal
 
 
-###############################################################################
+
 
 .p2align	6
 chacha20_poly1305_open_avx2:
@@ -5818,7 +5818,7 @@
 	vmovdqa	%xmm0,%xmm1
 	jb	1f
 	subq	$16,%rbx
-#load for decryption
+
 	vpxor	(%rsi),%xmm0,%xmm1
 	vmovdqu	%xmm1,(%rdi)
 	leaq	16(%rsi),%rsi
@@ -5828,7 +5828,7 @@
 1:
 	vzeroupper
 	jmp	open_sse_tail_16
-###############################################################################
+
 open_avx2_192:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -6100,7 +6100,7 @@
 1:
 	vzeroupper
 	jmp	open_sse_tail_16
-###############################################################################
+
 open_avx2_320:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -6263,8 +6263,8 @@
 	vperm2i128	$0x13,%ymm10,%ymm14,%ymm6
 	jmp	open_avx2_short
 
-###############################################################################
-###############################################################################
+
+
 
 .p2align	6
 chacha20_poly1305_seal_avx2:
@@ -7334,7 +7334,7 @@
 	xorq	%r8,%r8
 	cmpq	$128,%rbx
 	ja	3f
-###############################################################################
+
 seal_avx2_tail_128:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -7528,7 +7528,7 @@
 3:
 	cmpq	$256,%rbx
 	ja	3f
-###############################################################################
+
 seal_avx2_tail_256:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -7784,7 +7784,7 @@
 3:
 	cmpq	$384,%rbx
 	ja	seal_avx2_tail_512
-###############################################################################
+
 seal_avx2_tail_384:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -8096,7 +8096,7 @@
 	leaq	256(%rsi),%rsi
 	subq	$256,%rbx
 	jmp	seal_avx2_hash
-###############################################################################
+
 seal_avx2_tail_512:
 	vmovdqa	.chacha20_consts(%rip),%ymm0
 	vmovdqa	64(%rbp),%ymm4
@@ -8498,7 +8498,7 @@
 	leaq	384(%rsi),%rsi
 	subq	$384,%rbx
 	jmp	seal_avx2_hash
-################################################################################
+
 seal_avx2_320:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
@@ -8660,7 +8660,7 @@
 	vperm2i128	$0x13,%ymm2,%ymm6,%ymm2
 	vperm2i128	$0x13,%ymm10,%ymm14,%ymm6
 	jmp	seal_avx2_short
-################################################################################
+
 seal_avx2_192:
 	vmovdqa	%ymm0,%ymm1
 	vmovdqa	%ymm0,%ymm2
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
index b345316..8875d0a 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
@@ -91,8 +91,8 @@
 	movzbl	%bh,%edi
 	movzbl	%ch,%ebp
 	movzbl	2(%r14,%rsi,8),%r8d
-	movl	0(%r14,%rdi,8),%edi#%r10d
-	movl	0(%r14,%rbp,8),%ebp#%r11d
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
 
 	andl	$0x0000ff00,%edi
 	andl	$0x0000ff00,%ebp
@@ -104,8 +104,8 @@
 	movzbl	%dh,%esi
 	movzbl	%ah,%edi
 	shrl	$16,%edx
-	movl	0(%r14,%rsi,8),%esi#%r12d
-	movl	0(%r14,%rdi,8),%edi#%r8d
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
 
 	andl	$0x0000ff00,%esi
 	andl	$0x0000ff00,%edi
@@ -117,9 +117,9 @@
 	movzbl	%cl,%esi
 	movzbl	%dl,%edi
 	movzbl	%al,%ebp
-	movl	0(%r14,%rsi,8),%esi#%r10d
-	movl	0(%r14,%rdi,8),%edi#%r11d
-	movl	0(%r14,%rbp,8),%ebp#%r12d
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
 
 	andl	$0x00ff0000,%esi
 	andl	$0x00ff0000,%edi
@@ -132,9 +132,9 @@
 	movzbl	%bl,%esi
 	movzbl	%dh,%edi
 	movzbl	%ah,%ebp
-	movl	0(%r14,%rsi,8),%esi#%r8d
-	movl	2(%r14,%rdi,8),%edi#%r10d
-	movl	2(%r14,%rbp,8),%ebp#%r11d
+	movl	0(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	2(%r14,%rbp,8),%ebp
 
 	andl	$0x00ff0000,%esi
 	andl	$0xff000000,%edi
@@ -147,8 +147,8 @@
 	movzbl	%bh,%esi
 	movzbl	%ch,%edi
 	movl	16+12(%r15),%edx
-	movl	2(%r14,%rsi,8),%esi#%r12d
-	movl	2(%r14,%rdi,8),%edi#%r8d
+	movl	2(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
 	andl	$0xff000000,%esi
@@ -199,12 +199,12 @@
 	movzbl	(%r14,%r12,1),%r12d
 	movzbl	(%r14,%r8,1),%r8d
 
-	movzbl	(%r14,%rsi,1),%r9d#%r10d
+	movzbl	(%r14,%rsi,1),%r9d
 	movzbl	%ah,%esi
-	movzbl	(%r14,%rdi,1),%r13d#%r11d
+	movzbl	(%r14,%rdi,1),%r13d
 	movzbl	%cl,%edi
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
-	movzbl	(%r14,%rsi,1),%esi#%r8d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
 
 	shll	$8,%r9d
 	shrl	$16,%edx
@@ -216,16 +216,16 @@
 	xorl	%r13d,%r11d
 	shll	$8,%ebp
 	movzbl	%al,%r13d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
+	movzbl	(%r14,%rdi,1),%edi
 	xorl	%ebp,%r12d
 
 	shll	$8,%esi
 	movzbl	%bl,%ebp
 	shll	$16,%edi
 	xorl	%esi,%r8d
-	movzbl	(%r14,%r9,1),%r9d#%r11d
+	movzbl	(%r14,%r9,1),%r9d
 	movzbl	%dh,%esi
-	movzbl	(%r14,%r13,1),%r13d#%r12d
+	movzbl	(%r14,%r13,1),%r13d
 	xorl	%edi,%r10d
 
 	shrl	$8,%ecx
@@ -234,11 +234,11 @@
 	shrl	$8,%ebx
 	shll	$16,%r13d
 	xorl	%r9d,%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r8d
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%edi#%r11d
-	movzbl	(%r14,%rcx,1),%edx#%r8d
-	movzbl	(%r14,%rbx,1),%ecx#%r12d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rcx,1),%edx
+	movzbl	(%r14,%rbx,1),%ecx
 
 	shll	$16,%ebp
 	xorl	%r13d,%r12d
@@ -504,8 +504,8 @@
 	movzbl	%dh,%edi
 	movzbl	%ah,%ebp
 	movzbl	(%r14,%rsi,1),%r8d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
-	movzbl	(%r14,%rbp,1),%ebp#%r11d
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$8,%edi
 	shll	$8,%ebp
@@ -517,8 +517,8 @@
 	movzbl	%bh,%esi
 	movzbl	%ch,%edi
 	shrl	$16,%eax
-	movzbl	(%r14,%rsi,1),%esi#%r12d
-	movzbl	(%r14,%rdi,1),%edi#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
 
 	shll	$8,%esi
 	shll	$8,%edi
@@ -530,9 +530,9 @@
 	movzbl	%cl,%esi
 	movzbl	%dl,%edi
 	movzbl	%al,%ebp
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%edi#%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$16,%esi
 	shll	$16,%edi
@@ -545,9 +545,9 @@
 	movzbl	%bl,%esi
 	movzbl	%bh,%edi
 	movzbl	%ch,%ebp
-	movzbl	(%r14,%rsi,1),%esi#%r8d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
-	movzbl	(%r14,%rbp,1),%ebp#%r11d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
 
 	shll	$16,%esi
 	shll	$24,%edi
@@ -560,8 +560,8 @@
 	movzbl	%dh,%esi
 	movzbl	%ah,%edi
 	movl	16+12(%r15),%edx
-	movzbl	(%r14,%rsi,1),%esi#%r12d
-	movzbl	(%r14,%rdi,1),%edi#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
 	movl	16+0(%r15),%eax
 
 	shll	$24,%esi
@@ -614,11 +614,11 @@
 	movzbl	(%r14,%r12,1),%r12d
 	movzbl	(%r14,%r8,1),%r8d
 
-	movzbl	(%r14,%rsi,1),%r9d#%r10d
+	movzbl	(%r14,%rsi,1),%r9d
 	movzbl	%ch,%esi
-	movzbl	(%r14,%rdi,1),%r13d#%r11d
-	movzbl	(%r14,%rbp,1),%ebp#%r12d
-	movzbl	(%r14,%rsi,1),%esi#%r8d
+	movzbl	(%r14,%rdi,1),%r13d
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
 
 	shrl	$16,%ecx
 	shll	$8,%r13d
@@ -633,17 +633,17 @@
 	xorl	%r13d,%r11d
 	shll	$8,%esi
 	movzbl	%al,%r13d
-	movzbl	(%r14,%rdi,1),%edi#%r10d
+	movzbl	(%r14,%rdi,1),%edi
 	xorl	%ebp,%r12d
 	movzbl	%bl,%ebp
 
 	shll	$16,%edi
 	xorl	%esi,%r8d
-	movzbl	(%r14,%r9,1),%r9d#%r11d
+	movzbl	(%r14,%r9,1),%r9d
 	movzbl	%bh,%esi
-	movzbl	(%r14,%rbp,1),%ebp#%r8d
+	movzbl	(%r14,%rbp,1),%ebp
 	xorl	%edi,%r10d
-	movzbl	(%r14,%r13,1),%r13d#%r12d
+	movzbl	(%r14,%r13,1),%r13d
 	movzbl	%ch,%edi
 
 	shll	$16,%ebp
@@ -655,10 +655,10 @@
 	shrl	$8,%eax
 	xorl	%r13d,%r12d
 
-	movzbl	(%r14,%rsi,1),%esi#%r10d
-	movzbl	(%r14,%rdi,1),%ebx#%r11d
-	movzbl	(%r14,%rbp,1),%ecx#%r12d
-	movzbl	(%r14,%rax,1),%edx#%r8d
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%ebx
+	movzbl	(%r14,%rbp,1),%ecx
+	movzbl	(%r14,%rax,1),%edx
 
 	movl	%r10d,%eax
 	shll	$24,%esi
@@ -1445,7 +1445,7 @@
 
 	xchgq	%rsp,%r15
 
-#add	$8,%rsp
+
 	movq	%r15,16(%rsp)
 
 L$cbc_fast_body:
@@ -1496,7 +1496,7 @@
 	cmpq	$0,%rbx
 	je	L$FAST_DECRYPT
 
-#----------------------------- ENCRYPT -----------------------------#
+
 	movl	0(%rbp),%eax
 	movl	4(%rbp),%ebx
 	movl	8(%rbp),%ecx
@@ -1534,7 +1534,7 @@
 
 	jmp	L$cbc_fast_cleanup
 
-#----------------------------- DECRYPT -----------------------------#
+
 .p2align	4
 L$FAST_DECRYPT:
 	cmpq	%r8,%r9
@@ -1642,7 +1642,7 @@
 
 	jmp	L$cbc_exit
 
-#--------------------------- SLOW ROUTINE ---------------------------#
+
 .p2align	4
 L$cbc_slow_prologue:
 
@@ -1658,14 +1658,14 @@
 
 	xchgq	%rsp,%rbp
 
-#add	$8,%rsp
+
 	movq	%rbp,16(%rsp)
 
 L$cbc_slow_body:
-#mov	%rdi,24(%rsp)
-#mov	%rsi,32(%rsp)
-#mov	%rdx,40(%rsp)
-#mov	%rcx,48(%rsp)
+
+
+
+
 	movq	%r8,56(%rsp)
 	movq	%r8,%rbp
 	movq	%r9,%rbx
@@ -1690,7 +1690,7 @@
 	cmpq	$0,%rbx
 	je	L$SLOW_DECRYPT
 
-#--------------------------- SLOW ENCRYPT ---------------------------#
+
 	testq	$-16,%r10
 	movl	0(%rbp),%eax
 	movl	4(%rbp),%ebx
@@ -1751,7 +1751,7 @@
 	movq	%r11,%rax
 	movq	%r12,%rcx
 	jmp	L$cbc_slow_enc_loop
-#--------------------------- SLOW DECRYPT ---------------------------#
+
 .p2align	4
 L$SLOW_DECRYPT:
 	shrq	$3,%rax
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
index 0944fe4f..9fb4bef1 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
@@ -57,7 +57,7 @@
 
 
 
-#
+
 
 
 
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
index 3f0870df..5e12596 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
@@ -549,7 +549,7 @@
 	movl	%eax,%r10d
 	testl	%r8d,%r8d
 	jz	L$ecb_decrypt
-#--------------------------- ECB ENCRYPT ------------------------------#
+
 	cmpq	$0x80,%rdx
 	jb	L$ecb_enc_tail
 
@@ -690,7 +690,7 @@
 	movups	%xmm6,64(%rsi)
 	movups	%xmm7,80(%rsi)
 	jmp	L$ecb_ret
-#--------------------------- ECB DECRYPT ------------------------------#
+
 .p2align	4
 L$ecb_decrypt:
 	cmpq	$0x80,%rdx
@@ -879,168 +879,6 @@
 	.byte	0xf3,0xc3
 
 
-.globl	_aes_hw_ccm64_encrypt_blocks
-.private_extern _aes_hw_ccm64_encrypt_blocks
-
-.p2align	4
-_aes_hw_ccm64_encrypt_blocks:
-	movl	240(%rcx),%eax
-	movdqu	(%r8),%xmm6
-	movdqa	L$increment64(%rip),%xmm9
-	movdqa	L$bswap_mask(%rip),%xmm7
-
-	shll	$4,%eax
-	movl	$16,%r10d
-	leaq	0(%rcx),%r11
-	movdqu	(%r9),%xmm3
-	movdqa	%xmm6,%xmm2
-	leaq	32(%rcx,%rax,1),%rcx
-.byte	102,15,56,0,247
-	subq	%rax,%r10
-	jmp	L$ccm64_enc_outer
-.p2align	4
-L$ccm64_enc_outer:
-	movups	(%r11),%xmm0
-	movq	%r10,%rax
-	movups	(%rdi),%xmm8
-
-	xorps	%xmm0,%xmm2
-	movups	16(%r11),%xmm1
-	xorps	%xmm8,%xmm0
-	xorps	%xmm0,%xmm3
-	movups	32(%r11),%xmm0
-
-L$ccm64_enc2_loop:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ccm64_enc2_loop
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	paddq	%xmm9,%xmm6
-	decq	%rdx
-.byte	102,15,56,221,208
-.byte	102,15,56,221,216
-
-	leaq	16(%rdi),%rdi
-	xorps	%xmm2,%xmm8
-	movdqa	%xmm6,%xmm2
-	movups	%xmm8,(%rsi)
-.byte	102,15,56,0,215
-	leaq	16(%rsi),%rsi
-	jnz	L$ccm64_enc_outer
-
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	movups	%xmm3,(%r9)
-	pxor	%xmm3,%xmm3
-	pxor	%xmm8,%xmm8
-	pxor	%xmm6,%xmm6
-	.byte	0xf3,0xc3
-
-.globl	_aes_hw_ccm64_decrypt_blocks
-.private_extern _aes_hw_ccm64_decrypt_blocks
-
-.p2align	4
-_aes_hw_ccm64_decrypt_blocks:
-	movl	240(%rcx),%eax
-	movups	(%r8),%xmm6
-	movdqu	(%r9),%xmm3
-	movdqa	L$increment64(%rip),%xmm9
-	movdqa	L$bswap_mask(%rip),%xmm7
-
-	movaps	%xmm6,%xmm2
-	movl	%eax,%r10d
-	movq	%rcx,%r11
-.byte	102,15,56,0,247
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_enc1_5:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_enc1_5
-.byte	102,15,56,221,209
-	shll	$4,%r10d
-	movl	$16,%eax
-	movups	(%rdi),%xmm8
-	paddq	%xmm9,%xmm6
-	leaq	16(%rdi),%rdi
-	subq	%r10,%rax
-	leaq	32(%r11,%r10,1),%rcx
-	movq	%rax,%r10
-	jmp	L$ccm64_dec_outer
-.p2align	4
-L$ccm64_dec_outer:
-	xorps	%xmm2,%xmm8
-	movdqa	%xmm6,%xmm2
-	movups	%xmm8,(%rsi)
-	leaq	16(%rsi),%rsi
-.byte	102,15,56,0,215
-
-	subq	$1,%rdx
-	jz	L$ccm64_dec_break
-
-	movups	(%r11),%xmm0
-	movq	%r10,%rax
-	movups	16(%r11),%xmm1
-	xorps	%xmm0,%xmm8
-	xorps	%xmm0,%xmm2
-	xorps	%xmm8,%xmm3
-	movups	32(%r11),%xmm0
-	jmp	L$ccm64_dec2_loop
-.p2align	4
-L$ccm64_dec2_loop:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ccm64_dec2_loop
-	movups	(%rdi),%xmm8
-	paddq	%xmm9,%xmm6
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,221,208
-.byte	102,15,56,221,216
-	leaq	16(%rdi),%rdi
-	jmp	L$ccm64_dec_outer
-
-.p2align	4
-L$ccm64_dec_break:
-#xorps	%xmm8,%xmm3
-	movl	240(%r11),%eax
-	movups	(%r11),%xmm0
-	movups	16(%r11),%xmm1
-	xorps	%xmm0,%xmm8
-	leaq	32(%r11),%r11
-	xorps	%xmm8,%xmm3
-L$oop_enc1_6:
-.byte	102,15,56,220,217
-	decl	%eax
-	movups	(%r11),%xmm1
-	leaq	16(%r11),%r11
-	jnz	L$oop_enc1_6
-.byte	102,15,56,221,217
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	movups	%xmm3,(%r9)
-	pxor	%xmm3,%xmm3
-	pxor	%xmm8,%xmm8
-	pxor	%xmm6,%xmm6
-	.byte	0xf3,0xc3
-
 .globl	_aes_hw_ctr32_encrypt_blocks
 .private_extern _aes_hw_ctr32_encrypt_blocks
 
@@ -1064,12 +902,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-L$oop_enc1_7:
+L$oop_enc1_5:
 .byte	102,15,56,220,209
 	decl	%edx
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	L$oop_enc1_7
+	jnz	L$oop_enc1_5
 .byte	102,15,56,221,209
 	pxor	%xmm0,%xmm0
 	pxor	%xmm1,%xmm1
@@ -1454,7 +1292,7 @@
 	movdqa	64(%rsp),%xmm15
 .byte	102,68,15,56,221,193
 	movdqa	80(%rsp),%xmm0
-	movups	16-128(%rcx),%xmm1#real 1st-round key
+	movups	16-128(%rcx),%xmm1
 .byte	102,69,15,56,221,202
 
 	movups	%xmm2,(%rsi)
@@ -1626,1829 +1464,6 @@
 	.byte	0xf3,0xc3
 
 
-.globl	_aes_hw_xts_encrypt
-.private_extern _aes_hw_xts_encrypt
-
-.p2align	4
-_aes_hw_xts_encrypt:
-
-	leaq	(%rsp),%r11
-
-	pushq	%rbp
-
-	subq	$112,%rsp
-	andq	$-16,%rsp
-	movups	(%r9),%xmm2
-	movl	240(%r8),%eax
-	movl	240(%rcx),%r10d
-	movups	(%r8),%xmm0
-	movups	16(%r8),%xmm1
-	leaq	32(%r8),%r8
-	xorps	%xmm0,%xmm2
-L$oop_enc1_8:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%r8),%xmm1
-	leaq	16(%r8),%r8
-	jnz	L$oop_enc1_8
-.byte	102,15,56,221,209
-	movups	(%rcx),%xmm0
-	movq	%rcx,%rbp
-	movl	%r10d,%eax
-	shll	$4,%r10d
-	movq	%rdx,%r9
-	andq	$-16,%rdx
-
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqa	L$xts_magic(%rip),%xmm8
-	movdqa	%xmm2,%xmm15
-	pshufd	$0x5f,%xmm2,%xmm9
-	pxor	%xmm0,%xmm1
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm10
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm10
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm11
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm11
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm12
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm12
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm13
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm13
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm15,%xmm14
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm9
-	pxor	%xmm0,%xmm14
-	pxor	%xmm9,%xmm15
-	movaps	%xmm1,96(%rsp)
-
-	subq	$96,%rdx
-	jc	L$xts_enc_short
-
-	movl	$16+96,%eax
-	leaq	32(%rbp,%r10,1),%rcx
-	subq	%r10,%rax
-	movups	16(%rbp),%xmm1
-	movq	%rax,%r10
-	leaq	L$xts_magic(%rip),%r8
-	jmp	L$xts_enc_grandloop
-
-.p2align	5
-L$xts_enc_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqa	%xmm0,%xmm8
-	movdqu	16(%rdi),%xmm3
-	pxor	%xmm10,%xmm2
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm11,%xmm3
-.byte	102,15,56,220,209
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm12,%xmm4
-.byte	102,15,56,220,217
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm13,%xmm5
-.byte	102,15,56,220,225
-	movdqu	80(%rdi),%xmm7
-	pxor	%xmm15,%xmm8
-	movdqa	96(%rsp),%xmm9
-	pxor	%xmm14,%xmm6
-.byte	102,15,56,220,233
-	movups	32(%rbp),%xmm0
-	leaq	96(%rdi),%rdi
-	pxor	%xmm8,%xmm7
-
-	pxor	%xmm9,%xmm10
-.byte	102,15,56,220,241
-	pxor	%xmm9,%xmm11
-	movdqa	%xmm10,0(%rsp)
-.byte	102,15,56,220,249
-	movups	48(%rbp),%xmm1
-	pxor	%xmm9,%xmm12
-
-.byte	102,15,56,220,208
-	pxor	%xmm9,%xmm13
-	movdqa	%xmm11,16(%rsp)
-.byte	102,15,56,220,216
-	pxor	%xmm9,%xmm14
-	movdqa	%xmm12,32(%rsp)
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	pxor	%xmm9,%xmm8
-	movdqa	%xmm14,64(%rsp)
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	64(%rbp),%xmm0
-	movdqa	%xmm8,80(%rsp)
-	pshufd	$0x5f,%xmm15,%xmm9
-	jmp	L$xts_enc_loop6
-.p2align	5
-L$xts_enc_loop6:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	-64(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	-80(%rcx,%rax,1),%xmm0
-	jnz	L$xts_enc_loop6
-
-	movdqa	(%r8),%xmm8
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	paddq	%xmm15,%xmm15
-	psrad	$31,%xmm14
-.byte	102,15,56,220,217
-	pand	%xmm8,%xmm14
-	movups	(%rbp),%xmm10
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-	pxor	%xmm14,%xmm15
-	movaps	%xmm10,%xmm11
-.byte	102,15,56,220,249
-	movups	-64(%rcx),%xmm1
-
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,208
-	paddd	%xmm9,%xmm9
-	pxor	%xmm15,%xmm10
-.byte	102,15,56,220,216
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	pand	%xmm8,%xmm14
-	movaps	%xmm11,%xmm12
-.byte	102,15,56,220,240
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,248
-	movups	-48(%rcx),%xmm0
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	pxor	%xmm15,%xmm11
-	psrad	$31,%xmm14
-.byte	102,15,56,220,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movdqa	%xmm13,48(%rsp)
-	pxor	%xmm14,%xmm15
-.byte	102,15,56,220,241
-	movaps	%xmm12,%xmm13
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,220,249
-	movups	-32(%rcx),%xmm1
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,208
-	pxor	%xmm15,%xmm12
-	psrad	$31,%xmm14
-.byte	102,15,56,220,216
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-	pxor	%xmm14,%xmm15
-	movaps	%xmm13,%xmm14
-.byte	102,15,56,220,248
-
-	movdqa	%xmm9,%xmm0
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,220,209
-	pxor	%xmm15,%xmm13
-	psrad	$31,%xmm0
-.byte	102,15,56,220,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm0
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	pxor	%xmm0,%xmm15
-	movups	(%rbp),%xmm0
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	16(%rbp),%xmm1
-
-	pxor	%xmm15,%xmm14
-.byte	102,15,56,221,84,36,0
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,221,92,36,16
-.byte	102,15,56,221,100,36,32
-	pand	%xmm8,%xmm9
-	movq	%r10,%rax
-.byte	102,15,56,221,108,36,48
-.byte	102,15,56,221,116,36,64
-.byte	102,15,56,221,124,36,80
-	pxor	%xmm9,%xmm15
-
-	leaq	96(%rsi),%rsi
-	movups	%xmm2,-96(%rsi)
-	movups	%xmm3,-80(%rsi)
-	movups	%xmm4,-64(%rsi)
-	movups	%xmm5,-48(%rsi)
-	movups	%xmm6,-32(%rsi)
-	movups	%xmm7,-16(%rsi)
-	subq	$96,%rdx
-	jnc	L$xts_enc_grandloop
-
-	movl	$16+96,%eax
-	subl	%r10d,%eax
-	movq	%rbp,%rcx
-	shrl	$4,%eax
-
-L$xts_enc_short:
-
-	movl	%eax,%r10d
-	pxor	%xmm0,%xmm10
-	addq	$96,%rdx
-	jz	L$xts_enc_done
-
-	pxor	%xmm0,%xmm11
-	cmpq	$0x20,%rdx
-	jb	L$xts_enc_one
-	pxor	%xmm0,%xmm12
-	je	L$xts_enc_two
-
-	pxor	%xmm0,%xmm13
-	cmpq	$0x40,%rdx
-	jb	L$xts_enc_three
-	pxor	%xmm0,%xmm14
-	je	L$xts_enc_four
-
-	movdqu	(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm10,%xmm2
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm11,%xmm3
-	movdqu	64(%rdi),%xmm6
-	leaq	80(%rdi),%rdi
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	_aesni_encrypt6
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm15,%xmm10
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	xorps	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	xorps	%xmm14,%xmm6
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	movdqu	%xmm6,64(%rsi)
-	leaq	80(%rsi),%rsi
-	jmp	L$xts_enc_done
-
-.p2align	4
-L$xts_enc_one:
-	movups	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_enc1_9:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_enc1_9
-.byte	102,15,56,221,209
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm11,%xmm10
-	movups	%xmm2,(%rsi)
-	leaq	16(%rsi),%rsi
-	jmp	L$xts_enc_done
-
-.p2align	4
-L$xts_enc_two:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	leaq	32(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-
-	call	_aesni_encrypt2
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm12,%xmm10
-	xorps	%xmm11,%xmm3
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	leaq	32(%rsi),%rsi
-	jmp	L$xts_enc_done
-
-.p2align	4
-L$xts_enc_three:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	leaq	48(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-
-	call	_aesni_encrypt3
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm13,%xmm10
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	leaq	48(%rsi),%rsi
-	jmp	L$xts_enc_done
-
-.p2align	4
-L$xts_enc_four:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	xorps	%xmm10,%xmm2
-	movups	48(%rdi),%xmm5
-	leaq	64(%rdi),%rdi
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	xorps	%xmm13,%xmm5
-
-	call	_aesni_encrypt4
-
-	pxor	%xmm10,%xmm2
-	movdqa	%xmm14,%xmm10
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	pxor	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	leaq	64(%rsi),%rsi
-	jmp	L$xts_enc_done
-
-.p2align	4
-L$xts_enc_done:
-	andq	$15,%r9
-	jz	L$xts_enc_ret
-	movq	%r9,%rdx
-
-L$xts_enc_steal:
-	movzbl	(%rdi),%eax
-	movzbl	-16(%rsi),%ecx
-	leaq	1(%rdi),%rdi
-	movb	%al,-16(%rsi)
-	movb	%cl,0(%rsi)
-	leaq	1(%rsi),%rsi
-	subq	$1,%rdx
-	jnz	L$xts_enc_steal
-
-	subq	%r9,%rsi
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	-16(%rsi),%xmm2
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_enc1_10:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_enc1_10
-.byte	102,15,56,221,209
-	xorps	%xmm10,%xmm2
-	movups	%xmm2,-16(%rsi)
-
-L$xts_enc_ret:
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	movaps	%xmm0,0(%rsp)
-	pxor	%xmm8,%xmm8
-	movaps	%xmm0,16(%rsp)
-	pxor	%xmm9,%xmm9
-	movaps	%xmm0,32(%rsp)
-	pxor	%xmm10,%xmm10
-	movaps	%xmm0,48(%rsp)
-	pxor	%xmm11,%xmm11
-	movaps	%xmm0,64(%rsp)
-	pxor	%xmm12,%xmm12
-	movaps	%xmm0,80(%rsp)
-	pxor	%xmm13,%xmm13
-	movaps	%xmm0,96(%rsp)
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	movq	-8(%r11),%rbp
-
-	leaq	(%r11),%rsp
-
-L$xts_enc_epilogue:
-	.byte	0xf3,0xc3
-
-
-.globl	_aes_hw_xts_decrypt
-.private_extern _aes_hw_xts_decrypt
-
-.p2align	4
-_aes_hw_xts_decrypt:
-
-	leaq	(%rsp),%r11
-
-	pushq	%rbp
-
-	subq	$112,%rsp
-	andq	$-16,%rsp
-	movups	(%r9),%xmm2
-	movl	240(%r8),%eax
-	movl	240(%rcx),%r10d
-	movups	(%r8),%xmm0
-	movups	16(%r8),%xmm1
-	leaq	32(%r8),%r8
-	xorps	%xmm0,%xmm2
-L$oop_enc1_11:
-.byte	102,15,56,220,209
-	decl	%eax
-	movups	(%r8),%xmm1
-	leaq	16(%r8),%r8
-	jnz	L$oop_enc1_11
-.byte	102,15,56,221,209
-	xorl	%eax,%eax
-	testq	$15,%rdx
-	setnz	%al
-	shlq	$4,%rax
-	subq	%rax,%rdx
-
-	movups	(%rcx),%xmm0
-	movq	%rcx,%rbp
-	movl	%r10d,%eax
-	shll	$4,%r10d
-	movq	%rdx,%r9
-	andq	$-16,%rdx
-
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqa	L$xts_magic(%rip),%xmm8
-	movdqa	%xmm2,%xmm15
-	pshufd	$0x5f,%xmm2,%xmm9
-	pxor	%xmm0,%xmm1
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm10
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm10
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm11
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm11
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm12
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm12
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-	movdqa	%xmm15,%xmm13
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-	pxor	%xmm0,%xmm13
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm15,%xmm14
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm9
-	pxor	%xmm0,%xmm14
-	pxor	%xmm9,%xmm15
-	movaps	%xmm1,96(%rsp)
-
-	subq	$96,%rdx
-	jc	L$xts_dec_short
-
-	movl	$16+96,%eax
-	leaq	32(%rbp,%r10,1),%rcx
-	subq	%r10,%rax
-	movups	16(%rbp),%xmm1
-	movq	%rax,%r10
-	leaq	L$xts_magic(%rip),%r8
-	jmp	L$xts_dec_grandloop
-
-.p2align	5
-L$xts_dec_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqa	%xmm0,%xmm8
-	movdqu	16(%rdi),%xmm3
-	pxor	%xmm10,%xmm2
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm11,%xmm3
-.byte	102,15,56,222,209
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm12,%xmm4
-.byte	102,15,56,222,217
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm13,%xmm5
-.byte	102,15,56,222,225
-	movdqu	80(%rdi),%xmm7
-	pxor	%xmm15,%xmm8
-	movdqa	96(%rsp),%xmm9
-	pxor	%xmm14,%xmm6
-.byte	102,15,56,222,233
-	movups	32(%rbp),%xmm0
-	leaq	96(%rdi),%rdi
-	pxor	%xmm8,%xmm7
-
-	pxor	%xmm9,%xmm10
-.byte	102,15,56,222,241
-	pxor	%xmm9,%xmm11
-	movdqa	%xmm10,0(%rsp)
-.byte	102,15,56,222,249
-	movups	48(%rbp),%xmm1
-	pxor	%xmm9,%xmm12
-
-.byte	102,15,56,222,208
-	pxor	%xmm9,%xmm13
-	movdqa	%xmm11,16(%rsp)
-.byte	102,15,56,222,216
-	pxor	%xmm9,%xmm14
-	movdqa	%xmm12,32(%rsp)
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	pxor	%xmm9,%xmm8
-	movdqa	%xmm14,64(%rsp)
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	64(%rbp),%xmm0
-	movdqa	%xmm8,80(%rsp)
-	pshufd	$0x5f,%xmm15,%xmm9
-	jmp	L$xts_dec_loop6
-.p2align	5
-L$xts_dec_loop6:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	-64(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	-80(%rcx,%rax,1),%xmm0
-	jnz	L$xts_dec_loop6
-
-	movdqa	(%r8),%xmm8
-	movdqa	%xmm9,%xmm14
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	paddq	%xmm15,%xmm15
-	psrad	$31,%xmm14
-.byte	102,15,56,222,217
-	pand	%xmm8,%xmm14
-	movups	(%rbp),%xmm10
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-	pxor	%xmm14,%xmm15
-	movaps	%xmm10,%xmm11
-.byte	102,15,56,222,249
-	movups	-64(%rcx),%xmm1
-
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,208
-	paddd	%xmm9,%xmm9
-	pxor	%xmm15,%xmm10
-.byte	102,15,56,222,216
-	psrad	$31,%xmm14
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	pand	%xmm8,%xmm14
-	movaps	%xmm11,%xmm12
-.byte	102,15,56,222,240
-	pxor	%xmm14,%xmm15
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,248
-	movups	-48(%rcx),%xmm0
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	pxor	%xmm15,%xmm11
-	psrad	$31,%xmm14
-.byte	102,15,56,222,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movdqa	%xmm13,48(%rsp)
-	pxor	%xmm14,%xmm15
-.byte	102,15,56,222,241
-	movaps	%xmm12,%xmm13
-	movdqa	%xmm9,%xmm14
-.byte	102,15,56,222,249
-	movups	-32(%rcx),%xmm1
-
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,208
-	pxor	%xmm15,%xmm12
-	psrad	$31,%xmm14
-.byte	102,15,56,222,216
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm14
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-	pxor	%xmm14,%xmm15
-	movaps	%xmm13,%xmm14
-.byte	102,15,56,222,248
-
-	movdqa	%xmm9,%xmm0
-	paddd	%xmm9,%xmm9
-.byte	102,15,56,222,209
-	pxor	%xmm15,%xmm13
-	psrad	$31,%xmm0
-.byte	102,15,56,222,217
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm0
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	pxor	%xmm0,%xmm15
-	movups	(%rbp),%xmm0
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	16(%rbp),%xmm1
-
-	pxor	%xmm15,%xmm14
-.byte	102,15,56,223,84,36,0
-	psrad	$31,%xmm9
-	paddq	%xmm15,%xmm15
-.byte	102,15,56,223,92,36,16
-.byte	102,15,56,223,100,36,32
-	pand	%xmm8,%xmm9
-	movq	%r10,%rax
-.byte	102,15,56,223,108,36,48
-.byte	102,15,56,223,116,36,64
-.byte	102,15,56,223,124,36,80
-	pxor	%xmm9,%xmm15
-
-	leaq	96(%rsi),%rsi
-	movups	%xmm2,-96(%rsi)
-	movups	%xmm3,-80(%rsi)
-	movups	%xmm4,-64(%rsi)
-	movups	%xmm5,-48(%rsi)
-	movups	%xmm6,-32(%rsi)
-	movups	%xmm7,-16(%rsi)
-	subq	$96,%rdx
-	jnc	L$xts_dec_grandloop
-
-	movl	$16+96,%eax
-	subl	%r10d,%eax
-	movq	%rbp,%rcx
-	shrl	$4,%eax
-
-L$xts_dec_short:
-
-	movl	%eax,%r10d
-	pxor	%xmm0,%xmm10
-	pxor	%xmm0,%xmm11
-	addq	$96,%rdx
-	jz	L$xts_dec_done
-
-	pxor	%xmm0,%xmm12
-	cmpq	$0x20,%rdx
-	jb	L$xts_dec_one
-	pxor	%xmm0,%xmm13
-	je	L$xts_dec_two
-
-	pxor	%xmm0,%xmm14
-	cmpq	$0x40,%rdx
-	jb	L$xts_dec_three
-	je	L$xts_dec_four
-
-	movdqu	(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	pxor	%xmm10,%xmm2
-	movdqu	48(%rdi),%xmm5
-	pxor	%xmm11,%xmm3
-	movdqu	64(%rdi),%xmm6
-	leaq	80(%rdi),%rdi
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm6
-
-	call	_aesni_decrypt6
-
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	xorps	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	xorps	%xmm14,%xmm6
-	movdqu	%xmm4,32(%rsi)
-	pxor	%xmm14,%xmm14
-	movdqu	%xmm5,48(%rsi)
-	pcmpgtd	%xmm15,%xmm14
-	movdqu	%xmm6,64(%rsi)
-	leaq	80(%rsi),%rsi
-	pshufd	$0x13,%xmm14,%xmm11
-	andq	$15,%r9
-	jz	L$xts_dec_ret
-
-	movdqa	%xmm15,%xmm10
-	paddq	%xmm15,%xmm15
-	pand	%xmm8,%xmm11
-	pxor	%xmm15,%xmm11
-	jmp	L$xts_dec_done2
-
-.p2align	4
-L$xts_dec_one:
-	movups	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_dec1_12:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_dec1_12
-.byte	102,15,56,223,209
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm11,%xmm10
-	movups	%xmm2,(%rsi)
-	movdqa	%xmm12,%xmm11
-	leaq	16(%rsi),%rsi
-	jmp	L$xts_dec_done
-
-.p2align	4
-L$xts_dec_two:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	leaq	32(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-
-	call	_aesni_decrypt2
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm12,%xmm10
-	xorps	%xmm11,%xmm3
-	movdqa	%xmm13,%xmm11
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	leaq	32(%rsi),%rsi
-	jmp	L$xts_dec_done
-
-.p2align	4
-L$xts_dec_three:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	leaq	48(%rdi),%rdi
-	xorps	%xmm10,%xmm2
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-
-	call	_aesni_decrypt3
-
-	xorps	%xmm10,%xmm2
-	movdqa	%xmm13,%xmm10
-	xorps	%xmm11,%xmm3
-	movdqa	%xmm14,%xmm11
-	xorps	%xmm12,%xmm4
-	movups	%xmm2,(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	leaq	48(%rsi),%rsi
-	jmp	L$xts_dec_done
-
-.p2align	4
-L$xts_dec_four:
-	movups	(%rdi),%xmm2
-	movups	16(%rdi),%xmm3
-	movups	32(%rdi),%xmm4
-	xorps	%xmm10,%xmm2
-	movups	48(%rdi),%xmm5
-	leaq	64(%rdi),%rdi
-	xorps	%xmm11,%xmm3
-	xorps	%xmm12,%xmm4
-	xorps	%xmm13,%xmm5
-
-	call	_aesni_decrypt4
-
-	pxor	%xmm10,%xmm2
-	movdqa	%xmm14,%xmm10
-	pxor	%xmm11,%xmm3
-	movdqa	%xmm15,%xmm11
-	pxor	%xmm12,%xmm4
-	movdqu	%xmm2,(%rsi)
-	pxor	%xmm13,%xmm5
-	movdqu	%xmm3,16(%rsi)
-	movdqu	%xmm4,32(%rsi)
-	movdqu	%xmm5,48(%rsi)
-	leaq	64(%rsi),%rsi
-	jmp	L$xts_dec_done
-
-.p2align	4
-L$xts_dec_done:
-	andq	$15,%r9
-	jz	L$xts_dec_ret
-L$xts_dec_done2:
-	movq	%r9,%rdx
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	(%rdi),%xmm2
-	xorps	%xmm11,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_dec1_13:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_dec1_13
-.byte	102,15,56,223,209
-	xorps	%xmm11,%xmm2
-	movups	%xmm2,(%rsi)
-
-L$xts_dec_steal:
-	movzbl	16(%rdi),%eax
-	movzbl	(%rsi),%ecx
-	leaq	1(%rdi),%rdi
-	movb	%al,(%rsi)
-	movb	%cl,16(%rsi)
-	leaq	1(%rsi),%rsi
-	subq	$1,%rdx
-	jnz	L$xts_dec_steal
-
-	subq	%r9,%rsi
-	movq	%rbp,%rcx
-	movl	%r10d,%eax
-
-	movups	(%rsi),%xmm2
-	xorps	%xmm10,%xmm2
-	movups	(%rcx),%xmm0
-	movups	16(%rcx),%xmm1
-	leaq	32(%rcx),%rcx
-	xorps	%xmm0,%xmm2
-L$oop_dec1_14:
-.byte	102,15,56,222,209
-	decl	%eax
-	movups	(%rcx),%xmm1
-	leaq	16(%rcx),%rcx
-	jnz	L$oop_dec1_14
-.byte	102,15,56,223,209
-	xorps	%xmm10,%xmm2
-	movups	%xmm2,(%rsi)
-
-L$xts_dec_ret:
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	movaps	%xmm0,0(%rsp)
-	pxor	%xmm8,%xmm8
-	movaps	%xmm0,16(%rsp)
-	pxor	%xmm9,%xmm9
-	movaps	%xmm0,32(%rsp)
-	pxor	%xmm10,%xmm10
-	movaps	%xmm0,48(%rsp)
-	pxor	%xmm11,%xmm11
-	movaps	%xmm0,64(%rsp)
-	pxor	%xmm12,%xmm12
-	movaps	%xmm0,80(%rsp)
-	pxor	%xmm13,%xmm13
-	movaps	%xmm0,96(%rsp)
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	movq	-8(%r11),%rbp
-
-	leaq	(%r11),%rsp
-
-L$xts_dec_epilogue:
-	.byte	0xf3,0xc3
-
-
-.globl	_aes_hw_ocb_encrypt
-.private_extern _aes_hw_ocb_encrypt
-
-.p2align	5
-_aes_hw_ocb_encrypt:
-
-	leaq	(%rsp),%rax
-	pushq	%rbx
-
-	pushq	%rbp
-
-	pushq	%r12
-
-	pushq	%r13
-
-	pushq	%r14
-
-	movq	8(%rax),%rbx
-	movq	8+8(%rax),%rbp
-
-	movl	240(%rcx),%r10d
-	movq	%rcx,%r11
-	shll	$4,%r10d
-	movups	(%rcx),%xmm9
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqu	(%r9),%xmm15
-	pxor	%xmm1,%xmm9
-	pxor	%xmm1,%xmm15
-
-	movl	$16+32,%eax
-	leaq	32(%r11,%r10,1),%rcx
-	movups	16(%r11),%xmm1
-	subq	%r10,%rax
-	movq	%rax,%r10
-
-	movdqu	(%rbx),%xmm10
-	movdqu	(%rbp),%xmm8
-
-	testq	$1,%r8
-	jnz	L$ocb_enc_odd
-
-	bsfq	%r8,%r12
-	addq	$1,%r8
-	shlq	$4,%r12
-	movdqu	(%rbx,%r12,1),%xmm7
-	movdqu	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-
-	call	__ocb_encrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,(%rsi)
-	leaq	16(%rsi),%rsi
-	subq	$1,%rdx
-	jz	L$ocb_enc_done
-
-L$ocb_enc_odd:
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	leaq	6(%r8),%r8
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-	shlq	$4,%r12
-	shlq	$4,%r13
-	shlq	$4,%r14
-
-	subq	$6,%rdx
-	jc	L$ocb_enc_short
-	jmp	L$ocb_enc_grandloop
-
-.p2align	5
-L$ocb_enc_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	movdqu	48(%rdi),%xmm5
-	movdqu	64(%rdi),%xmm6
-	movdqu	80(%rdi),%xmm7
-	leaq	96(%rdi),%rdi
-
-	call	__ocb_encrypt6
-
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-	movups	%xmm6,64(%rsi)
-	movups	%xmm7,80(%rsi)
-	leaq	96(%rsi),%rsi
-	subq	$6,%rdx
-	jnc	L$ocb_enc_grandloop
-
-L$ocb_enc_short:
-	addq	$6,%rdx
-	jz	L$ocb_enc_done
-
-	movdqu	0(%rdi),%xmm2
-	cmpq	$2,%rdx
-	jb	L$ocb_enc_one
-	movdqu	16(%rdi),%xmm3
-	je	L$ocb_enc_two
-
-	movdqu	32(%rdi),%xmm4
-	cmpq	$4,%rdx
-	jb	L$ocb_enc_three
-	movdqu	48(%rdi),%xmm5
-	je	L$ocb_enc_four
-
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	__ocb_encrypt6
-
-	movdqa	%xmm14,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-	movups	%xmm6,64(%rsi)
-
-	jmp	L$ocb_enc_done
-
-.p2align	4
-L$ocb_enc_one:
-	movdqa	%xmm10,%xmm7
-
-	call	__ocb_encrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,0(%rsi)
-	jmp	L$ocb_enc_done
-
-.p2align	4
-L$ocb_enc_two:
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	%xmm11,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-
-	jmp	L$ocb_enc_done
-
-.p2align	4
-L$ocb_enc_three:
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	%xmm12,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-
-	jmp	L$ocb_enc_done
-
-.p2align	4
-L$ocb_enc_four:
-	call	__ocb_encrypt4
-
-	movdqa	%xmm13,%xmm15
-	movups	%xmm2,0(%rsi)
-	movups	%xmm3,16(%rsi)
-	movups	%xmm4,32(%rsi)
-	movups	%xmm5,48(%rsi)
-
-L$ocb_enc_done:
-	pxor	%xmm0,%xmm15
-	movdqu	%xmm8,(%rbp)
-	movdqu	%xmm15,(%r9)
-
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	pxor	%xmm8,%xmm8
-	pxor	%xmm9,%xmm9
-	pxor	%xmm10,%xmm10
-	pxor	%xmm11,%xmm11
-	pxor	%xmm12,%xmm12
-	pxor	%xmm13,%xmm13
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	leaq	40(%rsp),%rax
-
-	movq	-40(%rax),%r14
-
-	movq	-32(%rax),%r13
-
-	movq	-24(%rax),%r12
-
-	movq	-16(%rax),%rbp
-
-	movq	-8(%rax),%rbx
-
-	leaq	(%rax),%rsp
-
-L$ocb_enc_epilogue:
-	.byte	0xf3,0xc3
-
-
-
-
-.p2align	5
-__ocb_encrypt6:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	movdqa	%xmm10,%xmm14
-	pxor	%xmm15,%xmm10
-	movdqu	(%rbx,%r14,1),%xmm15
-	pxor	%xmm10,%xmm11
-	pxor	%xmm2,%xmm8
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm3,%xmm8
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm4,%xmm8
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm14
-	pxor	%xmm5,%xmm8
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm15
-	pxor	%xmm6,%xmm8
-	pxor	%xmm14,%xmm6
-	pxor	%xmm7,%xmm8
-	pxor	%xmm15,%xmm7
-	movups	32(%r11),%xmm0
-
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	addq	$6,%r8
-	pxor	%xmm9,%xmm10
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-.byte	102,15,56,220,241
-	pxor	%xmm9,%xmm13
-	pxor	%xmm9,%xmm14
-.byte	102,15,56,220,249
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm15
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	64(%r11),%xmm0
-	shlq	$4,%r12
-	shlq	$4,%r13
-	jmp	L$ocb_enc_loop6
-
-.p2align	5
-L$ocb_enc_loop6:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-.byte	102,15,56,220,240
-.byte	102,15,56,220,248
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_enc_loop6
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-.byte	102,15,56,220,241
-.byte	102,15,56,220,249
-	movups	16(%r11),%xmm1
-	shlq	$4,%r14
-
-.byte	102,65,15,56,221,210
-	movdqu	(%rbx),%xmm10
-	movq	%r10,%rax
-.byte	102,65,15,56,221,219
-.byte	102,65,15,56,221,228
-.byte	102,65,15,56,221,237
-.byte	102,65,15,56,221,246
-.byte	102,65,15,56,221,255
-	.byte	0xf3,0xc3
-
-
-
-.p2align	5
-__ocb_encrypt4:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	pxor	%xmm15,%xmm10
-	pxor	%xmm10,%xmm11
-	pxor	%xmm2,%xmm8
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm3,%xmm8
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm4,%xmm8
-	pxor	%xmm12,%xmm4
-	pxor	%xmm5,%xmm8
-	pxor	%xmm13,%xmm5
-	movups	32(%r11),%xmm0
-
-	pxor	%xmm9,%xmm10
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-	pxor	%xmm9,%xmm13
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	48(%r11),%xmm1
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	movups	64(%r11),%xmm0
-	jmp	L$ocb_enc_loop4
-
-.p2align	5
-L$ocb_enc_loop4:
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-.byte	102,15,56,220,216
-.byte	102,15,56,220,224
-.byte	102,15,56,220,232
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_enc_loop4
-
-.byte	102,15,56,220,209
-.byte	102,15,56,220,217
-.byte	102,15,56,220,225
-.byte	102,15,56,220,233
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,65,15,56,221,210
-.byte	102,65,15,56,221,219
-.byte	102,65,15,56,221,228
-.byte	102,65,15,56,221,237
-	.byte	0xf3,0xc3
-
-
-
-.p2align	5
-__ocb_encrypt1:
-	pxor	%xmm15,%xmm7
-	pxor	%xmm9,%xmm7
-	pxor	%xmm2,%xmm8
-	pxor	%xmm7,%xmm2
-	movups	32(%r11),%xmm0
-
-.byte	102,15,56,220,209
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm7
-
-.byte	102,15,56,220,208
-	movups	64(%r11),%xmm0
-	jmp	L$ocb_enc_loop1
-
-.p2align	5
-L$ocb_enc_loop1:
-.byte	102,15,56,220,209
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,220,208
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_enc_loop1
-
-.byte	102,15,56,220,209
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,15,56,221,215
-	.byte	0xf3,0xc3
-
-
-.globl	_aes_hw_ocb_decrypt
-.private_extern _aes_hw_ocb_decrypt
-
-.p2align	5
-_aes_hw_ocb_decrypt:
-
-	leaq	(%rsp),%rax
-	pushq	%rbx
-
-	pushq	%rbp
-
-	pushq	%r12
-
-	pushq	%r13
-
-	pushq	%r14
-
-	movq	8(%rax),%rbx
-	movq	8+8(%rax),%rbp
-
-	movl	240(%rcx),%r10d
-	movq	%rcx,%r11
-	shll	$4,%r10d
-	movups	(%rcx),%xmm9
-	movups	16(%rcx,%r10,1),%xmm1
-
-	movdqu	(%r9),%xmm15
-	pxor	%xmm1,%xmm9
-	pxor	%xmm1,%xmm15
-
-	movl	$16+32,%eax
-	leaq	32(%r11,%r10,1),%rcx
-	movups	16(%r11),%xmm1
-	subq	%r10,%rax
-	movq	%rax,%r10
-
-	movdqu	(%rbx),%xmm10
-	movdqu	(%rbp),%xmm8
-
-	testq	$1,%r8
-	jnz	L$ocb_dec_odd
-
-	bsfq	%r8,%r12
-	addq	$1,%r8
-	shlq	$4,%r12
-	movdqu	(%rbx,%r12,1),%xmm7
-	movdqu	(%rdi),%xmm2
-	leaq	16(%rdi),%rdi
-
-	call	__ocb_decrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,(%rsi)
-	xorps	%xmm2,%xmm8
-	leaq	16(%rsi),%rsi
-	subq	$1,%rdx
-	jz	L$ocb_dec_done
-
-L$ocb_dec_odd:
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	leaq	6(%r8),%r8
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-	shlq	$4,%r12
-	shlq	$4,%r13
-	shlq	$4,%r14
-
-	subq	$6,%rdx
-	jc	L$ocb_dec_short
-	jmp	L$ocb_dec_grandloop
-
-.p2align	5
-L$ocb_dec_grandloop:
-	movdqu	0(%rdi),%xmm2
-	movdqu	16(%rdi),%xmm3
-	movdqu	32(%rdi),%xmm4
-	movdqu	48(%rdi),%xmm5
-	movdqu	64(%rdi),%xmm6
-	movdqu	80(%rdi),%xmm7
-	leaq	96(%rdi),%rdi
-
-	call	__ocb_decrypt6
-
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-	movups	%xmm6,64(%rsi)
-	pxor	%xmm6,%xmm8
-	movups	%xmm7,80(%rsi)
-	pxor	%xmm7,%xmm8
-	leaq	96(%rsi),%rsi
-	subq	$6,%rdx
-	jnc	L$ocb_dec_grandloop
-
-L$ocb_dec_short:
-	addq	$6,%rdx
-	jz	L$ocb_dec_done
-
-	movdqu	0(%rdi),%xmm2
-	cmpq	$2,%rdx
-	jb	L$ocb_dec_one
-	movdqu	16(%rdi),%xmm3
-	je	L$ocb_dec_two
-
-	movdqu	32(%rdi),%xmm4
-	cmpq	$4,%rdx
-	jb	L$ocb_dec_three
-	movdqu	48(%rdi),%xmm5
-	je	L$ocb_dec_four
-
-	movdqu	64(%rdi),%xmm6
-	pxor	%xmm7,%xmm7
-
-	call	__ocb_decrypt6
-
-	movdqa	%xmm14,%xmm15
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-	movups	%xmm6,64(%rsi)
-	pxor	%xmm6,%xmm8
-
-	jmp	L$ocb_dec_done
-
-.p2align	4
-L$ocb_dec_one:
-	movdqa	%xmm10,%xmm7
-
-	call	__ocb_decrypt1
-
-	movdqa	%xmm7,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	jmp	L$ocb_dec_done
-
-.p2align	4
-L$ocb_dec_two:
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	%xmm11,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	xorps	%xmm3,%xmm8
-
-	jmp	L$ocb_dec_done
-
-.p2align	4
-L$ocb_dec_three:
-	pxor	%xmm5,%xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	%xmm12,%xmm15
-	movups	%xmm2,0(%rsi)
-	xorps	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	xorps	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	xorps	%xmm4,%xmm8
-
-	jmp	L$ocb_dec_done
-
-.p2align	4
-L$ocb_dec_four:
-	call	__ocb_decrypt4
-
-	movdqa	%xmm13,%xmm15
-	movups	%xmm2,0(%rsi)
-	pxor	%xmm2,%xmm8
-	movups	%xmm3,16(%rsi)
-	pxor	%xmm3,%xmm8
-	movups	%xmm4,32(%rsi)
-	pxor	%xmm4,%xmm8
-	movups	%xmm5,48(%rsi)
-	pxor	%xmm5,%xmm8
-
-L$ocb_dec_done:
-	pxor	%xmm0,%xmm15
-	movdqu	%xmm8,(%rbp)
-	movdqu	%xmm15,(%r9)
-
-	xorps	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-	pxor	%xmm8,%xmm8
-	pxor	%xmm9,%xmm9
-	pxor	%xmm10,%xmm10
-	pxor	%xmm11,%xmm11
-	pxor	%xmm12,%xmm12
-	pxor	%xmm13,%xmm13
-	pxor	%xmm14,%xmm14
-	pxor	%xmm15,%xmm15
-	leaq	40(%rsp),%rax
-
-	movq	-40(%rax),%r14
-
-	movq	-32(%rax),%r13
-
-	movq	-24(%rax),%r12
-
-	movq	-16(%rax),%rbp
-
-	movq	-8(%rax),%rbx
-
-	leaq	(%rax),%rsp
-
-L$ocb_dec_epilogue:
-	.byte	0xf3,0xc3
-
-
-
-
-.p2align	5
-__ocb_decrypt6:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	movdqa	%xmm10,%xmm14
-	pxor	%xmm15,%xmm10
-	movdqu	(%rbx,%r14,1),%xmm15
-	pxor	%xmm10,%xmm11
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm14
-	pxor	%xmm13,%xmm5
-	pxor	%xmm14,%xmm15
-	pxor	%xmm14,%xmm6
-	pxor	%xmm15,%xmm7
-	movups	32(%r11),%xmm0
-
-	leaq	1(%r8),%r12
-	leaq	3(%r8),%r13
-	leaq	5(%r8),%r14
-	addq	$6,%r8
-	pxor	%xmm9,%xmm10
-	bsfq	%r12,%r12
-	bsfq	%r13,%r13
-	bsfq	%r14,%r14
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-.byte	102,15,56,222,241
-	pxor	%xmm9,%xmm13
-	pxor	%xmm9,%xmm14
-.byte	102,15,56,222,249
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm15
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	64(%r11),%xmm0
-	shlq	$4,%r12
-	shlq	$4,%r13
-	jmp	L$ocb_dec_loop6
-
-.p2align	5
-L$ocb_dec_loop6:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-.byte	102,15,56,222,240
-.byte	102,15,56,222,248
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_dec_loop6
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-.byte	102,15,56,222,241
-.byte	102,15,56,222,249
-	movups	16(%r11),%xmm1
-	shlq	$4,%r14
-
-.byte	102,65,15,56,223,210
-	movdqu	(%rbx),%xmm10
-	movq	%r10,%rax
-.byte	102,65,15,56,223,219
-.byte	102,65,15,56,223,228
-.byte	102,65,15,56,223,237
-.byte	102,65,15,56,223,246
-.byte	102,65,15,56,223,255
-	.byte	0xf3,0xc3
-
-
-
-.p2align	5
-__ocb_decrypt4:
-	pxor	%xmm9,%xmm15
-	movdqu	(%rbx,%r12,1),%xmm11
-	movdqa	%xmm10,%xmm12
-	movdqu	(%rbx,%r13,1),%xmm13
-	pxor	%xmm15,%xmm10
-	pxor	%xmm10,%xmm11
-	pxor	%xmm10,%xmm2
-	pxor	%xmm11,%xmm12
-	pxor	%xmm11,%xmm3
-	pxor	%xmm12,%xmm13
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm5
-	movups	32(%r11),%xmm0
-
-	pxor	%xmm9,%xmm10
-	pxor	%xmm9,%xmm11
-	pxor	%xmm9,%xmm12
-	pxor	%xmm9,%xmm13
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	48(%r11),%xmm1
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	movups	64(%r11),%xmm0
-	jmp	L$ocb_dec_loop4
-
-.p2align	5
-L$ocb_dec_loop4:
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-.byte	102,15,56,222,216
-.byte	102,15,56,222,224
-.byte	102,15,56,222,232
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_dec_loop4
-
-.byte	102,15,56,222,209
-.byte	102,15,56,222,217
-.byte	102,15,56,222,225
-.byte	102,15,56,222,233
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,65,15,56,223,210
-.byte	102,65,15,56,223,219
-.byte	102,65,15,56,223,228
-.byte	102,65,15,56,223,237
-	.byte	0xf3,0xc3
-
-
-
-.p2align	5
-__ocb_decrypt1:
-	pxor	%xmm15,%xmm7
-	pxor	%xmm9,%xmm7
-	pxor	%xmm7,%xmm2
-	movups	32(%r11),%xmm0
-
-.byte	102,15,56,222,209
-	movups	48(%r11),%xmm1
-	pxor	%xmm9,%xmm7
-
-.byte	102,15,56,222,208
-	movups	64(%r11),%xmm0
-	jmp	L$ocb_dec_loop1
-
-.p2align	5
-L$ocb_dec_loop1:
-.byte	102,15,56,222,209
-	movups	(%rcx,%rax,1),%xmm1
-	addq	$32,%rax
-
-.byte	102,15,56,222,208
-	movups	-16(%rcx,%rax,1),%xmm0
-	jnz	L$ocb_dec_loop1
-
-.byte	102,15,56,222,209
-	movups	16(%r11),%xmm1
-	movq	%r10,%rax
-
-.byte	102,15,56,223,215
-	.byte	0xf3,0xc3
-
 .globl	_aes_hw_cbc_encrypt
 .private_extern _aes_hw_cbc_encrypt
 
@@ -3462,7 +1477,7 @@
 	movq	%rcx,%r11
 	testl	%r9d,%r9d
 	jz	L$cbc_decrypt
-#--------------------------- CBC ENCRYPT ------------------------------#
+
 	movups	(%r8),%xmm2
 	movl	%r10d,%eax
 	cmpq	$16,%rdx
@@ -3473,18 +1488,18 @@
 L$cbc_enc_loop:
 	movups	(%rdi),%xmm3
 	leaq	16(%rdi),%rdi
-#xorps	%xmm3,%xmm2
+
 	movups	(%rcx),%xmm0
 	movups	16(%rcx),%xmm1
 	xorps	%xmm0,%xmm3
 	leaq	32(%rcx),%rcx
 	xorps	%xmm3,%xmm2
-L$oop_enc1_15:
+L$oop_enc1_6:
 .byte	102,15,56,220,209
 	decl	%eax
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	L$oop_enc1_15
+	jnz	L$oop_enc1_6
 .byte	102,15,56,221,209
 	movl	%r10d,%eax
 	movq	%r11,%rcx
@@ -3515,7 +1530,7 @@
 	movq	%r11,%rcx
 	xorq	%rdx,%rdx
 	jmp	L$cbc_enc_loop
-#--------------------------- CBC DECRYPT ------------------------------#
+
 .p2align	4
 L$cbc_decrypt:
 	cmpq	$16,%rdx
@@ -3530,12 +1545,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-L$oop_dec1_16:
+L$oop_dec1_7:
 .byte	102,15,56,222,209
 	decl	%r10d
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	L$oop_dec1_16
+	jnz	L$oop_dec1_7
 .byte	102,15,56,223,209
 	pxor	%xmm0,%xmm0
 	pxor	%xmm1,%xmm1
@@ -3948,12 +1963,12 @@
 	movups	16(%rcx),%xmm1
 	leaq	32(%rcx),%rcx
 	xorps	%xmm0,%xmm2
-L$oop_dec1_17:
+L$oop_dec1_8:
 .byte	102,15,56,222,209
 	decl	%eax
 	movups	(%rcx),%xmm1
 	leaq	16(%rcx),%rcx
-	jnz	L$oop_dec1_17
+	jnz	L$oop_dec1_8
 .byte	102,15,56,223,209
 	xorps	%xmm10,%xmm2
 	movaps	%xmm11,%xmm10
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S
index baf70cb..5a65960 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S
@@ -219,7 +219,7 @@
 	pxor	%xmm13,%xmm8
 	pxor	%xmm14,%xmm7
 
-#Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
+
 
 
 
@@ -690,7 +690,7 @@
 	pxor	%xmm13,%xmm8
 	pxor	%xmm14,%xmm7
 
-#Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
+
 
 
 
@@ -1077,7 +1077,7 @@
 	jnz	L$key_loop
 
 	movdqa	80(%r11),%xmm7
-#movdqa	%xmm6, (%rax)
+
 	.byte	0xf3,0xc3
 
 
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
index 2bdeef2..d7dcf5d6 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -718,7 +718,7 @@
 	pshufd	$255,%xmm2,%xmm4
 	movdqa	%xmm2,%xmm3
 	psllq	$1,%xmm2
-	pxor	%xmm5,%xmm5#
+	pxor	%xmm5,%xmm5
 	psrlq	$63,%xmm3
 	pcmpgtd	%xmm4,%xmm5
 	pslldq	$8,%xmm3
@@ -732,43 +732,43 @@
 	pshufd	$78,%xmm2,%xmm6
 	movdqa	%xmm2,%xmm0
 	pxor	%xmm2,%xmm6
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	pshufd	$78,%xmm2,%xmm3
 	pshufd	$78,%xmm0,%xmm4
 	pxor	%xmm2,%xmm3
@@ -777,81 +777,81 @@
 	movdqu	%xmm0,16(%rdi)
 .byte	102,15,58,15,227,8
 	movdqu	%xmm4,32(%rdi)
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	movdqa	%xmm0,%xmm5
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,222,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	pshufd	$78,%xmm5,%xmm3
 	pshufd	$78,%xmm0,%xmm4
 	pxor	%xmm5,%xmm3
@@ -875,43 +875,43 @@
 	movdqu	(%rsi),%xmm2
 	movdqu	32(%rsi),%xmm4
 .byte	102,15,56,0,197
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,220,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 .byte	102,15,56,0,197
 	movdqu	%xmm0,(%rdi)
 	.byte	0xf3,0xc3
@@ -949,9 +949,9 @@
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
-#######
 
-#
+
+
 	movdqu	48(%rdx),%xmm3
 	movdqu	32(%rdx),%xmm11
 .byte	102,65,15,56,0,218
@@ -1018,28 +1018,28 @@
 
 	pxor	%xmm0,%xmm8
 	movdqa	%xmm3,%xmm5
-	pxor	%xmm1,%xmm8#
+	pxor	%xmm1,%xmm8
 	pxor	%xmm3,%xmm4
-	movdqa	%xmm8,%xmm9#
+	movdqa	%xmm8,%xmm9
 .byte	102,68,15,58,68,234,17
 	pslldq	$8,%xmm8
-	psrldq	$8,%xmm9#
+	psrldq	$8,%xmm9
 	pxor	%xmm8,%xmm0
 	movdqa	L$7_mask(%rip),%xmm8
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 .byte	102,76,15,110,200
 
 	pand	%xmm0,%xmm8
 .byte	102,69,15,56,0,200
-	pxor	%xmm0,%xmm9#
+	pxor	%xmm0,%xmm9
 .byte	102,68,15,58,68,231,0
-	psllq	$57,%xmm9#
-	movdqa	%xmm9,%xmm8#
+	psllq	$57,%xmm9
+	movdqa	%xmm9,%xmm8
 	pslldq	$8,%xmm9
 .byte	102,15,58,68,222,0
-	psrldq	$8,%xmm8#
+	psrldq	$8,%xmm8
 	pxor	%xmm9,%xmm0
-	pxor	%xmm8,%xmm1#
+	pxor	%xmm8,%xmm1
 	movdqu	0(%rdx),%xmm8
 
 	movdqa	%xmm0,%xmm9
@@ -1052,19 +1052,19 @@
 	xorps	%xmm13,%xmm5
 	movups	80(%rsi),%xmm7
 .byte	102,69,15,56,0,194
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 	pxor	%xmm0,%xmm9
 	psrlq	$5,%xmm0
 
 	movdqa	%xmm11,%xmm13
 	pxor	%xmm12,%xmm4
 	pshufd	$78,%xmm11,%xmm12
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 	pxor	%xmm8,%xmm1
 	pxor	%xmm11,%xmm12
 .byte	102,69,15,58,68,222,0
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	movdqa	%xmm0,%xmm1
 .byte	102,69,15,58,68,238,17
 	xorps	%xmm11,%xmm3
@@ -1088,48 +1088,48 @@
 	pxor	%xmm0,%xmm1
 	pxor	%xmm4,%xmm8
 
-	pxor	%xmm1,%xmm8#
+	pxor	%xmm1,%xmm8
 	pxor	%xmm0,%xmm1
 
-	movdqa	%xmm8,%xmm9#
+	movdqa	%xmm8,%xmm9
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm9#
+	pslldq	$8,%xmm9
 	pxor	%xmm8,%xmm1
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	addq	$0x40,%rcx
 	jz	L$done
 	movdqu	32(%rsi),%xmm7
 	subq	$0x10,%rcx
 	jz	L$odd_tail
 L$skip4x:
-#######
 
-#	[(H*Ii+1) + (H*Xi+1)] mod P =
-#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-#
+
+
+
+
 	movdqu	(%rdx),%xmm8
 	movdqu	16(%rdx),%xmm3
 .byte	102,69,15,56,0,194
@@ -1154,8 +1154,8 @@
 L$mod_loop:
 	movdqa	%xmm0,%xmm1
 	movdqa	%xmm4,%xmm8
-	pshufd	$78,%xmm0,%xmm4#
-	pxor	%xmm0,%xmm4#
+	pshufd	$78,%xmm0,%xmm4
+	pxor	%xmm0,%xmm4
 
 .byte	102,15,58,68,198,0
 .byte	102,15,58,68,206,17
@@ -1172,41 +1172,41 @@
 	pxor	%xmm9,%xmm1
 	pxor	%xmm8,%xmm4
 .byte	102,65,15,56,0,218
-	movdqa	%xmm4,%xmm8#
+	movdqa	%xmm4,%xmm8
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm8,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm3,%xmm5#
+	movdqa	%xmm3,%xmm5
 
 	movdqa	%xmm0,%xmm9
 	movdqa	%xmm0,%xmm8
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm8#
+	pxor	%xmm0,%xmm8
 .byte	102,15,58,68,218,0
 	psllq	$1,%xmm0
-	pxor	%xmm8,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm8#
+	pxor	%xmm8,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm8
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm8#
+	psrldq	$8,%xmm8
 	pxor	%xmm9,%xmm0
 	pshufd	$78,%xmm5,%xmm4
-	pxor	%xmm8,%xmm1#
-	pxor	%xmm5,%xmm4#
+	pxor	%xmm8,%xmm1
+	pxor	%xmm5,%xmm4
 
 	movdqa	%xmm0,%xmm9
 	psrlq	$1,%xmm0
 .byte	102,15,58,68,234,17
-	pxor	%xmm9,%xmm1#
+	pxor	%xmm9,%xmm1
 	pxor	%xmm0,%xmm9
 	psrlq	$5,%xmm0
-	pxor	%xmm9,%xmm0#
+	pxor	%xmm9,%xmm0
 	leaq	32(%rdx),%rdx
-	psrlq	$1,%xmm0#
+	psrlq	$1,%xmm0
 .byte	102,15,58,68,231,0
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm1,%xmm0
 
 	subq	$0x20,%rcx
 	ja	L$mod_loop
@@ -1214,8 +1214,8 @@
 L$even_tail:
 	movdqa	%xmm0,%xmm1
 	movdqa	%xmm4,%xmm8
-	pshufd	$78,%xmm0,%xmm4#
-	pxor	%xmm0,%xmm4#
+	pshufd	$78,%xmm0,%xmm4
+	pxor	%xmm0,%xmm4
 
 .byte	102,15,58,68,198,0
 .byte	102,15,58,68,206,17
@@ -1226,34 +1226,34 @@
 	pxor	%xmm0,%xmm8
 	pxor	%xmm1,%xmm8
 	pxor	%xmm8,%xmm4
-	movdqa	%xmm4,%xmm8#
+	movdqa	%xmm4,%xmm8
 	psrldq	$8,%xmm8
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm8,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 	testq	%rcx,%rcx
 	jnz	L$done
 
@@ -1261,43 +1261,43 @@
 	movdqu	(%rdx),%xmm8
 .byte	102,69,15,56,0,194
 	pxor	%xmm8,%xmm0
-	movdqa	%xmm0,%xmm1#
+	movdqa	%xmm0,%xmm1
 	pshufd	$78,%xmm0,%xmm3
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 .byte	102,15,58,68,194,0
 .byte	102,15,58,68,202,17
 .byte	102,15,58,68,223,0
-	pxor	%xmm0,%xmm3#
-	pxor	%xmm1,%xmm3#
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
 
-	movdqa	%xmm3,%xmm4#
+	movdqa	%xmm3,%xmm4
 	psrldq	$8,%xmm3
-	pslldq	$8,%xmm4#
+	pslldq	$8,%xmm4
 	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm0#
+	pxor	%xmm4,%xmm0
 
-	movdqa	%xmm0,%xmm4#
+	movdqa	%xmm0,%xmm4
 	movdqa	%xmm0,%xmm3
 	psllq	$5,%xmm0
-	pxor	%xmm0,%xmm3#
+	pxor	%xmm0,%xmm3
 	psllq	$1,%xmm0
-	pxor	%xmm3,%xmm0#
-	psllq	$57,%xmm0#
-	movdqa	%xmm0,%xmm3#
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm3
 	pslldq	$8,%xmm0
-	psrldq	$8,%xmm3#
+	psrldq	$8,%xmm3
 	pxor	%xmm4,%xmm0
-	pxor	%xmm3,%xmm1#
+	pxor	%xmm3,%xmm1
 
 
 	movdqa	%xmm0,%xmm4
 	psrlq	$1,%xmm0
-	pxor	%xmm4,%xmm1#
+	pxor	%xmm4,%xmm1
 	pxor	%xmm0,%xmm4
 	psrlq	$5,%xmm0
-	pxor	%xmm4,%xmm0#
-	psrlq	$1,%xmm0#
-	pxor	%xmm1,%xmm0#
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm1,%xmm0
 L$done:
 .byte	102,65,15,56,0,194
 	movdqu	%xmm0,(%rdi)
@@ -1319,7 +1319,7 @@
 	vpshufd	$255,%xmm2,%xmm4
 	vpsrlq	$63,%xmm2,%xmm3
 	vpsllq	$1,%xmm2,%xmm2
-	vpxor	%xmm5,%xmm5,%xmm5#
+	vpxor	%xmm5,%xmm5,%xmm5
 	vpcmpgtd	%xmm4,%xmm5,%xmm5
 	vpslldq	$8,%xmm3,%xmm3
 	vpor	%xmm3,%xmm2,%xmm2
@@ -1338,65 +1338,65 @@
 	vpalignr	$8,%xmm3,%xmm4,%xmm5
 	vmovdqu	%xmm5,-16(%rdi)
 	vpunpckhqdq	%xmm0,%xmm0,%xmm3
-	vpxor	%xmm0,%xmm3,%xmm3#
-	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1#######
-	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0#######
-	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3#######
-	vpxor	%xmm0,%xmm1,%xmm4#
-	vpxor	%xmm4,%xmm3,%xmm3#
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
 
-	vpslldq	$8,%xmm3,%xmm4#
+	vpslldq	$8,%xmm3,%xmm4
 	vpsrldq	$8,%xmm3,%xmm3
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpsllq	$57,%xmm0,%xmm3
 	vpsllq	$62,%xmm0,%xmm4
-	vpxor	%xmm3,%xmm4,%xmm4#
+	vpxor	%xmm3,%xmm4,%xmm4
 	vpsllq	$63,%xmm0,%xmm3
-	vpxor	%xmm3,%xmm4,%xmm4#
-	vpslldq	$8,%xmm4,%xmm3#
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
 	vpsrldq	$8,%xmm4,%xmm4
-	vpxor	%xmm3,%xmm0,%xmm0#
+	vpxor	%xmm3,%xmm0,%xmm0
 	vpxor	%xmm4,%xmm1,%xmm1
 
 	vpsrlq	$1,%xmm0,%xmm4
 	vpxor	%xmm0,%xmm1,%xmm1
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpsrlq	$5,%xmm4,%xmm4
-	vpxor	%xmm4,%xmm0,%xmm0#
-	vpsrlq	$1,%xmm0,%xmm0#
-	vpxor	%xmm1,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
 L$init_start_avx:
 	vmovdqa	%xmm0,%xmm5
 	vpunpckhqdq	%xmm0,%xmm0,%xmm3
-	vpxor	%xmm0,%xmm3,%xmm3#
-	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1#######
-	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0#######
-	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3#######
-	vpxor	%xmm0,%xmm1,%xmm4#
-	vpxor	%xmm4,%xmm3,%xmm3#
+	vpxor	%xmm0,%xmm3,%xmm3
+	vpclmulqdq	$0x11,%xmm2,%xmm0,%xmm1
+	vpclmulqdq	$0x00,%xmm2,%xmm0,%xmm0
+	vpclmulqdq	$0x00,%xmm6,%xmm3,%xmm3
+	vpxor	%xmm0,%xmm1,%xmm4
+	vpxor	%xmm4,%xmm3,%xmm3
 
-	vpslldq	$8,%xmm3,%xmm4#
+	vpslldq	$8,%xmm3,%xmm4
 	vpsrldq	$8,%xmm3,%xmm3
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpxor	%xmm3,%xmm1,%xmm1
 	vpsllq	$57,%xmm0,%xmm3
 	vpsllq	$62,%xmm0,%xmm4
-	vpxor	%xmm3,%xmm4,%xmm4#
+	vpxor	%xmm3,%xmm4,%xmm4
 	vpsllq	$63,%xmm0,%xmm3
-	vpxor	%xmm3,%xmm4,%xmm4#
-	vpslldq	$8,%xmm4,%xmm3#
+	vpxor	%xmm3,%xmm4,%xmm4
+	vpslldq	$8,%xmm4,%xmm3
 	vpsrldq	$8,%xmm4,%xmm4
-	vpxor	%xmm3,%xmm0,%xmm0#
+	vpxor	%xmm3,%xmm0,%xmm0
 	vpxor	%xmm4,%xmm1,%xmm1
 
 	vpsrlq	$1,%xmm0,%xmm4
 	vpxor	%xmm0,%xmm1,%xmm1
-	vpxor	%xmm4,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
 	vpsrlq	$5,%xmm4,%xmm4
-	vpxor	%xmm4,%xmm0,%xmm0#
-	vpsrlq	$1,%xmm0,%xmm0#
-	vpxor	%xmm1,%xmm0,%xmm0#
+	vpxor	%xmm4,%xmm0,%xmm0
+	vpsrlq	$1,%xmm0,%xmm0
+	vpxor	%xmm1,%xmm0,%xmm0
 	vpshufd	$78,%xmm5,%xmm3
 	vpshufd	$78,%xmm0,%xmm4
 	vpxor	%xmm5,%xmm3,%xmm3
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
index 59d4596..237c0a3 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
@@ -34,7 +34,7 @@
 L$ordK:
 .quad	0xccd1c8aaee00bc4f
 
-################################################################################
+
 
 .globl	_ecp_nistz256_neg
 .private_extern _ecp_nistz256_neg
@@ -90,7 +90,7 @@
 	.byte	0xf3,0xc3
 
 
-################################################################################
+
 
 
 
@@ -126,7 +126,7 @@
 	leaq	L$ord(%rip),%r14
 	movq	L$ordK(%rip),%r15
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	movq	%rax,%r8
@@ -154,7 +154,7 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-################################
+
 	mulq	0(%r14)
 	movq	%r8,%rbp
 	addq	%rax,%r13
@@ -184,7 +184,7 @@
 	adcq	%rbp,%r12
 	adcq	$0,%r13
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r9
@@ -220,7 +220,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r8
 
-################################
+
 	mulq	0(%r14)
 	movq	%r9,%rbp
 	addq	%rax,%rcx
@@ -249,7 +249,7 @@
 	adcq	%rbp,%r13
 	adcq	$0,%r8
 
-#################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r10
@@ -285,7 +285,7 @@
 	adcq	%rdx,%r8
 	adcq	$0,%r9
 
-################################
+
 	mulq	0(%r14)
 	movq	%r10,%rbp
 	addq	%rax,%rcx
@@ -314,7 +314,7 @@
 	adcq	%rbp,%r8
 	adcq	$0,%r9
 
-################################
+
 	movq	%rax,%rcx
 	mulq	0(%rsi)
 	addq	%rax,%r11
@@ -350,7 +350,7 @@
 	adcq	%rdx,%r9
 	adcq	$0,%r10
 
-################################
+
 	mulq	0(%r14)
 	movq	%r11,%rbp
 	addq	%rax,%rcx
@@ -378,7 +378,7 @@
 	adcq	%rbp,%r9
 	adcq	$0,%r10
 
-################################
+
 	movq	%r12,%rsi
 	subq	0(%r14),%r12
 	movq	%r13,%r11
@@ -418,7 +418,7 @@
 
 
 
-################################################################################
+
 
 
 
@@ -459,7 +459,7 @@
 
 .p2align	5
 L$oop_ord_sqr:
-################################
+
 	movq	%rax,%rbp
 	mulq	%r8
 	movq	%rax,%r9
@@ -481,13 +481,13 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-################################
+
 	mulq	%r14
 	movq	%rax,%r13
 	movq	%r14,%rax
 	movq	%rdx,%r14
 
-################################
+
 	mulq	%rbp
 	addq	%rax,%r11
 	movq	%r15,%rax
@@ -502,7 +502,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r14
 
-################################
+
 	xorq	%r15,%r15
 	movq	%r8,%rax
 	addq	%r9,%r9
@@ -513,7 +513,7 @@
 	adcq	%r14,%r14
 	adcq	$0,%r15
 
-################################
+
 	mulq	%rax
 	movq	%rax,%r8
 .byte	102,72,15,126,200
@@ -542,7 +542,7 @@
 	movq	0(%rsi),%rax
 	adcq	%rdx,%r15
 
-################################
+
 	mulq	%r8
 	movq	%r8,%rbp
 	addq	%rax,%rcx
@@ -573,7 +573,7 @@
 	addq	%rbp,%r11
 	adcq	$0,%r8
 
-################################
+
 	mulq	%r9
 	movq	%r9,%rbp
 	addq	%rax,%rcx
@@ -604,7 +604,7 @@
 	addq	%rbp,%r8
 	adcq	$0,%r9
 
-################################
+
 	mulq	%r10
 	movq	%r10,%rbp
 	addq	%rax,%rcx
@@ -635,7 +635,7 @@
 	addq	%rbp,%r9
 	adcq	$0,%r10
 
-################################
+
 	mulq	%r11
 	movq	%r11,%rbp
 	addq	%rax,%rcx
@@ -662,7 +662,7 @@
 	addq	%rbp,%r10
 	adcq	$0,%r11
 
-################################
+
 	xorq	%rdx,%rdx
 	addq	%r12,%r8
 	adcq	%r13,%r9
@@ -672,7 +672,7 @@
 	movq	%r9,%rax
 	adcq	$0,%rdx
 
-################################
+
 	subq	0(%rsi),%r8
 	movq	%r10,%r14
 	sbbq	8(%rsi),%r9
@@ -715,7 +715,7 @@
 	.byte	0xf3,0xc3
 
 
-################################################################################
+
 
 .p2align	5
 ecp_nistz256_ord_mul_montx:
@@ -745,7 +745,7 @@
 	leaq	L$ord-128(%rip),%r14
 	movq	L$ordK(%rip),%r15
 
-################################
+
 	mulxq	%r9,%r8,%r9
 	mulxq	%r10,%rcx,%r10
 	mulxq	%r11,%rbp,%r11
@@ -757,7 +757,7 @@
 	adcq	%rcx,%r11
 	adcq	$0,%r12
 
-################################
+
 	xorq	%r13,%r13
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r8
@@ -779,7 +779,7 @@
 	adoxq	%r8,%r13
 	adcq	$0,%r13
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r9
 	adoxq	%rbp,%r10
@@ -802,7 +802,7 @@
 	adoxq	%r8,%r8
 	adcq	$0,%r8
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r9
 	adoxq	%rbp,%r10
@@ -823,7 +823,7 @@
 	adoxq	%r9,%r8
 	adcq	$0,%r8
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r10
 	adoxq	%rbp,%r11
@@ -846,7 +846,7 @@
 	adoxq	%r9,%r9
 	adcq	$0,%r9
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r10
 	adoxq	%rbp,%r11
@@ -867,7 +867,7 @@
 	adoxq	%r10,%r9
 	adcq	$0,%r9
 
-################################
+
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -890,7 +890,7 @@
 	adoxq	%r10,%r10
 	adcq	$0,%r10
 
-################################
+
 	mulxq	0+128(%r14),%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -913,7 +913,7 @@
 	adoxq	%r11,%r10
 	adcq	$0,%r10
 
-#################################
+
 
 	movq	%r8,%rcx
 	subq	0(%r14),%r12
@@ -992,7 +992,7 @@
 	adcq	%rbp,%r11
 	adcq	$0,%r12
 	xorq	%r13,%r13
-#################################
+
 	mulxq	%r15,%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -1002,7 +1002,7 @@
 	adcxq	%rcx,%r12
 	adoxq	%rbp,%r13
 	adcq	$0,%r13
-#################################
+
 	mulxq	%r8,%rcx,%r14
 	movq	%rax,%rdx
 .byte	102,73,15,110,216
@@ -1012,7 +1012,7 @@
 	adcxq	%r10,%r10
 	adoxq	%r15,%r14
 
-################################
+
 	mulxq	%rdx,%r8,%rbp
 .byte	102,72,15,126,202
 	adcxq	%r11,%r11
@@ -1034,7 +1034,7 @@
 	adoxq	%rcx,%r14
 	adoxq	%rax,%r15
 
-################################
+
 	movq	%r8,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1053,7 +1053,7 @@
 	adoxq	%rbp,%r8
 	adcxq	%rax,%r8
 
-#################################
+
 	movq	%r9,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1071,7 +1071,7 @@
 	adcxq	%rbp,%r9
 	adoxq	%rax,%r9
 
-#################################
+
 	movq	%r10,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1089,7 +1089,7 @@
 	adoxq	%rbp,%r10
 	adcxq	%rax,%r10
 
-#################################
+
 	movq	%r11,%rdx
 	mulxq	32(%rsi),%rdx,%rcx
 
@@ -1107,7 +1107,7 @@
 	adcxq	%rbp,%r11
 	adoxq	%rax,%r11
 
-################################
+
 	addq	%r8,%r12
 	adcq	%r13,%r9
 	movq	%r12,%rdx
@@ -1116,7 +1116,7 @@
 	movq	%r9,%r14
 	adcq	$0,%rax
 
-################################
+
 	subq	0(%rsi),%r12
 	movq	%r10,%r15
 	sbbq	8(%rsi),%r9
@@ -1159,7 +1159,7 @@
 	.byte	0xf3,0xc3
 
 
-################################################################################
+
 
 
 
@@ -1235,7 +1235,7 @@
 .p2align	5
 __ecp_nistz256_mul_montq:
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	%r9
@@ -1264,12 +1264,12 @@
 	xorq	%r13,%r13
 	movq	%rdx,%r12
 
-########################################################################
 
 
 
 
-#
+
+
 
 
 
@@ -1285,7 +1285,7 @@
 	adcq	$0,%r13
 	xorq	%r8,%r8
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1318,7 +1318,7 @@
 	adcq	%rdx,%r13
 	adcq	$0,%r8
 
-########################################################################
+
 
 	movq	%r9,%rbp
 	shlq	$32,%r9
@@ -1332,7 +1332,7 @@
 	adcq	$0,%r8
 	xorq	%r9,%r9
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1365,7 +1365,7 @@
 	adcq	%rdx,%r8
 	adcq	$0,%r9
 
-########################################################################
+
 
 	movq	%r10,%rbp
 	shlq	$32,%r10
@@ -1379,7 +1379,7 @@
 	adcq	$0,%r9
 	xorq	%r10,%r10
 
-########################################################################
+
 
 	movq	%rax,%rbp
 	mulq	0(%rsi)
@@ -1412,7 +1412,7 @@
 	adcq	%rdx,%r9
 	adcq	$0,%r10
 
-########################################################################
+
 
 	movq	%r11,%rbp
 	shlq	$32,%r11
@@ -1426,7 +1426,7 @@
 	movq	%r13,%rbp
 	adcq	$0,%r10
 
-########################################################################
+
 
 	subq	$-1,%r12
 	movq	%r8,%rbx
@@ -1449,7 +1449,7 @@
 
 
 
-################################################################################
+
 
 
 
@@ -1539,7 +1539,7 @@
 	adcq	$0,%rdx
 	movq	%rdx,%r12
 
-#################################
+
 	mulq	%r14
 	addq	%rax,%r11
 	movq	%r8,%rax
@@ -1554,7 +1554,7 @@
 	movq	%rdx,%r13
 	adcq	$0,%r13
 
-#################################
+
 	mulq	%r15
 	xorq	%r15,%r15
 	addq	%rax,%r13
@@ -1598,7 +1598,7 @@
 	movq	L$poly+8(%rip),%rsi
 	movq	L$poly+24(%rip),%rbp
 
-##########################################
+
 
 
 	movq	%r8,%rcx
@@ -1611,7 +1611,7 @@
 	movq	%r9,%rax
 	adcq	$0,%rdx
 
-##########################################
+
 
 	movq	%r9,%rcx
 	shlq	$32,%r9
@@ -1624,7 +1624,7 @@
 	movq	%r10,%rax
 	adcq	$0,%rdx
 
-##########################################
+
 
 	movq	%r10,%rcx
 	shlq	$32,%r10
@@ -1637,7 +1637,7 @@
 	movq	%r11,%rax
 	adcq	$0,%rdx
 
-###########################################
+
 
 	movq	%r11,%rcx
 	shlq	$32,%r11
@@ -1650,7 +1650,7 @@
 	adcq	$0,%rdx
 	xorq	%r11,%r11
 
-############################################
+
 
 	addq	%r8,%r12
 	adcq	%r9,%r13
@@ -1684,7 +1684,7 @@
 .p2align	5
 __ecp_nistz256_mul_montx:
 
-########################################################################
+
 
 	mulxq	%r9,%r8,%r9
 	mulxq	%r10,%rcx,%r10
@@ -1701,7 +1701,7 @@
 	shrxq	%r14,%r8,%rcx
 	adcq	$0,%r12
 
-########################################################################
+
 
 	addq	%rbp,%r9
 	adcq	%rcx,%r10
@@ -1713,7 +1713,7 @@
 	adcq	$0,%r13
 	xorq	%r8,%r8
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r9
@@ -1738,7 +1738,7 @@
 	adoxq	%r8,%r8
 	adcq	$0,%r8
 
-########################################################################
+
 
 	addq	%rcx,%r10
 	adcq	%rbp,%r11
@@ -1750,7 +1750,7 @@
 	adcq	$0,%r8
 	xorq	%r9,%r9
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r10
@@ -1775,7 +1775,7 @@
 	adoxq	%r9,%r9
 	adcq	$0,%r9
 
-########################################################################
+
 
 	addq	%rcx,%r11
 	adcq	%rbp,%r12
@@ -1787,7 +1787,7 @@
 	adcq	$0,%r9
 	xorq	%r10,%r10
 
-########################################################################
+
 
 	mulxq	0+128(%rsi),%rcx,%rbp
 	adcxq	%rcx,%r11
@@ -1812,7 +1812,7 @@
 	adoxq	%r10,%r10
 	adcq	$0,%r10
 
-########################################################################
+
 
 	addq	%rcx,%r12
 	adcq	%rbp,%r13
@@ -1825,7 +1825,7 @@
 	adcq	%rbp,%r9
 	adcq	$0,%r10
 
-########################################################################
+
 
 	xorl	%eax,%eax
 	movq	%r8,%rcx
@@ -1863,7 +1863,7 @@
 	adcq	$0,%r12
 	xorq	%r13,%r13
 
-#################################
+
 	mulxq	%r15,%rcx,%rbp
 	adcxq	%rcx,%r11
 	adoxq	%rbp,%r12
@@ -1874,7 +1874,7 @@
 	adoxq	%rbp,%r13
 	adcq	$0,%r13
 
-#################################
+
 	mulxq	%r8,%rcx,%r14
 	movq	0+128(%rsi),%rdx
 	xorq	%r15,%r15
@@ -1978,7 +1978,7 @@
 	.byte	0xf3,0xc3
 
 
-################################################################################
+
 
 .globl	_ecp_nistz256_select_w5
 .private_extern _ecp_nistz256_select_w5
@@ -2045,7 +2045,7 @@
 L$SEH_end_ecp_nistz256_select_w5:
 
 
-################################################################################
+
 
 .globl	_ecp_nistz256_select_w7
 .private_extern _ecp_nistz256_select_w7
@@ -2100,7 +2100,7 @@
 
 L$SEH_end_ecp_nistz256_select_w7:
 
-################################################################################
+
 
 
 .p2align	5
@@ -2164,7 +2164,7 @@
 L$SEH_end_ecp_nistz256_avx2_select_w5:
 
 
-################################################################################
+
 
 .globl	_ecp_nistz256_avx2_select_w7
 .private_extern _ecp_nistz256_avx2_select_w7
@@ -2857,9 +2857,9 @@
 	movq	24+32(%rsp),%r12
 	leaq	192(%rsp),%rdi
 	call	__ecp_nistz256_mul_montq
-#lea	192(%rsp), %rsi
-#lea	32(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -3096,7 +3096,7 @@
 	pcmpeqd	%xmm4,%xmm5
 	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rax
-#lea	0x00(%rbx), %rbx
+
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
@@ -3186,9 +3186,9 @@
 	movq	24+128(%rsp),%r12
 	leaq	0(%rsp),%rdi
 	call	__ecp_nistz256_mul_montq
-#lea	0(%rsp), %rsi
-#lea	128(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -3960,9 +3960,9 @@
 	movq	24+32(%rsp),%r12
 	leaq	192(%rsp),%rdi
 	call	__ecp_nistz256_mul_montx
-#lea	192(%rsp), %rsi
-#lea	32(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
@@ -4193,7 +4193,7 @@
 	pcmpeqd	%xmm4,%xmm5
 	pshufd	$0xb1,%xmm3,%xmm4
 	movq	0(%rbx),%rdx
-#lea	0x00(%rbx), %rbx
+
 	movq	%r12,%r9
 	por	%xmm3,%xmm4
 	pshufd	$0,%xmm5,%xmm5
@@ -4283,9 +4283,9 @@
 	movq	24+128(%rsp),%r12
 	leaq	0(%rsp),%rdi
 	call	__ecp_nistz256_mul_montx
-#lea	0(%rsp), %rsi
-#lea	128(%rsp), %rdi
-#call	__ecp_nistz256_mul_by_2
+
+
+
 
 	xorq	%r11,%r11
 	addq	%r12,%r12
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S
index e65b5d6..f6f2be7 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S
@@ -23,12 +23,10 @@
 _CRYPTO_rdrand:
 
 	xorq	%rax,%rax
-
-
-.byte	0x48, 0x0f, 0xc7, 0xf1
+.byte	72,15,199,242
 
 	adcq	%rax,%rax
-	movq	%rcx,0(%rdi)
+	movq	%rdx,0(%rdi)
 	.byte	0xf3,0xc3
 
 
@@ -36,6 +34,7 @@
 
 
 
+
 .globl	_CRYPTO_rdrand_multiple8_buf
 .private_extern _CRYPTO_rdrand_multiple8_buf
 
@@ -46,9 +45,7 @@
 	jz	L$out
 	movq	$8,%rdx
 L$loop:
-
-
-.byte	0x48, 0x0f, 0xc7, 0xf1
+.byte	72,15,199,241
 	jnc	L$err
 	movq	%rcx,0(%rdi)
 	addq	%rdx,%rdi
@@ -61,4 +58,5 @@
 	xorq	%rax,%rax
 	.byte	0xf3,0xc3
 
+
 #endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
index b703ae91..e9cae78 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -382,9 +382,9 @@
 	vpaddq	%ymm10,%ymm7,%ymm7
 	vpmuludq	256-128(%r13),%ymm12,%ymm14
 	vmovd	%eax,%xmm12
-#vmovdqu	32*1-8-128(%r13), %ymm11
+
 	vpaddq	%ymm14,%ymm8,%ymm8
-#vmovdqu	32*2-8-128(%r13), %ymm10
+
 	vpbroadcastq	%xmm12,%ymm12
 
 	vpmuludq	32-8-128(%r13),%ymm13,%ymm11
@@ -460,7 +460,7 @@
 	addq	%r12,%rax
 	vpaddq	%ymm14,%ymm7,%ymm7
 	vpmuludq	%ymm12,%ymm11,%ymm11
-#vmovdqu	32*2-24-128(%r13), %ymm14
+
 	movq	%rax,%r9
 	imull	%ecx,%eax
 	vpaddq	%ymm11,%ymm8,%ymm8
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
index 626c7df..5e46e81c 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
@@ -1818,8 +1818,8 @@
 	movl	20(%rdi),%r9d
 	movl	24(%rdi),%r10d
 	movl	28(%rdi),%r11d
-#movdqa	K256+512+32(%rip),%xmm8
-#movdqa	K256+512+64(%rip),%xmm9
+
+
 	jmp	L$loop_ssse3
 .p2align	4
 L$loop_ssse3:
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S
index 5d35ee04..2733c07 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S
@@ -13,21 +13,21 @@
 #endif
 .text	
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-##
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_encrypt_core:
@@ -115,11 +115,11 @@
 
 
 
-##
-#
-##
-#
-##
+
+
+
+
+
 
 .p2align	4
 _vpaes_decrypt_core:
@@ -149,9 +149,9 @@
 
 .p2align	4
 L$dec_loop:
-##
-#
-##
+
+
+
 	movdqa	-32(%r10),%xmm4
 	movdqa	-16(%r10),%xmm1
 .byte	102,15,56,0,226
@@ -223,11 +223,11 @@
 
 
 
-########################################################
-#
-#
-#
-########################################################
+
+
+
+
+
 
 .p2align	4
 _vpaes_schedule_core:
@@ -268,14 +268,14 @@
 	je	L$schedule_192
 
 
-##
-#
-##
-#
-##
-#
-#
-##
+
+
+
+
+
+
+
+
 L$schedule_128:
 	movl	$10,%esi
 
@@ -286,21 +286,21 @@
 	call	_vpaes_schedule_mangle
 	jmp	L$oop_schedule_128
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 .p2align	4
 L$schedule_192:
 	movdqu	8(%rdi),%xmm0
@@ -323,16 +323,16 @@
 	call	_vpaes_schedule_192_smear
 	jmp	L$oop_schedule_192
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
 .p2align	4
 L$schedule_256:
 	movdqu	16(%rdi),%xmm0
@@ -359,16 +359,16 @@
 	jmp	L$oop_schedule_256
 
 
-##
-#
-##
-#
-#
-#
-#
-##
-#
-##
+
+
+
+
+
+
+
+
+
+
 .p2align	4
 L$schedule_mangle_last:
 
@@ -401,20 +401,20 @@
 
 
 
-##
-#
-##
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_schedule_192_smear:
@@ -430,24 +430,24 @@
 
 
 
-##
-#
-##
-#
-##
-#
-#
-#
-##
-#
-#
-##
-#
-#
-##
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_schedule_round:
@@ -508,15 +508,15 @@
 
 
 
-##
-#
-##
-#
-##
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_schedule_transform:
@@ -534,29 +534,29 @@
 
 
 
-##
-#
-##
-#
-#
-##
-#
-#
-#
-#
-##
-#
-#
-#
-#
-#
-##
-##
-#
-#
-#
-#
-##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_schedule_mangle:
@@ -628,9 +628,9 @@
 
 
 
-#
 
-#
+
+
 .globl	_vpaes_set_encrypt_key
 .private_extern _vpaes_set_encrypt_key
 
@@ -744,12 +744,12 @@
 	.byte	0xf3,0xc3
 
 
-##
-#
-##
-#
-#
-##
+
+
+
+
+
+
 
 .p2align	4
 _vpaes_preheat:
@@ -765,11 +765,11 @@
 	.byte	0xf3,0xc3
 
 
-########################################################
-#
-#
-#
-########################################################
+
+
+
+
+
 
 .p2align	6
 _vpaes_consts:
@@ -826,10 +826,10 @@
 .quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
 .quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
 
-##
-#
-#
-##
+
+
+
+
 L$k_dksd:
 .quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
 .quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
@@ -843,10 +843,10 @@
 .quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
 .quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
 
-##
-#
-#
-##
+
+
+
+
 L$k_dipt:
 .quad	0x0F505B040B545F00, 0x154A411E114E451A
 .quad	0x86E383E660056500, 0x12771772F491F194
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
index a7b8d9ee..8d6444c 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
@@ -58,7 +58,7 @@
 	andq	$-1024,%r10
 
 
-#
+
 
 
 
@@ -733,11 +733,11 @@
 	shlq	$3+2,%r10
 	negq	%r9
 
-##############################################################
 
 
 
-#
+
+
 	leaq	-64(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	movq	(%r8),%r8
@@ -940,7 +940,6 @@
 L$mulx4x_page_walk_done:
 
 	leaq	(%rdx,%r9,1),%r10
-##############################################################
 
 
 
@@ -951,7 +950,8 @@
 
 
 
-#
+
+
 	movq	%r9,0(%rsp)
 	shrq	$5,%r9
 	movq	%r10,16(%rsp)
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
index af2c250a..4bd36fe 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
@@ -53,7 +53,7 @@
 	andq	$-1024,%r10
 
 
-#
+
 
 
 
@@ -486,7 +486,6 @@
 	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
-##############################################################
 
 
 
@@ -494,7 +493,8 @@
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -565,6 +565,7 @@
 
 .p2align	5
 mul4x_internal:
+
 	shlq	$5,%r9
 	movd	8(%rax),%xmm5
 	leaq	L$inc(%rip),%rax
@@ -1087,6 +1088,7 @@
 	movq	24(%rbp),%r15
 	jmp	L$sqr4x_sub_entry
 
+
 .globl	_bn_power5
 .private_extern _bn_power5
 
@@ -1119,13 +1121,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -1165,15 +1167,15 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
 
 
-#
+
+
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 
@@ -1231,14 +1233,15 @@
 .p2align	5
 _bn_sqr8x_internal:
 __bn_sqr8x_internal:
-##############################################################
-
-#
 
 
 
-#
-##############################################################
+
+
+
+
+
+
 
 
 
@@ -2007,8 +2010,10 @@
 	.byte	0xf3,0xc3
 
 
+
 .p2align	5
 __bn_post4x_internal:
+
 	movq	0(%rbp),%r12
 	leaq	(%rdi,%r9,1),%rbx
 	movq	%r9,%rcx
@@ -2060,11 +2065,13 @@
 	negq	%r9
 	.byte	0xf3,0xc3
 
+
 .globl	_bn_from_montgomery
 .private_extern _bn_from_montgomery
 
 .p2align	5
 _bn_from_montgomery:
+
 	testl	$7,%r9d
 	jz	bn_from_mont8x
 	xorl	%eax,%eax
@@ -2072,6 +2079,7 @@
 
 
 
+
 .p2align	5
 bn_from_mont8x:
 
@@ -2097,13 +2105,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2143,15 +2151,15 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
 
 
-#
+
+
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 
@@ -2265,7 +2273,6 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
@@ -2273,7 +2280,8 @@
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2309,7 +2317,6 @@
 	ja	L$mulx4x_page_walk
 L$mulx4x_page_walk_done:
 
-##############################################################
 
 
 
@@ -2320,7 +2327,8 @@
 
 
 
-#
+
+
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 
@@ -2353,6 +2361,7 @@
 
 .p2align	5
 mulx4x_internal:
+
 	movq	%r9,8(%rsp)
 	movq	%r9,%r10
 	negq	%r9
@@ -2773,6 +2782,7 @@
 	jmp	L$sqrx4x_sub_entry
 
 
+
 .p2align	5
 bn_powerx5:
 
@@ -2798,13 +2808,13 @@
 	negq	%r9
 	movq	(%r8),%r8
 
-##############################################################
 
 
 
 
 
-#
+
+
 	leaq	-320(%rsp,%r9,2),%r11
 	movq	%rsp,%rbp
 	subq	%rdi,%r11
@@ -2844,9 +2854,6 @@
 	movq	%r9,%r10
 	negq	%r9
 
-##############################################################
-
-#
 
 
 
@@ -2854,7 +2861,10 @@
 
 
 
-#
+
+
+
+
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,72,15,110,209
@@ -2915,22 +2925,6 @@
 _bn_sqrx8x_internal:
 __bn_sqrx8x_internal:
 
-##################################################################
-
-#
-
-
-
-#
-##################################################################
-
-
-
-
-
-
-
-#
 
 
 
@@ -2947,7 +2941,23 @@
 
 
 
-#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -2979,7 +2989,7 @@
 	jnz	L$sqrx8x_zero
 
 	movq	0(%rsi),%rdx
-#xor	%r9,%r9
+
 	xorq	%r10,%r10
 	xorq	%r11,%r11
 	xorq	%r12,%r12
@@ -3096,7 +3106,7 @@
 	movq	%r14,%rdx
 	adoxq	%rbx,%r11
 	adcxq	%r12,%r11
-#adox	%rbp,%rax
+
 	adcxq	%rbp,%rax
 
 	mulxq	%r15,%r14,%rbx
@@ -3135,7 +3145,7 @@
 	movq	%rax,16+8(%rsp)
 	movq	%rdi,24+8(%rsp)
 
-#lea	8*8(%rdi),%rdi
+
 	xorl	%eax,%eax
 	jmp	L$sqrx8x_loop
 
@@ -3258,7 +3268,7 @@
 	adoxq	%r11,%r11
 	movq	16(%rdi),%r12
 	movq	24(%rdi),%r13
-#jmp	.Lsqrx4x_shift_n_add
+
 
 .p2align	5
 L$sqrx4x_shift_n_add:
@@ -3323,7 +3333,7 @@
 	movq	32+8(%rsp),%rbx
 	movq	48+8(%rsp),%rdx
 	leaq	-64(%rbp,%r9,1),%rcx
-#lea	48+8(%rsp,%r9,2),%rdi
+
 	movq	%rcx,0+8(%rsp)
 	movq	%rdi,8+8(%rsp)
 
@@ -3529,13 +3539,15 @@
 
 
 .p2align	5
+
 __bn_postx4x_internal:
+
 	movq	0(%rbp),%r12
 	movq	%rcx,%r10
 	movq	%rcx,%r9
 	negq	%rax
 	sarq	$3+2,%rcx
-#lea	48+8(%rsp,%r9),%rdi
+
 .byte	102,72,15,126,202
 .byte	102,72,15,126,206
 	decq	%r12
@@ -3578,11 +3590,13 @@
 
 	.byte	0xf3,0xc3
 
+
 .globl	_bn_scatter5
 .private_extern _bn_scatter5
 
 .p2align	4
 _bn_scatter5:
+
 	cmpl	$0,%esi
 	jz	L$scatter_epilogue
 	leaq	(%rdx,%rcx,8),%rdx
@@ -3597,15 +3611,18 @@
 	.byte	0xf3,0xc3
 
 
+
 .globl	_bn_gather5
 .private_extern _bn_gather5
 
 .p2align	5
 _bn_gather5:
+
 L$SEH_begin_bn_gather5:
 
-.byte	0x4c,0x8d,0x14,0x24			#lea    (%rsp),%r10
-.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00	#sub	src/crypto/fipsmodule/bn/asm/x86_64-mont5.plx108,%rsp
+.byte	0x4c,0x8d,0x14,0x24
+
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
 	leaq	L$inc(%rip),%rax
 	andq	$-16,%rsp
 
@@ -3758,9 +3775,11 @@
 	jnz	L$gather
 
 	leaq	(%r10),%rsp
+
 	.byte	0xf3,0xc3
 L$SEH_end_bn_gather5:
 
+
 .p2align	6
 L$inc:
 .long	0,0, 1,1
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
index bffc13ed..874596d7 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
@@ -904,226 +904,6 @@
 	DB	0F3h,0C3h		;repret
 
 $L$SEH_end_aes_hw_ecb_encrypt:
-global	aes_hw_ccm64_encrypt_blocks
-
-ALIGN	16
-aes_hw_ccm64_encrypt_blocks:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_ccm64_encrypt_blocks:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-	lea	rsp,[((-88))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	movaps	XMMWORD[32+rsp],xmm8
-	movaps	XMMWORD[48+rsp],xmm9
-$L$ccm64_enc_body:
-	mov	eax,DWORD[240+rcx]
-	movdqu	xmm6,XMMWORD[r8]
-	movdqa	xmm9,XMMWORD[$L$increment64]
-	movdqa	xmm7,XMMWORD[$L$bswap_mask]
-
-	shl	eax,4
-	mov	r10d,16
-	lea	r11,[rcx]
-	movdqu	xmm3,XMMWORD[r9]
-	movdqa	xmm2,xmm6
-	lea	rcx,[32+rax*1+rcx]
-DB	102,15,56,0,247
-	sub	r10,rax
-	jmp	NEAR $L$ccm64_enc_outer
-ALIGN	16
-$L$ccm64_enc_outer:
-	movups	xmm0,XMMWORD[r11]
-	mov	rax,r10
-	movups	xmm8,XMMWORD[rdi]
-
-	xorps	xmm2,xmm0
-	movups	xmm1,XMMWORD[16+r11]
-	xorps	xmm0,xmm8
-	xorps	xmm3,xmm0
-	movups	xmm0,XMMWORD[32+r11]
-
-$L$ccm64_enc2_loop:
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ccm64_enc2_loop
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-	paddq	xmm6,xmm9
-	dec	rdx
-DB	102,15,56,221,208
-DB	102,15,56,221,216
-
-	lea	rdi,[16+rdi]
-	xorps	xmm8,xmm2
-	movdqa	xmm2,xmm6
-	movups	XMMWORD[rsi],xmm8
-DB	102,15,56,0,215
-	lea	rsi,[16+rsi]
-	jnz	NEAR $L$ccm64_enc_outer
-
-	pxor	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	movups	XMMWORD[r9],xmm3
-	pxor	xmm3,xmm3
-	pxor	xmm8,xmm8
-	pxor	xmm6,xmm6
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	XMMWORD[rsp],xmm0
-	movaps	xmm7,XMMWORD[16+rsp]
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	xmm8,XMMWORD[32+rsp]
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	xmm9,XMMWORD[48+rsp]
-	movaps	XMMWORD[48+rsp],xmm0
-	lea	rsp,[88+rsp]
-$L$ccm64_enc_ret:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_aes_hw_ccm64_encrypt_blocks:
-global	aes_hw_ccm64_decrypt_blocks
-
-ALIGN	16
-aes_hw_ccm64_decrypt_blocks:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_ccm64_decrypt_blocks:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-	lea	rsp,[((-88))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	movaps	XMMWORD[32+rsp],xmm8
-	movaps	XMMWORD[48+rsp],xmm9
-$L$ccm64_dec_body:
-	mov	eax,DWORD[240+rcx]
-	movups	xmm6,XMMWORD[r8]
-	movdqu	xmm3,XMMWORD[r9]
-	movdqa	xmm9,XMMWORD[$L$increment64]
-	movdqa	xmm7,XMMWORD[$L$bswap_mask]
-
-	movaps	xmm2,xmm6
-	mov	r10d,eax
-	mov	r11,rcx
-DB	102,15,56,0,247
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_enc1_5:
-DB	102,15,56,220,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_enc1_5
-DB	102,15,56,221,209
-	shl	r10d,4
-	mov	eax,16
-	movups	xmm8,XMMWORD[rdi]
-	paddq	xmm6,xmm9
-	lea	rdi,[16+rdi]
-	sub	rax,r10
-	lea	rcx,[32+r10*1+r11]
-	mov	r10,rax
-	jmp	NEAR $L$ccm64_dec_outer
-ALIGN	16
-$L$ccm64_dec_outer:
-	xorps	xmm8,xmm2
-	movdqa	xmm2,xmm6
-	movups	XMMWORD[rsi],xmm8
-	lea	rsi,[16+rsi]
-DB	102,15,56,0,215
-
-	sub	rdx,1
-	jz	NEAR $L$ccm64_dec_break
-
-	movups	xmm0,XMMWORD[r11]
-	mov	rax,r10
-	movups	xmm1,XMMWORD[16+r11]
-	xorps	xmm8,xmm0
-	xorps	xmm2,xmm0
-	xorps	xmm3,xmm8
-	movups	xmm0,XMMWORD[32+r11]
-	jmp	NEAR $L$ccm64_dec2_loop
-ALIGN	16
-$L$ccm64_dec2_loop:
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ccm64_dec2_loop
-	movups	xmm8,XMMWORD[rdi]
-	paddq	xmm6,xmm9
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,221,208
-DB	102,15,56,221,216
-	lea	rdi,[16+rdi]
-	jmp	NEAR $L$ccm64_dec_outer
-
-ALIGN	16
-$L$ccm64_dec_break:
-
-	mov	eax,DWORD[240+r11]
-	movups	xmm0,XMMWORD[r11]
-	movups	xmm1,XMMWORD[16+r11]
-	xorps	xmm8,xmm0
-	lea	r11,[32+r11]
-	xorps	xmm3,xmm8
-$L$oop_enc1_6:
-DB	102,15,56,220,217
-	dec	eax
-	movups	xmm1,XMMWORD[r11]
-	lea	r11,[16+r11]
-	jnz	NEAR $L$oop_enc1_6
-DB	102,15,56,221,217
-	pxor	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	movups	XMMWORD[r9],xmm3
-	pxor	xmm3,xmm3
-	pxor	xmm8,xmm8
-	pxor	xmm6,xmm6
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	XMMWORD[rsp],xmm0
-	movaps	xmm7,XMMWORD[16+rsp]
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	xmm8,XMMWORD[32+rsp]
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	xmm9,XMMWORD[48+rsp]
-	movaps	XMMWORD[48+rsp],xmm0
-	lea	rsp,[88+rsp]
-$L$ccm64_dec_ret:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_aes_hw_ccm64_decrypt_blocks:
 global	aes_hw_ctr32_encrypt_blocks
 
 ALIGN	16
@@ -1157,12 +937,12 @@
 	movups	xmm1,XMMWORD[16+rcx]
 	lea	rcx,[32+rcx]
 	xorps	xmm2,xmm0
-$L$oop_enc1_7:
+$L$oop_enc1_5:
 DB	102,15,56,220,209
 	dec	edx
 	movups	xmm1,XMMWORD[rcx]
 	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_enc1_7
+	jnz	NEAR $L$oop_enc1_5
 DB	102,15,56,221,209
 	pxor	xmm0,xmm0
 	pxor	xmm1,xmm1
@@ -1742,1967 +1522,6 @@
 	DB	0F3h,0C3h		;repret
 
 $L$SEH_end_aes_hw_ctr32_encrypt_blocks:
-global	aes_hw_xts_encrypt
-
-ALIGN	16
-aes_hw_xts_encrypt:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_xts_encrypt:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-
-	lea	r11,[rsp]
-
-	push	rbp
-
-	sub	rsp,272
-	and	rsp,-16
-	movaps	XMMWORD[(-168)+r11],xmm6
-	movaps	XMMWORD[(-152)+r11],xmm7
-	movaps	XMMWORD[(-136)+r11],xmm8
-	movaps	XMMWORD[(-120)+r11],xmm9
-	movaps	XMMWORD[(-104)+r11],xmm10
-	movaps	XMMWORD[(-88)+r11],xmm11
-	movaps	XMMWORD[(-72)+r11],xmm12
-	movaps	XMMWORD[(-56)+r11],xmm13
-	movaps	XMMWORD[(-40)+r11],xmm14
-	movaps	XMMWORD[(-24)+r11],xmm15
-$L$xts_enc_body:
-	movups	xmm2,XMMWORD[r9]
-	mov	eax,DWORD[240+r8]
-	mov	r10d,DWORD[240+rcx]
-	movups	xmm0,XMMWORD[r8]
-	movups	xmm1,XMMWORD[16+r8]
-	lea	r8,[32+r8]
-	xorps	xmm2,xmm0
-$L$oop_enc1_8:
-DB	102,15,56,220,209
-	dec	eax
-	movups	xmm1,XMMWORD[r8]
-	lea	r8,[16+r8]
-	jnz	NEAR $L$oop_enc1_8
-DB	102,15,56,221,209
-	movups	xmm0,XMMWORD[rcx]
-	mov	rbp,rcx
-	mov	eax,r10d
-	shl	r10d,4
-	mov	r9,rdx
-	and	rdx,-16
-
-	movups	xmm1,XMMWORD[16+r10*1+rcx]
-
-	movdqa	xmm8,XMMWORD[$L$xts_magic]
-	movdqa	xmm15,xmm2
-	pshufd	xmm9,xmm2,0x5f
-	pxor	xmm1,xmm0
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm10,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm10,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm11,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm11,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm12,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm12,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm13,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm13,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm15
-	psrad	xmm9,31
-	paddq	xmm15,xmm15
-	pand	xmm9,xmm8
-	pxor	xmm14,xmm0
-	pxor	xmm15,xmm9
-	movaps	XMMWORD[96+rsp],xmm1
-
-	sub	rdx,16*6
-	jc	NEAR $L$xts_enc_short
-
-	mov	eax,16+96
-	lea	rcx,[32+r10*1+rbp]
-	sub	rax,r10
-	movups	xmm1,XMMWORD[16+rbp]
-	mov	r10,rax
-	lea	r8,[$L$xts_magic]
-	jmp	NEAR $L$xts_enc_grandloop
-
-ALIGN	32
-$L$xts_enc_grandloop:
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqa	xmm8,xmm0
-	movdqu	xmm3,XMMWORD[16+rdi]
-	pxor	xmm2,xmm10
-	movdqu	xmm4,XMMWORD[32+rdi]
-	pxor	xmm3,xmm11
-DB	102,15,56,220,209
-	movdqu	xmm5,XMMWORD[48+rdi]
-	pxor	xmm4,xmm12
-DB	102,15,56,220,217
-	movdqu	xmm6,XMMWORD[64+rdi]
-	pxor	xmm5,xmm13
-DB	102,15,56,220,225
-	movdqu	xmm7,XMMWORD[80+rdi]
-	pxor	xmm8,xmm15
-	movdqa	xmm9,XMMWORD[96+rsp]
-	pxor	xmm6,xmm14
-DB	102,15,56,220,233
-	movups	xmm0,XMMWORD[32+rbp]
-	lea	rdi,[96+rdi]
-	pxor	xmm7,xmm8
-
-	pxor	xmm10,xmm9
-DB	102,15,56,220,241
-	pxor	xmm11,xmm9
-	movdqa	XMMWORD[rsp],xmm10
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[48+rbp]
-	pxor	xmm12,xmm9
-
-DB	102,15,56,220,208
-	pxor	xmm13,xmm9
-	movdqa	XMMWORD[16+rsp],xmm11
-DB	102,15,56,220,216
-	pxor	xmm14,xmm9
-	movdqa	XMMWORD[32+rsp],xmm12
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-	pxor	xmm8,xmm9
-	movdqa	XMMWORD[64+rsp],xmm14
-DB	102,15,56,220,240
-DB	102,15,56,220,248
-	movups	xmm0,XMMWORD[64+rbp]
-	movdqa	XMMWORD[80+rsp],xmm8
-	pshufd	xmm9,xmm15,0x5f
-	jmp	NEAR $L$xts_enc_loop6
-ALIGN	32
-$L$xts_enc_loop6:
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-DB	102,15,56,220,241
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[((-64))+rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-DB	102,15,56,220,240
-DB	102,15,56,220,248
-	movups	xmm0,XMMWORD[((-80))+rax*1+rcx]
-	jnz	NEAR $L$xts_enc_loop6
-
-	movdqa	xmm8,XMMWORD[r8]
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-DB	102,15,56,220,209
-	paddq	xmm15,xmm15
-	psrad	xmm14,31
-DB	102,15,56,220,217
-	pand	xmm14,xmm8
-	movups	xmm10,XMMWORD[rbp]
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-DB	102,15,56,220,241
-	pxor	xmm15,xmm14
-	movaps	xmm11,xmm10
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[((-64))+rcx]
-
-	movdqa	xmm14,xmm9
-DB	102,15,56,220,208
-	paddd	xmm9,xmm9
-	pxor	xmm10,xmm15
-DB	102,15,56,220,216
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-	pand	xmm14,xmm8
-	movaps	xmm12,xmm11
-DB	102,15,56,220,240
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-DB	102,15,56,220,248
-	movups	xmm0,XMMWORD[((-48))+rcx]
-
-	paddd	xmm9,xmm9
-DB	102,15,56,220,209
-	pxor	xmm11,xmm15
-	psrad	xmm14,31
-DB	102,15,56,220,217
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	movdqa	XMMWORD[48+rsp],xmm13
-	pxor	xmm15,xmm14
-DB	102,15,56,220,241
-	movaps	xmm13,xmm12
-	movdqa	xmm14,xmm9
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[((-32))+rcx]
-
-	paddd	xmm9,xmm9
-DB	102,15,56,220,208
-	pxor	xmm12,xmm15
-	psrad	xmm14,31
-DB	102,15,56,220,216
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-DB	102,15,56,220,240
-	pxor	xmm15,xmm14
-	movaps	xmm14,xmm13
-DB	102,15,56,220,248
-
-	movdqa	xmm0,xmm9
-	paddd	xmm9,xmm9
-DB	102,15,56,220,209
-	pxor	xmm13,xmm15
-	psrad	xmm0,31
-DB	102,15,56,220,217
-	paddq	xmm15,xmm15
-	pand	xmm0,xmm8
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	pxor	xmm15,xmm0
-	movups	xmm0,XMMWORD[rbp]
-DB	102,15,56,220,241
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[16+rbp]
-
-	pxor	xmm14,xmm15
-DB	102,15,56,221,84,36,0
-	psrad	xmm9,31
-	paddq	xmm15,xmm15
-DB	102,15,56,221,92,36,16
-DB	102,15,56,221,100,36,32
-	pand	xmm9,xmm8
-	mov	rax,r10
-DB	102,15,56,221,108,36,48
-DB	102,15,56,221,116,36,64
-DB	102,15,56,221,124,36,80
-	pxor	xmm15,xmm9
-
-	lea	rsi,[96+rsi]
-	movups	XMMWORD[(-96)+rsi],xmm2
-	movups	XMMWORD[(-80)+rsi],xmm3
-	movups	XMMWORD[(-64)+rsi],xmm4
-	movups	XMMWORD[(-48)+rsi],xmm5
-	movups	XMMWORD[(-32)+rsi],xmm6
-	movups	XMMWORD[(-16)+rsi],xmm7
-	sub	rdx,16*6
-	jnc	NEAR $L$xts_enc_grandloop
-
-	mov	eax,16+96
-	sub	eax,r10d
-	mov	rcx,rbp
-	shr	eax,4
-
-$L$xts_enc_short:
-
-	mov	r10d,eax
-	pxor	xmm10,xmm0
-	add	rdx,16*6
-	jz	NEAR $L$xts_enc_done
-
-	pxor	xmm11,xmm0
-	cmp	rdx,0x20
-	jb	NEAR $L$xts_enc_one
-	pxor	xmm12,xmm0
-	je	NEAR $L$xts_enc_two
-
-	pxor	xmm13,xmm0
-	cmp	rdx,0x40
-	jb	NEAR $L$xts_enc_three
-	pxor	xmm14,xmm0
-	je	NEAR $L$xts_enc_four
-
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqu	xmm3,XMMWORD[16+rdi]
-	movdqu	xmm4,XMMWORD[32+rdi]
-	pxor	xmm2,xmm10
-	movdqu	xmm5,XMMWORD[48+rdi]
-	pxor	xmm3,xmm11
-	movdqu	xmm6,XMMWORD[64+rdi]
-	lea	rdi,[80+rdi]
-	pxor	xmm4,xmm12
-	pxor	xmm5,xmm13
-	pxor	xmm6,xmm14
-	pxor	xmm7,xmm7
-
-	call	_aesni_encrypt6
-
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm15
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-	movdqu	XMMWORD[rsi],xmm2
-	xorps	xmm5,xmm13
-	movdqu	XMMWORD[16+rsi],xmm3
-	xorps	xmm6,xmm14
-	movdqu	XMMWORD[32+rsi],xmm4
-	movdqu	XMMWORD[48+rsi],xmm5
-	movdqu	XMMWORD[64+rsi],xmm6
-	lea	rsi,[80+rsi]
-	jmp	NEAR $L$xts_enc_done
-
-ALIGN	16
-$L$xts_enc_one:
-	movups	xmm2,XMMWORD[rdi]
-	lea	rdi,[16+rdi]
-	xorps	xmm2,xmm10
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_enc1_9:
-DB	102,15,56,220,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_enc1_9
-DB	102,15,56,221,209
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm11
-	movups	XMMWORD[rsi],xmm2
-	lea	rsi,[16+rsi]
-	jmp	NEAR $L$xts_enc_done
-
-ALIGN	16
-$L$xts_enc_two:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	lea	rdi,[32+rdi]
-	xorps	xmm2,xmm10
-	xorps	xmm3,xmm11
-
-	call	_aesni_encrypt2
-
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm12
-	xorps	xmm3,xmm11
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	lea	rsi,[32+rsi]
-	jmp	NEAR $L$xts_enc_done
-
-ALIGN	16
-$L$xts_enc_three:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	movups	xmm4,XMMWORD[32+rdi]
-	lea	rdi,[48+rdi]
-	xorps	xmm2,xmm10
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-
-	call	_aesni_encrypt3
-
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm13
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	lea	rsi,[48+rsi]
-	jmp	NEAR $L$xts_enc_done
-
-ALIGN	16
-$L$xts_enc_four:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	movups	xmm4,XMMWORD[32+rdi]
-	xorps	xmm2,xmm10
-	movups	xmm5,XMMWORD[48+rdi]
-	lea	rdi,[64+rdi]
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-	xorps	xmm5,xmm13
-
-	call	_aesni_encrypt4
-
-	pxor	xmm2,xmm10
-	movdqa	xmm10,xmm14
-	pxor	xmm3,xmm11
-	pxor	xmm4,xmm12
-	movdqu	XMMWORD[rsi],xmm2
-	pxor	xmm5,xmm13
-	movdqu	XMMWORD[16+rsi],xmm3
-	movdqu	XMMWORD[32+rsi],xmm4
-	movdqu	XMMWORD[48+rsi],xmm5
-	lea	rsi,[64+rsi]
-	jmp	NEAR $L$xts_enc_done
-
-ALIGN	16
-$L$xts_enc_done:
-	and	r9,15
-	jz	NEAR $L$xts_enc_ret
-	mov	rdx,r9
-
-$L$xts_enc_steal:
-	movzx	eax,BYTE[rdi]
-	movzx	ecx,BYTE[((-16))+rsi]
-	lea	rdi,[1+rdi]
-	mov	BYTE[((-16))+rsi],al
-	mov	BYTE[rsi],cl
-	lea	rsi,[1+rsi]
-	sub	rdx,1
-	jnz	NEAR $L$xts_enc_steal
-
-	sub	rsi,r9
-	mov	rcx,rbp
-	mov	eax,r10d
-
-	movups	xmm2,XMMWORD[((-16))+rsi]
-	xorps	xmm2,xmm10
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_enc1_10:
-DB	102,15,56,220,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_enc1_10
-DB	102,15,56,221,209
-	xorps	xmm2,xmm10
-	movups	XMMWORD[(-16)+rsi],xmm2
-
-$L$xts_enc_ret:
-	xorps	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	movaps	xmm6,XMMWORD[((-168))+r11]
-	movaps	XMMWORD[(-168)+r11],xmm0
-	movaps	xmm7,XMMWORD[((-152))+r11]
-	movaps	XMMWORD[(-152)+r11],xmm0
-	movaps	xmm8,XMMWORD[((-136))+r11]
-	movaps	XMMWORD[(-136)+r11],xmm0
-	movaps	xmm9,XMMWORD[((-120))+r11]
-	movaps	XMMWORD[(-120)+r11],xmm0
-	movaps	xmm10,XMMWORD[((-104))+r11]
-	movaps	XMMWORD[(-104)+r11],xmm0
-	movaps	xmm11,XMMWORD[((-88))+r11]
-	movaps	XMMWORD[(-88)+r11],xmm0
-	movaps	xmm12,XMMWORD[((-72))+r11]
-	movaps	XMMWORD[(-72)+r11],xmm0
-	movaps	xmm13,XMMWORD[((-56))+r11]
-	movaps	XMMWORD[(-56)+r11],xmm0
-	movaps	xmm14,XMMWORD[((-40))+r11]
-	movaps	XMMWORD[(-40)+r11],xmm0
-	movaps	xmm15,XMMWORD[((-24))+r11]
-	movaps	XMMWORD[(-24)+r11],xmm0
-	movaps	XMMWORD[rsp],xmm0
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	XMMWORD[48+rsp],xmm0
-	movaps	XMMWORD[64+rsp],xmm0
-	movaps	XMMWORD[80+rsp],xmm0
-	movaps	XMMWORD[96+rsp],xmm0
-	mov	rbp,QWORD[((-8))+r11]
-
-	lea	rsp,[r11]
-
-$L$xts_enc_epilogue:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-
-$L$SEH_end_aes_hw_xts_encrypt:
-global	aes_hw_xts_decrypt
-
-ALIGN	16
-aes_hw_xts_decrypt:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_xts_decrypt:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-
-	lea	r11,[rsp]
-
-	push	rbp
-
-	sub	rsp,272
-	and	rsp,-16
-	movaps	XMMWORD[(-168)+r11],xmm6
-	movaps	XMMWORD[(-152)+r11],xmm7
-	movaps	XMMWORD[(-136)+r11],xmm8
-	movaps	XMMWORD[(-120)+r11],xmm9
-	movaps	XMMWORD[(-104)+r11],xmm10
-	movaps	XMMWORD[(-88)+r11],xmm11
-	movaps	XMMWORD[(-72)+r11],xmm12
-	movaps	XMMWORD[(-56)+r11],xmm13
-	movaps	XMMWORD[(-40)+r11],xmm14
-	movaps	XMMWORD[(-24)+r11],xmm15
-$L$xts_dec_body:
-	movups	xmm2,XMMWORD[r9]
-	mov	eax,DWORD[240+r8]
-	mov	r10d,DWORD[240+rcx]
-	movups	xmm0,XMMWORD[r8]
-	movups	xmm1,XMMWORD[16+r8]
-	lea	r8,[32+r8]
-	xorps	xmm2,xmm0
-$L$oop_enc1_11:
-DB	102,15,56,220,209
-	dec	eax
-	movups	xmm1,XMMWORD[r8]
-	lea	r8,[16+r8]
-	jnz	NEAR $L$oop_enc1_11
-DB	102,15,56,221,209
-	xor	eax,eax
-	test	rdx,15
-	setnz	al
-	shl	rax,4
-	sub	rdx,rax
-
-	movups	xmm0,XMMWORD[rcx]
-	mov	rbp,rcx
-	mov	eax,r10d
-	shl	r10d,4
-	mov	r9,rdx
-	and	rdx,-16
-
-	movups	xmm1,XMMWORD[16+r10*1+rcx]
-
-	movdqa	xmm8,XMMWORD[$L$xts_magic]
-	movdqa	xmm15,xmm2
-	pshufd	xmm9,xmm2,0x5f
-	pxor	xmm1,xmm0
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm10,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm10,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm11,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm11,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm12,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm12,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-	movdqa	xmm13,xmm15
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-	pxor	xmm13,xmm0
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm15
-	psrad	xmm9,31
-	paddq	xmm15,xmm15
-	pand	xmm9,xmm8
-	pxor	xmm14,xmm0
-	pxor	xmm15,xmm9
-	movaps	XMMWORD[96+rsp],xmm1
-
-	sub	rdx,16*6
-	jc	NEAR $L$xts_dec_short
-
-	mov	eax,16+96
-	lea	rcx,[32+r10*1+rbp]
-	sub	rax,r10
-	movups	xmm1,XMMWORD[16+rbp]
-	mov	r10,rax
-	lea	r8,[$L$xts_magic]
-	jmp	NEAR $L$xts_dec_grandloop
-
-ALIGN	32
-$L$xts_dec_grandloop:
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqa	xmm8,xmm0
-	movdqu	xmm3,XMMWORD[16+rdi]
-	pxor	xmm2,xmm10
-	movdqu	xmm4,XMMWORD[32+rdi]
-	pxor	xmm3,xmm11
-DB	102,15,56,222,209
-	movdqu	xmm5,XMMWORD[48+rdi]
-	pxor	xmm4,xmm12
-DB	102,15,56,222,217
-	movdqu	xmm6,XMMWORD[64+rdi]
-	pxor	xmm5,xmm13
-DB	102,15,56,222,225
-	movdqu	xmm7,XMMWORD[80+rdi]
-	pxor	xmm8,xmm15
-	movdqa	xmm9,XMMWORD[96+rsp]
-	pxor	xmm6,xmm14
-DB	102,15,56,222,233
-	movups	xmm0,XMMWORD[32+rbp]
-	lea	rdi,[96+rdi]
-	pxor	xmm7,xmm8
-
-	pxor	xmm10,xmm9
-DB	102,15,56,222,241
-	pxor	xmm11,xmm9
-	movdqa	XMMWORD[rsp],xmm10
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[48+rbp]
-	pxor	xmm12,xmm9
-
-DB	102,15,56,222,208
-	pxor	xmm13,xmm9
-	movdqa	XMMWORD[16+rsp],xmm11
-DB	102,15,56,222,216
-	pxor	xmm14,xmm9
-	movdqa	XMMWORD[32+rsp],xmm12
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-	pxor	xmm8,xmm9
-	movdqa	XMMWORD[64+rsp],xmm14
-DB	102,15,56,222,240
-DB	102,15,56,222,248
-	movups	xmm0,XMMWORD[64+rbp]
-	movdqa	XMMWORD[80+rsp],xmm8
-	pshufd	xmm9,xmm15,0x5f
-	jmp	NEAR $L$xts_dec_loop6
-ALIGN	32
-$L$xts_dec_loop6:
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-DB	102,15,56,222,241
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[((-64))+rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,222,208
-DB	102,15,56,222,216
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-DB	102,15,56,222,240
-DB	102,15,56,222,248
-	movups	xmm0,XMMWORD[((-80))+rax*1+rcx]
-	jnz	NEAR $L$xts_dec_loop6
-
-	movdqa	xmm8,XMMWORD[r8]
-	movdqa	xmm14,xmm9
-	paddd	xmm9,xmm9
-DB	102,15,56,222,209
-	paddq	xmm15,xmm15
-	psrad	xmm14,31
-DB	102,15,56,222,217
-	pand	xmm14,xmm8
-	movups	xmm10,XMMWORD[rbp]
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-DB	102,15,56,222,241
-	pxor	xmm15,xmm14
-	movaps	xmm11,xmm10
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[((-64))+rcx]
-
-	movdqa	xmm14,xmm9
-DB	102,15,56,222,208
-	paddd	xmm9,xmm9
-	pxor	xmm10,xmm15
-DB	102,15,56,222,216
-	psrad	xmm14,31
-	paddq	xmm15,xmm15
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-	pand	xmm14,xmm8
-	movaps	xmm12,xmm11
-DB	102,15,56,222,240
-	pxor	xmm15,xmm14
-	movdqa	xmm14,xmm9
-DB	102,15,56,222,248
-	movups	xmm0,XMMWORD[((-48))+rcx]
-
-	paddd	xmm9,xmm9
-DB	102,15,56,222,209
-	pxor	xmm11,xmm15
-	psrad	xmm14,31
-DB	102,15,56,222,217
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	movdqa	XMMWORD[48+rsp],xmm13
-	pxor	xmm15,xmm14
-DB	102,15,56,222,241
-	movaps	xmm13,xmm12
-	movdqa	xmm14,xmm9
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[((-32))+rcx]
-
-	paddd	xmm9,xmm9
-DB	102,15,56,222,208
-	pxor	xmm12,xmm15
-	psrad	xmm14,31
-DB	102,15,56,222,216
-	paddq	xmm15,xmm15
-	pand	xmm14,xmm8
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-DB	102,15,56,222,240
-	pxor	xmm15,xmm14
-	movaps	xmm14,xmm13
-DB	102,15,56,222,248
-
-	movdqa	xmm0,xmm9
-	paddd	xmm9,xmm9
-DB	102,15,56,222,209
-	pxor	xmm13,xmm15
-	psrad	xmm0,31
-DB	102,15,56,222,217
-	paddq	xmm15,xmm15
-	pand	xmm0,xmm8
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	pxor	xmm15,xmm0
-	movups	xmm0,XMMWORD[rbp]
-DB	102,15,56,222,241
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[16+rbp]
-
-	pxor	xmm14,xmm15
-DB	102,15,56,223,84,36,0
-	psrad	xmm9,31
-	paddq	xmm15,xmm15
-DB	102,15,56,223,92,36,16
-DB	102,15,56,223,100,36,32
-	pand	xmm9,xmm8
-	mov	rax,r10
-DB	102,15,56,223,108,36,48
-DB	102,15,56,223,116,36,64
-DB	102,15,56,223,124,36,80
-	pxor	xmm15,xmm9
-
-	lea	rsi,[96+rsi]
-	movups	XMMWORD[(-96)+rsi],xmm2
-	movups	XMMWORD[(-80)+rsi],xmm3
-	movups	XMMWORD[(-64)+rsi],xmm4
-	movups	XMMWORD[(-48)+rsi],xmm5
-	movups	XMMWORD[(-32)+rsi],xmm6
-	movups	XMMWORD[(-16)+rsi],xmm7
-	sub	rdx,16*6
-	jnc	NEAR $L$xts_dec_grandloop
-
-	mov	eax,16+96
-	sub	eax,r10d
-	mov	rcx,rbp
-	shr	eax,4
-
-$L$xts_dec_short:
-
-	mov	r10d,eax
-	pxor	xmm10,xmm0
-	pxor	xmm11,xmm0
-	add	rdx,16*6
-	jz	NEAR $L$xts_dec_done
-
-	pxor	xmm12,xmm0
-	cmp	rdx,0x20
-	jb	NEAR $L$xts_dec_one
-	pxor	xmm13,xmm0
-	je	NEAR $L$xts_dec_two
-
-	pxor	xmm14,xmm0
-	cmp	rdx,0x40
-	jb	NEAR $L$xts_dec_three
-	je	NEAR $L$xts_dec_four
-
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqu	xmm3,XMMWORD[16+rdi]
-	movdqu	xmm4,XMMWORD[32+rdi]
-	pxor	xmm2,xmm10
-	movdqu	xmm5,XMMWORD[48+rdi]
-	pxor	xmm3,xmm11
-	movdqu	xmm6,XMMWORD[64+rdi]
-	lea	rdi,[80+rdi]
-	pxor	xmm4,xmm12
-	pxor	xmm5,xmm13
-	pxor	xmm6,xmm14
-
-	call	_aesni_decrypt6
-
-	xorps	xmm2,xmm10
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-	movdqu	XMMWORD[rsi],xmm2
-	xorps	xmm5,xmm13
-	movdqu	XMMWORD[16+rsi],xmm3
-	xorps	xmm6,xmm14
-	movdqu	XMMWORD[32+rsi],xmm4
-	pxor	xmm14,xmm14
-	movdqu	XMMWORD[48+rsi],xmm5
-	pcmpgtd	xmm14,xmm15
-	movdqu	XMMWORD[64+rsi],xmm6
-	lea	rsi,[80+rsi]
-	pshufd	xmm11,xmm14,0x13
-	and	r9,15
-	jz	NEAR $L$xts_dec_ret
-
-	movdqa	xmm10,xmm15
-	paddq	xmm15,xmm15
-	pand	xmm11,xmm8
-	pxor	xmm11,xmm15
-	jmp	NEAR $L$xts_dec_done2
-
-ALIGN	16
-$L$xts_dec_one:
-	movups	xmm2,XMMWORD[rdi]
-	lea	rdi,[16+rdi]
-	xorps	xmm2,xmm10
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_dec1_12:
-DB	102,15,56,222,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_dec1_12
-DB	102,15,56,223,209
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm11
-	movups	XMMWORD[rsi],xmm2
-	movdqa	xmm11,xmm12
-	lea	rsi,[16+rsi]
-	jmp	NEAR $L$xts_dec_done
-
-ALIGN	16
-$L$xts_dec_two:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	lea	rdi,[32+rdi]
-	xorps	xmm2,xmm10
-	xorps	xmm3,xmm11
-
-	call	_aesni_decrypt2
-
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm12
-	xorps	xmm3,xmm11
-	movdqa	xmm11,xmm13
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	lea	rsi,[32+rsi]
-	jmp	NEAR $L$xts_dec_done
-
-ALIGN	16
-$L$xts_dec_three:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	movups	xmm4,XMMWORD[32+rdi]
-	lea	rdi,[48+rdi]
-	xorps	xmm2,xmm10
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-
-	call	_aesni_decrypt3
-
-	xorps	xmm2,xmm10
-	movdqa	xmm10,xmm13
-	xorps	xmm3,xmm11
-	movdqa	xmm11,xmm14
-	xorps	xmm4,xmm12
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	lea	rsi,[48+rsi]
-	jmp	NEAR $L$xts_dec_done
-
-ALIGN	16
-$L$xts_dec_four:
-	movups	xmm2,XMMWORD[rdi]
-	movups	xmm3,XMMWORD[16+rdi]
-	movups	xmm4,XMMWORD[32+rdi]
-	xorps	xmm2,xmm10
-	movups	xmm5,XMMWORD[48+rdi]
-	lea	rdi,[64+rdi]
-	xorps	xmm3,xmm11
-	xorps	xmm4,xmm12
-	xorps	xmm5,xmm13
-
-	call	_aesni_decrypt4
-
-	pxor	xmm2,xmm10
-	movdqa	xmm10,xmm14
-	pxor	xmm3,xmm11
-	movdqa	xmm11,xmm15
-	pxor	xmm4,xmm12
-	movdqu	XMMWORD[rsi],xmm2
-	pxor	xmm5,xmm13
-	movdqu	XMMWORD[16+rsi],xmm3
-	movdqu	XMMWORD[32+rsi],xmm4
-	movdqu	XMMWORD[48+rsi],xmm5
-	lea	rsi,[64+rsi]
-	jmp	NEAR $L$xts_dec_done
-
-ALIGN	16
-$L$xts_dec_done:
-	and	r9,15
-	jz	NEAR $L$xts_dec_ret
-$L$xts_dec_done2:
-	mov	rdx,r9
-	mov	rcx,rbp
-	mov	eax,r10d
-
-	movups	xmm2,XMMWORD[rdi]
-	xorps	xmm2,xmm11
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_dec1_13:
-DB	102,15,56,222,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_dec1_13
-DB	102,15,56,223,209
-	xorps	xmm2,xmm11
-	movups	XMMWORD[rsi],xmm2
-
-$L$xts_dec_steal:
-	movzx	eax,BYTE[16+rdi]
-	movzx	ecx,BYTE[rsi]
-	lea	rdi,[1+rdi]
-	mov	BYTE[rsi],al
-	mov	BYTE[16+rsi],cl
-	lea	rsi,[1+rsi]
-	sub	rdx,1
-	jnz	NEAR $L$xts_dec_steal
-
-	sub	rsi,r9
-	mov	rcx,rbp
-	mov	eax,r10d
-
-	movups	xmm2,XMMWORD[rsi]
-	xorps	xmm2,xmm10
-	movups	xmm0,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+rcx]
-	lea	rcx,[32+rcx]
-	xorps	xmm2,xmm0
-$L$oop_dec1_14:
-DB	102,15,56,222,209
-	dec	eax
-	movups	xmm1,XMMWORD[rcx]
-	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_dec1_14
-DB	102,15,56,223,209
-	xorps	xmm2,xmm10
-	movups	XMMWORD[rsi],xmm2
-
-$L$xts_dec_ret:
-	xorps	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	movaps	xmm6,XMMWORD[((-168))+r11]
-	movaps	XMMWORD[(-168)+r11],xmm0
-	movaps	xmm7,XMMWORD[((-152))+r11]
-	movaps	XMMWORD[(-152)+r11],xmm0
-	movaps	xmm8,XMMWORD[((-136))+r11]
-	movaps	XMMWORD[(-136)+r11],xmm0
-	movaps	xmm9,XMMWORD[((-120))+r11]
-	movaps	XMMWORD[(-120)+r11],xmm0
-	movaps	xmm10,XMMWORD[((-104))+r11]
-	movaps	XMMWORD[(-104)+r11],xmm0
-	movaps	xmm11,XMMWORD[((-88))+r11]
-	movaps	XMMWORD[(-88)+r11],xmm0
-	movaps	xmm12,XMMWORD[((-72))+r11]
-	movaps	XMMWORD[(-72)+r11],xmm0
-	movaps	xmm13,XMMWORD[((-56))+r11]
-	movaps	XMMWORD[(-56)+r11],xmm0
-	movaps	xmm14,XMMWORD[((-40))+r11]
-	movaps	XMMWORD[(-40)+r11],xmm0
-	movaps	xmm15,XMMWORD[((-24))+r11]
-	movaps	XMMWORD[(-24)+r11],xmm0
-	movaps	XMMWORD[rsp],xmm0
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	XMMWORD[48+rsp],xmm0
-	movaps	XMMWORD[64+rsp],xmm0
-	movaps	XMMWORD[80+rsp],xmm0
-	movaps	XMMWORD[96+rsp],xmm0
-	mov	rbp,QWORD[((-8))+r11]
-
-	lea	rsp,[r11]
-
-$L$xts_dec_epilogue:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-
-$L$SEH_end_aes_hw_xts_decrypt:
-global	aes_hw_ocb_encrypt
-
-ALIGN	32
-aes_hw_ocb_encrypt:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_ocb_encrypt:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-
-	lea	rax,[rsp]
-	push	rbx
-
-	push	rbp
-
-	push	r12
-
-	push	r13
-
-	push	r14
-
-	lea	rsp,[((-160))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	movaps	XMMWORD[32+rsp],xmm8
-	movaps	XMMWORD[48+rsp],xmm9
-	movaps	XMMWORD[64+rsp],xmm10
-	movaps	XMMWORD[80+rsp],xmm11
-	movaps	XMMWORD[96+rsp],xmm12
-	movaps	XMMWORD[112+rsp],xmm13
-	movaps	XMMWORD[128+rsp],xmm14
-	movaps	XMMWORD[144+rsp],xmm15
-$L$ocb_enc_body:
-	mov	rbx,QWORD[56+rax]
-	mov	rbp,QWORD[((56+8))+rax]
-
-	mov	r10d,DWORD[240+rcx]
-	mov	r11,rcx
-	shl	r10d,4
-	movups	xmm9,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+r10*1+rcx]
-
-	movdqu	xmm15,XMMWORD[r9]
-	pxor	xmm9,xmm1
-	pxor	xmm15,xmm1
-
-	mov	eax,16+32
-	lea	rcx,[32+r10*1+r11]
-	movups	xmm1,XMMWORD[16+r11]
-	sub	rax,r10
-	mov	r10,rax
-
-	movdqu	xmm10,XMMWORD[rbx]
-	movdqu	xmm8,XMMWORD[rbp]
-
-	test	r8,1
-	jnz	NEAR $L$ocb_enc_odd
-
-	bsf	r12,r8
-	add	r8,1
-	shl	r12,4
-	movdqu	xmm7,XMMWORD[r12*1+rbx]
-	movdqu	xmm2,XMMWORD[rdi]
-	lea	rdi,[16+rdi]
-
-	call	__ocb_encrypt1
-
-	movdqa	xmm15,xmm7
-	movups	XMMWORD[rsi],xmm2
-	lea	rsi,[16+rsi]
-	sub	rdx,1
-	jz	NEAR $L$ocb_enc_done
-
-$L$ocb_enc_odd:
-	lea	r12,[1+r8]
-	lea	r13,[3+r8]
-	lea	r14,[5+r8]
-	lea	r8,[6+r8]
-	bsf	r12,r12
-	bsf	r13,r13
-	bsf	r14,r14
-	shl	r12,4
-	shl	r13,4
-	shl	r14,4
-
-	sub	rdx,6
-	jc	NEAR $L$ocb_enc_short
-	jmp	NEAR $L$ocb_enc_grandloop
-
-ALIGN	32
-$L$ocb_enc_grandloop:
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqu	xmm3,XMMWORD[16+rdi]
-	movdqu	xmm4,XMMWORD[32+rdi]
-	movdqu	xmm5,XMMWORD[48+rdi]
-	movdqu	xmm6,XMMWORD[64+rdi]
-	movdqu	xmm7,XMMWORD[80+rdi]
-	lea	rdi,[96+rdi]
-
-	call	__ocb_encrypt6
-
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	movups	XMMWORD[48+rsi],xmm5
-	movups	XMMWORD[64+rsi],xmm6
-	movups	XMMWORD[80+rsi],xmm7
-	lea	rsi,[96+rsi]
-	sub	rdx,6
-	jnc	NEAR $L$ocb_enc_grandloop
-
-$L$ocb_enc_short:
-	add	rdx,6
-	jz	NEAR $L$ocb_enc_done
-
-	movdqu	xmm2,XMMWORD[rdi]
-	cmp	rdx,2
-	jb	NEAR $L$ocb_enc_one
-	movdqu	xmm3,XMMWORD[16+rdi]
-	je	NEAR $L$ocb_enc_two
-
-	movdqu	xmm4,XMMWORD[32+rdi]
-	cmp	rdx,4
-	jb	NEAR $L$ocb_enc_three
-	movdqu	xmm5,XMMWORD[48+rdi]
-	je	NEAR $L$ocb_enc_four
-
-	movdqu	xmm6,XMMWORD[64+rdi]
-	pxor	xmm7,xmm7
-
-	call	__ocb_encrypt6
-
-	movdqa	xmm15,xmm14
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	movups	XMMWORD[48+rsi],xmm5
-	movups	XMMWORD[64+rsi],xmm6
-
-	jmp	NEAR $L$ocb_enc_done
-
-ALIGN	16
-$L$ocb_enc_one:
-	movdqa	xmm7,xmm10
-
-	call	__ocb_encrypt1
-
-	movdqa	xmm15,xmm7
-	movups	XMMWORD[rsi],xmm2
-	jmp	NEAR $L$ocb_enc_done
-
-ALIGN	16
-$L$ocb_enc_two:
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	xmm15,xmm11
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-
-	jmp	NEAR $L$ocb_enc_done
-
-ALIGN	16
-$L$ocb_enc_three:
-	pxor	xmm5,xmm5
-
-	call	__ocb_encrypt4
-
-	movdqa	xmm15,xmm12
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-
-	jmp	NEAR $L$ocb_enc_done
-
-ALIGN	16
-$L$ocb_enc_four:
-	call	__ocb_encrypt4
-
-	movdqa	xmm15,xmm13
-	movups	XMMWORD[rsi],xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	movups	XMMWORD[48+rsi],xmm5
-
-$L$ocb_enc_done:
-	pxor	xmm15,xmm0
-	movdqu	XMMWORD[rbp],xmm8
-	movdqu	XMMWORD[r9],xmm15
-
-	xorps	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	XMMWORD[rsp],xmm0
-	movaps	xmm7,XMMWORD[16+rsp]
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	xmm8,XMMWORD[32+rsp]
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	xmm9,XMMWORD[48+rsp]
-	movaps	XMMWORD[48+rsp],xmm0
-	movaps	xmm10,XMMWORD[64+rsp]
-	movaps	XMMWORD[64+rsp],xmm0
-	movaps	xmm11,XMMWORD[80+rsp]
-	movaps	XMMWORD[80+rsp],xmm0
-	movaps	xmm12,XMMWORD[96+rsp]
-	movaps	XMMWORD[96+rsp],xmm0
-	movaps	xmm13,XMMWORD[112+rsp]
-	movaps	XMMWORD[112+rsp],xmm0
-	movaps	xmm14,XMMWORD[128+rsp]
-	movaps	XMMWORD[128+rsp],xmm0
-	movaps	xmm15,XMMWORD[144+rsp]
-	movaps	XMMWORD[144+rsp],xmm0
-	lea	rax,[((160+40))+rsp]
-$L$ocb_enc_pop:
-	mov	r14,QWORD[((-40))+rax]
-
-	mov	r13,QWORD[((-32))+rax]
-
-	mov	r12,QWORD[((-24))+rax]
-
-	mov	rbp,QWORD[((-16))+rax]
-
-	mov	rbx,QWORD[((-8))+rax]
-
-	lea	rsp,[rax]
-
-$L$ocb_enc_epilogue:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-
-$L$SEH_end_aes_hw_ocb_encrypt:
-
-
-ALIGN	32
-__ocb_encrypt6:
-	pxor	xmm15,xmm9
-	movdqu	xmm11,XMMWORD[r12*1+rbx]
-	movdqa	xmm12,xmm10
-	movdqu	xmm13,XMMWORD[r13*1+rbx]
-	movdqa	xmm14,xmm10
-	pxor	xmm10,xmm15
-	movdqu	xmm15,XMMWORD[r14*1+rbx]
-	pxor	xmm11,xmm10
-	pxor	xmm8,xmm2
-	pxor	xmm2,xmm10
-	pxor	xmm12,xmm11
-	pxor	xmm8,xmm3
-	pxor	xmm3,xmm11
-	pxor	xmm13,xmm12
-	pxor	xmm8,xmm4
-	pxor	xmm4,xmm12
-	pxor	xmm14,xmm13
-	pxor	xmm8,xmm5
-	pxor	xmm5,xmm13
-	pxor	xmm15,xmm14
-	pxor	xmm8,xmm6
-	pxor	xmm6,xmm14
-	pxor	xmm8,xmm7
-	pxor	xmm7,xmm15
-	movups	xmm0,XMMWORD[32+r11]
-
-	lea	r12,[1+r8]
-	lea	r13,[3+r8]
-	lea	r14,[5+r8]
-	add	r8,6
-	pxor	xmm10,xmm9
-	bsf	r12,r12
-	bsf	r13,r13
-	bsf	r14,r14
-
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	pxor	xmm11,xmm9
-	pxor	xmm12,xmm9
-DB	102,15,56,220,241
-	pxor	xmm13,xmm9
-	pxor	xmm14,xmm9
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[48+r11]
-	pxor	xmm15,xmm9
-
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-DB	102,15,56,220,240
-DB	102,15,56,220,248
-	movups	xmm0,XMMWORD[64+r11]
-	shl	r12,4
-	shl	r13,4
-	jmp	NEAR $L$ocb_enc_loop6
-
-ALIGN	32
-$L$ocb_enc_loop6:
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-DB	102,15,56,220,241
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-DB	102,15,56,220,240
-DB	102,15,56,220,248
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_enc_loop6
-
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-DB	102,15,56,220,241
-DB	102,15,56,220,249
-	movups	xmm1,XMMWORD[16+r11]
-	shl	r14,4
-
-DB	102,65,15,56,221,210
-	movdqu	xmm10,XMMWORD[rbx]
-	mov	rax,r10
-DB	102,65,15,56,221,219
-DB	102,65,15,56,221,228
-DB	102,65,15,56,221,237
-DB	102,65,15,56,221,246
-DB	102,65,15,56,221,255
-	DB	0F3h,0C3h		;repret
-
-
-
-ALIGN	32
-__ocb_encrypt4:
-	pxor	xmm15,xmm9
-	movdqu	xmm11,XMMWORD[r12*1+rbx]
-	movdqa	xmm12,xmm10
-	movdqu	xmm13,XMMWORD[r13*1+rbx]
-	pxor	xmm10,xmm15
-	pxor	xmm11,xmm10
-	pxor	xmm8,xmm2
-	pxor	xmm2,xmm10
-	pxor	xmm12,xmm11
-	pxor	xmm8,xmm3
-	pxor	xmm3,xmm11
-	pxor	xmm13,xmm12
-	pxor	xmm8,xmm4
-	pxor	xmm4,xmm12
-	pxor	xmm8,xmm5
-	pxor	xmm5,xmm13
-	movups	xmm0,XMMWORD[32+r11]
-
-	pxor	xmm10,xmm9
-	pxor	xmm11,xmm9
-	pxor	xmm12,xmm9
-	pxor	xmm13,xmm9
-
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	movups	xmm1,XMMWORD[48+r11]
-
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-	movups	xmm0,XMMWORD[64+r11]
-	jmp	NEAR $L$ocb_enc_loop4
-
-ALIGN	32
-$L$ocb_enc_loop4:
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,220,208
-DB	102,15,56,220,216
-DB	102,15,56,220,224
-DB	102,15,56,220,232
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_enc_loop4
-
-DB	102,15,56,220,209
-DB	102,15,56,220,217
-DB	102,15,56,220,225
-DB	102,15,56,220,233
-	movups	xmm1,XMMWORD[16+r11]
-	mov	rax,r10
-
-DB	102,65,15,56,221,210
-DB	102,65,15,56,221,219
-DB	102,65,15,56,221,228
-DB	102,65,15,56,221,237
-	DB	0F3h,0C3h		;repret
-
-
-
-ALIGN	32
-__ocb_encrypt1:
-	pxor	xmm7,xmm15
-	pxor	xmm7,xmm9
-	pxor	xmm8,xmm2
-	pxor	xmm2,xmm7
-	movups	xmm0,XMMWORD[32+r11]
-
-DB	102,15,56,220,209
-	movups	xmm1,XMMWORD[48+r11]
-	pxor	xmm7,xmm9
-
-DB	102,15,56,220,208
-	movups	xmm0,XMMWORD[64+r11]
-	jmp	NEAR $L$ocb_enc_loop1
-
-ALIGN	32
-$L$ocb_enc_loop1:
-DB	102,15,56,220,209
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,220,208
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_enc_loop1
-
-DB	102,15,56,220,209
-	movups	xmm1,XMMWORD[16+r11]
-	mov	rax,r10
-
-DB	102,15,56,221,215
-	DB	0F3h,0C3h		;repret
-
-
-global	aes_hw_ocb_decrypt
-
-ALIGN	32
-aes_hw_ocb_decrypt:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_aes_hw_ocb_decrypt:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-
-	lea	rax,[rsp]
-	push	rbx
-
-	push	rbp
-
-	push	r12
-
-	push	r13
-
-	push	r14
-
-	lea	rsp,[((-160))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	movaps	XMMWORD[32+rsp],xmm8
-	movaps	XMMWORD[48+rsp],xmm9
-	movaps	XMMWORD[64+rsp],xmm10
-	movaps	XMMWORD[80+rsp],xmm11
-	movaps	XMMWORD[96+rsp],xmm12
-	movaps	XMMWORD[112+rsp],xmm13
-	movaps	XMMWORD[128+rsp],xmm14
-	movaps	XMMWORD[144+rsp],xmm15
-$L$ocb_dec_body:
-	mov	rbx,QWORD[56+rax]
-	mov	rbp,QWORD[((56+8))+rax]
-
-	mov	r10d,DWORD[240+rcx]
-	mov	r11,rcx
-	shl	r10d,4
-	movups	xmm9,XMMWORD[rcx]
-	movups	xmm1,XMMWORD[16+r10*1+rcx]
-
-	movdqu	xmm15,XMMWORD[r9]
-	pxor	xmm9,xmm1
-	pxor	xmm15,xmm1
-
-	mov	eax,16+32
-	lea	rcx,[32+r10*1+r11]
-	movups	xmm1,XMMWORD[16+r11]
-	sub	rax,r10
-	mov	r10,rax
-
-	movdqu	xmm10,XMMWORD[rbx]
-	movdqu	xmm8,XMMWORD[rbp]
-
-	test	r8,1
-	jnz	NEAR $L$ocb_dec_odd
-
-	bsf	r12,r8
-	add	r8,1
-	shl	r12,4
-	movdqu	xmm7,XMMWORD[r12*1+rbx]
-	movdqu	xmm2,XMMWORD[rdi]
-	lea	rdi,[16+rdi]
-
-	call	__ocb_decrypt1
-
-	movdqa	xmm15,xmm7
-	movups	XMMWORD[rsi],xmm2
-	xorps	xmm8,xmm2
-	lea	rsi,[16+rsi]
-	sub	rdx,1
-	jz	NEAR $L$ocb_dec_done
-
-$L$ocb_dec_odd:
-	lea	r12,[1+r8]
-	lea	r13,[3+r8]
-	lea	r14,[5+r8]
-	lea	r8,[6+r8]
-	bsf	r12,r12
-	bsf	r13,r13
-	bsf	r14,r14
-	shl	r12,4
-	shl	r13,4
-	shl	r14,4
-
-	sub	rdx,6
-	jc	NEAR $L$ocb_dec_short
-	jmp	NEAR $L$ocb_dec_grandloop
-
-ALIGN	32
-$L$ocb_dec_grandloop:
-	movdqu	xmm2,XMMWORD[rdi]
-	movdqu	xmm3,XMMWORD[16+rdi]
-	movdqu	xmm4,XMMWORD[32+rdi]
-	movdqu	xmm5,XMMWORD[48+rdi]
-	movdqu	xmm6,XMMWORD[64+rdi]
-	movdqu	xmm7,XMMWORD[80+rdi]
-	lea	rdi,[96+rdi]
-
-	call	__ocb_decrypt6
-
-	movups	XMMWORD[rsi],xmm2
-	pxor	xmm8,xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	pxor	xmm8,xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	pxor	xmm8,xmm4
-	movups	XMMWORD[48+rsi],xmm5
-	pxor	xmm8,xmm5
-	movups	XMMWORD[64+rsi],xmm6
-	pxor	xmm8,xmm6
-	movups	XMMWORD[80+rsi],xmm7
-	pxor	xmm8,xmm7
-	lea	rsi,[96+rsi]
-	sub	rdx,6
-	jnc	NEAR $L$ocb_dec_grandloop
-
-$L$ocb_dec_short:
-	add	rdx,6
-	jz	NEAR $L$ocb_dec_done
-
-	movdqu	xmm2,XMMWORD[rdi]
-	cmp	rdx,2
-	jb	NEAR $L$ocb_dec_one
-	movdqu	xmm3,XMMWORD[16+rdi]
-	je	NEAR $L$ocb_dec_two
-
-	movdqu	xmm4,XMMWORD[32+rdi]
-	cmp	rdx,4
-	jb	NEAR $L$ocb_dec_three
-	movdqu	xmm5,XMMWORD[48+rdi]
-	je	NEAR $L$ocb_dec_four
-
-	movdqu	xmm6,XMMWORD[64+rdi]
-	pxor	xmm7,xmm7
-
-	call	__ocb_decrypt6
-
-	movdqa	xmm15,xmm14
-	movups	XMMWORD[rsi],xmm2
-	pxor	xmm8,xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	pxor	xmm8,xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	pxor	xmm8,xmm4
-	movups	XMMWORD[48+rsi],xmm5
-	pxor	xmm8,xmm5
-	movups	XMMWORD[64+rsi],xmm6
-	pxor	xmm8,xmm6
-
-	jmp	NEAR $L$ocb_dec_done
-
-ALIGN	16
-$L$ocb_dec_one:
-	movdqa	xmm7,xmm10
-
-	call	__ocb_decrypt1
-
-	movdqa	xmm15,xmm7
-	movups	XMMWORD[rsi],xmm2
-	xorps	xmm8,xmm2
-	jmp	NEAR $L$ocb_dec_done
-
-ALIGN	16
-$L$ocb_dec_two:
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	xmm15,xmm11
-	movups	XMMWORD[rsi],xmm2
-	xorps	xmm8,xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	xorps	xmm8,xmm3
-
-	jmp	NEAR $L$ocb_dec_done
-
-ALIGN	16
-$L$ocb_dec_three:
-	pxor	xmm5,xmm5
-
-	call	__ocb_decrypt4
-
-	movdqa	xmm15,xmm12
-	movups	XMMWORD[rsi],xmm2
-	xorps	xmm8,xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	xorps	xmm8,xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	xorps	xmm8,xmm4
-
-	jmp	NEAR $L$ocb_dec_done
-
-ALIGN	16
-$L$ocb_dec_four:
-	call	__ocb_decrypt4
-
-	movdqa	xmm15,xmm13
-	movups	XMMWORD[rsi],xmm2
-	pxor	xmm8,xmm2
-	movups	XMMWORD[16+rsi],xmm3
-	pxor	xmm8,xmm3
-	movups	XMMWORD[32+rsi],xmm4
-	pxor	xmm8,xmm4
-	movups	XMMWORD[48+rsi],xmm5
-	pxor	xmm8,xmm5
-
-$L$ocb_dec_done:
-	pxor	xmm15,xmm0
-	movdqu	XMMWORD[rbp],xmm8
-	movdqu	XMMWORD[r9],xmm15
-
-	xorps	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	XMMWORD[rsp],xmm0
-	movaps	xmm7,XMMWORD[16+rsp]
-	movaps	XMMWORD[16+rsp],xmm0
-	movaps	xmm8,XMMWORD[32+rsp]
-	movaps	XMMWORD[32+rsp],xmm0
-	movaps	xmm9,XMMWORD[48+rsp]
-	movaps	XMMWORD[48+rsp],xmm0
-	movaps	xmm10,XMMWORD[64+rsp]
-	movaps	XMMWORD[64+rsp],xmm0
-	movaps	xmm11,XMMWORD[80+rsp]
-	movaps	XMMWORD[80+rsp],xmm0
-	movaps	xmm12,XMMWORD[96+rsp]
-	movaps	XMMWORD[96+rsp],xmm0
-	movaps	xmm13,XMMWORD[112+rsp]
-	movaps	XMMWORD[112+rsp],xmm0
-	movaps	xmm14,XMMWORD[128+rsp]
-	movaps	XMMWORD[128+rsp],xmm0
-	movaps	xmm15,XMMWORD[144+rsp]
-	movaps	XMMWORD[144+rsp],xmm0
-	lea	rax,[((160+40))+rsp]
-$L$ocb_dec_pop:
-	mov	r14,QWORD[((-40))+rax]
-
-	mov	r13,QWORD[((-32))+rax]
-
-	mov	r12,QWORD[((-24))+rax]
-
-	mov	rbp,QWORD[((-16))+rax]
-
-	mov	rbx,QWORD[((-8))+rax]
-
-	lea	rsp,[rax]
-
-$L$ocb_dec_epilogue:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-
-$L$SEH_end_aes_hw_ocb_decrypt:
-
-
-ALIGN	32
-__ocb_decrypt6:
-	pxor	xmm15,xmm9
-	movdqu	xmm11,XMMWORD[r12*1+rbx]
-	movdqa	xmm12,xmm10
-	movdqu	xmm13,XMMWORD[r13*1+rbx]
-	movdqa	xmm14,xmm10
-	pxor	xmm10,xmm15
-	movdqu	xmm15,XMMWORD[r14*1+rbx]
-	pxor	xmm11,xmm10
-	pxor	xmm2,xmm10
-	pxor	xmm12,xmm11
-	pxor	xmm3,xmm11
-	pxor	xmm13,xmm12
-	pxor	xmm4,xmm12
-	pxor	xmm14,xmm13
-	pxor	xmm5,xmm13
-	pxor	xmm15,xmm14
-	pxor	xmm6,xmm14
-	pxor	xmm7,xmm15
-	movups	xmm0,XMMWORD[32+r11]
-
-	lea	r12,[1+r8]
-	lea	r13,[3+r8]
-	lea	r14,[5+r8]
-	add	r8,6
-	pxor	xmm10,xmm9
-	bsf	r12,r12
-	bsf	r13,r13
-	bsf	r14,r14
-
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	pxor	xmm11,xmm9
-	pxor	xmm12,xmm9
-DB	102,15,56,222,241
-	pxor	xmm13,xmm9
-	pxor	xmm14,xmm9
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[48+r11]
-	pxor	xmm15,xmm9
-
-DB	102,15,56,222,208
-DB	102,15,56,222,216
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-DB	102,15,56,222,240
-DB	102,15,56,222,248
-	movups	xmm0,XMMWORD[64+r11]
-	shl	r12,4
-	shl	r13,4
-	jmp	NEAR $L$ocb_dec_loop6
-
-ALIGN	32
-$L$ocb_dec_loop6:
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-DB	102,15,56,222,241
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,222,208
-DB	102,15,56,222,216
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-DB	102,15,56,222,240
-DB	102,15,56,222,248
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_dec_loop6
-
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-DB	102,15,56,222,241
-DB	102,15,56,222,249
-	movups	xmm1,XMMWORD[16+r11]
-	shl	r14,4
-
-DB	102,65,15,56,223,210
-	movdqu	xmm10,XMMWORD[rbx]
-	mov	rax,r10
-DB	102,65,15,56,223,219
-DB	102,65,15,56,223,228
-DB	102,65,15,56,223,237
-DB	102,65,15,56,223,246
-DB	102,65,15,56,223,255
-	DB	0F3h,0C3h		;repret
-
-
-
-ALIGN	32
-__ocb_decrypt4:
-	pxor	xmm15,xmm9
-	movdqu	xmm11,XMMWORD[r12*1+rbx]
-	movdqa	xmm12,xmm10
-	movdqu	xmm13,XMMWORD[r13*1+rbx]
-	pxor	xmm10,xmm15
-	pxor	xmm11,xmm10
-	pxor	xmm2,xmm10
-	pxor	xmm12,xmm11
-	pxor	xmm3,xmm11
-	pxor	xmm13,xmm12
-	pxor	xmm4,xmm12
-	pxor	xmm5,xmm13
-	movups	xmm0,XMMWORD[32+r11]
-
-	pxor	xmm10,xmm9
-	pxor	xmm11,xmm9
-	pxor	xmm12,xmm9
-	pxor	xmm13,xmm9
-
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	movups	xmm1,XMMWORD[48+r11]
-
-DB	102,15,56,222,208
-DB	102,15,56,222,216
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-	movups	xmm0,XMMWORD[64+r11]
-	jmp	NEAR $L$ocb_dec_loop4
-
-ALIGN	32
-$L$ocb_dec_loop4:
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,222,208
-DB	102,15,56,222,216
-DB	102,15,56,222,224
-DB	102,15,56,222,232
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_dec_loop4
-
-DB	102,15,56,222,209
-DB	102,15,56,222,217
-DB	102,15,56,222,225
-DB	102,15,56,222,233
-	movups	xmm1,XMMWORD[16+r11]
-	mov	rax,r10
-
-DB	102,65,15,56,223,210
-DB	102,65,15,56,223,219
-DB	102,65,15,56,223,228
-DB	102,65,15,56,223,237
-	DB	0F3h,0C3h		;repret
-
-
-
-ALIGN	32
-__ocb_decrypt1:
-	pxor	xmm7,xmm15
-	pxor	xmm7,xmm9
-	pxor	xmm2,xmm7
-	movups	xmm0,XMMWORD[32+r11]
-
-DB	102,15,56,222,209
-	movups	xmm1,XMMWORD[48+r11]
-	pxor	xmm7,xmm9
-
-DB	102,15,56,222,208
-	movups	xmm0,XMMWORD[64+r11]
-	jmp	NEAR $L$ocb_dec_loop1
-
-ALIGN	32
-$L$ocb_dec_loop1:
-DB	102,15,56,222,209
-	movups	xmm1,XMMWORD[rax*1+rcx]
-	add	rax,32
-
-DB	102,15,56,222,208
-	movups	xmm0,XMMWORD[((-16))+rax*1+rcx]
-	jnz	NEAR $L$ocb_dec_loop1
-
-DB	102,15,56,222,209
-	movups	xmm1,XMMWORD[16+r11]
-	mov	rax,r10
-
-DB	102,15,56,223,215
-	DB	0F3h,0C3h		;repret
-
 global	aes_hw_cbc_encrypt
 
 ALIGN	16
@@ -3744,12 +1563,12 @@
 	xorps	xmm3,xmm0
 	lea	rcx,[32+rcx]
 	xorps	xmm2,xmm3
-$L$oop_enc1_15:
+$L$oop_enc1_6:
 DB	102,15,56,220,209
 	dec	eax
 	movups	xmm1,XMMWORD[rcx]
 	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_enc1_15
+	jnz	NEAR $L$oop_enc1_6
 DB	102,15,56,221,209
 	mov	eax,r10d
 	mov	rcx,r11
@@ -3795,12 +1614,12 @@
 	movups	xmm1,XMMWORD[16+rcx]
 	lea	rcx,[32+rcx]
 	xorps	xmm2,xmm0
-$L$oop_dec1_16:
+$L$oop_dec1_7:
 DB	102,15,56,222,209
 	dec	r10d
 	movups	xmm1,XMMWORD[rcx]
 	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_dec1_16
+	jnz	NEAR $L$oop_dec1_7
 DB	102,15,56,223,209
 	pxor	xmm0,xmm0
 	pxor	xmm1,xmm1
@@ -4224,12 +2043,12 @@
 	movups	xmm1,XMMWORD[16+rcx]
 	lea	rcx,[32+rcx]
 	xorps	xmm2,xmm0
-$L$oop_dec1_17:
+$L$oop_dec1_8:
 DB	102,15,56,222,209
 	dec	eax
 	movups	xmm1,XMMWORD[rcx]
 	lea	rcx,[16+rcx]
-	jnz	NEAR $L$oop_dec1_17
+	jnz	NEAR $L$oop_dec1_8
 DB	102,15,56,223,209
 	xorps	xmm2,xmm10
 	movaps	xmm10,xmm11
@@ -4874,64 +2693,6 @@
 
 
 ALIGN	16
-ocb_se_handler:
-	push	rsi
-	push	rdi
-	push	rbx
-	push	rbp
-	push	r12
-	push	r13
-	push	r14
-	push	r15
-	pushfq
-	sub	rsp,64
-
-	mov	rax,QWORD[120+r8]
-	mov	rbx,QWORD[248+r8]
-
-	mov	rsi,QWORD[8+r9]
-	mov	r11,QWORD[56+r9]
-
-	mov	r10d,DWORD[r11]
-	lea	r10,[r10*1+rsi]
-	cmp	rbx,r10
-	jb	NEAR $L$common_seh_tail
-
-	mov	r10d,DWORD[4+r11]
-	lea	r10,[r10*1+rsi]
-	cmp	rbx,r10
-	jae	NEAR $L$common_seh_tail
-
-	mov	r10d,DWORD[8+r11]
-	lea	r10,[r10*1+rsi]
-	cmp	rbx,r10
-	jae	NEAR $L$ocb_no_xmm
-
-	mov	rax,QWORD[152+r8]
-
-	lea	rsi,[rax]
-	lea	rdi,[512+r8]
-	mov	ecx,20
-	DD	0xa548f3fc
-	lea	rax,[((160+40))+rax]
-
-$L$ocb_no_xmm:
-	mov	rbx,QWORD[((-8))+rax]
-	mov	rbp,QWORD[((-16))+rax]
-	mov	r12,QWORD[((-24))+rax]
-	mov	r13,QWORD[((-32))+rax]
-	mov	r14,QWORD[((-40))+rax]
-
-	mov	QWORD[144+r8],rbx
-	mov	QWORD[160+r8],rbp
-	mov	QWORD[216+r8],r12
-	mov	QWORD[224+r8],r13
-	mov	QWORD[232+r8],r14
-
-	jmp	NEAR $L$common_seh_tail
-
-
-ALIGN	16
 cbc_se_handler:
 	push	rsi
 	push	rdi
@@ -5019,33 +2780,9 @@
 	DD	$L$SEH_end_aes_hw_ecb_encrypt wrt ..imagebase
 	DD	$L$SEH_info_ecb wrt ..imagebase
 
-	DD	$L$SEH_begin_aes_hw_ccm64_encrypt_blocks wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_ccm64_encrypt_blocks wrt ..imagebase
-	DD	$L$SEH_info_ccm64_enc wrt ..imagebase
-
-	DD	$L$SEH_begin_aes_hw_ccm64_decrypt_blocks wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_ccm64_decrypt_blocks wrt ..imagebase
-	DD	$L$SEH_info_ccm64_dec wrt ..imagebase
-
 	DD	$L$SEH_begin_aes_hw_ctr32_encrypt_blocks wrt ..imagebase
 	DD	$L$SEH_end_aes_hw_ctr32_encrypt_blocks wrt ..imagebase
 	DD	$L$SEH_info_ctr32 wrt ..imagebase
-
-	DD	$L$SEH_begin_aes_hw_xts_encrypt wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_xts_encrypt wrt ..imagebase
-	DD	$L$SEH_info_xts_enc wrt ..imagebase
-
-	DD	$L$SEH_begin_aes_hw_xts_decrypt wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_xts_decrypt wrt ..imagebase
-	DD	$L$SEH_info_xts_dec wrt ..imagebase
-
-	DD	$L$SEH_begin_aes_hw_ocb_encrypt wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_ocb_encrypt wrt ..imagebase
-	DD	$L$SEH_info_ocb_enc wrt ..imagebase
-
-	DD	$L$SEH_begin_aes_hw_ocb_decrypt wrt ..imagebase
-	DD	$L$SEH_end_aes_hw_ocb_decrypt wrt ..imagebase
-	DD	$L$SEH_info_ocb_dec wrt ..imagebase
 	DD	$L$SEH_begin_aes_hw_cbc_encrypt wrt ..imagebase
 	DD	$L$SEH_end_aes_hw_cbc_encrypt wrt ..imagebase
 	DD	$L$SEH_info_cbc wrt ..imagebase
@@ -5063,38 +2800,10 @@
 DB	9,0,0,0
 	DD	ecb_ccm64_se_handler wrt ..imagebase
 	DD	$L$ecb_enc_body wrt ..imagebase,$L$ecb_enc_ret wrt ..imagebase
-$L$SEH_info_ccm64_enc:
-DB	9,0,0,0
-	DD	ecb_ccm64_se_handler wrt ..imagebase
-	DD	$L$ccm64_enc_body wrt ..imagebase,$L$ccm64_enc_ret wrt ..imagebase
-$L$SEH_info_ccm64_dec:
-DB	9,0,0,0
-	DD	ecb_ccm64_se_handler wrt ..imagebase
-	DD	$L$ccm64_dec_body wrt ..imagebase,$L$ccm64_dec_ret wrt ..imagebase
 $L$SEH_info_ctr32:
 DB	9,0,0,0
 	DD	ctr_xts_se_handler wrt ..imagebase
 	DD	$L$ctr32_body wrt ..imagebase,$L$ctr32_epilogue wrt ..imagebase
-$L$SEH_info_xts_enc:
-DB	9,0,0,0
-	DD	ctr_xts_se_handler wrt ..imagebase
-	DD	$L$xts_enc_body wrt ..imagebase,$L$xts_enc_epilogue wrt ..imagebase
-$L$SEH_info_xts_dec:
-DB	9,0,0,0
-	DD	ctr_xts_se_handler wrt ..imagebase
-	DD	$L$xts_dec_body wrt ..imagebase,$L$xts_dec_epilogue wrt ..imagebase
-$L$SEH_info_ocb_enc:
-DB	9,0,0,0
-	DD	ocb_se_handler wrt ..imagebase
-	DD	$L$ocb_enc_body wrt ..imagebase,$L$ocb_enc_epilogue wrt ..imagebase
-	DD	$L$ocb_enc_pop wrt ..imagebase
-	DD	0
-$L$SEH_info_ocb_dec:
-DB	9,0,0,0
-	DD	ocb_se_handler wrt ..imagebase
-	DD	$L$ocb_dec_body wrt ..imagebase,$L$ocb_dec_epilogue wrt ..imagebase
-	DD	$L$ocb_dec_pop wrt ..imagebase
-	DD	0
 $L$SEH_info_cbc:
 DB	9,0,0,0
 	DD	cbc_se_handler wrt ..imagebase
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm
index a34249b..89b91de1 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm
@@ -19,23 +19,12 @@
 
 ALIGN	16
 CRYPTO_rdrand:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_CRYPTO_rdrand:
-	mov	rdi,rcx
-
-
 
 	xor	rax,rax
-
-
-DB	0x48,0x0f,0xc7,0xf1
+DB	73,15,199,240
 
 	adc	rax,rax
-	mov	QWORD[rdi],rcx
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
+	mov	QWORD[rcx],r8
 	DB	0F3h,0C3h		;repret
 
 
@@ -43,39 +32,27 @@
 
 
 
+
 global	CRYPTO_rdrand_multiple8_buf
 
 ALIGN	16
 CRYPTO_rdrand_multiple8_buf:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_CRYPTO_rdrand_multiple8_buf:
-	mov	rdi,rcx
-	mov	rsi,rdx
 
-
-
-	test	rsi,rsi
+	test	rdx,rdx
 	jz	NEAR $L$out
-	mov	rdx,8
+	mov	r8,8
 $L$loop:
-
-
-DB	0x48,0x0f,0xc7,0xf1
+DB	73,15,199,241
 	jnc	NEAR $L$err
-	mov	QWORD[rdi],rcx
-	add	rdi,rdx
-	sub	rsi,rdx
+	mov	QWORD[rcx],r9
+	add	rcx,r8
+	sub	rdx,r8
 	jnz	NEAR $L$loop
 $L$out:
 	mov	rax,1
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
 	DB	0F3h,0C3h		;repret
 $L$err:
 	xor	rax,rax
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
 	DB	0F3h,0C3h		;repret
 
+
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
index 298fd05..7a1d5db 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
@@ -591,6 +591,7 @@
 
 ALIGN	32
 mul4x_internal:
+
 	shl	r9,5
 	movd	xmm5,DWORD[56+rax]
 	lea	rax,[$L$inc]
@@ -1113,6 +1114,7 @@
 	mov	r15,QWORD[24+rbp]
 	jmp	NEAR $L$sqr4x_sub_entry
 
+
 global	bn_power5
 
 ALIGN	32
@@ -1342,6 +1344,7 @@
 
 
 
+
 	lea	rbp,[32+r10]
 	lea	rsi,[r9*1+rsi]
 
@@ -2045,8 +2048,10 @@
 	DB	0F3h,0C3h		;repret
 
 
+
 ALIGN	32
 __bn_post4x_internal:
+
 	mov	r12,QWORD[rbp]
 	lea	rbx,[r9*1+rdi]
 	mov	rcx,r9
@@ -2098,10 +2103,12 @@
 	neg	r9
 	DB	0F3h,0C3h		;repret
 
+
 global	bn_from_montgomery
 
 ALIGN	32
 bn_from_montgomery:
+
 	test	DWORD[48+rsp],7
 	jz	NEAR bn_from_mont8x
 	xor	eax,eax
@@ -2109,6 +2116,7 @@
 
 
 
+
 ALIGN	32
 bn_from_mont8x:
 	mov	QWORD[8+rsp],rdi	;WIN64 prologue
@@ -2418,6 +2426,7 @@
 
 ALIGN	32
 mulx4x_internal:
+
 	mov	QWORD[8+rsp],r9
 	mov	r10,r9
 	neg	r9
@@ -2838,6 +2847,7 @@
 	jmp	NEAR $L$sqrx4x_sub_entry
 
 
+
 ALIGN	32
 bn_powerx5:
 	mov	QWORD[8+rsp],rdi	;WIN64 prologue
@@ -3607,7 +3617,9 @@
 
 
 ALIGN	32
+
 __bn_postx4x_internal:
+
 	mov	r12,QWORD[rbp]
 	mov	r10,rcx
 	mov	r9,rcx
@@ -3656,10 +3668,12 @@
 
 	DB	0F3h,0C3h		;repret
 
+
 global	bn_scatter5
 
 ALIGN	16
 bn_scatter5:
+
 	cmp	edx,0
 	jz	NEAR $L$scatter_epilogue
 	lea	r8,[r9*8+r8]
@@ -3674,13 +3688,16 @@
 	DB	0F3h,0C3h		;repret
 
 
+
 global	bn_gather5
 
 ALIGN	32
 bn_gather5:
+
 $L$SEH_begin_bn_gather5:
 
 DB	0x4c,0x8d,0x14,0x24
+
 DB	0x48,0x81,0xec,0x08,0x01,0x00,0x00
 	lea	rax,[$L$inc]
 	and	rsp,-16
@@ -3834,9 +3851,11 @@
 	jnz	NEAR $L$gather
 
 	lea	rsp,[r10]
+
 	DB	0F3h,0C3h		;repret
 $L$SEH_end_bn_gather5:
 
+
 ALIGN	64
 $L$inc:
 	DD	0,0,1,1
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js
index 2ac951d..7d440bfa 100644
--- a/third_party/closure_compiler/externs/automation.js
+++ b/third_party/closure_compiler/externs/automation.js
@@ -594,6 +594,13 @@
 chrome.automation.AutomationNode.prototype.nameFrom;
 
 /**
+ * The image annotation for image nodes, which may be a human-readable string that is the contextualized annotation or a status string related to annotations.
+ * @type {(string|undefined)}
+ * @see https://developer.chrome.com/extensions/automation#type-imageAnnotation
+ */
+chrome.automation.AutomationNode.prototype.imageAnnotation;
+
+/**
  * The value for this node: for example the <code>value</code> attribute of an <code>&lt;input&gt; element.
  * @type {(string|undefined)}
  * @see https://developer.chrome.com/extensions/automation#type-value
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
index c77276c..ac875c0 100644
--- a/third_party/libxml/README.chromium
+++ b/third_party/libxml/README.chromium
@@ -15,8 +15,10 @@
 - Applied these patches in chromium/*.patch:
   chromium-issue-599427.patch: workaround for VS 2015 Update 2 code-gen bug
   chromium-issue-628581.patch: See https://crbug.com/628581#c18
+  chromium-issue-894933.patch: Use ptrdiff_t instead of unsigned long for
+    pointer differences in parser.c
   libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch:
-  See https://crbug.com/708433
+    See https://crbug.com/708433
   libxml2-2.9.4-security-xpath-nodetab-uaf.patch: See https://crbug.com/705445
   chromium-issue-708434.patch: Guard against input counter overflow.
 - Delete various unused files, see chromium/roll.py
diff --git a/third_party/libxml/chromium/chromium-issue-894933.patch b/third_party/libxml/chromium/chromium-issue-894933.patch
new file mode 100644
index 0000000..418fed5
--- /dev/null
+++ b/third_party/libxml/chromium/chromium-issue-894933.patch
@@ -0,0 +1,113 @@
+diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c
+index 3a8a0d79e966..4e767091683d 100644
+--- a/third_party/libxml/src/parser.c
++++ b/third_party/libxml/src/parser.c
+@@ -2081,8 +2081,8 @@ static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
+ 	xmlGROW (ctxt);
+ 
+ static void xmlGROW (xmlParserCtxtPtr ctxt) {
+-    unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
+-    unsigned long curBase = ctxt->input->cur - ctxt->input->base;
++    ptrdiff_t curEnd = ctxt->input->end - ctxt->input->cur;
++    ptrdiff_t curBase = ctxt->input->cur - ctxt->input->base;
+ 
+     if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
+          (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
+@@ -8857,6 +8857,18 @@ xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
+  *     caller if it was copied, this can be detected by val[*len] == 0.
+  */
+ 
++#define GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) \
++    const xmlChar *oldbase = ctxt->input->base;\
++    GROW;\
++    if (ctxt->instate == XML_PARSER_EOF)\
++        return(NULL);\
++    if (oldbase != ctxt->input->base) {\
++        ptrdiff_t delta = ctxt->input->base - oldbase;\
++        start = start + delta;\
++        in = in + delta;\
++    }\
++    end = ctxt->input->end;
++
+ static xmlChar *
+ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+                          int normalize)
+@@ -8886,14 +8898,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+     end = ctxt->input->end;
+     start = in;
+     if (in >= end) {
+-        const xmlChar *oldbase = ctxt->input->base;
+-	GROW;
+-	if (oldbase != ctxt->input->base) {
+-	    long delta = ctxt->input->base - oldbase;
+-	    start = start + delta;
+-	    in = in + delta;
+-	}
+-	end = ctxt->input->end;
++        GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+     }
+     if (normalize) {
+         /*
+@@ -8910,16 +8915,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    in++;
+ 	    start = in;
+ 	    if (in >= end) {
+-		const xmlChar *oldbase = ctxt->input->base;
+-		GROW;
+-                if (ctxt->instate == XML_PARSER_EOF)
+-                    return(NULL);
+-		if (oldbase != ctxt->input->base) {
+-		    long delta = ctxt->input->base - oldbase;
+-		    start = start + delta;
+-		    in = in + delta;
+-		}
+-		end = ctxt->input->end;
++                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+@@ -8933,16 +8929,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    col++;
+ 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
+ 	    if (in >= end) {
+-		const xmlChar *oldbase = ctxt->input->base;
+-		GROW;
+-                if (ctxt->instate == XML_PARSER_EOF)
+-                    return(NULL);
+-		if (oldbase != ctxt->input->base) {
+-		    long delta = ctxt->input->base - oldbase;
+-		    start = start + delta;
+-		    in = in + delta;
+-		}
+-		end = ctxt->input->end;
++                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+@@ -8971,7 +8958,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+                 if (ctxt->instate == XML_PARSER_EOF)
+                     return(NULL);
+ 		if (oldbase != ctxt->input->base) {
+-		    long delta = ctxt->input->base - oldbase;
++		    ptrdiff_t delta = ctxt->input->base - oldbase;
+ 		    start = start + delta;
+ 		    in = in + delta;
+ 		    last = last + delta;
+@@ -8998,16 +8985,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    in++;
+ 	    col++;
+ 	    if (in >= end) {
+-		const xmlChar *oldbase = ctxt->input->base;
+-		GROW;
+-                if (ctxt->instate == XML_PARSER_EOF)
+-                    return(NULL);
+-		if (oldbase != ctxt->input->base) {
+-		    long delta = ctxt->input->base - oldbase;
+-		    start = start + delta;
+-		    in = in + delta;
+-		}
+-		end = ctxt->input->end;
++                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c
index 3a8a0d7..4e76709 100644
--- a/third_party/libxml/src/parser.c
+++ b/third_party/libxml/src/parser.c
@@ -2081,8 +2081,8 @@
 	xmlGROW (ctxt);
 
 static void xmlGROW (xmlParserCtxtPtr ctxt) {
-    unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
-    unsigned long curBase = ctxt->input->cur - ctxt->input->base;
+    ptrdiff_t curEnd = ctxt->input->end - ctxt->input->cur;
+    ptrdiff_t curBase = ctxt->input->cur - ctxt->input->base;
 
     if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
          (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
@@ -8857,6 +8857,18 @@
  *     caller if it was copied, this can be detected by val[*len] == 0.
  */
 
+#define GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) \
+    const xmlChar *oldbase = ctxt->input->base;\
+    GROW;\
+    if (ctxt->instate == XML_PARSER_EOF)\
+        return(NULL);\
+    if (oldbase != ctxt->input->base) {\
+        ptrdiff_t delta = ctxt->input->base - oldbase;\
+        start = start + delta;\
+        in = in + delta;\
+    }\
+    end = ctxt->input->end;
+
 static xmlChar *
 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
                          int normalize)
@@ -8886,14 +8898,7 @@
     end = ctxt->input->end;
     start = in;
     if (in >= end) {
-        const xmlChar *oldbase = ctxt->input->base;
-	GROW;
-	if (oldbase != ctxt->input->base) {
-	    long delta = ctxt->input->base - oldbase;
-	    start = start + delta;
-	    in = in + delta;
-	}
-	end = ctxt->input->end;
+        GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
     }
     if (normalize) {
         /*
@@ -8910,16 +8915,7 @@
 	    in++;
 	    start = in;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -8933,16 +8929,7 @@
 	    col++;
 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -8971,7 +8958,7 @@
                 if (ctxt->instate == XML_PARSER_EOF)
                     return(NULL);
 		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
+		    ptrdiff_t delta = ctxt->input->base - oldbase;
 		    start = start + delta;
 		    in = in + delta;
 		    last = last + delta;
@@ -8998,16 +8985,7 @@
 	    in++;
 	    col++;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
diff --git a/third_party/robolectric/BUILD.gn b/third_party/robolectric/BUILD.gn
index 3bc3d7e..c6ca0b5 100644
--- a/third_party/robolectric/BUILD.gn
+++ b/third_party/robolectric/BUILD.gn
@@ -70,9 +70,9 @@
     ":robolectric_shadowapi_java",
     ":robolectric_utils_java",
     ":shadows_core_java",
-    "//third_party/androidx:androidx_core_java",
-    "//third_party/androidx:androidx_junit_java",
-    "//third_party/androidx:androidx_monitor_java",
+    "//third_party/android_deps:androidx_test_core_java",
+    "//third_party/android_deps:androidx_test_ext_junit_java",
+    "//third_party/android_deps:androidx_test_monitor_java",
     "//third_party/bouncycastle:bouncycastle_java",
     "//third_party/guava:guava_java",
     "//third_party/jsr-305:jsr_305_javalib",
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index cd32e9df..563cfce 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -73,6 +73,7 @@
         <message key="name.invalidPattern" value="Static field names start with s."/>
     </module>
     <module name="MethodName">
+        <property name="id" value="MethodNameCheck"/>
         <property name="severity" value="error"/>
         <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
         <message key="name.invalidPattern" value="Method names should start with a lower case letter (e.g. getWidth())"/>
diff --git a/tools/android/checkstyle/suppressions.xml b/tools/android/checkstyle/suppressions.xml
index 3ff06d9..1a85a50f 100644
--- a/tools/android/checkstyle/suppressions.xml
+++ b/tools/android/checkstyle/suppressions.xml
@@ -8,4 +8,6 @@
   <suppress id="AlertDialogCheck"
     files="src/(android_webview|base|build|chromecast|components|content|device|media|mojo|net|printing|services|testing|third_party|tools|ui|url)/"/>
   <suppress id="StringBufferCheck" files="src/chrome/android/webapk/"/>
+  <!-- Robolectric shadows can overwrite constructor by implementing __constructor__() method. -->
+  <suppress id="MethodNameCheck" files="FirstRunIntegrationUnitTest.java"/>
 </suppressions>
diff --git a/tools/android/roll/android_deps/build.gradle b/tools/android/roll/android_deps/build.gradle
index e191312..12c9917 100644
--- a/tools/android/roll/android_deps/build.gradle
+++ b/tools/android/roll/android_deps/build.gradle
@@ -79,6 +79,10 @@
     // ARCore - needed for WebXR implementation on Android
     compile "com.google.ar:core:1.6.0"
 
+    // Androidx test libraries
+    compile "androidx.test:core:1.0.0"
+    compile "androidx.test:monitor:1.1.0"
+    compile "androidx.test.ext:junit:1.0.0"
 }
 
 task setUpRepository(type: BuildConfigGenerator) {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index b47eb35..fe79e405 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -3234,6 +3234,15 @@
   <int value="2" label="New profile created"/>
 </enum>
 
+<enum name="AutofillProfileSyncChangeOrigin">
+  <int value="0" label="Change in a local profile"/>
+  <int value="1"
+      label="Change in a converted local profile (that still equals to a
+             server profile)"/>
+  <int value="2" label="Resolving conflict in incremental remote update"/>
+  <int value="3" label="Upload / conflict resolution in initial sync"/>
+</enum>
+
 <enum name="AutofillQuality">
   <int value="0" label="Submitted"/>
   <int value="1" label="Autofilled"/>
@@ -15510,6 +15519,9 @@
   <int value="526" label="PrintingPinDefault"/>
   <int value="527" label="VoiceInteractionContextEnabled"/>
   <int value="528" label="UseKDCConstrainedDelegation"/>
+  <int value="529" label="VoiceInteractionHotwordEnabled"/>
+  <int value="530" label="BrowserSwitcherChromePath"/>
+  <int value="531" label="BrowserSwitcherChromeParameters"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -21664,6 +21676,7 @@
   <int value="2792" label="ClientHintsUAModel"/>
   <int value="2793" label="AnimationFrameCancelledWithinFrame"/>
   <int value="2794" label="SchedulingIsInputPending"/>
+  <int value="2795" label="V8StringNormalize"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
@@ -21725,6 +21738,13 @@
   <int value="7" label="Supervised User Interstitial"/>
 </enum>
 
+<enum name="FeedHostMismatch">
+  <int value="0" label="Agree neither are set"/>
+  <int value="1" label="Feed is set only"/>
+  <int value="2" label="Host is set only"/>
+  <int value="3" label="Agree both are set"/>
+</enum>
+
 <enum name="FeedImageFetchResult">
   <int value="0" label="Fetch cache success"/>
   <int value="1" label="Fetch network success"/>
@@ -31686,6 +31706,7 @@
   <int value="-621382525" label="VizDisplayCompositor:enabled"/>
   <int value="-621044227" label="OmniboxReverseTabSwitchLogic:enabled"/>
   <int value="-620030047" label="CrosCompUpdates:disabled"/>
+  <int value="-619740638" label="ListAllDisplayModes:enabled"/>
   <int value="-617452890" label="media-router"/>
   <int value="-612633819" label="NotificationScrollBar:disabled"/>
   <int value="-612480090" label="FasterLocationReload:enabled"/>
@@ -31933,6 +31954,7 @@
   <int value="-174564579"
       label="ServiceWorkerImportedScriptUpdateCheck:enabled"/>
   <int value="-174319545" label="BulkPrinters:enabled"/>
+  <int value="-171232290" label="ListAllDisplayModes:disabled"/>
   <int value="-171173736" label="VrBrowsingExperimentalFeatures:disabled"/>
   <int value="-170986053" label="EnableManualFallbacksFilling:enabled"/>
   <int value="-169745744" label="SyncPseudoUSSPreferences:enabled"/>
@@ -57532,6 +57554,8 @@
   <int value="997" label="IO_PENDING"/>
   <int value="998" label="NOACCESS"/>
   <int value="999" label="SWAPERROR"/>
+  <int value="1784" label="INVALID_USER_BUFFER"/>
+  <int value="1816" label="NOT_ENOUGH_QUOTA"/>
 </enum>
 
 <enum name="WinJumplistCategory">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 5662c3c..6c1a516 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -17648,6 +17648,33 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.Scheduler.HasContent"
+    enum="FeedHostMismatch" expires_after="2020-2-20">
+  <owner>skym@chromium.org</owner>
+  <owner>gangwu@chromium.org</owner>
+  <summary>
+    The match status between Feed and the host when the scheduler's
+    ShouldSessionRequestData method is called. This occurs whenever the NTP is
+    opened, and tries to track if the Feed and host state agrees or disagrees.
+    If the device already has content, new requests are not necessarily required
+    for a reasonable user experience.
+  </summary>
+</histogram>
+
+<histogram name="ContentSuggestions.Feed.Scheduler.OutstandingRequest"
+    enum="FeedHostMismatch" expires_after="2020-2-20">
+  <owner>skym@chromium.org</owner>
+  <owner>gangwu@chromium.org</owner>
+  <summary>
+    The match status between Feed and the host when the scheduler's
+    ShouldSessionRequestData method is called. This occurs whenever the NTP is
+    opened, and tries to track if the Feed and host state agrees or disagrees.
+    The type of request that could be outstanding is to fetch new or more news
+    articles, and when requests are outstanding new requests should not be
+    started.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.Scheduler.RefreshTrigger"
     enum="RefreshTrigger" expires_after="2019-10-01">
   <owner>skym@chromium.org</owner>
@@ -22836,6 +22863,15 @@
   </summary>
 </histogram>
 
+<histogram name="Discarding.DiscardsPer10Minutes" units="tabs">
+<!-- Name completed by histogram_suffixes name="DiscardReason" -->
+
+  <owner>fdoray@chromium.org</owner>
+  <summary>
+    Number of tabs discarded in each interval of 10 minutes, per discard reason.
+  </summary>
+</histogram>
+
 <histogram name="Discarding.OnlineOnReload" enum="Boolean">
 <!-- Name completed by histogram_suffixes name="DiscardReason" -->
 
@@ -22845,6 +22881,16 @@
   </summary>
 </histogram>
 
+<histogram name="Discarding.ReloadsPer10Minutes" units="tabs">
+<!-- Name completed by histogram_suffixes name="DiscardReason" -->
+
+  <owner>fdoray@chromium.org</owner>
+  <summary>
+    Number of discarded tabs reloaded in each interval of 10 minutes, grouped by
+    their discard reason.
+  </summary>
+</histogram>
+
 <histogram name="Discarding.Urgent.NumAliveTabs" units="tabs">
   <owner>fdoray@chromium.org</owner>
   <summary>
@@ -107229,6 +107275,14 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="Setup.Install.LzmaUnPackResult"
+    enum="WinGetLastError">
+  <owner>etiennep@chromium.org</owner>
+  <summary>
+    Record the return value of unpacking the contents of a 7z file.
+  </summary>
+</histogram>
+
 <histogram name="Setup.Install.LzmaUnPackStatus" enum="UnPackStatus">
   <owner>zmin@chromium.org</owner>
   <summary>Record the status of unpacking the contents of a 7z file.</summary>
@@ -114823,6 +114877,26 @@
   </summary>
 </histogram>
 
+<histogram name="Sync.AutofillProfile.AddOrUpdateOrigin"
+    enum="AutofillProfileSyncChangeOrigin" expires_after="M75">
+  <owner>jkrcal@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <summary>
+    Reported for autofill profile sync once per every locally committed entity
+    creation/update. It breaks down the origin of such a local change.
+  </summary>
+</histogram>
+
+<histogram name="Sync.AutofillProfile.DeleteOrigin"
+    enum="AutofillProfileSyncChangeOrigin" expires_after="M73">
+  <owner>jkrcal@chromium.org</owner>
+  <owner>treib@chromium.org</owner>
+  <summary>
+    Reported for autofill profile sync once per every locally committed entity
+    deletion. It breaks down the origin of such a local deletion.
+  </summary>
+</histogram>
+
 <histogram name="Sync.AutofillProfileAssociationTime" units="ms">
   <obsolete>
     Replaced by Sync.AutofillProfilesAssociationTime.
@@ -135876,7 +135950,9 @@
   <suffix name="Urgent"
       label="The browser urgently discarded a tab because there was memory
              pressure."/>
+  <affected-histogram name="Discarding.DiscardsPer10Minutes"/>
   <affected-histogram name="Discarding.OnlineOnReload"/>
+  <affected-histogram name="Discarding.ReloadsPer10Minutes"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="DiskUsagePerUserCount" separator=".">
@@ -144651,7 +144727,7 @@
       label="The time to perform the 'keys' operation on a given Cache. This
              includes measurements for both invocations targeting all entries
              or only entries for a specific request parameter."/>
-  <suffix base="true" name="Match"
+  <suffix name="Match"
       label="The time to perform a 'match' operation on a given Cache. This
              includes measurements for all invocations, including hits,
              misses, errors, etc."/>
@@ -144768,8 +144844,8 @@
              opening operations may happen asynchronously after the 'open'
              returns a Cache object. That deferred asynchronous work is not
              included in this measurement."/>
-  <affected-histogram name="ServiceWorkerCache.Cache.Browser"/>
-  <affected-histogram name="ServiceWorkerCache.Cache.Renderer"/>
+  <affected-histogram name="ServiceWorkerCache.CacheStorage.Browser"/>
+  <affected-histogram name="ServiceWorkerCache.CacheStorage.Renderer"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="ServiceWorkerCache.ProcessSuffixes" separator=".">
@@ -146177,6 +146253,7 @@
   <suffix name="UncompressedChromeArchive"
       label="uncompressed archive: chrome.7z holding install dir (big)."/>
   <affected-histogram name="Setup.Install.LzmaUnPackNTSTATUS"/>
+  <affected-histogram name="Setup.Install.LzmaUnPackResult"/>
   <affected-histogram name="Setup.Install.LzmaUnPackStatus"/>
 </histogram_suffixes>
 
diff --git a/tools/vim/chromium.ycm_extra_conf.py b/tools/vim/chromium.ycm_extra_conf.py
index ee0ad67..fb9c2b0 100644
--- a/tools/vim/chromium.ycm_extra_conf.py
+++ b/tools/vim/chromium.ycm_extra_conf.py
@@ -296,13 +296,6 @@
   # Chromium's includes are relative to that.
   additional_flags = ['-I' + os.path.join(chrome_root)]
 
-  # Fix missing system headers. For details, see
-  # <https://github.com/Valloric/YouCompleteMe/issues/303>
-  clang_root = os.path.join(
-    chrome_root, 'third_party/llvm-build/Release+Asserts')
-  additional_flags += ['-isystem', os.path.join(clang_root, 'include')]
-  additional_flags += ['-isystem', os.path.join(clang_root, 'include/c++/v1')]
-
   # Version of Clang used to compile Chromium can be newer then version of
   # libclang that YCM uses for completion. So it's possible that YCM's libclang
   # doesn't know about some used warning options, which causes compilation
diff --git a/tools/vim/tests/chromium.ycm_extra_conf_unittest.py b/tools/vim/tests/chromium.ycm_extra_conf_unittest.py
index cfecd70..3662fee 100755
--- a/tools/vim/tests/chromium.ycm_extra_conf_unittest.py
+++ b/tools/vim/tests/chromium.ycm_extra_conf_unittest.py
@@ -20,12 +20,6 @@
 import tempfile
 import unittest
 
-_common_flags = [
-  '-I[SRC]',
-  '-isystem', '[SRC]/third_party/llvm-build/Release+Asserts/include',
-  '-isystem', '[SRC]/third_party/llvm-build/Release+Asserts/include/c++/v1',
-  '-Wno-unknown-warning-option'
-]
 
 def CreateFile(path, copy_from=None, format_with=None, make_executable=False):
   """Creates a file.
@@ -169,8 +163,9 @@
         self.ycm_extra_conf.GetClangOptionsFromNinjaForFilename(
             self.chrome_root, os.path.join(self.chrome_root, 'one.cpp'))
     self.assertEquals(
-        self.NormalizeStringsInList(clang_options), _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-one'
+        self.NormalizeStringsInList(clang_options), [
+            '-I[SRC]', '-Wno-unknown-warning-option', '-I[OUT]/a',
+            '-I[OUT]/tag-one'
         ])
 
   def testOutDirNames(self):
@@ -195,9 +190,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-one'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-one'
         ])
 
   def testGetFlagsForFileForUnknownCppFile(self):
@@ -209,9 +203,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-default'
         ])
 
   def testGetFlagsForFileForUnknownCppNotTestFile(self):
@@ -223,9 +216,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-default'
         ])
 
   testGetFlagsForFileForKnownObjcFile = TestLanguage('eight.m', 'objective-c')
@@ -249,9 +241,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-default'
         ])
 
   def testGetFlagsForFileForUnknownUnittestFile(self):
@@ -263,9 +254,9 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default-test'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a',
+            '-I[OUT]/tag-default-test'
         ])
 
   def testGetFlagsForFileForUnknownBrowsertestFile2(self):
@@ -277,9 +268,9 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default-test'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a',
+            '-I[OUT]/tag-default-test'
         ])
 
   def testGetFlagsForFileForKnownHeaderFileWithAssociatedCppFile(self):
@@ -291,9 +282,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-three'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-three'
         ])
 
   def testSourceFileWithNonClangOutputs(self):
@@ -319,9 +309,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-four'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-four'
         ])
 
   def testSourceFileWithOnlyNonClangOutputs(self):
@@ -333,9 +322,8 @@
     self.assertTrue('flags' in result)
     self.assertEquals(
         self.NormalizeStringsInList(result['flags']), [
-            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++'
-        ] + _common_flags + [
-            '-I[OUT]/a', '-I[OUT]/tag-default'
+            '-DUSE_CLANG_COMPLETER', '-std=c++14', '-x', 'c++', '-I[SRC]',
+            '-Wno-unknown-warning-option', '-I[OUT]/a', '-I[OUT]/tag-default'
         ])
 
   def testGetFlagsForSysrootAbsPath(self):
@@ -351,7 +339,8 @@
             '-std=c++14',
             '-x',
             'c++',
-        ] + _common_flags + [
+            '-I[SRC]',
+            '-Wno-unknown-warning-option',
             '-I[OUT]/a',
             '--sysroot=/usr/lib/sysroot-image',
             '-isysroot',
@@ -371,7 +360,8 @@
             '-std=c++14',
             '-x',
             'c++',
-        ] + _common_flags + [
+            '-I[SRC]',
+            '-Wno-unknown-warning-option',
             '-I[OUT]/a',
             '--sysroot=[SRC]/build/sysroot-image',
             '-isysroot',
@@ -389,7 +379,8 @@
             '-std=c++14',
             '-x',
             'c++',
-        ] + _common_flags + [
+            '-I[SRC]',
+            '-Wno-unknown-warning-option',
             '-I[OUT]/b',
             '-isystem[OUT]/a',
             '-isystem', '[SRC]/build/c',
@@ -407,7 +398,8 @@
             '-std=c++14',
             '-x',
             'c++',
-        ] + _common_flags + [
+            '-I[SRC]',
+            '-Wno-unknown-warning-option',
             '-I', '[OUT]/a',
             '-I', '[OUT]/tag-eleven'
         ])
diff --git a/tools/win/IdleWakeups/IdleWakeups.vcxproj b/tools/win/IdleWakeups/IdleWakeups.vcxproj
index 07e5b3c..278930a 100644
--- a/tools/win/IdleWakeups/IdleWakeups.vcxproj
+++ b/tools/win/IdleWakeups/IdleWakeups.vcxproj
@@ -1,163 +1,163 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{CE6B94A5-2753-4DF1-9C4E-5A210D355CA2}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>IdleWakeups</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="Shared">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="power_sampler.h" />
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="system_information_sampler.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="idle_wakeups.cpp" />
-    <ClCompile Include="power_sampler.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
-    </ClCompile>
-    <ClCompile Include="system_information_sampler.cpp" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup Label="ProjectConfigurations">

+    <ProjectConfiguration Include="Debug|Win32">

+      <Configuration>Debug</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug|x64">

+      <Configuration>Debug</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|x64">

+      <Configuration>Release</Configuration>

+      <Platform>x64</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{CE6B94A5-2753-4DF1-9C4E-5A210D355CA2}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>IdleWakeups</RootNamespace>

+    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <PlatformToolset>v141</PlatformToolset>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <PlatformToolset>v141</PlatformToolset>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <PlatformToolset>v141</PlatformToolset>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <PlatformToolset>v141</PlatformToolset>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="Shared">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <LinkIncremental>true</LinkIncremental>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <LinkIncremental>true</LinkIncremental>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <LinkIncremental>false</LinkIncremental>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <LinkIncremental>false</LinkIncremental>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <SDLCheck>true</SDLCheck>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

+    <ClCompile>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <SDLCheck>true</SDLCheck>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <SDLCheck>true</SDLCheck>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <SDLCheck>true</SDLCheck>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemGroup>

+    <ClInclude Include="power_sampler.h" />

+    <ClInclude Include="stdafx.h" />

+    <ClInclude Include="system_information_sampler.h" />

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="idle_wakeups.cpp" />

+    <ClCompile Include="power_sampler.cpp" />

+    <ClCompile Include="stdafx.cpp">

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>

+    </ClCompile>

+    <ClCompile Include="system_information_sampler.cpp" />

+  </ItemGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

 </Project>
\ No newline at end of file
diff --git a/tools/win/IdleWakeups/idle_wakeups.cpp b/tools/win/IdleWakeups/idle_wakeups.cpp
index cb9dacc9..52a5174 100644
--- a/tools/win/IdleWakeups/idle_wakeups.cpp
+++ b/tools/win/IdleWakeups/idle_wakeups.cpp
@@ -255,6 +255,7 @@
       "------------------------------------------------------------------------"
       "----------\n");
   printf(
+      "                                                            Private\n"
       "                       Context switches/sec    CPU usage    Working set "
       "     Power\n");
   printf(
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 57665b56..9c5c982 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -3413,6 +3413,10 @@
       break;
 
     case UIA_ScrollPatternId:
+      if (IsScrollable()) {
+        AddRef();
+        *result = static_cast<IScrollProvider*>(this);
+      }
       break;
 
     case UIA_ScrollItemPatternId:
diff --git a/ui/aura/test/aura_test_context_factory.cc b/ui/aura/test/aura_test_context_factory.cc
index 902b658..25bbbb8 100644
--- a/ui/aura/test/aura_test_context_factory.cc
+++ b/ui/aura/test/aura_test_context_factory.cc
@@ -5,6 +5,7 @@
 #include "ui/aura/test/aura_test_context_factory.h"
 
 #include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/fake_skia_output_surface.h"
 #include "components/viz/test/test_context_provider.h"
 #include "components/viz/test/test_layer_tree_frame_sink.h"
 
@@ -19,6 +20,11 @@
       : display_context_provider_(std::move(display_context_provider)) {}
 
   // viz::TestLayerTreeFrameSinkClient:
+  std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
+      override {
+    return viz::FakeSkiaOutputSurface::Create3d();
+  }
+
   std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface(
       scoped_refptr<viz::ContextProvider> compositor_context_provider)
       override {
diff --git a/ui/base/cocoa/remote_layer_api.h b/ui/base/cocoa/remote_layer_api.h
index 291a11b4..2057fe6 100644
--- a/ui/base/cocoa/remote_layer_api.h
+++ b/ui/base/cocoa/remote_layer_api.h
@@ -19,7 +19,7 @@
 extern "C" {
 typedef uint32_t CGSConnectionID;
 CGSConnectionID CGSMainConnectionID(void);
-};
+}
 
 // The CAContextID type identifies a CAContext across processes. This is the
 // token that is passed from the process that is sharing the CALayer that it is
diff --git a/ui/base/dragdrop/drop_target_event.cc b/ui/base/dragdrop/drop_target_event.cc
index 8ae61d4f..9c21225 100644
--- a/ui/base/dragdrop/drop_target_event.cc
+++ b/ui/base/dragdrop/drop_target_event.cc
@@ -23,5 +23,10 @@
       data_(data),
       source_operations_(source_operations) {}
 
+DropTargetEvent::DropTargetEvent(const DropTargetEvent& other)
+    : LocatedEvent(other),
+      data_(other.data_),
+      source_operations_(other.source_operations_) {}
+
 }  // namespace ui
 
diff --git a/ui/base/dragdrop/drop_target_event.h b/ui/base/dragdrop/drop_target_event.h
index 410bb4c..47f1b4e 100644
--- a/ui/base/dragdrop/drop_target_event.h
+++ b/ui/base/dragdrop/drop_target_event.h
@@ -11,12 +11,15 @@
 
 namespace ui {
 
+// Note: This object must not outlive the OSExchangeData used to construct it,
+// as it stores that by reference.
 class UI_BASE_EXPORT DropTargetEvent : public LocatedEvent {
  public:
   DropTargetEvent(const OSExchangeData& data,
                   const gfx::PointF& location,
                   const gfx::PointF& root_location,
                   int source_operations);
+  DropTargetEvent(const DropTargetEvent& other);
 
   const OSExchangeData& data() const { return data_; }
   int source_operations() const { return source_operations_; }
@@ -27,8 +30,6 @@
 
   // Bitmask of supported DragDropTypes::DragOperation by the source.
   int source_operations_;
-
-  DISALLOW_COPY_AND_ASSIGN(DropTargetEvent);
 };
 
 }  // namespace ui
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn
index e5185ec..c17d29b 100644
--- a/ui/display/BUILD.gn
+++ b/ui/display/BUILD.gn
@@ -14,6 +14,8 @@
     "display_change_notifier.cc",
     "display_change_notifier.h",
     "display_export.h",
+    "display_features.cc",
+    "display_features.h",
     "display_finder.cc",
     "display_finder.h",
     "display_layout.cc",
diff --git a/ui/display/display_features.cc b/ui/display/display_features.cc
new file mode 100644
index 0000000..b902dba
--- /dev/null
+++ b/ui/display/display_features.cc
@@ -0,0 +1,32 @@
+// 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 "ui/display/display_features.h"
+
+namespace display {
+namespace features {
+
+const base::Feature kHighDynamicRange{"HighDynamicRange",
+                                      base::FEATURE_ENABLED_BY_DEFAULT};
+
+#if defined(OS_CHROMEOS)
+// Enables using the monitor's provided color space information when
+// rendering.
+// TODO(mcasas): remove this flag http://crbug.com/771345.
+const base::Feature kUseMonitorColorSpace{"UseMonitorColorSpace",
+                                          base::FEATURE_ENABLED_BY_DEFAULT};
+#endif  // OS_CHROMEOS
+
+// This features allows listing all display modes of external displays in the
+// display settings and setting any one of them exactly as requested, which can
+// be very useful for debugging and development purposes.
+const base::Feature kListAllDisplayModes = {"ListAllDisplayModes",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsListAllDisplayModesEnabled() {
+  return base::FeatureList::IsEnabled(kListAllDisplayModes);
+}
+
+}  // namespace features
+}  // namespace display
diff --git a/ui/display/display_features.h b/ui/display/display_features.h
new file mode 100644
index 0000000..fbb27b6
--- /dev/null
+++ b/ui/display/display_features.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_DISPLAY_DISPLAY_FEATURES_H_
+#define UI_DISPLAY_DISPLAY_FEATURES_H_
+
+#include "base/feature_list.h"
+#include "ui/display/display_export.h"
+
+namespace display {
+namespace features {
+
+DISPLAY_EXPORT extern const base::Feature kHighDynamicRange;
+
+#if defined(OS_CHROMEOS)
+DISPLAY_EXPORT extern const base::Feature kUseMonitorColorSpace;
+#endif
+
+DISPLAY_EXPORT extern const base::Feature kListAllDisplayModes;
+
+DISPLAY_EXPORT bool IsListAllDisplayModesEnabled();
+
+}  // namespace features
+}  // namespace display
+
+#endif  // UI_DISPLAY_DISPLAY_FEATURES_H_
diff --git a/ui/display/display_switches.cc b/ui/display/display_switches.cc
index 9e2d1f0..f2c0f56 100644
--- a/ui/display/display_switches.cc
+++ b/ui/display/display_switches.cc
@@ -59,18 +59,3 @@
 #endif
 
 }  // namespace switches
-
-namespace features {
-
-const base::Feature kHighDynamicRange{"HighDynamicRange",
-                                      base::FEATURE_ENABLED_BY_DEFAULT};
-
-#if defined(OS_CHROMEOS)
-// Enables using the monitor's provided color space information when
-// rendering.
-// TODO(mcasas): remove this flag http://crbug.com/771345.
-const base::Feature kUseMonitorColorSpace{"UseMonitorColorSpace",
-                                          base::FEATURE_ENABLED_BY_DEFAULT};
-#endif  // OS_CHROMEOS
-
-}  // namespace features
diff --git a/ui/display/display_switches.h b/ui/display/display_switches.h
index 70fac73..ff76d74 100644
--- a/ui/display/display_switches.h
+++ b/ui/display/display_switches.h
@@ -30,14 +30,4 @@
 
 }  // namespace switches
 
-namespace features {
-
-DISPLAY_EXPORT extern const base::Feature kHighDynamicRange;
-
-#if defined(OS_CHROMEOS)
-DISPLAY_EXPORT extern const base::Feature kUseMonitorColorSpace;
-#endif
-
-}  // namespace features
-
 #endif  // UI_DISPLAY_DISPLAY_SWITCHES_H_
diff --git a/ui/display/manager/display_change_observer.cc b/ui/display/manager/display_change_observer.cc
index 73657edf..3634bc90 100644
--- a/ui/display/manager/display_change_observer.cc
+++ b/ui/display/manager/display_change_observer.cc
@@ -8,6 +8,7 @@
 #include <map>
 #include <set>
 #include <string>
+#include <tuple>
 #include <utility>
 #include <vector>
 
@@ -16,6 +17,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/user_activity/user_activity_detector.h"
 #include "ui/display/display.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_layout.h"
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/display_layout_store.h"
@@ -47,6 +49,31 @@
     {150.0f, 1.25f}, {0.0f, 1.0f},
 };
 
+// Returns a list of display modes for the given |output| that doesn't exclude
+// any mode. The returned list is sorted by size, then by refresh rate, then by
+// is_interlaced.
+ManagedDisplayInfo::ManagedDisplayModeList GetModeListWithAllRefreshRates(
+    const DisplaySnapshot& output) {
+  ManagedDisplayInfo::ManagedDisplayModeList display_mode_list;
+  for (const auto& mode_info : output.modes()) {
+    display_mode_list.emplace_back(mode_info->size(), mode_info->refresh_rate(),
+                                   mode_info->is_interlaced(),
+                                   output.native_mode() == mode_info.get(),
+                                   1.0);
+  }
+
+  std::sort(
+      display_mode_list.begin(), display_mode_list.end(),
+      [](const ManagedDisplayMode& lhs, const ManagedDisplayMode& rhs) {
+        return std::forward_as_tuple(lhs.size().width(), lhs.size().height(),
+                                     lhs.refresh_rate(), lhs.is_interlaced()) <
+               std::forward_as_tuple(rhs.size().width(), rhs.size().height(),
+                                     rhs.refresh_rate(), rhs.is_interlaced());
+      });
+
+  return display_mode_list;
+}
+
 }  // namespace
 
 // static
@@ -66,13 +93,25 @@
 ManagedDisplayInfo::ManagedDisplayModeList
 DisplayChangeObserver::GetExternalManagedDisplayModeList(
     const DisplaySnapshot& output) {
-  using DisplayModeMap = std::map<std::pair<int, int>, ManagedDisplayMode>;
+  if (display::features::IsListAllDisplayModesEnabled())
+    return GetModeListWithAllRefreshRates(output);
+
+  struct SizeComparator {
+    constexpr bool operator()(const gfx::Size& lhs,
+                              const gfx::Size& rhs) const {
+      return std::forward_as_tuple(lhs.width(), lhs.height()) <
+             std::forward_as_tuple(rhs.width(), rhs.height());
+    }
+  };
+
+  using DisplayModeMap =
+      std::map<gfx::Size, ManagedDisplayMode, SizeComparator>;
   DisplayModeMap display_mode_map;
 
   ManagedDisplayMode native_mode;
   for (const auto& mode_info : output.modes()) {
-    const std::pair<int, int> size(mode_info->size().width(),
-                                   mode_info->size().height());
+    const gfx::Size size = mode_info->size();
+
     ManagedDisplayMode display_mode(
         mode_info->size(), mode_info->refresh_rate(),
         mode_info->is_interlaced(), output.native_mode() == mode_info.get(),
@@ -87,7 +126,7 @@
     // rate but is interlaced.
     auto display_mode_it = display_mode_map.find(size);
     if (display_mode_it == display_mode_map.end()) {
-      display_mode_map.insert(std::make_pair(size, display_mode));
+      display_mode_map.emplace(size, display_mode);
     } else if (display_mode_it->second.is_interlaced() &&
                !display_mode.is_interlaced()) {
       display_mode_it->second = std::move(display_mode);
@@ -103,8 +142,8 @@
     display_mode_list.push_back(std::move(display_mode_pair.second));
 
   if (output.native_mode()) {
-    const std::pair<int, int> size(native_mode.size().width(),
-                                   native_mode.size().height());
+    const gfx::Size size = native_mode.size();
+
     auto it = display_mode_map.find(size);
     DCHECK(it != display_mode_map.end())
         << "Native mode must be part of the mode list.";
@@ -117,11 +156,8 @@
   return display_mode_list;
 }
 
-DisplayChangeObserver::DisplayChangeObserver(
-    DisplayConfigurator* display_configurator,
-    DisplayManager* display_manager)
-    : display_configurator_(display_configurator),
-      display_manager_(display_manager) {
+DisplayChangeObserver::DisplayChangeObserver(DisplayManager* display_manager)
+    : display_manager_(display_manager) {
   ui::InputDeviceManager::GetInstance()->AddObserver(this);
 }
 
@@ -144,13 +180,10 @@
              : MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED;
 }
 
-bool DisplayChangeObserver::GetResolutionForDisplayId(int64_t display_id,
-                                                      gfx::Size* size) const {
-  ManagedDisplayMode mode;
-  if (!display_manager_->GetSelectedModeForDisplayId(display_id, &mode))
-    return false;
-  *size = mode.size();
-  return true;
+bool DisplayChangeObserver::GetSelectedModeForDisplayId(
+    int64_t display_id,
+    ManagedDisplayMode* out_mode) const {
+  return display_manager_->GetSelectedModeForDisplayId(display_id, out_mode);
 }
 
 void DisplayChangeObserver::OnDisplayModeChanged(
@@ -197,7 +230,8 @@
     // case there aren't any touchscreens to associate. For the second case,
     // the displays and touch input-devices will get associated when display
     // configuration finishes.
-    const auto& cached_displays = display_configurator_->cached_displays();
+    const auto& cached_displays =
+        display_manager_->configurator()->cached_displays();
     if (!cached_displays.empty())
       OnDisplayModeChanged(cached_displays);
   }
@@ -237,29 +271,6 @@
 ManagedDisplayInfo DisplayChangeObserver::CreateManagedDisplayInfo(
     const DisplaySnapshot* snapshot,
     const DisplayMode* mode_info) {
-  float device_scale_factor = 1.0f;
-  // Sets dpi only if the screen size is not blacklisted.
-  float dpi = IsDisplaySizeBlackListed(snapshot->physical_size())
-                  ? 0
-                  : kInchInMm * mode_info->size().width() /
-                        snapshot->physical_size().width();
-  constexpr gfx::Size k225DisplaySizeHack(3000, 2000);
-
-  if (snapshot->type() == DISPLAY_CONNECTION_TYPE_INTERNAL) {
-    // TODO(oshima): This is a stopgap hack to deal with b/74845106.
-    // Remove this hack when it's resolved.
-    if (mode_info->size() == k225DisplaySizeHack)
-      device_scale_factor = 2.25f;
-    else if (dpi)
-      device_scale_factor = FindDeviceScaleFactor(dpi);
-  } else {
-    ManagedDisplayMode mode;
-    if (display_manager_->GetSelectedModeForDisplayId(snapshot->display_id(),
-                                                      &mode)) {
-      device_scale_factor = mode.device_scale_factor();
-    }
-  }
-
   std::string name = (snapshot->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
                          ? l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL)
                          : snapshot->display_name();
@@ -284,16 +295,44 @@
   new_info.set_year_of_manufacture(snapshot->year_of_manufacture());
 
   new_info.set_sys_path(snapshot->sys_path());
+  new_info.set_native(true);
+
+  float device_scale_factor = 1.0f;
+  // Sets dpi only if the screen size is not blacklisted.
+  const float dpi = IsDisplaySizeBlackListed(snapshot->physical_size())
+                        ? 0
+                        : kInchInMm * mode_info->size().width() /
+                              snapshot->physical_size().width();
+  constexpr gfx::Size k225DisplaySizeHack(3000, 2000);
+
+  if (snapshot->type() == DISPLAY_CONNECTION_TYPE_INTERNAL) {
+    // TODO(oshima): This is a stopgap hack to deal with b/74845106.
+    // Remove this hack when it's resolved.
+    if (mode_info->size() == k225DisplaySizeHack)
+      device_scale_factor = 2.25f;
+    else if (dpi)
+      device_scale_factor = FindDeviceScaleFactor(dpi);
+  } else {
+    ManagedDisplayMode mode;
+    if (display_manager_->GetSelectedModeForDisplayId(snapshot->display_id(),
+                                                      &mode)) {
+      device_scale_factor = mode.device_scale_factor();
+      new_info.set_native(mode.native());
+    }
+  }
   new_info.set_device_scale_factor(device_scale_factor);
+
   const gfx::Rect display_bounds(snapshot->origin(), mode_info->size());
   new_info.SetBounds(display_bounds);
-  new_info.set_native(true);
   new_info.set_is_aspect_preserving_scaling(
       snapshot->is_aspect_preserving_scaling());
   if (dpi)
     new_info.set_device_dpi(dpi);
   new_info.set_color_space(snapshot->color_space());
 
+  new_info.set_refresh_rate(mode_info->refresh_rate());
+  new_info.set_is_interlaced(mode_info->is_interlaced());
+
   ManagedDisplayInfo::ManagedDisplayModeList display_modes =
       (snapshot->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
           ? GetInternalManagedDisplayModeList(new_info, *snapshot)
diff --git a/ui/display/manager/display_change_observer.h b/ui/display/manager/display_change_observer.h
index a81a5d8..0e896e2 100644
--- a/ui/display/manager/display_change_observer.h
+++ b/ui/display/manager/display_change_observer.h
@@ -37,15 +37,14 @@
   DISPLAY_EXPORT static ManagedDisplayInfo::ManagedDisplayModeList
   GetExternalManagedDisplayModeList(const DisplaySnapshot& output);
 
-  DisplayChangeObserver(DisplayConfigurator* display_configurator,
-                        DisplayManager* display_manager);
+  explicit DisplayChangeObserver(DisplayManager* display_manager);
   ~DisplayChangeObserver() override;
 
   // DisplayConfigurator::StateController overrides:
   MultipleDisplayState GetStateForDisplayIds(
       const DisplayConfigurator::DisplayStateList& outputs) override;
-  bool GetResolutionForDisplayId(int64_t display_id,
-                                 gfx::Size* size) const override;
+  bool GetSelectedModeForDisplayId(int64_t display_id,
+                                   ManagedDisplayMode* out_mode) const override;
 
   // Overriden from DisplayConfigurator::Observer:
   void OnDisplayModeChanged(
@@ -67,9 +66,7 @@
   ManagedDisplayInfo CreateManagedDisplayInfo(const DisplaySnapshot* snapshot,
                                               const DisplayMode* mode_info);
 
-  // Both |display_configurator_| and |display_manager_| are not owned and must
-  // outlive DisplayChangeObserver.
-  DisplayConfigurator* display_configurator_;
+  // |display_manager_| is not owned and must outlive DisplayChangeObserver.
   DisplayManager* display_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(DisplayChangeObserver);
diff --git a/ui/display/manager/display_change_observer_unittest.cc b/ui/display/manager/display_change_observer_unittest.cc
index 199b6f7e3..31fbc4bf9 100644
--- a/ui/display/manager/display_change_observer_unittest.cc
+++ b/ui/display/manager/display_change_observer_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/display_configurator.h"
 #include "ui/display/manager/fake_display_snapshot.h"
@@ -39,9 +40,31 @@
 
 }  // namespace
 
-using DisplayChangeObserverTest = testing::Test;
+class DisplayChangeObserverTest : public testing::Test,
+                                  public testing::WithParamInterface<bool> {
+ public:
+  DisplayChangeObserverTest() = default;
+  ~DisplayChangeObserverTest() override = default;
 
-TEST_F(DisplayChangeObserverTest, GetExternalManagedDisplayModeList) {
+  // testing::Test:
+  void SetUp() override {
+    if (GetParam()) {
+      scoped_feature_list_.InitAndEnableFeature(features::kListAllDisplayModes);
+    } else {
+      scoped_feature_list_.InitAndDisableFeature(
+          features::kListAllDisplayModes);
+    }
+
+    Test::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(DisplayChangeObserverTest);
+};
+
+TEST_P(DisplayChangeObserverTest, GetExternalManagedDisplayModeList) {
   std::unique_ptr<DisplaySnapshot> display_snapshot =
       FakeDisplaySnapshot::Builder()
           .SetId(123)
@@ -67,33 +90,80 @@
   ManagedDisplayInfo::ManagedDisplayModeList display_modes =
       DisplayChangeObserver::GetExternalManagedDisplayModeList(
           *display_snapshot);
-  ASSERT_EQ(6u, display_modes.size());
-  EXPECT_EQ("640x480", display_modes[0].size().ToString());
-  EXPECT_TRUE(display_modes[0].is_interlaced());
-  EXPECT_EQ(display_modes[0].refresh_rate(), 60);
 
-  EXPECT_EQ("1024x600", display_modes[1].size().ToString());
-  EXPECT_FALSE(display_modes[1].is_interlaced());
-  EXPECT_EQ(display_modes[1].refresh_rate(), 70);
+  const bool listing_all_modes = GetParam();
+  if (listing_all_modes) {
+    ASSERT_EQ(12u, display_modes.size());
+    EXPECT_EQ("640x480", display_modes[0].size().ToString());
+    EXPECT_TRUE(display_modes[0].is_interlaced());
+    EXPECT_EQ(display_modes[0].refresh_rate(), 60);
 
-  EXPECT_EQ("1024x768", display_modes[2].size().ToString());
-  EXPECT_TRUE(display_modes[2].is_interlaced());
-  EXPECT_EQ(display_modes[2].refresh_rate(), 70);
+    EXPECT_EQ("1024x600", display_modes[1].size().ToString());
+    EXPECT_FALSE(display_modes[1].is_interlaced());
+    EXPECT_EQ(display_modes[1].refresh_rate(), 60);
+    EXPECT_EQ("1024x600", display_modes[2].size().ToString());
+    EXPECT_TRUE(display_modes[2].is_interlaced());
+    EXPECT_EQ(display_modes[2].refresh_rate(), 60);
+    EXPECT_EQ("1024x600", display_modes[3].size().ToString());
+    EXPECT_FALSE(display_modes[3].is_interlaced());
+    EXPECT_EQ(display_modes[3].refresh_rate(), 70);
 
-  EXPECT_EQ("1280x720", display_modes[3].size().ToString());
-  EXPECT_FALSE(display_modes[3].is_interlaced());
-  EXPECT_EQ(display_modes[3].refresh_rate(), 60);
+    EXPECT_EQ("1024x768", display_modes[4].size().ToString());
+    EXPECT_TRUE(display_modes[4].is_interlaced());
+    EXPECT_EQ(display_modes[4].refresh_rate(), 60);
+    EXPECT_EQ("1024x768", display_modes[5].size().ToString());
+    EXPECT_TRUE(display_modes[5].is_interlaced());
+    EXPECT_EQ(display_modes[5].refresh_rate(), 70);
 
-  EXPECT_EQ("1920x1080", display_modes[4].size().ToString());
-  EXPECT_FALSE(display_modes[4].is_interlaced());
-  EXPECT_EQ(display_modes[4].refresh_rate(), 80);
+    EXPECT_EQ("1280x720", display_modes[6].size().ToString());
+    EXPECT_FALSE(display_modes[6].is_interlaced());
+    EXPECT_EQ(display_modes[6].refresh_rate(), 60);
+    EXPECT_EQ("1280x720", display_modes[7].size().ToString());
+    EXPECT_TRUE(display_modes[7].is_interlaced());
+    EXPECT_EQ(display_modes[7].refresh_rate(), 60);
 
-  EXPECT_EQ("1920x1200", display_modes[5].size().ToString());
-  EXPECT_FALSE(display_modes[5].is_interlaced());
-  EXPECT_EQ(display_modes[5].refresh_rate(), 60);
+    EXPECT_EQ("1920x1080", display_modes[8].size().ToString());
+    EXPECT_FALSE(display_modes[8].is_interlaced());
+    EXPECT_EQ(display_modes[8].refresh_rate(), 60);
+    EXPECT_EQ("1920x1080", display_modes[9].size().ToString());
+    EXPECT_FALSE(display_modes[9].is_interlaced());
+    EXPECT_EQ(display_modes[9].refresh_rate(), 70);
+    EXPECT_EQ("1920x1080", display_modes[10].size().ToString());
+    EXPECT_FALSE(display_modes[10].is_interlaced());
+    EXPECT_EQ(display_modes[10].refresh_rate(), 80);
+
+    EXPECT_EQ("1920x1200", display_modes[11].size().ToString());
+    EXPECT_FALSE(display_modes[11].is_interlaced());
+    EXPECT_EQ(display_modes[11].refresh_rate(), 60);
+  } else {
+    ASSERT_EQ(6u, display_modes.size());
+    EXPECT_EQ("640x480", display_modes[0].size().ToString());
+    EXPECT_TRUE(display_modes[0].is_interlaced());
+    EXPECT_EQ(display_modes[0].refresh_rate(), 60);
+
+    EXPECT_EQ("1024x600", display_modes[1].size().ToString());
+    EXPECT_FALSE(display_modes[1].is_interlaced());
+    EXPECT_EQ(display_modes[1].refresh_rate(), 70);
+
+    EXPECT_EQ("1024x768", display_modes[2].size().ToString());
+    EXPECT_TRUE(display_modes[2].is_interlaced());
+    EXPECT_EQ(display_modes[2].refresh_rate(), 70);
+
+    EXPECT_EQ("1280x720", display_modes[3].size().ToString());
+    EXPECT_FALSE(display_modes[3].is_interlaced());
+    EXPECT_EQ(display_modes[3].refresh_rate(), 60);
+
+    EXPECT_EQ("1920x1080", display_modes[4].size().ToString());
+    EXPECT_FALSE(display_modes[4].is_interlaced());
+    EXPECT_EQ(display_modes[4].refresh_rate(), 80);
+
+    EXPECT_EQ("1920x1200", display_modes[5].size().ToString());
+    EXPECT_FALSE(display_modes[5].is_interlaced());
+    EXPECT_EQ(display_modes[5].refresh_rate(), 60);
+  }
 }
 
-TEST_F(DisplayChangeObserverTest, GetEmptyExternalManagedDisplayModeList) {
+TEST_P(DisplayChangeObserverTest, GetEmptyExternalManagedDisplayModeList) {
   FakeDisplaySnapshot display_snapshot(
       123, gfx::Point(), gfx::Size(), DISPLAY_CONNECTION_TYPE_UNKNOWN, false,
       false, false, false, std::string(), {}, nullptr, nullptr, 0, gfx::Size());
@@ -104,7 +174,7 @@
   EXPECT_EQ(0u, display_modes.size());
 }
 
-TEST_F(DisplayChangeObserverTest, FindDeviceScaleFactor) {
+TEST_P(DisplayChangeObserverTest, FindDeviceScaleFactor) {
   EXPECT_EQ(1.0f, ComputeDeviceScaleFactor(19.5f, gfx::Rect(1600, 900)));
 
   // 21.5" 1920x1080
@@ -140,7 +210,7 @@
   EXPECT_EQ(2.25f, DisplayChangeObserver::FindDeviceScaleFactor(10000.0f));
 }
 
-TEST_F(DisplayChangeObserverTest,
+TEST_P(DisplayChangeObserverTest,
        FindExternalDisplayNativeModeWhenOverwritten) {
   std::unique_ptr<DisplaySnapshot> display_snapshot =
       FakeDisplaySnapshot::Builder()
@@ -164,4 +234,8 @@
   EXPECT_EQ(display_modes[1].refresh_rate(), 60);
 }
 
+INSTANTIATE_TEST_CASE_P(,
+                        DisplayChangeObserverTest,
+                        ::testing::Values(false, true));
+
 }  // namespace display
diff --git a/ui/display/manager/display_configurator.cc b/ui/display/manager/display_configurator.cc
index a114d43..8e740fd 100644
--- a/ui/display/manager/display_configurator.cc
+++ b/ui/display/manager/display_configurator.cc
@@ -15,10 +15,12 @@
 #include "base/time/time.h"
 #include "chromeos/system/devicemode.h"
 #include "ui/display/display.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/apply_content_protection_task.h"
 #include "ui/display/manager/display_layout_manager.h"
 #include "ui/display/manager/display_util.h"
+#include "ui/display/manager/managed_display_info.h"
 #include "ui/display/manager/update_display_configuration_task.h"
 #include "ui/display/types/display_mode.h"
 #include "ui/display/types/display_snapshot.h"
@@ -69,6 +71,35 @@
   return false;
 }
 
+// Returns true if a platform native |mode| is equal to a |managed_mode|.
+bool AreModesEqual(const DisplayMode& mode,
+                   const ManagedDisplayMode& managed_mode) {
+  return mode.size() == managed_mode.size() &&
+         mode.refresh_rate() == managed_mode.refresh_rate() &&
+         mode.is_interlaced() == managed_mode.is_interlaced();
+}
+
+// Finds and returns a pointer to a platform native mode in the given |display|
+// snapshot's modes which exactly matches the given |managed_mode|. Returns
+// nullptr if nothing was found.
+const DisplayMode* FindExactMatchingMode(
+    const DisplaySnapshot& display,
+    const ManagedDisplayMode& managed_mode) {
+  if (managed_mode.native()) {
+    return display.native_mode() &&
+                   AreModesEqual(*display.native_mode(), managed_mode)
+               ? display.native_mode()
+               : nullptr;
+  }
+
+  for (const std::unique_ptr<const DisplayMode>& mode : display.modes()) {
+    if (AreModesEqual(*mode, managed_mode))
+      return mode.get();
+  }
+
+  return nullptr;
+}
+
 }  // namespace
 
 const int DisplayConfigurator::kSetDisplayPowerNoFlags = 0;
@@ -373,11 +404,23 @@
 const DisplayMode*
 DisplayConfigurator::DisplayLayoutManagerImpl::GetUserSelectedMode(
     const DisplaySnapshot& display) const {
-  gfx::Size size;
   const DisplayMode* selected_mode = nullptr;
-  if (GetStateController() && GetStateController()->GetResolutionForDisplayId(
-                                  display.display_id(), &size)) {
-    selected_mode = FindDisplayModeMatchingSize(display, size);
+  auto* state_controller = GetStateController();
+  if (state_controller) {
+    ManagedDisplayMode mode;
+    const bool mode_found = state_controller->GetSelectedModeForDisplayId(
+        display.display_id(), &mode);
+    if (display::features::IsListAllDisplayModesEnabled()) {
+      // When selecting any arbitrary display mode is enabled, we don't try to
+      // be smart about finding the best mode matching the user-selected display
+      // size, rather we find an exact match to the selected display mode.
+      selected_mode =
+          mode_found ? FindExactMatchingMode(display, mode) : nullptr;
+    } else {
+      selected_mode = mode_found
+                          ? FindDisplayModeMatchingSize(display, mode.size())
+                          : nullptr;
+    }
   }
 
   // Fall back to native mode.
diff --git a/ui/display/manager/display_configurator.h b/ui/display/manager/display_configurator.h
index 5e69a3c3..b458d7af 100644
--- a/ui/display/manager/display_configurator.h
+++ b/ui/display/manager/display_configurator.h
@@ -36,6 +36,7 @@
 class DisplayLayoutManager;
 class DisplayMode;
 class DisplaySnapshot;
+class ManagedDisplayMode;
 class NativeDisplayDelegate;
 class UpdateDisplayConfigurationTask;
 
@@ -98,10 +99,9 @@
     virtual MultipleDisplayState GetStateForDisplayIds(
         const DisplayConfigurator::DisplayStateList& outputs) = 0;
 
-    // Queries the resolution (|size|) in pixels to select display mode for the
-    // given display id.
-    virtual bool GetResolutionForDisplayId(int64_t display_id,
-                                           gfx::Size* size) const = 0;
+    virtual bool GetSelectedModeForDisplayId(
+        int64_t display_id,
+        ManagedDisplayMode* out_mode) const = 0;
   };
 
   // Interface for classes that implement software based mirroring.
diff --git a/ui/display/manager/display_configurator_unittest.cc b/ui/display/manager/display_configurator_unittest.cc
index 76b5c6f..8e92b23 100644
--- a/ui/display/manager/display_configurator_unittest.cc
+++ b/ui/display/manager/display_configurator_unittest.cc
@@ -113,8 +113,9 @@
       const DisplayConfigurator::DisplayStateList& outputs) override {
     return state_;
   }
-  bool GetResolutionForDisplayId(int64_t display_id,
-                                 gfx::Size* size) const override {
+  bool GetSelectedModeForDisplayId(
+      int64_t display_id,
+      ManagedDisplayMode* out_mode) const override {
     return false;
   }
 
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc
index 2e445ba..4aae4ec8 100644
--- a/ui/display/manager/display_manager.cc
+++ b/ui/display/manager/display_manager.cc
@@ -28,6 +28,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/display/display.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_finder.h"
 #include "ui/display/display_observer.h"
 #include "ui/display/display_switches.h"
@@ -43,7 +44,10 @@
 #include "base/system/sys_info.h"
 #include "base/time/time.h"
 #include "chromeos/system/devicemode.h"
+#include "ui/display/manager/display_change_observer.h"
+#include "ui/display/manager/display_configurator.h"
 #include "ui/display/manager/display_util.h"
+#include "ui/display/types/native_display_delegate.h"
 #endif
 
 #if defined(OS_WIN)
@@ -589,6 +593,17 @@
         info.set_device_scale_factor(display_mode.device_scale_factor());
         display_property_changed = true;
       }
+
+      if (features::IsListAllDisplayModesEnabled()) {
+        if (info.refresh_rate() != display_mode.refresh_rate()) {
+          info.set_refresh_rate(display_mode.refresh_rate());
+          resolution_changed = true;
+        }
+        if (info.is_interlaced() != display_mode.is_interlaced()) {
+          info.set_is_interlaced(display_mode.is_interlaced());
+          resolution_changed = true;
+        }
+      }
     }
     display_info_list.emplace_back(info);
   }
@@ -605,7 +620,7 @@
     ReconfigureDisplays();
 #if defined(OS_CHROMEOS)
   else if (resolution_changed && configure_displays_)
-    delegate_->display_configurator()->OnConfigurationChanged();
+    display_configurator_->OnConfigurationChanged();
 #endif  // defined(OS_CHROMEOS)
 
   return resolution_changed || display_property_changed;
@@ -618,7 +633,9 @@
     const gfx::Insets* overscan_insets,
     const gfx::Size& resolution_in_pixels,
     float device_scale_factor,
-    float display_zoom_factor) {
+    float display_zoom_factor,
+    float refresh_rate,
+    bool is_interlaced) {
   if (display_info_.find(display_id) == display_info_.end())
     display_info_[display_id] =
         ManagedDisplayInfo(display_id, std::string(), false);
@@ -627,10 +644,9 @@
   if (display_id == kUnifiedDisplayId)
     rotation = Display::ROTATE_0;
 
-  display_info_[display_id].SetRotation(rotation,
-                                        Display::RotationSource::USER);
-  display_info_[display_id].SetRotation(rotation,
-                                        Display::RotationSource::ACTIVE);
+  ManagedDisplayInfo& info = display_info_[display_id];
+  info.SetRotation(rotation, Display::RotationSource::USER);
+  info.SetRotation(rotation, Display::RotationSource::ACTIVE);
 
   // TODO(malaykeshav|oshima): Remove this code in m71.
   //
@@ -647,21 +663,22 @@
   // display zoom enabled, and hence we do not need to port the value for
   // zoom scale from |ui_scale|.
   if (ui_scale < 0) {
-    display_info_[display_id].set_zoom_factor(display_zoom_factor);
+    info.set_zoom_factor(display_zoom_factor);
   } else {
-    display_info_[display_id].set_zoom_factor(1.f / ui_scale);
-    display_info_[display_id].set_is_zoom_factor_from_ui_scale(true);
+    info.set_zoom_factor(1.f / ui_scale);
+    info.set_is_zoom_factor_from_ui_scale(true);
   }
 
   if (overscan_insets)
-    display_info_[display_id].SetOverscanInsets(*overscan_insets);
+    info.SetOverscanInsets(*overscan_insets);
+
+  info.set_refresh_rate(refresh_rate);
+  info.set_is_interlaced(is_interlaced);
 
   if (!resolution_in_pixels.IsEmpty()) {
     DCHECK(!Display::IsInternalDisplayId(display_id));
-    // Default refresh rate, until OnNativeDisplaysChanged() updates us with the
-    // actual display info, is 60 Hz.
-    ManagedDisplayMode mode(resolution_in_pixels, 60.0f, false, false,
-                            device_scale_factor);
+    ManagedDisplayMode mode(resolution_in_pixels, refresh_rate, is_interlaced,
+                            false, device_scale_factor);
     display_modes_[display_id] = mode;
   }
 }
@@ -809,10 +826,11 @@
       new_display_info_list.emplace_back(display_info);
     }
 
-    ManagedDisplayMode new_mode(display_info.bounds_in_native().size(),
-                                0.0 /* refresh rate */, false /* interlaced */,
-                                false /* native */,
-                                display_info.device_scale_factor());
+    ManagedDisplayMode new_mode(
+        display_info.bounds_in_native().size(), display_info.refresh_rate(),
+        display_info.is_interlaced(), display_info.native(),
+        display_info.device_scale_factor());
+
     const ManagedDisplayInfo::ManagedDisplayModeList& display_modes =
         display_info.display_modes();
     // This is empty the displays are initialized from InitFromCommandLine.
@@ -1354,7 +1372,7 @@
     MultipleDisplayState new_state =
         enabled ? MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
                 : MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED;
-    delegate_->display_configurator()->SetDisplayMode(new_state);
+    display_configurator_->SetDisplayMode(new_state);
     return;
   }
 #endif
@@ -1423,6 +1441,25 @@
 }
 
 #if defined(OS_CHROMEOS)
+void DisplayManager::InitConfigurator(
+    std::unique_ptr<NativeDisplayDelegate> delegate) {
+  display_configurator_ = std::make_unique<display::DisplayConfigurator>();
+  display_configurator_->Init(std::move(delegate),
+                              false /* is_panel_fitting_enabled */);
+}
+
+void DisplayManager::ForceInitialConfigureWithObservers(
+    display::DisplayChangeObserver* display_change_observer,
+    display::DisplayConfigurator::Observer* display_error_observer) {
+  // Register |display_change_observer_| first so that the rest of
+  // observer gets invoked after the root windows are configured.
+  display_configurator_->AddObserver(display_change_observer);
+  display_configurator_->AddObserver(display_error_observer);
+  display_configurator_->set_state_controller(display_change_observer);
+  display_configurator_->set_mirroring_controller(this);
+  display_configurator_->ForceInitialConfigure();
+}
+
 void DisplayManager::SetSoftwareMirroring(bool enabled) {
   SetMultiDisplayMode(enabled ? MIRRORING
                               : current_default_multi_display_mode_);
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h
index fe3e4c1..2fbfc79 100644
--- a/ui/display/manager/display_manager.h
+++ b/ui/display/manager/display_manager.h
@@ -12,6 +12,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/callback.h"
@@ -44,8 +45,10 @@
 }  // namespace gfx
 
 namespace display {
+class DisplayChangeObserver;
 class DisplayLayoutStore;
 class DisplayObserver;
+class NativeDisplayDelegate;
 class Screen;
 
 namespace test {
@@ -79,11 +82,6 @@
     // window and set the focus window to NULL.
     virtual void PreDisplayConfigurationChange(bool clear_focus) = 0;
     virtual void PostDisplayConfigurationChange() = 0;
-
-#if defined(OS_CHROMEOS)
-    // Get the DisplayConfigurator.
-    virtual DisplayConfigurator* display_configurator() = 0;
-#endif
   };
 
   // How secondary displays will be used.
@@ -140,6 +138,8 @@
   TouchDeviceManager* touch_device_manager() const {
     return touch_device_manager_.get();
   }
+
+  DisplayConfigurator* configurator() { return display_configurator_.get(); }
 #endif
 
   const UnifiedDesktopLayoutMatrix& current_unified_desktop_matrix() const {
@@ -216,7 +216,9 @@
                                const gfx::Insets* overscan_insets,
                                const gfx::Size& resolution_in_pixels,
                                float device_scale_factor,
-                               float display_zoom_factor);
+                               float display_zoom_factor,
+                               float refresh_rate,
+                               bool is_interlaced);
 
   // Register stored rotation properties for the internal display.
   void RegisterDisplayRotationProperties(bool rotation_lock,
@@ -423,8 +425,13 @@
       ManagedDisplayInfo::ManagedDisplayModeList display_modes = {});
   void ToggleDisplayScaleFactor();
 
-// SoftwareMirroringController override:
 #if defined(OS_CHROMEOS)
+  void InitConfigurator(std::unique_ptr<NativeDisplayDelegate> delegate);
+  void ForceInitialConfigureWithObservers(
+      display::DisplayChangeObserver* display_change_observer,
+      display::DisplayConfigurator::Observer* display_error_observer);
+
+  // SoftwareMirroringController override:
   void SetSoftwareMirroring(bool enabled) override;
   bool SoftwareMirroringEnabled() const override;
   bool IsSoftwareMirroringEnforced() const override;
@@ -671,6 +678,8 @@
   int notify_depth_ = 0;
 
 #if defined(OS_CHROMEOS)
+  std::unique_ptr<display::DisplayConfigurator> display_configurator_;
+
   std::unique_ptr<TouchDeviceManager> touch_device_manager_;
 
   // A cancelable callback to trigger sending UMA metrics when display zoom is
diff --git a/ui/display/manager/managed_display_info.cc b/ui/display/manager/managed_display_info.cc
index b91b1daab..77d7df01 100644
--- a/ui/display/manager/managed_display_info.cc
+++ b/ui/display/manager/managed_display_info.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "ui/display/display.h"
+#include "ui/display/display_features.h"
 #include "ui/display/display_switches.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/size_f.h"
@@ -118,11 +119,22 @@
 }
 
 bool ManagedDisplayMode::IsEquivalent(const ManagedDisplayMode& other) const {
+  if (display::features::IsListAllDisplayModesEnabled())
+    return *this == other;
+
   const float kEpsilon = 0.0001f;
   return size_ == other.size_ &&
          std::abs(device_scale_factor_ - other.device_scale_factor_) < kEpsilon;
 }
 
+std::string ManagedDisplayMode::ToString() const {
+  return base::StringPrintf(
+      "DisplayMode{size: %s, refresh_rate: %f, interlaced:"
+      " %d, native: %d, device_scale_factor: %f}",
+      size_.ToString().c_str(), refresh_rate_, is_interlaced_, native_,
+      device_scale_factor_);
+}
+
 // static
 ManagedDisplayInfo ManagedDisplayInfo::CreateFromSpec(const std::string& spec) {
   return CreateFromSpecWithID(spec, kInvalidDisplayId);
@@ -272,6 +284,8 @@
       device_dpi_(kDpi96),
       overscan_insets_in_dip_(0, 0, 0, 0),
       zoom_factor_(1.f),
+      refresh_rate_(60.f),
+      is_interlaced_(false),
       is_zoom_factor_from_ui_scale_(false),
       native_(false),
       is_aspect_preserving_scaling_(false),
@@ -290,6 +304,8 @@
       device_dpi_(kDpi96),
       overscan_insets_in_dip_(0, 0, 0, 0),
       zoom_factor_(1.f),
+      refresh_rate_(60.f),
+      is_interlaced_(false),
       is_zoom_factor_from_ui_scale_(false),
       native_(false),
       is_aspect_preserving_scaling_(false),
@@ -337,6 +353,8 @@
   display_modes_ = native_info.display_modes_;
   maximum_cursor_size_ = native_info.maximum_cursor_size_;
   color_space_ = native_info.color_space_;
+  refresh_rate_ = native_info.refresh_rate_;
+  is_interlaced_ = native_info.is_interlaced_;
 
   // Rotation, color_profile and overscan are given by preference,
   // or unit tests. Don't copy if this native_info came from
diff --git a/ui/display/manager/managed_display_info.h b/ui/display/manager/managed_display_info.h
index d1548174..3a42f24 100644
--- a/ui/display/manager/managed_display_info.h
+++ b/ui/display/manager/managed_display_info.h
@@ -56,6 +56,8 @@
   // Missing from ui::ManagedDisplayMode
   float device_scale_factor() const { return device_scale_factor_; }
 
+  std::string ToString() const;
+
  private:
   gfx::Size size_;              // Physical pixel size of the display.
   float refresh_rate_ = 0.0f;   // Refresh rate of the display, in Hz.
@@ -64,6 +66,20 @@
   float device_scale_factor_ = 1.0f;  // The device scale factor of the mode.
 };
 
+inline bool operator==(const ManagedDisplayMode& lhs,
+                       const ManagedDisplayMode& rhs) {
+  return lhs.size() == rhs.size() &&
+         lhs.is_interlaced() == rhs.is_interlaced() &&
+         lhs.refresh_rate() == rhs.refresh_rate() &&
+         lhs.native() == rhs.native() &&
+         lhs.device_scale_factor() == rhs.device_scale_factor();
+}
+
+inline bool operator!=(const ManagedDisplayMode& lhs,
+                       const ManagedDisplayMode& rhs) {
+  return !(lhs == rhs);
+}
+
 // ManagedDisplayInfo contains metadata for each display. This is used to create
 // |Display| as well as to maintain extra infomation to manage displays in ash
 // environment. This class is intentionally made copiable.
@@ -149,6 +165,11 @@
     return is_zoom_factor_from_ui_scale_;
   }
 
+  float refresh_rate() const { return refresh_rate_; }
+  void set_refresh_rate(float refresh_rate) { refresh_rate_ = refresh_rate; }
+  bool is_interlaced() const { return is_interlaced_; }
+  void set_is_interlaced(bool is_interlaced) { is_interlaced_ = is_interlaced; }
+
   // Gets/Sets the device DPI of the display.
   float device_dpi() const { return device_dpi_; }
   void set_device_dpi(float dpi) { device_dpi_ = dpi; }
@@ -293,6 +314,13 @@
   // for a display.
   float zoom_factor_;
 
+  // The value of the current display mode refresh rate.
+  float refresh_rate_;
+
+  // True if the current display mode is interlaced (i.e. the display's odd
+  // and even lines are scanned alternately in two interwoven rasterized lines).
+  bool is_interlaced_;
+
   // True if the |zoom_factor_| currently set is a port of the ui-scale. This is
   // needed to correctly compute zoom values and effective device scale factor
   // for FHD devices with 1.25 device scale factor.
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc
index 27f934c..cdc68677 100644
--- a/ui/events/ozone/evdev/event_factory_evdev.cc
+++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -407,7 +407,7 @@
   TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchStylusStateChanged");
   DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
   observer->OnStylusStateChanged(stylus_state);
-};
+}
 
 void EventFactoryEvdev::DispatchGamepadDevicesUpdated(
     const std::vector<InputDevice>& devices) {
diff --git a/ui/events/ozone/gamepad/static_gamepad_mapping.cc b/ui/events/ozone/gamepad/static_gamepad_mapping.cc
index 6cf8dcca..e59507d 100644
--- a/ui/events/ozone/gamepad/static_gamepad_mapping.cc
+++ b/ui/events/ozone/gamepad/static_gamepad_mapping.cc
@@ -516,7 +516,7 @@
            GamepadEventType* mapped_type,
            uint16_t* mapped_code) const override {
     return mapper_fp_(type, code, mapped_type, mapped_code);
-  };
+  }
 
  private:
   GamepadMapperFunction mapper_fp_;
diff --git a/ui/gl/gl_image_io_surface_egl.mm b/ui/gl/gl_image_io_surface_egl.mm
index 690af44d..d0e7624 100644
--- a/ui/gl/gl_image_io_surface_egl.mm
+++ b/ui/gl/gl_image_io_surface_egl.mm
@@ -190,21 +190,23 @@
   EGLSurface y_surface = EGL_NO_SURFACE;
   EGLSurface uv_surface = EGL_NO_SURFACE;
 
+  EGLSurface* y_surface_ptr = &y_surface;
+  EGLSurface* uv_surface_ptr = &uv_surface;
   glGetIntegerv(target_getter, &rgb_texture);
   base::ScopedClosureRunner destroy_resources_runner(
       base::BindOnce(base::RetainBlock(^{
-        if (y_surface != EGL_NO_SURFACE) {
+        if (*y_surface_ptr != EGL_NO_SURFACE) {
           EGLBoolean result =
-              eglReleaseTexImage(display_, y_surface, EGL_BACK_BUFFER);
+              eglReleaseTexImage(display_, *y_surface_ptr, EGL_BACK_BUFFER);
           DCHECK(result == EGL_TRUE);
-          result = eglDestroySurface(display_, y_surface);
+          result = eglDestroySurface(display_, *y_surface_ptr);
           DCHECK(result == EGL_TRUE);
         }
-        if (uv_surface != EGL_NO_SURFACE) {
+        if (*uv_surface_ptr != EGL_NO_SURFACE) {
           EGLBoolean result =
-              eglReleaseTexImage(display_, uv_surface, EGL_BACK_BUFFER);
+              eglReleaseTexImage(display_, *uv_surface_ptr, EGL_BACK_BUFFER);
           DCHECK(result == EGL_TRUE);
-          result = eglDestroySurface(display_, uv_surface);
+          result = eglDestroySurface(display_, *uv_surface_ptr);
           DCHECK(result == EGL_TRUE);
         }
         glBindTexture(target, rgb_texture);
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
index 84809836..60c79d0 100644
--- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
+++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -25,7 +25,7 @@
   void* GetMemoryAddress(size_t plane) const override {
     NOTREACHED();
     return nullptr;
-  };
+  }
   void Unmap() override { NOTREACHED(); }
   int GetStride(size_t plane) const override {
     NOTREACHED();
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc
index 1e3aac6..6d4c27f 100644
--- a/ui/views/controls/scroll_view.cc
+++ b/ui/views/controls/scroll_view.cc
@@ -749,7 +749,6 @@
                                         contents_viewport_->height());
 
   ScrollToOffset(gfx::ScrollOffset(new_x, new_y));
-  UpdateScrollBarPositions();
 }
 
 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size,
@@ -834,6 +833,7 @@
     ScrollHeader();
   }
   UpdateOverflowIndicatorVisibility(offset);
+  UpdateScrollBarPositions();
 }
 
 bool ScrollView::ScrollsWithLayers() const {
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc
index 41565d3..377b8fa 100644
--- a/ui/views/controls/scroll_view_unittest.cc
+++ b/ui/views/controls/scroll_view_unittest.cc
@@ -682,6 +682,34 @@
   EXPECT_EQ("-1,0", header->origin().ToString());
 }
 
+// Test that calling ScrollToPosition() also updates the position of the
+// corresponding ScrollBar.
+TEST_F(ScrollViewTest, ScrollToPositionUpdatesScrollBar) {
+  ScrollViewTestApi test_api(scroll_view_.get());
+  View* contents = InstallContents();
+
+  // Scroll the horizontal scrollbar, after which, the scroll bar thumb position
+  // should be updated (i.e. it should be non-zero).
+  contents->SetBounds(0, 0, 400, 50);
+  scroll_view_->Layout();
+  auto* scroll_bar = test_api.GetBaseScrollBar(HORIZONTAL);
+  ASSERT_TRUE(scroll_bar);
+  EXPECT_TRUE(scroll_bar->visible());
+  EXPECT_EQ(0, scroll_bar->GetPosition());
+  scroll_view_->ScrollToPosition(scroll_bar, 20);
+  EXPECT_GT(scroll_bar->GetPosition(), 0);
+
+  // Scroll the vertical scrollbar.
+  contents->SetBounds(0, 0, 50, 400);
+  scroll_view_->Layout();
+  scroll_bar = test_api.GetBaseScrollBar(VERTICAL);
+  ASSERT_TRUE(scroll_bar);
+  EXPECT_TRUE(scroll_bar->visible());
+  EXPECT_EQ(0, scroll_bar->GetPosition());
+  scroll_view_->ScrollToPosition(scroll_bar, 20);
+  EXPECT_GT(scroll_bar->GetPosition(), 0);
+}
+
 // Verifies ScrollRectToVisible() on the child works.
 TEST_F(ScrollViewTest, ScrollRectToVisible) {
   ScrollViewTestApi test_api(scroll_view_.get());
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm
index ceea26b..6086be1 100644
--- a/ui/views/widget/native_widget_mac_unittest.mm
+++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1774,8 +1774,8 @@
   // WidgetDelegate:
   base::string16 GetWindowTitle() const override { return title_; }
   bool ShouldShowWindowTitle() const override { return should_show_title_; }
-  Widget* GetWidget() override { return widget_; };
-  const Widget* GetWidget() const override { return widget_; };
+  Widget* GetWidget() override { return widget_; }
+  const Widget* GetWidget() const override { return widget_; }
 
  private:
   Widget* widget_;
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 04a14bf9..d25169e 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -804,6 +804,9 @@
   dragged_view_ = view;
   OnDragWillStart();
 
+  for (WidgetObserver& observer : observers_)
+    observer.OnWidgetDragWillStart(this);
+
   WidgetDeletionObserver widget_deletion_observer(this);
   native_widget_->RunShellDrag(view, data, location, operation, source);
 
@@ -818,6 +821,9 @@
     view->OnDragDone();
   }
   OnDragComplete();
+
+  for (WidgetObserver& observer : observers_)
+    observer.OnWidgetDragComplete(this);
 }
 
 void Widget::SchedulePaintInRect(const gfx::Rect& rect) {
diff --git a/ui/views/widget/widget_observer.h b/ui/views/widget/widget_observer.h
index aa3e17f2..698ee1e 100644
--- a/ui/views/widget/widget_observer.h
+++ b/ui/views/widget/widget_observer.h
@@ -37,8 +37,11 @@
   // widget has been destroyed.
   virtual void OnWidgetDestroyed(Widget* widget) {}
 
-  virtual void OnWidgetVisibilityChanging(Widget* widget, bool visible) {}
+  // Called before RunShellDrag() is called and after it returns.
+  virtual void OnWidgetDragWillStart(Widget* widget) {}
+  virtual void OnWidgetDragComplete(Widget* widget) {}
 
+  virtual void OnWidgetVisibilityChanging(Widget* widget, bool visible) {}
   virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) {}
 
   virtual void OnWidgetActivationChanged(Widget* widget, bool active) {}