diff --git a/DEPS b/DEPS
index beb4e26a..78324c8 100644
--- a/DEPS
+++ b/DEPS
@@ -145,11 +145,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': '6808e2d1faaccd6fc739f436c2470f199aa4d1a8',
+  'skia_revision': '1a607e7b6e9afa4ced12fe44fa63fa8977913a80',
   # 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': '38a850d9c915db6aed80c65ed7ccac346c897dcb',
+  'v8_revision': 'f99c5871c63b691664039d0366c5524db9bced65',
   # 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.
@@ -157,7 +157,7 @@
   # 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': '34ebecc19c6bbee5d7f9270bc2f0418ce6b8907d',
+  'angle_revision': '3e493c48d2da71f045582fe80e44343316cec5f1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -208,7 +208,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': '88aae3b05111daa5754f6c098e071d7bf330beb4',
+  'catapult_revision': '471a922d82cac522a2046194a597210ace8e057a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -834,7 +834,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c0758331ea123f64269ed26d71624751cbd8f892',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '364640e2491e6288452cc9cdc8c7913a0bf1d17e',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1207,7 +1207,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'ccb430fd4ebb8cb9b38d919625ab8afdad338ed4',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'e2248cbc238c392747af86dc007f6b7fe97b22c9',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1375,7 +1375,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'e529ecb5bb99f6d437df685a478b5143b35cbb3f',
+    Var('webrtc_git') + '/src.git' + '@' + 'd0b67c2a70b3812fb60c6fdf7a049e645be4f7b3',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1416,7 +1416,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bf1198869aba9c2252b7f3829d37788d9a877f0a',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@80dc3d15d3e3a3368fc20dff40dbb8e23d57d399',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index bd1e1f3..dab3e80 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -1188,8 +1188,9 @@
     scale *= browser_view_renderer_.dip_scale();
 
   DCHECK_GE(duration_ms, 0);
-  render_view_host_ext_->SmoothScroll(target_x / scale, target_y / scale,
-                                      duration_ms);
+  render_view_host_ext_->SmoothScroll(
+      target_x / scale, target_y / scale,
+      base::TimeDelta::FromMilliseconds(duration_ms));
 }
 
 void AwContents::OnWebLayoutPageScaleFactorChanged(float page_scale_factor) {
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 7789d3b..7c9349db4 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
@@ -134,10 +134,10 @@
 
 void AwRenderViewHostExt::SmoothScroll(int target_x,
                                        int target_y,
-                                       uint64_t duration_ms) {
+                                       base::TimeDelta duration) {
   web_contents()->GetMainFrame()->Send(
       new AwViewMsg_SmoothScroll(web_contents()->GetMainFrame()->GetRoutingID(),
-                                 target_x, target_y, duration_ms));
+                                 target_x, target_y, duration));
 }
 
 void AwRenderViewHostExt::RenderViewHostChanged(
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 fe2d3a2..7d80e11 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
@@ -78,7 +78,7 @@
   void SetWillSuppressErrorPage(bool suppress);
   void SetJsOnlineProperty(bool network_up);
 
-  void SmoothScroll(int target_x, int target_y, uint64_t duration_ms);
+  void SmoothScroll(int target_x, int target_y, base::TimeDelta duration);
 
  private:
   // content::WebContentsObserver implementation.
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index 10a4f4b..4e0fa848 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -85,7 +85,7 @@
 IPC_MESSAGE_ROUTED3(AwViewMsg_SmoothScroll,
                     int /* target_x */,
                     int /* target_y */,
-                    uint64_t /* duration_ms */)
+                    base::TimeDelta /* duration */)
 
 // Sent to inform renderers whether the internal error page should be shown or
 // not.
diff --git a/android_webview/renderer/aw_render_frame_ext.cc b/android_webview/renderer/aw_render_frame_ext.cc
index b2f1535..c6c220b3 100644
--- a/android_webview/renderer/aw_render_frame_ext.cc
+++ b/android_webview/renderer/aw_render_frame_ext.cc
@@ -341,12 +341,12 @@
 
 void AwRenderFrameExt::OnSmoothScroll(int target_x,
                                       int target_y,
-                                      uint64_t duration_ms) {
+                                      base::TimeDelta duration) {
   blink::WebView* webview = GetWebView();
   if (!webview)
     return;
 
-  webview->SmoothScroll(target_x, target_y, duration_ms);
+  webview->SmoothScroll(target_x, target_y, duration);
 }
 
 void AwRenderFrameExt::OnSetWillSuppressErrorPage(bool suppress) {
diff --git a/android_webview/renderer/aw_render_frame_ext.h b/android_webview/renderer/aw_render_frame_ext.h
index 389a6bf..3225ab0 100644
--- a/android_webview/renderer/aw_render_frame_ext.h
+++ b/android_webview/renderer/aw_render_frame_ext.h
@@ -59,7 +59,7 @@
 
   void OnSetBackgroundColor(SkColor c);
 
-  void OnSmoothScroll(int target_x, int target_y, uint64_t duration_ms);
+  void OnSmoothScroll(int target_x, int target_y, base::TimeDelta duration);
 
   void OnSetWillSuppressErrorPage(bool suppress);
 
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc
index c0adf96..ac1ae589 100644
--- a/ash/accessibility/accessibility_controller_impl.cc
+++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -523,6 +523,11 @@
   active_user_prefs_->CommitPendingWrite();
 }
 
+bool AccessibilityControllerImpl::GetTrayVisiblityOfLargeCursorSetting() {
+  return IsAccessibilityFeatureVisibleInTrayMenu(
+      prefs::kAccessibilityLargeCursorEnabled);
+}
+
 void AccessibilityControllerImpl::SetMonoAudioEnabled(bool enabled) {
   if (!active_user_prefs_)
     return;
@@ -1354,4 +1359,15 @@
     observer.OnAccessibilityStatusChanged();
 }
 
+bool AccessibilityControllerImpl::IsAccessibilityFeatureVisibleInTrayMenu(
+    const std::string& path) {
+  if (!active_user_prefs_)
+    return true;
+  if (active_user_prefs_->FindPreference(path)->IsManaged() &&
+      !active_user_prefs_->GetBoolean(path)) {
+    return false;
+  }
+  return true;
+}
+
 }  // namespace ash
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h
index 6c237d1..b965a8a7 100644
--- a/ash/accessibility/accessibility_controller_impl.h
+++ b/ash/accessibility/accessibility_controller_impl.h
@@ -105,6 +105,10 @@
 
   void SetLargeCursorEnabled(bool enabled);
   bool large_cursor_enabled() const { return large_cursor_enabled_; }
+  // Returns true if the large cursor is being controlled by a policy which
+  // enforces turning it on or its not being controlled by any type of policy
+  // and false otherwise.
+  bool GetTrayVisiblityOfLargeCursorSetting();
 
   void SetMonoAudioEnabled(bool enabled);
   bool mono_audio_enabled() const { return mono_audio_enabled_; }
@@ -195,6 +199,8 @@
   base::string16 GetBatteryDescription() const override;
   void SetVirtualKeyboardVisible(bool is_visible) override;
   void NotifyAccessibilityStatusChanged() override;
+  bool IsAccessibilityFeatureVisibleInTrayMenu(
+      const std::string& path) override;
 
   // SessionObserver:
   void OnSigninScreenPrefServiceInitialized(PrefService* prefs) override;
diff --git a/ash/accessibility/accessibility_controller_unittest.cc b/ash/accessibility/accessibility_controller_unittest.cc
index 8e8c0c73..3c34152 100644
--- a/ash/accessibility/accessibility_controller_unittest.cc
+++ b/ash/accessibility/accessibility_controller_unittest.cc
@@ -13,6 +13,7 @@
 #include "ash/public/cpp/ash_constants.h"
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/session/session_controller_impl.h"
+#include "ash/session/test_pref_service_provider.h"
 #include "ash/shell.h"
 #include "ash/sticky_keys/sticky_keys_controller.h"
 #include "ash/test/ash_test_base.h"
@@ -22,6 +23,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "ui/message_center/message_center.h"
 
 using message_center::MessageCenter;
@@ -190,6 +192,46 @@
   controller->RemoveObserver(&observer);
 }
 
+TEST_F(AccessibilityControllerTest, LargeCursorTrayMenuVisibility) {
+  // Check that when the pref isn't being controlled by any policy will be
+  // visible in the accessibility tray menu despite its value.
+  PrefService* prefs =
+      Shell::Get()->session_controller()->GetLastActiveUserPrefService();
+  AccessibilityControllerImpl* controller =
+      Shell::Get()->accessibility_controller();
+  // Check when the value is true and not being controlled by any policy.
+  controller->SetLargeCursorEnabled(true);
+  EXPECT_TRUE(controller->large_cursor_enabled());
+  EXPECT_FALSE(
+      prefs->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
+  EXPECT_TRUE(controller->GetTrayVisiblityOfLargeCursorSetting());
+  // Check when the value is false and not being controlled by any policy.
+  controller->SetLargeCursorEnabled(false);
+  EXPECT_FALSE(controller->large_cursor_enabled());
+  EXPECT_FALSE(
+      prefs->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
+  EXPECT_TRUE(controller->GetTrayVisiblityOfLargeCursorSetting());
+
+  // Check that when the pref is managed and being forced on then it will be
+  // visible.
+  static_cast<TestingPrefServiceSimple*>(prefs)->SetManagedPref(
+      prefs::kAccessibilityLargeCursorEnabled,
+      std::make_unique<base::Value>(true));
+  EXPECT_TRUE(
+      prefs->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
+  EXPECT_TRUE(controller->large_cursor_enabled());
+  EXPECT_TRUE(controller->GetTrayVisiblityOfLargeCursorSetting());
+  // Check that when the pref is managed and only being forced off then it will
+  // be invisible.
+  static_cast<TestingPrefServiceSimple*>(prefs)->SetManagedPref(
+      prefs::kAccessibilityLargeCursorEnabled,
+      std::make_unique<base::Value>(false));
+  EXPECT_TRUE(
+      prefs->IsManagedPreference(prefs::kAccessibilityLargeCursorEnabled));
+  EXPECT_FALSE(controller->large_cursor_enabled());
+  EXPECT_FALSE(controller->GetTrayVisiblityOfLargeCursorSetting());
+}
+
 TEST_F(AccessibilityControllerTest, DisableLargeCursorResetsSize) {
   PrefService* prefs =
       Shell::Get()->session_controller()->GetLastActiveUserPrefService();
diff --git a/ash/app_list/views/app_list_main_view.cc b/ash/app_list/views/app_list_main_view.cc
index 742a4b6..26bfac8 100644
--- a/ash/app_list/views/app_list_main_view.cc
+++ b/ash/app_list/views/app_list_main_view.cc
@@ -211,10 +211,9 @@
 
   SearchResultBaseView* first_result_view =
       contents_view_->search_results_page_view()->first_result_view();
-  if (!first_result_view || !first_result_view->background_highlighted())
+  if (!first_result_view || !first_result_view->selected())
     return;
-
-  first_result_view->SetBackgroundHighlighted(false);
+  first_result_view->SetSelected(false, base::nullopt);
 }
 
 void AppListMainView::AssistantButtonPressed() {
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc
index 60e1cf8..1de1816 100644
--- a/ash/app_list/views/app_list_view_unittest.cc
+++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -1373,7 +1373,7 @@
   EXPECT_EQ(search_box_view()->search_box(), focused_view());
   EXPECT_EQ(list_view->GetResultViewAt(0),
             contents_view()->search_results_page_view()->first_result_view());
-  EXPECT_TRUE(list_view->GetResultViewAt(0)->background_highlighted());
+  EXPECT_TRUE(list_view->GetResultViewAt(0)->selected());
 
   // Populate both fake list results and tile results.
   const int kTileResults = 3;
@@ -1385,7 +1385,7 @@
   EXPECT_EQ(search_box_view()->search_box(), focused_view());
   EXPECT_EQ(tile_views[0],
             contents_view()->search_results_page_view()->first_result_view());
-  EXPECT_TRUE(tile_views[0]->background_highlighted());
+  EXPECT_TRUE(tile_views[0]->selected());
 
   // This section should remain after flag is removed.
   if (app_list_features::IsSearchBoxSelectionEnabled()) {
@@ -1399,7 +1399,7 @@
 
     // Ensure current highlighted result loses highlight on transition
     SimulateKeyPress(ui::VKEY_TAB, false);
-    EXPECT_FALSE(tile_views[0]->background_highlighted());
+    EXPECT_FALSE(tile_views[0]->selected());
   }
 
   // Populate only answer card.
@@ -1411,7 +1411,7 @@
           ->GetAnswerCardResultViewForTest());
   EXPECT_EQ(answer_container,
             contents_view()->search_results_page_view()->first_result_view());
-  EXPECT_TRUE(answer_container->background_highlighted());
+  EXPECT_TRUE(answer_container->selected());
 
   // SearchBoxSelection keeps selection within existing results. Tabbing from
   // within a single result has no effect.
@@ -1423,7 +1423,7 @@
     EXPECT_EQ(search_box_view()->close_button(), focused_view());
     EXPECT_EQ(answer_container,
               contents_view()->search_results_page_view()->first_result_view());
-    EXPECT_FALSE(answer_container->background_highlighted());
+    EXPECT_FALSE(answer_container->selected());
     SimulateKeyPress(ui::VKEY_TAB, true);
   }
 
@@ -1458,7 +1458,7 @@
       contents_view()->search_results_page_view()->first_result_view();
   EXPECT_EQ(search_box_view()->search_box(), focused_view());
   EXPECT_EQ(list_view->GetResultViewAt(0), first_result_view);
-  EXPECT_TRUE(first_result_view->background_highlighted());
+  EXPECT_TRUE(first_result_view->selected());
 
   // Type something else.
   search_box_view()->search_box()->InsertText(base::ASCIIToUTF16("test2"));
@@ -1470,7 +1470,7 @@
   EXPECT_EQ(search_box_view()->close_button(), focused_view());
   SimulateKeyPress(ui::VKEY_TAB, false);
   EXPECT_EQ(list_view->GetResultViewAt(0), focused_view());
-  EXPECT_TRUE(first_result_view->background_highlighted());
+  EXPECT_TRUE(first_result_view->selected());
 
   // Update search results, both list and tile results are populated.
   const int kTileResults = 3;
@@ -1484,7 +1484,7 @@
   EXPECT_EQ(list_view->GetResultViewAt(0), focused_view());
   EXPECT_EQ(tile_views[0], first_result_view);
   EXPECT_FALSE(first_result_view->HasFocus());
-  EXPECT_TRUE(list_view->GetResultViewAt(0)->background_highlighted());
+  EXPECT_TRUE(list_view->GetResultViewAt(0)->selected());
 }
 
 // Tests hitting Enter key when focus is on search box.
diff --git a/ash/app_list/views/assistant/dialog_plate.cc b/ash/app_list/views/assistant/dialog_plate.cc
index dfa98c4..331b2ef8 100644
--- a/ash/app_list/views/assistant/dialog_plate.cc
+++ b/ash/app_list/views/assistant/dialog_plate.cc
@@ -315,7 +315,7 @@
 
   auto textfield_hint =
       l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_HINT);
-  textfield_->set_placeholder_text(textfield_hint);
+  textfield_->SetPlaceholderText(textfield_hint);
   textfield_->SetAccessibleName(textfield_hint);
   textfield_->set_placeholder_text_color(ash::kTextColorSecondary);
   textfield_->SetTextColor(ash::kTextColorPrimary);
diff --git a/ash/app_list/views/folder_header_view.cc b/ash/app_list/views/folder_header_view.cc
index 0a88c834..fe28d6e60 100644
--- a/ash/app_list/views/folder_header_view.cc
+++ b/ash/app_list/views/folder_header_view.cc
@@ -101,7 +101,7 @@
       folder_name_visible_(true),
       is_tablet_mode_(false) {
   folder_name_view_->set_placeholder_text_color(kFolderTitleHintTextColor);
-  folder_name_view_->set_placeholder_text(folder_name_placeholder_text_);
+  folder_name_view_->SetPlaceholderText(folder_name_placeholder_text_);
   folder_name_view_->SetBorder(views::NullBorder());
 
   // Make folder name font size 14px.
@@ -265,8 +265,8 @@
   if (new_contents.length() >
       AppListConfig::instance().max_folder_name_chars()) {
     folder_name_view_->SetText(previous_folder_name_.value());
-    sender->SelectRange(gfx::Range(previous_cursor_position_.value(),
-                                   previous_cursor_position_.value()));
+    sender->SetSelectedRange(gfx::Range(previous_cursor_position_.value(),
+                                        previous_cursor_position_.value()));
   } else {
     previous_folder_name_ = new_contents;
     delegate_->SetItemName(folder_item_, base::UTF16ToUTF8(new_contents));
diff --git a/ash/app_list/views/result_selection_controller.cc b/ash/app_list/views/result_selection_controller.cc
index aae7cb39..881c66c 100644
--- a/ash/app_list/views/result_selection_controller.cc
+++ b/ash/app_list/views/result_selection_controller.cc
@@ -43,7 +43,9 @@
 bool ResultSelectionController::MoveSelection(const ui::KeyEvent& event) {
   ResultLocationDetails next_location = GetNextResultLocation(event);
   bool selection_changed = !(next_location == *selected_location_details_);
-  SetSelection(next_location);
+  if (selection_changed) {
+    SetSelection(next_location, event.IsShiftDown());
+  }
   return selection_changed;
 }
 
@@ -51,7 +53,7 @@
   // Prevents crash on start up
   if (result_selection_model_->size() == 0)
     return;
-  ClearSelection();
+
   selected_location_details_ = std::make_unique<ResultLocationDetails>(
       0 /* container_index */,
       result_selection_model_->size() /* container_count */,
@@ -60,15 +62,23 @@
       result_selection_model_->at(0)
           ->horizontally_traversable() /* container_is_horizontal */);
 
-  selected_result_ = result_selection_model_->at(0)->GetFirstResultView();
+  auto* new_selection = result_selection_model_->at(0)->GetFirstResultView();
+  if (new_selection && new_selection->selected())
+    return;
+
   if (selected_result_)
-    selected_result_->SetBackgroundHighlighted(true);
+    selected_result_->SetSelected(false, base::nullopt);
+
+  selected_result_ = new_selection;
+
+  if (selected_result_)
+    selected_result_->SetSelected(true, base::nullopt);
 }
 
 void ResultSelectionController::ClearSelection() {
   selected_location_details_ = nullptr;
   if (selected_result_)
-    selected_result_->SetBackgroundHighlighted(false);
+    selected_result_->SetSelected(false, base::nullopt);
   selected_result_ = nullptr;
 }
 
@@ -88,20 +98,27 @@
   if (!(IsUnhandledArrowKeyEvent(event) || event.key_code() == ui::VKEY_TAB))
     return new_location;
 
+  if (selected_result_ && event.key_code() == ui::VKEY_TAB &&
+      selected_result_->SelectNextResultAction(event.IsShiftDown())) {
+    return new_location;
+  }
+
   switch (event.key_code()) {
     case ui::VKEY_TAB:
       if (event.IsShiftDown()) {
         // Reverse tab traversal always goes to the 'previous' result.
-        if (location.is_first_result())
+        if (location.is_first_result()) {
           ChangeContainer(&new_location, location.container_index - 1);
-        else
+        } else {
           --new_location.result_index;
+        }
       } else {
         // Forward tab traversal always goes to the 'next' result.
-        if (location.is_last_result())
+        if (location.is_last_result()) {
           ChangeContainer(&new_location, location.container_index + 1);
-        else
+        } else {
           ++new_location.result_index;
+        }
       }
 
       break;
@@ -162,13 +179,14 @@
 }
 
 void ResultSelectionController::SetSelection(
-    const ResultLocationDetails& location) {
+    const ResultLocationDetails& location,
+    bool reverse_tab_order) {
   ClearSelection();
 
   selected_result_ = GetResultAtLocation(location);
   selected_location_details_ =
       std::make_unique<ResultLocationDetails>(location);
-  selected_result_->SetBackgroundHighlighted(true);
+  selected_result_->SetSelected(true, reverse_tab_order);
 }
 
 SearchResultBaseView* ResultSelectionController::GetResultAtLocation(
diff --git a/ash/app_list/views/result_selection_controller.h b/ash/app_list/views/result_selection_controller.h
index b28a248..32549ab1 100644
--- a/ash/app_list/views/result_selection_controller.h
+++ b/ash/app_list/views/result_selection_controller.h
@@ -5,6 +5,7 @@
 #ifndef ASH_APP_LIST_VIEWS_RESULT_SELECTION_CONTROLLER_H_
 #define ASH_APP_LIST_VIEWS_RESULT_SELECTION_CONTROLLER_H_
 
+#include <memory>
 #include <vector>
 
 #include "ash/app_list/app_list_export.h"
@@ -93,7 +94,8 @@
       const ResultLocationDetails& location);
 
   // Sets the current selection to the provided |location|.
-  void SetSelection(const ResultLocationDetails& location);
+  void SetSelection(const ResultLocationDetails& location,
+                    bool reverse_tab_order);
 
   SearchResultBaseView* GetResultAtLocation(
       const ResultLocationDetails& location);
diff --git a/ash/app_list/views/result_selection_controller_unittest.cc b/ash/app_list/views/result_selection_controller_unittest.cc
index 9b73060..1135054 100644
--- a/ash/app_list/views/result_selection_controller_unittest.cc
+++ b/ash/app_list/views/result_selection_controller_unittest.cc
@@ -13,6 +13,8 @@
 #include <vector>
 
 #include "ash/app_list/test/app_list_test_view_delegate.h"
+#include "ash/app_list/views/search_result_actions_view.h"
+#include "ash/app_list/views/search_result_actions_view_delegate.h"
 #include "ash/app_list/views/search_result_container_view.h"
 #include "base/macros.h"
 #include "ui/events/event.h"
@@ -20,11 +22,17 @@
 namespace app_list {
 namespace {
 
+class TestResultViewWithActions;
+
 class TestResultView : public SearchResultBaseView {
  public:
   TestResultView() = default;
   ~TestResultView() override = default;
 
+  virtual TestResultViewWithActions* AsResultViewWithActions() {
+    return nullptr;
+  }
+
   void ButtonPressed(Button* sender, const ui::Event& event) override {
     // Do nothing for test.
   }
@@ -33,6 +41,32 @@
   DISALLOW_COPY_AND_ASSIGN(TestResultView);
 };
 
+class TestResultViewWithActions : public TestResultView,
+                                  public SearchResultActionsViewDelegate {
+ public:
+  TestResultViewWithActions()
+      : actions_view_owned_(std::make_unique<SearchResultActionsView>(this)) {
+    set_actions_view(actions_view_owned_.get());
+  }
+
+  // TestResultView:
+  TestResultViewWithActions* AsResultViewWithActions() override { return this; }
+
+  // SearchResultActionsViewDelegate:
+  void OnSearchResultActionActivated(size_t index, int event_flags) override {}
+  void OnSearchResultActionsUnSelected() override {}
+  bool IsSearchResultHoveredOrSelected() override { return selected(); }
+
+  SearchResultActionsView* GetActionsView() {
+    return actions_view_owned_.get();
+  }
+
+ private:
+  std::unique_ptr<SearchResultActionsView> actions_view_owned_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestResultViewWithActions);
+};
+
 // Allows immediate invocation of |VerticalTestContainer| and its derivatives,
 // by handling the fake delegate's setup.
 class TestContainerDelegateHarness {
@@ -51,42 +85,66 @@
   DISALLOW_COPY_AND_ASSIGN(TestContainerDelegateHarness);
 };
 
-class VerticalTestContainer : public TestContainerDelegateHarness,
-                              public SearchResultContainerView {
+struct TestContainerParams {
+  TestContainerParams() = default;
+  TestContainerParams(bool horizontal, int result_count)
+      : horizontal(horizontal), result_count(result_count) {}
+  TestContainerParams(bool horizontal, int result_count, int actions_per_result)
+      : horizontal(horizontal),
+        result_count(result_count),
+        actions_per_result(actions_per_result) {}
+
+  // Whether the contairne is horizontal.
+  bool horizontal = false;
+
+  // Number of results in the container.
+  int result_count = 0;
+
+  // If set, the container will contain TestResultViewWithActions that
+  // have |actions_per_result| actions each.
+  base::Optional<int> actions_per_result;
+};
+
+class TestContainer : public TestContainerDelegateHarness,
+                      public SearchResultContainerView {
  public:
-  explicit VerticalTestContainer(int num_results)
+  explicit TestContainer(const TestContainerParams& params)
       : SearchResultContainerView(app_list_test_delegate_.get()) {
-    for (int i = 0; i < num_results; ++i) {
-      search_result_views_.emplace_back(std::make_unique<TestResultView>());
+    set_horizontally_traversable(params.horizontal);
+
+    for (int i = 0; i < params.result_count; ++i) {
+      if (params.actions_per_result.has_value()) {
+        auto result = std::make_unique<TestResultViewWithActions>();
+        result->GetActionsView()->SetActions(std::vector<SearchResult::Action>(
+            params.actions_per_result.value(),
+            SearchResult::Action(gfx::ImageSkia(), base::string16(), false)));
+        search_result_views_.emplace_back(std::move(result));
+      } else {
+        search_result_views_.emplace_back(std::make_unique<TestResultView>());
+      }
+
       search_result_views_.back()->set_index_in_container(i);
     }
+
     Update();
   }
-  ~VerticalTestContainer() override = default;
+  ~TestContainer() override = default;
 
-  TestResultView* GetResultViewAt(size_t index) override {
+  // SearchResultContainerView:
+  SearchResultBaseView* GetResultViewAt(size_t index) override {
     DCHECK_LT(index, search_result_views_.size());
     return search_result_views_[index].get();
   }
+  SearchResultBaseView* GetFirstResultView() override {
+    return GetResultViewAt(0);
+  }
 
  private:
   int DoUpdate() override { return search_result_views_.size(); }
 
   std::vector<std::unique_ptr<TestResultView>> search_result_views_;
 
-  DISALLOW_COPY_AND_ASSIGN(VerticalTestContainer);
-};
-
-class HorizontalTestContainer : public VerticalTestContainer {
- public:
-  explicit HorizontalTestContainer(int num_results)
-      : VerticalTestContainer(num_results) {
-    set_horizontally_traversable(true);
-  }
-
-  ~HorizontalTestContainer() override = default;
-
-  DISALLOW_COPY_AND_ASSIGN(HorizontalTestContainer);
+  DISALLOW_COPY_AND_ASSIGN(TestContainer);
 };
 
 class ResultSelectionTest : public testing::Test,
@@ -115,17 +173,13 @@
   }
 
  protected:
-  std::vector<std::unique_ptr<SearchResultContainerView>>
-  CreateContainerVector(int container_count, int results, bool horizontal) {
+  std::vector<std::unique_ptr<SearchResultContainerView>> CreateContainerVector(
+      int container_count,
+      const TestContainerParams& container_params) {
     std::vector<std::unique_ptr<SearchResultContainerView>> containers;
     for (int i = 0; i < container_count; i++) {
-      if (horizontal) {
-        containers.emplace_back(
-            std::make_unique<HorizontalTestContainer>(results));
-      } else {
-        containers.emplace_back(
-            std::make_unique<VerticalTestContainer>(results));
-      }
+      containers.emplace_back(
+          std::make_unique<TestContainer>(container_params));
     }
     return containers;
   }
@@ -145,6 +199,68 @@
     return locations;
   }
 
+  ResultLocationDetails GetCurrentLocation() const {
+    return *result_selection_controller_->selected_location_details();
+  }
+
+  TestResultView* GetCurrentSelection() {
+    ResultLocationDetails location = GetCurrentLocation();
+    SearchResultBaseView* view =
+        containers_[location.container_index]->GetResultViewAt(
+            location.result_index);
+    return static_cast<TestResultView*>(view);
+  }
+
+  // Asserts that currently selected result has a result action selected.
+  // |action_index| - the index of the selected result action.
+  testing::AssertionResult CurrentResultActionSelected(int action_index) {
+    TestResultViewWithActions* view =
+        GetCurrentSelection()->AsResultViewWithActions();
+    if (!view) {
+      return testing::AssertionFailure()
+             << "Selected view with no action support";
+    }
+
+    if (!view->selected())
+      return testing::AssertionFailure() << "View not selected";
+
+    if (!view->GetActionsView()->HasSelectedAction())
+      return testing::AssertionFailure() << "No selected action";
+
+    int selected_action = view->GetActionsView()->GetSelectedAction();
+    if (selected_action != action_index) {
+      return testing::AssertionFailure()
+             << "Wrong selected action " << selected_action;
+    }
+
+    return testing::AssertionSuccess();
+  }
+
+  // Asserts that the currently selected result has no selected result actions.
+  testing::AssertionResult CurrentResultActionNotSelected() {
+    TestResultViewWithActions* view =
+        GetCurrentSelection()->AsResultViewWithActions();
+    if (!view) {
+      return testing::AssertionFailure()
+             << "Selected view with no action support";
+    }
+
+    if (!view->selected())
+      return testing::AssertionFailure() << "View not selected";
+
+    int selected_action = view->GetActionsView()->GetSelectedAction();
+    if (view->GetActionsView()->HasSelectedAction()) {
+      return testing::AssertionFailure()
+             << "Selected action found " << selected_action;
+    }
+
+    if (selected_action != -1) {
+      return testing::AssertionFailure()
+             << "Expected selected action index -1; found " << selected_action;
+    }
+    return testing::AssertionSuccess();
+  }
+
   void SetContainers(
       const std::vector<std::unique_ptr<SearchResultContainerView>>&
           containers) {
@@ -175,7 +291,7 @@
     // Starts at the beginning
     ASSERT_EQ(*result_selection_controller_->selected_location_details(),
               locations[0]);
-    for (int i = 1; i < (int)locations.size(); i++) {
+    for (size_t i = 1; i < locations.size(); i++) {
       result_selection_controller_->MoveSelection(*forward);
       ASSERT_EQ(*result_selection_controller_->selected_location_details(),
                 locations[i]);
@@ -211,15 +327,16 @@
   void TestSingleAxisBackward(
       ui::KeyEvent* backward,
       const std::vector<ResultLocationDetails>& locations) {
-    const int last_index = (int)locations.size() - 1;
+    ASSERT_FALSE(locations.empty());
+    const size_t last_index = locations.size() - 1;
 
     // Test reverse direction from last result
     ASSERT_EQ(*result_selection_controller_->selected_location_details(),
               locations[last_index]);
-    for (int i = last_index - 1; i >= 0; i--) {
+    for (size_t i = last_index; i > 0; i--) {
       result_selection_controller_->MoveSelection(*backward);
       ASSERT_EQ(*result_selection_controller_->selected_location_details(),
-                locations[i]);
+                locations[i - 1]);
     }
   }
 
@@ -270,6 +387,116 @@
     }
   }
 
+  // Runs test for TAB traversal over containers that contain results with extra
+  // result actions.
+  void TestTabTraversalWithResultActions(bool horizontal_containers) {
+    const int kContainerCount = 2;
+    const int kResultsPerContainer = 2;
+    const int kActionsPerResult = 2;
+    std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+        CreateContainerVector(
+            kContainerCount,
+            TestContainerParams(horizontal_containers, kResultsPerContainer,
+                                kActionsPerResult));
+    SetContainers(containers);
+
+    auto create_test_location = [horizontal_containers](int container_index,
+                                                        int result_index) {
+      return ResultLocationDetails(container_index, kContainerCount,
+                                   result_index, kResultsPerContainer,
+                                   horizontal_containers);
+    };
+
+    // Initialize the RSC for test.
+    result_selection_controller_->ResetSelection();
+
+    ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionNotSelected());
+
+    // TAB - the result should remain the same, but the selected action is
+    // expected to change.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(0));
+
+    // TAB - the result should remain the same, but the selected action is
+    // expected to change.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(1));
+
+    // TAB - move to the next result.
+    TestResultView* previous_result = GetCurrentSelection();
+    EXPECT_TRUE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionNotSelected());
+    EXPECT_FALSE(previous_result->selected());
+
+    // Shift-TAB - move back to the previous result, and expect the last action
+    // to be selected.
+    EXPECT_TRUE(result_selection_controller_->MoveSelection(shift_tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(1));
+
+    // TAB - move back to next result.
+    previous_result = GetCurrentSelection();
+    EXPECT_TRUE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionNotSelected());
+    EXPECT_FALSE(previous_result->selected());
+
+    // TAB - stay at the same result, but select next action.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(0));
+
+    // Shift-TAB - same result, but deselects actions.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(shift_tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionNotSelected());
+
+    // TAB - reselect the first action.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(0));
+
+    // TAB - select the next action.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(1));
+
+    // TAB - select a result in the next container.
+    previous_result = GetCurrentSelection();
+    EXPECT_TRUE(result_selection_controller_->MoveSelection(tab_key_));
+
+    ASSERT_EQ(create_test_location(1, 0), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionNotSelected());
+    EXPECT_FALSE(previous_result->selected());
+
+    // Shift-TAB - move to previous result/action.
+    previous_result = GetCurrentSelection();
+    EXPECT_TRUE(result_selection_controller_->MoveSelection(shift_tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(1));
+    EXPECT_FALSE(previous_result->selected());
+
+    // Shift-TAB - move to previous action.
+    EXPECT_FALSE(result_selection_controller_->MoveSelection(shift_tab_key_));
+
+    ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+    EXPECT_TRUE(CurrentResultActionSelected(0));
+  }
+
   std::unique_ptr<ResultSelectionController> result_selection_controller_;
   std::vector<SearchResultContainerView*> containers_;
 
@@ -297,8 +524,8 @@
 }  // namespace
 
 TEST_F(ResultSelectionTest, VerticalTraversalOneContainerArrowKeys) {
-  std::unique_ptr<VerticalTestContainer> vertical_container =
-      std::make_unique<VerticalTestContainer>(4);
+  std::unique_ptr<TestContainer> vertical_container =
+      std::make_unique<TestContainer>(TestContainerParams(false, 4));
   // The vertical container is not horizontally traversable
   ASSERT_FALSE(vertical_container->horizontally_traversable());
 
@@ -312,8 +539,8 @@
 }
 
 TEST_F(ResultSelectionTest, VerticalTraversalOneContainerTabKey) {
-  std::unique_ptr<VerticalTestContainer> vertical_container =
-      std::make_unique<VerticalTestContainer>(4);
+  std::unique_ptr<TestContainer> vertical_container =
+      std::make_unique<TestContainer>(TestContainerParams(false, 4));
 
   // The vertical container is not horizontally traversable
   ASSERT_FALSE(vertical_container->horizontally_traversable());
@@ -331,8 +558,8 @@
   ui::KeyEvent* forward = is_rtl_ ? &left_arrow_ : &right_arrow_;
   ui::KeyEvent* backward = is_rtl_ ? &right_arrow_ : &left_arrow_;
 
-  std::unique_ptr<HorizontalTestContainer> horizontal_container =
-      std::make_unique<HorizontalTestContainer>(4);
+  std::unique_ptr<TestContainer> horizontal_container =
+      std::make_unique<TestContainer>(TestContainerParams(true, 4));
 
   // The horizontal container is horizontally traversable
   ASSERT_TRUE(horizontal_container->horizontally_traversable());
@@ -347,10 +574,10 @@
 }
 
 TEST_P(ResultSelectionTest, HorizontalVerticalArrowKeys) {
-  std::unique_ptr<HorizontalTestContainer> horizontal_container =
-      std::make_unique<HorizontalTestContainer>(4);
-  std::unique_ptr<VerticalTestContainer> vertical_container =
-      std::make_unique<VerticalTestContainer>(4);
+  std::unique_ptr<TestContainer> horizontal_container =
+      std::make_unique<TestContainer>(TestContainerParams(true, 4));
+  std::unique_ptr<TestContainer> vertical_container =
+      std::make_unique<TestContainer>(TestContainerParams(false, 4));
 
   containers_.clear();
   containers_.emplace_back(horizontal_container.get());
@@ -363,10 +590,10 @@
 }
 
 TEST_F(ResultSelectionTest, HorizontalVerticalTab) {
-  std::unique_ptr<HorizontalTestContainer> horizontal_container =
-      std::make_unique<HorizontalTestContainer>(4);
-  std::unique_ptr<VerticalTestContainer> vertical_container =
-      std::make_unique<VerticalTestContainer>(4);
+  std::unique_ptr<TestContainer> horizontal_container =
+      std::make_unique<TestContainer>(TestContainerParams(true, 4));
+  std::unique_ptr<TestContainer> vertical_container =
+      std::make_unique<TestContainer>(TestContainerParams(false, 4));
 
   containers_.clear();
   containers_.emplace_back(horizontal_container.get());
@@ -380,7 +607,7 @@
 
 TEST_F(ResultSelectionTest, TestVerticalStackArrows) {
   std::vector<std::unique_ptr<SearchResultContainerView>> vertical_containers =
-      CreateContainerVector(4, 4, false);
+      CreateContainerVector(4, TestContainerParams(false, 4));
   SetContainers(vertical_containers);
 
   // Initialize the RSC for test.
@@ -391,7 +618,7 @@
 
 TEST_F(ResultSelectionTest, TestVerticalStackTab) {
   std::vector<std::unique_ptr<SearchResultContainerView>> vertical_containers =
-      CreateContainerVector(4, 4, false);
+      CreateContainerVector(4, TestContainerParams(false, 4));
   SetContainers(vertical_containers);
 
   // Initialize the RSC for test.
@@ -402,7 +629,8 @@
 
 TEST_P(ResultSelectionTest, TestHorizontalStackArrows) {
   std::vector<std::unique_ptr<SearchResultContainerView>>
-      horizontal_containers = CreateContainerVector(4, 4, true);
+      horizontal_containers =
+          CreateContainerVector(4, TestContainerParams(true, 4));
   SetContainers(horizontal_containers);
 
   // Initialize the RSC for test.
@@ -413,7 +641,8 @@
 
 TEST_F(ResultSelectionTest, TestHorizontalStackTab) {
   std::vector<std::unique_ptr<SearchResultContainerView>>
-      horizontal_containers = CreateContainerVector(4, 4, true);
+      horizontal_containers =
+          CreateContainerVector(4, TestContainerParams(true, 4));
   SetContainers(horizontal_containers);
 
   // Initialize the RSC for test.
@@ -422,4 +651,282 @@
   TestMultiAxisTraversal(true);
 }
 
+TEST_P(ResultSelectionTest, TestHorizontalStackWithResultActionsArrows) {
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(4, TestContainerParams(true, 4, 2));
+  SetContainers(containers);
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  TestMultiAxisTraversal(false);
+}
+
+TEST_F(ResultSelectionTest, TestVerticalStackWithResultActionsArrows) {
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(4, TestContainerParams(false, 4, 2));
+  SetContainers(containers);
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  TestMultiAxisTraversal(false);
+}
+
+TEST_F(ResultSelectionTest, TestVerticalStackWithEmptyResultActionsTab) {
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(4, TestContainerParams(false, 4, 0));
+  SetContainers(containers);
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  TestMultiAxisTraversal(false);
+}
+
+TEST_F(ResultSelectionTest, TestHorizontalStackWithEmptyResultActionsTab) {
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(4, TestContainerParams(false, 4, 0));
+  SetContainers(containers);
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  TestMultiAxisTraversal(false);
+}
+
+TEST_F(ResultSelectionTest, TestHorizontalStackWithResultActionsTab) {
+  TestTabTraversalWithResultActions(true /*horizontal_container*/);
+}
+
+TEST_F(ResultSelectionTest, TestVerticalStackWithResultActionsTab) {
+  TestTabTraversalWithResultActions(false /*horizontal_container*/);
+}
+
+TEST_P(ResultSelectionTest,
+       TestHorizontalStackWithResultActions_ForwardBackWithActionSelected) {
+  const int kContainerCount = 2;
+  const int kResultsPerContainer = 2;
+  const int kActionsPerResult = 2;
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(
+          kContainerCount,
+          TestContainerParams(true, kResultsPerContainer, kActionsPerResult));
+  SetContainers(containers);
+
+  auto create_test_location = [](int container_index, int result_index) {
+    return ResultLocationDetails(container_index, kContainerCount, result_index,
+                                 kResultsPerContainer,
+                                 true /*container_is_horizontal*/);
+  };
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  ui::KeyEvent* forward = is_rtl_ ? &left_arrow_ : &right_arrow_;
+  ui::KeyEvent* backward = is_rtl_ ? &right_arrow_ : &left_arrow_;
+
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // Forward selects the next result.
+  TestResultView* previous_result = GetCurrentSelection();
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(*forward));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+  EXPECT_FALSE(previous_result->selected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // Backward selects the previous result.
+  previous_result = GetCurrentSelection();
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(*backward));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+  EXPECT_FALSE(previous_result->selected());
+}
+
+TEST_F(ResultSelectionTest,
+       TestVerticalStackWithResultActions_UpDownWithActionSelected) {
+  const int kContainerCount = 2;
+  const int kResultsPerContainer = 2;
+  const int kActionsPerResult = 2;
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(
+          kContainerCount,
+          TestContainerParams(false, kResultsPerContainer, kActionsPerResult));
+  SetContainers(containers);
+
+  auto create_test_location = [](int container_index, int result_index) {
+    return ResultLocationDetails(container_index, kContainerCount, result_index,
+                                 kResultsPerContainer,
+                                 false /*container_is_horizontal*/);
+  };
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // DOWN selects the next result.
+  TestResultView* previous_result = GetCurrentSelection();
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(down_arrow_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+  EXPECT_FALSE(previous_result->selected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // UP selects the previous result.
+  previous_result = GetCurrentSelection();
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(up_arrow_));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+  EXPECT_FALSE(previous_result->selected());
+}
+
+TEST_F(ResultSelectionTest, ResetWhileFirstResultActionSelected) {
+  const int kContainerCount = 2;
+  const int kResultsPerContainer = 2;
+  const int kActionsPerResult = 2;
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(
+          kContainerCount,
+          TestContainerParams(false, kResultsPerContainer, kActionsPerResult));
+  SetContainers(containers);
+
+  auto create_test_location = [](int container_index, int result_index) {
+    return ResultLocationDetails(container_index, kContainerCount, result_index,
+                                 kResultsPerContainer,
+                                 false /*container_is_horizontal*/);
+  };
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // Reset selection - reset selects the new first result, i.e. the same result
+  // as before reset. The selected action should remain the same.
+  TestResultView* pre_reset_selection = GetCurrentSelection();
+  result_selection_controller_->ResetSelection();
+  EXPECT_EQ(pre_reset_selection, GetCurrentSelection());
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+}
+
+TEST_F(ResultSelectionTest, ResetWhileResultActionSelected) {
+  const int kContainerCount = 2;
+  const int kResultsPerContainer = 2;
+  const int kActionsPerResult = 2;
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(
+          kContainerCount,
+          TestContainerParams(false, kResultsPerContainer, kActionsPerResult));
+  SetContainers(containers);
+
+  auto create_test_location = [](int container_index, int result_index) {
+    return ResultLocationDetails(container_index, kContainerCount, result_index,
+                                 kResultsPerContainer,
+                                 false /*container_is_horizontal*/);
+  };
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // DOWN to select another result.
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(down_arrow_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // TAB to select an action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(0));
+
+  // Reset selection.
+  TestResultView* pre_reset_selection = GetCurrentSelection();
+  result_selection_controller_->ResetSelection();
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+  EXPECT_FALSE(pre_reset_selection->selected());
+}
+
+TEST_F(ResultSelectionTest, ActionRemovedWhileSelected) {
+  const int kContainerCount = 2;
+  const int kResultsPerContainer = 2;
+  const int kActionsPerResult = 3;
+  std::vector<std::unique_ptr<SearchResultContainerView>> containers =
+      CreateContainerVector(
+          kContainerCount,
+          TestContainerParams(false, kResultsPerContainer, kActionsPerResult));
+  SetContainers(containers);
+
+  auto create_test_location = [](int container_index, int result_index) {
+    return ResultLocationDetails(container_index, kContainerCount, result_index,
+                                 kResultsPerContainer,
+                                 false /*container_is_horizontal*/);
+  };
+
+  // Initialize the RSC for test.
+  result_selection_controller_->ResetSelection();
+
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // DOWN to select another result.
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(down_arrow_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // TAB to select the last action.
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  EXPECT_FALSE(result_selection_controller_->MoveSelection(tab_key_));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(2));
+
+  TestResultView* selected_view = GetCurrentSelection();
+  ASSERT_TRUE(selected_view);
+  ASSERT_TRUE(selected_view->AsResultViewWithActions());
+
+  // Remove two trailing actions - the result action is de-selected.
+  selected_view->AsResultViewWithActions()->GetActionsView()->SetActions(
+      std::vector<SearchResult::Action>(
+          1, SearchResult::Action(gfx::ImageSkia(), base::string16(), false)));
+  ASSERT_EQ(create_test_location(0, 1), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionNotSelected());
+
+  // Shift-TAB move selection to the previous result.
+  EXPECT_TRUE(result_selection_controller_->MoveSelection(shift_tab_key_));
+  ASSERT_EQ(create_test_location(0, 0), GetCurrentLocation());
+  EXPECT_TRUE(CurrentResultActionSelected(2));
+}
+
 }  // namespace app_list
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index 040d2bb9..3242dfd 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -549,7 +549,7 @@
   // The controller was null briefly, so it was unaware of a highlight change.
   // As a result, we need to manually declare the range to allow for proper
   // selection behavior.
-  search_box()->SelectRange(highlight_range_);
+  search_box()->SetSelectedRange(highlight_range_);
 
   // Send an event to alert ChromeVox that an autocomplete has occurred.
   // The |kValueChanged| type lets ChromeVox know that it should scan
@@ -670,10 +670,6 @@
     if (!selection_controller->MoveSelection(key_event))
       return true;
 
-    // Tells ChromeVox to read this result
-    selection_controller->selected_result()->NotifyAccessibilityEvent(
-        ax::mojom::Event::kSelection, true);
-
     // Fill text on result change.
     SearchResultBaseView* selected_result_view =
         selection_controller->selected_result();
@@ -776,7 +772,7 @@
 void SearchBoxView::HintTextChanged() {
   const app_list::SearchBoxModel* search_box_model =
       search_model_->search_box();
-  search_box()->set_placeholder_text(search_box_model->hint_text());
+  search_box()->SetPlaceholderText(search_box_model->hint_text());
   search_box()->SetAccessibleName(search_box_model->accessible_name());
   SchedulePaint();
 }
diff --git a/ash/app_list/views/search_result_actions_view.cc b/ash/app_list/views/search_result_actions_view.cc
index ba7d9b6..e482547 100644
--- a/ash/app_list/views/search_result_actions_view.cc
+++ b/ash/app_list/views/search_result_actions_view.cc
@@ -79,6 +79,7 @@
   SearchResultActionsView* parent_;
   const bool visible_on_hover_;
   bool to_be_activate_by_long_press_ = false;
+  bool selected_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(SearchResultImageButton);
 };
@@ -180,17 +181,23 @@
 }
 
 void SearchResultImageButton::UpdateOnStateChanged() {
-  if (!visible_on_hover_)
-    return;
-
   // Show button if the associated result row is hovered or selected, or one
   // of the action buttons is selected.
-  SetVisible(parent_->IsSearchResultHoveredOrSelected() ||
-             parent()->Contains(GetFocusManager()->GetFocusedView()));
+  if (visible_on_hover_) {
+    SetVisible(parent_->IsSearchResultHoveredOrSelected() ||
+               parent()->Contains(GetFocusManager()->GetFocusedView()));
+  }
+
+  const bool selected = parent_->GetSelectedAction() == tag();
+  if (selected_ != selected) {
+    selected_ = selected;
+    if (selected)
+      NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
+  }
 }
 
 void SearchResultImageButton::OnPaintBackground(gfx::Canvas* canvas) {
-  if (HasFocus()) {
+  if (HasFocus() || parent_->GetSelectedAction() == tag()) {
     cc::PaintFlags circle_flags;
     circle_flags.setAntiAlias(true);
     circle_flags.setColor(kButtonHoverColor);
@@ -227,15 +234,20 @@
 SearchResultActionsView::~SearchResultActionsView() {}
 
 void SearchResultActionsView::SetActions(const SearchResult::Actions& actions) {
+  if (selected_action_.has_value()) {
+    selected_action_.reset();
+    delegate_->OnSearchResultActionsUnSelected();
+  }
   buttons_.clear();
   RemoveAllChildViews(true);
-  for (const auto& action : actions)
-    CreateImageButton(action);
+
+  for (size_t i = 0; i < actions.size(); ++i)
+    CreateImageButton(actions[i], i);
   PreferredSizeChanged();
 }
 
 bool SearchResultActionsView::IsValidActionIndex(size_t action_index) const {
-  return action_index < children().size();
+  return action_index < GetActionCount();
 }
 
 bool SearchResultActionsView::IsSearchResultHoveredOrSelected() const {
@@ -255,13 +267,71 @@
   return "SearchResultActionsView";
 }
 
+bool SearchResultActionsView::SelectInitialAction(bool reverse_tab_order) {
+  if (GetActionCount() == 0)
+    return false;
+
+  if (reverse_tab_order) {
+    selected_action_ = GetActionCount() - 1;
+  } else {
+    selected_action_.reset();
+  }
+  UpdateButtonsOnStateChanged();
+  return selected_action_.has_value();
+}
+
+bool SearchResultActionsView::SelectNextAction(bool reverse_tab_order) {
+  if (GetActionCount() == 0)
+    return false;
+
+  // For reverse tab order, consider moving to non-selected state.
+  if (reverse_tab_order) {
+    if (!selected_action_.has_value())
+      return false;
+
+    if (selected_action_.value() == 0) {
+      ClearSelectedAction();
+      return true;
+    }
+  }
+
+  const int next_index =
+      selected_action_.value_or(-1) + (reverse_tab_order ? -1 : 1);
+  if (!IsValidActionIndex(next_index))
+    return false;
+
+  selected_action_ = next_index;
+  UpdateButtonsOnStateChanged();
+  return true;
+}
+
+void SearchResultActionsView::ClearSelectedAction() {
+  selected_action_.reset();
+  delegate_->OnSearchResultActionsUnSelected();
+  UpdateButtonsOnStateChanged();
+}
+
+int SearchResultActionsView::GetSelectedAction() const {
+  return selected_action_.value_or(-1);
+}
+
+bool SearchResultActionsView::HasSelectedAction() const {
+  return selected_action_.has_value();
+}
+
 void SearchResultActionsView::CreateImageButton(
-    const SearchResult::Action& action) {
+    const SearchResult::Action& action,
+    int action_index) {
   SearchResultImageButton* button = new SearchResultImageButton(this, action);
+  button->set_tag(action_index);
   AddChildView(button);
   buttons_.emplace_back(button);
 }
 
+size_t SearchResultActionsView::GetActionCount() const {
+  return buttons_.size();
+}
+
 void SearchResultActionsView::ChildVisibilityChanged(views::View* child) {
   PreferredSizeChanged();
 }
@@ -271,9 +341,9 @@
   if (!delegate_)
     return;
 
-  const int index = GetIndexOf(sender);
-  DCHECK_NE(-1, index);
-  delegate_->OnSearchResultActionActivated(index, event.flags());
+  DCHECK_GE(sender->tag(), 0);
+  DCHECK_LT(sender->tag(), static_cast<int>(GetActionCount()));
+  delegate_->OnSearchResultActionActivated(sender->tag(), event.flags());
 }
 
 }  // namespace app_list
diff --git a/ash/app_list/views/search_result_actions_view.h b/ash/app_list/views/search_result_actions_view.h
index bcc1960..85acce4 100644
--- a/ash/app_list/views/search_result_actions_view.h
+++ b/ash/app_list/views/search_result_actions_view.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "ash/app_list/app_list_export.h"
 #include "ash/app_list/model/search/search_result.h"
 #include "base/macros.h"
 #include "ui/views/controls/button/button.h"
@@ -20,8 +21,8 @@
 
 // SearchResultActionsView displays a SearchResult::Actions in a button
 // strip. Each action is presented as a button and horizontally laid out.
-class SearchResultActionsView : public views::View,
-                                public views::ButtonListener {
+class APP_LIST_EXPORT SearchResultActionsView : public views::View,
+                                                public views::ButtonListener {
  public:
   explicit SearchResultActionsView(SearchResultActionsViewDelegate* delegate);
   ~SearchResultActionsView() override;
@@ -41,8 +42,38 @@
   // views::View:
   const char* GetClassName() const override;
 
+  // Selects the result action expected to be initially selected when the parent
+  // result view gets selected.
+  // |reverse_tab_order| - Whether the parent result view was selected in
+  //     reverse tab order.
+  //  Returns whether an action was selected (returns false if selected_action_
+  //  is not set).
+  bool SelectInitialAction(bool reverse_tab_order);
+
+  // Select the next result action that should be selected during tab traversal.
+  // It will not change selection if the next selection would be invalid.
+  // Note that "no selected action" is treated as a valid (zero) state.
+  //
+  // |reverse_tab_order| - Whether the selection should be changed assuming
+  //     reverse tab order.
+  // Returns whether the selection was changed (which includes selected action
+  // getting cleared).
+  bool SelectNextAction(bool reverse_tab_order);
+
+  // Clears selected action state.
+  void ClearSelectedAction();
+
+  // Returns the selected action index, or -1 if an action is not selected.
+  int GetSelectedAction() const;
+
+  // Whether an action is currently selected.
+  bool HasSelectedAction() const;
+
  private:
-  void CreateImageButton(const SearchResult::Action& action);
+  void CreateImageButton(const SearchResult::Action& action, int action_index);
+
+  // Returns the number of available actions.
+  size_t GetActionCount() const;
 
   // views::View overrides:
   void ChildVisibilityChanged(views::View* child) override;
@@ -50,6 +81,9 @@
   // views::ButtonListener overrides:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+  // If an action is currently selected, the selected action index.
+  base::Optional<int> selected_action_;
+
   SearchResultActionsViewDelegate* delegate_;  // Not owned.
   std::vector<SearchResultImageButton*> buttons_;
 
diff --git a/ash/app_list/views/search_result_actions_view_delegate.h b/ash/app_list/views/search_result_actions_view_delegate.h
index 31b3cf70..87a4c28 100644
--- a/ash/app_list/views/search_result_actions_view_delegate.h
+++ b/ash/app_list/views/search_result_actions_view_delegate.h
@@ -15,6 +15,11 @@
   // in SearchResultActionsView.
   virtual void OnSearchResultActionActivated(size_t index, int event_flags) = 0;
 
+  // Invoked when result action selection is cleared (it changes from the state
+  // where a result action is selected to the state where no actions are
+  // selected).
+  virtual void OnSearchResultActionsUnSelected() = 0;
+
   // Returns true if the associated search result is hovered by mouse, or
   // or selected by keyboard.
   virtual bool IsSearchResultHoveredOrSelected() = 0;
diff --git a/ash/app_list/views/search_result_answer_card_view.cc b/ash/app_list/views/search_result_answer_card_view.cc
index 13d0147..a58fb04 100644
--- a/ash/app_list/views/search_result_answer_card_view.cc
+++ b/ash/app_list/views/search_result_answer_card_view.cc
@@ -186,11 +186,11 @@
   // views::Button overrides:
   const char* GetClassName() const override { return "AnswerCardResultView"; }
 
-  void OnBlur() override { SetBackgroundHighlighted(false); }
+  void OnBlur() override { SetSelected(false, base::nullopt); }
 
   void OnFocus() override {
     ScrollRectToVisible(GetLocalBounds());
-    SetBackgroundHighlighted(true);
+    SetSelected(true, base::nullopt);
   }
 
   bool OnKeyPressed(const ui::KeyEvent& event) override {
@@ -210,7 +210,7 @@
   }
 
   void PaintButtonContents(gfx::Canvas* canvas) override {
-    if (background_highlighted())
+    if (selected())
       canvas->FillRect(GetContentsBounds(), kAnswerCardSelectedColor);
   }
 
diff --git a/ash/app_list/views/search_result_base_view.cc b/ash/app_list/views/search_result_base_view.cc
index c76bff1..5bd86eb 100644
--- a/ash/app_list/views/search_result_base_view.cc
+++ b/ash/app_list/views/search_result_base_view.cc
@@ -5,6 +5,8 @@
 #include "ash/app_list/views/search_result_base_view.h"
 
 #include "ash/app_list/model/search/search_result.h"
+#include "ash/app_list/views/search_result_actions_view.h"
+#include "ash/public/cpp/app_list/app_list_features.h"
 #include "base/strings/utf_string_conversions.h"
 
 namespace app_list {
@@ -26,11 +28,37 @@
   return "SearchResultBaseView";
 }
 
-void SearchResultBaseView::SetBackgroundHighlighted(bool enabled) {
-  background_highlighted_ = enabled;
+void SearchResultBaseView::SetSelected(bool selected,
+                                       base::Optional<bool> reverse_tab_order) {
+  if (selected_ == selected)
+    return;
+
+  selected_ = selected;
+
+  if (app_list_features::IsSearchBoxSelectionEnabled()) {
+    if (selected) {
+      SelectInitialResultAction(reverse_tab_order.value_or(false));
+    } else {
+      ClearSelectedResultAction();
+    }
+  }
+
   SchedulePaint();
 }
 
+bool SearchResultBaseView::SelectNextResultAction(bool reverse_tab_order) {
+  DCHECK(app_list_features::IsSearchBoxSelectionEnabled());
+
+  if (!selected() || !actions_view_)
+    return false;
+
+  if (!actions_view_->SelectNextAction(reverse_tab_order))
+    return false;
+
+  SchedulePaint();
+  return true;
+}
+
 void SearchResultBaseView::SetResult(SearchResult* result) {
   OnResultChanging(result);
   ClearResult();
@@ -68,4 +96,20 @@
   result_ = nullptr;
 }
 
+void SearchResultBaseView::SelectInitialResultAction(bool reverse_tab_order) {
+  DCHECK(app_list_features::IsSearchBoxSelectionEnabled());
+
+  if (actions_view_ && actions_view_->SelectInitialAction(reverse_tab_order))
+    return;
+
+  NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
+}
+
+void SearchResultBaseView::ClearSelectedResultAction() {
+  DCHECK(app_list_features::IsSearchBoxSelectionEnabled());
+
+  if (actions_view_)
+    actions_view_->ClearSelectedAction();
+}
+
 }  // namespace app_list
diff --git a/ash/app_list/views/search_result_base_view.h b/ash/app_list/views/search_result_base_view.h
index eedd78b..c15920d 100644
--- a/ash/app_list/views/search_result_base_view.h
+++ b/ash/app_list/views/search_result_base_view.h
@@ -13,6 +13,7 @@
 namespace app_list {
 
 class SearchResult;
+class SearchResultActionsView;
 
 // Base class for views that observe and display a search result
 class APP_LIST_EXPORT SearchResultBaseView : public views::Button,
@@ -21,8 +22,22 @@
  public:
   SearchResultBaseView();
 
-  // Set or remove the background highlight.
-  void SetBackgroundHighlighted(bool enabled);
+  // Set whether the result is selected. It updates the background highlight,
+  // and selects the result action associated with the result if
+  // SearchBoxSelection feature is enabled.
+  //
+  // |reverse_tab_order| - Indicates whether the selection was set as part of
+  //     reverse tab traversal. Should be set when selection was changed while
+  //     handling TAB keyboard key. Ignored if |selected| is false.
+  void SetSelected(bool selected, base::Optional<bool> reverse_tab_order);
+
+  // Selects the next result action for the view, if the result supports
+  // non-default actions (see actions_view_).
+  // |reverse_tab_order| - whether the action was selected while handling TAB
+  // key in reverse tab order.
+  //
+  // Returns whether the selected result action was changed.
+  bool SelectNextResultAction(bool reverse_tab_order);
 
   SearchResult* result() const { return result_; }
   void SetResult(SearchResult* result);
@@ -42,7 +57,7 @@
   // Clears the result without calling |OnResultChanged| or |OnResultChanging|
   void ClearResult();
 
-  bool background_highlighted() const { return background_highlighted_; }
+  bool selected() const { return selected_; }
 
   int index_in_container() const { return index_in_container_.value(); }
 
@@ -59,8 +74,31 @@
 
   void UpdateAccessibleName();
 
+  void set_actions_view(SearchResultActionsView* actions_view) {
+    actions_view_ = actions_view;
+  }
+
+  SearchResultActionsView* actions_view() { return actions_view_; }
+
  private:
-  bool background_highlighted_ = false;
+  // Selects the initial action that should be associated with the result view,
+  // notifying a11y hierarchy of the selection. If the result view does not
+  // support result actions (i.e. does not have actions_view_), this will just
+  // announce the current result view selection.
+  // |reverse_tab_order| - whether the action was selected in reverse tab order.
+  void SelectInitialResultAction(bool reverse_tab_order);
+
+  // If non-default result action was selected, clears the actions_view_'s
+  // selection state.
+  void ClearSelectedResultAction();
+
+  // Whether the result is currently selected.
+  bool selected_ = false;
+
+  // Expected to be set by result view implementations that supports
+  // extra result actions. It points to the view containing result actions
+  // buttons. Owned by the views hierarchy.
+  SearchResultActionsView* actions_view_ = nullptr;
 
   // The index of this view within a |SearchResultContainerView| that holds it.
   base::Optional<int> index_in_container_;
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc
index bf0a107..e0846c2 100644
--- a/ash/app_list/views/search_result_page_view.cc
+++ b/ash/app_list/views/search_result_page_view.cc
@@ -214,7 +214,7 @@
 
 bool SearchResultPageView::IsFirstResultHighlighted() const {
   DCHECK(first_result_view_);
-  return first_result_view_->background_highlighted();
+  return first_result_view_->selected();
 }
 
 bool SearchResultPageView::OnKeyPressed(const ui::KeyEvent& event) {
@@ -317,7 +317,7 @@
 
     // Clear the first search result view's background highlight.
     if (first_result_view_ && first_result_view_ != focused_view)
-      first_result_view_->SetBackgroundHighlighted(false);
+      first_result_view_->SetSelected(false, base::nullopt);
   }
 
   first_result_view_ = result_container_views_[0]->GetFirstResultView();
@@ -344,7 +344,7 @@
     // the focus is not set on the first result to prevent frequent focus switch
     // between the search box and the first result when the user is typing
     // query.
-    first_result_view_->SetBackgroundHighlighted(true);
+    first_result_view_->SetSelected(true, base::nullopt);
   }
 }
 
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 6e239f8..aae2733 100644
--- a/ash/app_list/views/search_result_tile_item_view.cc
+++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -290,12 +290,12 @@
   } else {
     ScrollRectToVisible(GetLocalBounds());
   }
-  SetBackgroundHighlighted(true);
+  SetSelected(true, base::nullopt);
   UpdateBackgroundColor();
 }
 
 void SearchResultTileItemView::OnBlur() {
-  SetBackgroundHighlighted(false);
+  SetSelected(false, base::nullopt);
   UpdateBackgroundColor();
 }
 
@@ -304,7 +304,7 @@
 }
 
 void SearchResultTileItemView::PaintButtonContents(gfx::Canvas* canvas) {
-  if (!result() || !background_highlighted())
+  if (!result() || !selected())
     return;
 
   gfx::Rect rect(GetContentsBounds());
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc
index 8122648..ffa92a03 100644
--- a/ash/app_list/views/search_result_view.cc
+++ b/ash/app_list/views/search_result_view.cc
@@ -65,21 +65,21 @@
                                    AppListViewDelegate* view_delegate)
     : list_view_(list_view),
       view_delegate_(view_delegate),
-      icon_(new views::ImageView),
-      display_icon_(new views::ImageView),
-      badge_icon_(new views::ImageView),
-      actions_view_(new SearchResultActionsView(this)),
       weak_ptr_factory_(this) {
   SetFocusBehavior(FocusBehavior::ALWAYS);
+
+  icon_ = AddChildView(std::make_unique<views::ImageView>());
+  display_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  badge_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  auto* actions_view =
+      AddChildView(std::make_unique<SearchResultActionsView>(this));
+  set_actions_view(actions_view);
+
   icon_->set_can_process_events_within_subtree(false);
   display_icon_->set_can_process_events_within_subtree(false);
   SetDisplayIcon(gfx::ImageSkia());
   badge_icon_->set_can_process_events_within_subtree(false);
 
-  AddChildView(icon_);
-  AddChildView(display_icon_);
-  AddChildView(badge_icon_);
-  AddChildView(actions_view_);
   set_context_menu_controller(this);
   set_notify_enter_exit_on_child(true);
 }
@@ -165,7 +165,7 @@
 
   if (confirm_remove_by_long_press_) {
     confirm_remove_by_long_press_ = false;
-    SetBackgroundHighlighted(false);
+    SetSelected(false, base::nullopt);
   }
 
   RecordZeroStateSearchResultRemovalHistogram(
@@ -213,12 +213,12 @@
   const int max_actions_width =
       (rect.right() - kActionButtonRightMargin - icon_bounds.right()) / 2;
   int actions_width =
-      std::min(max_actions_width, actions_view_->GetPreferredSize().width());
+      std::min(max_actions_width, actions_view()->GetPreferredSize().width());
 
   gfx::Rect actions_bounds(rect);
   actions_bounds.set_x(rect.right() - kActionButtonRightMargin - actions_width);
   actions_bounds.set_width(actions_width);
-  actions_view_->SetBoundsRect(actions_bounds);
+  actions_view()->SetBoundsRect(actions_bounds);
 }
 
 bool SearchResultView::OnKeyPressed(const ui::KeyEvent& event) {
@@ -228,11 +228,17 @@
 
   switch (event.key_code()) {
     case ui::VKEY_RETURN:
-      list_view_->SearchResultActivated(this, event.flags());
+      if (actions_view()->HasSelectedAction()) {
+        OnSearchResultActionActivated(static_cast<ash::OmniBoxZeroStateAction>(
+                                          actions_view()->GetSelectedAction()),
+                                      event.flags());
+      } else {
+        list_view_->SearchResultActivated(this, event.flags());
+      }
       return true;
     case ui::VKEY_UP:
     case ui::VKEY_DOWN:
-      return !actions_view_->children().empty() &&
+      return !actions_view()->children().empty() &&
              list_view_->HandleVerticalFocusMovement(
                  this, event.key_code() == ui::VKEY_UP);
     case ui::VKEY_DELETE:
@@ -254,11 +260,11 @@
   gfx::Rect content_rect(rect);
   gfx::Rect text_bounds(rect);
   text_bounds.set_x(kPreferredIconViewWidth);
-  if (actions_view_->GetVisible()) {
+  if (actions_view()->GetVisible()) {
     text_bounds.set_width(
         rect.width() - kPreferredIconViewWidth - kTextTrailPadding -
-        actions_view_->bounds().width() -
-        (actions_view_->children().empty() ? 0 : kActionButtonRightMargin));
+        actions_view()->bounds().width() -
+        (actions_view()->children().empty() ? 0 : kActionButtonRightMargin));
   } else {
     text_bounds.set_width(rect.width() - kPreferredIconViewWidth -
                           kTextTrailPadding - kActionButtonRightMargin);
@@ -273,8 +279,9 @@
 
   // Possibly call FillRect a second time (these colours are partially
   // transparent, so the previous FillRect is not redundant).
-  if (background_highlighted())
+  if (selected() && !actions_view()->HasSelectedAction()) {
     canvas->FillRect(content_rect, kRowHighlightedColor);
+  }
 
   gfx::Rect border_bottom = gfx::SubtractRects(rect, content_rect);
   canvas->FillRect(border_bottom, kResultBorderColor);
@@ -305,23 +312,21 @@
 
 void SearchResultView::OnFocus() {
   ScrollRectToVisible(GetLocalBounds());
-  SetBackgroundHighlighted(true);
-  selected_ = true;
-  actions_view_->UpdateButtonsOnStateChanged();
+  SetSelected(true, base::nullopt);
+  actions_view()->UpdateButtonsOnStateChanged();
 }
 
 void SearchResultView::OnBlur() {
-  SetBackgroundHighlighted(false);
-  selected_ = false;
-  actions_view_->UpdateButtonsOnStateChanged();
+  SetSelected(false, base::nullopt);
+  actions_view()->UpdateButtonsOnStateChanged();
 }
 
 void SearchResultView::OnMouseEntered(const ui::MouseEvent& event) {
-  actions_view_->UpdateButtonsOnStateChanged();
+  actions_view()->UpdateButtonsOnStateChanged();
 }
 
 void SearchResultView::OnMouseExited(const ui::MouseEvent& event) {
-  actions_view_->UpdateButtonsOnStateChanged();
+  actions_view()->UpdateButtonsOnStateChanged();
 }
 
 void SearchResultView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
@@ -346,11 +351,11 @@
 void SearchResultView::OnGestureEvent(ui::GestureEvent* event) {
   switch (event->type()) {
     case ui::ET_GESTURE_LONG_PRESS:
-      if (actions_view_->IsValidActionIndex(
+      if (actions_view()->IsValidActionIndex(
               ash::OmniBoxZeroStateAction::kRemoveSuggestion)) {
         ScrollRectToVisible(GetLocalBounds());
         NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
-        SetBackgroundHighlighted(true);
+        SetSelected(true, base::nullopt);
         confirm_remove_by_long_press_ = true;
         OnSearchResultActionActivated(
             ash::OmniBoxZeroStateAction::kRemoveSuggestion, event->flags());
@@ -393,9 +398,9 @@
     badge_icon_->SetVisible(true);
   }
 
-  // Updates |actions_view_|.
-  actions_view_->SetActions(result() ? result()->actions()
-                                     : SearchResult::Actions());
+  // Updates |actions_view()|.
+  actions_view()->SetActions(result() ? result()->actions()
+                                      : SearchResult::Actions());
 }
 
 void SearchResultView::SetIconImage(const gfx::ImageSkia& source,
@@ -439,6 +444,13 @@
   }
 }
 
+void SearchResultView::OnSearchResultActionsUnSelected() {
+  // If the selection has changed to default result action, announce the
+  // selection change to a11y stack.
+  if (selected())
+    NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
+}
+
 bool SearchResultView::IsSearchResultHoveredOrSelected() {
   return IsMouseHovered() || selected();
 }
diff --git a/ash/app_list/views/search_result_view.h b/ash/app_list/views/search_result_view.h
index aee30bd0..a0a59c2 100644
--- a/ash/app_list/views/search_result_view.h
+++ b/ash/app_list/views/search_result_view.h
@@ -37,7 +37,6 @@
 class AppListViewDelegate;
 class SearchResult;
 class SearchResultListView;
-class SearchResultActionsView;
 
 // SearchResultView displays a SearchResult.
 class APP_LIST_EXPORT SearchResultView
@@ -55,8 +54,6 @@
   // Sets/gets SearchResult displayed by this view.
   void OnResultChanged() override;
 
-  bool selected() const { return selected_; }
-
   void SetDisplayIcon(const gfx::ImageSkia& source);
 
  private:
@@ -111,6 +108,7 @@
 
   // SearchResultActionsViewDelegate overrides:
   void OnSearchResultActionActivated(size_t index, int event_flags) override;
+  void OnSearchResultActionsUnSelected() override;
   bool IsSearchResultHoveredOrSelected() override;
 
   // Invoked when the context menu closes.
@@ -127,12 +125,9 @@
   views::ImageView* badge_icon_;    // Owned by views hierarchy.
   std::unique_ptr<gfx::RenderText> title_text_;
   std::unique_ptr<gfx::RenderText> details_text_;
-  SearchResultActionsView* actions_view_;  // Owned by the views hierarchy.
 
   std::unique_ptr<AppListMenuModelAdapter> context_menu_;
 
-  // Whether this view is selected.
-  bool selected_ = false;
   // Whether the removal confirmation dialog is invoked by long press touch.
   bool confirm_remove_by_long_press_ = false;
 
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 061dd7e..5759f80b 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -391,11 +391,14 @@
         Your administrator is rolling back your device. All data will be deleted when the device is restarted.
       </message>
 
-      <message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the volume slider.">
-        Volume
+      <message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the toggle volume muted button in the tray.">
+        Toggle Volume. <ph name="STATE_TEXT">$1<ex>Volume is muted</ex></ph>
       </message>
-      <message name="IDS_ASH_STATUS_TRAY_VOLUME_MUTE" desc="The accessible text for the volume mute button.">
-        Mute
+      <message name="IDS_ASH_STATUS_TRAY_VOLUME_STATE_ON" desc="The accessible text used when the volume button is in the on state.">
+        Volume is on.
+      </message>
+      <message name="IDS_ASH_STATUS_TRAY_VOLUME_STATE_MUTED" desc="The accessible text used when the volume button is in the muted state.">
+        Volume is muted.
       </message>
 
       <message name="IDS_ASH_FEATURE_DISABLED_BY_POLICY" desc="The message used to indicate that this feature is disabled by policy.">
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME.png.sha1
new file mode 100644
index 0000000..b44958a6
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME.png.sha1
@@ -0,0 +1 @@
+a5ab56f941551b0e37b965a245281e5ff922e8bd
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_MUTED.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_MUTED.png.sha1
new file mode 100644
index 0000000..b44958a6
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_MUTED.png.sha1
@@ -0,0 +1 @@
+a5ab56f941551b0e37b965a245281e5ff922e8bd
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_ON.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_ON.png.sha1
new file mode 100644
index 0000000..b44958a6
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_VOLUME_STATE_ON.png.sha1
@@ -0,0 +1 @@
+a5ab56f941551b0e37b965a245281e5ff922e8bd
\ No newline at end of file
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc
index fd722545..d960a0b 100644
--- a/ash/assistant/ui/dialog_plate/dialog_plate.cc
+++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -318,7 +318,7 @@
 
   auto textfield_hint =
       l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_HINT);
-  textfield_->set_placeholder_text(textfield_hint);
+  textfield_->SetPlaceholderText(textfield_hint);
   textfield_->SetAccessibleName(textfield_hint);
   textfield_->set_placeholder_text_color(kTextColorSecondary);
   textfield_->SetTextColor(kTextColorPrimary);
diff --git a/ash/components/shortcut_viewer/views/ksv_search_box_view.cc b/ash/components/shortcut_viewer/views/ksv_search_box_view.cc
index f06d76b..9ecc7d8 100644
--- a/ash/components/shortcut_viewer/views/ksv_search_box_view.cc
+++ b/ash/components/shortcut_viewer/views/ksv_search_box_view.cc
@@ -39,7 +39,7 @@
   search_box()->set_placeholder_text_draw_flags(gfx::Canvas::TEXT_ALIGN_CENTER);
   const base::string16 search_box_name(
       l10n_util::GetStringUTF16(IDS_KSV_SEARCH_BOX_ACCESSIBILITY_NAME));
-  search_box()->set_placeholder_text(search_box_name);
+  search_box()->SetPlaceholderText(search_box_name);
   search_box()->SetAccessibleName(search_box_name);
   SetSearchIconImage(
       gfx::CreateVectorIcon(kKsvSearchBarIcon, gfx::kGoogleGrey900));
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
index 4b90f9d..4209db6 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -22,17 +22,24 @@
 
 class TestWidgetDelegate : public views::WidgetDelegateView {
  public:
-  TestWidgetDelegate(bool can_maximize, bool can_minimize)
-      : can_maximize_(can_maximize), can_minimize_(can_minimize) {}
+  TestWidgetDelegate(bool can_maximize,
+                     bool can_minimize,
+                     bool close_button_visible)
+      : can_maximize_(can_maximize),
+        can_minimize_(can_minimize),
+        close_button_visible_(close_button_visible) {}
   ~TestWidgetDelegate() override = default;
 
   bool CanMaximize() const override { return can_maximize_; }
 
   bool CanMinimize() const override { return can_minimize_; }
 
+  bool ShouldShowCloseButton() const override { return close_button_visible_; }
+
  private:
   bool can_maximize_;
   bool can_minimize_;
+  bool close_button_visible_;
 
   DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
 };
@@ -45,6 +52,8 @@
 
   enum MinimizeAllowed { MINIMIZE_ALLOWED, MINIMIZE_DISALLOWED };
 
+  enum CloseButtonVisible { CLOSE_BUTTON_VISIBLE, CLOSE_BUTTON_NOT_VISIBLE };
+
   FrameCaptionButtonContainerViewTest() = default;
 
   ~FrameCaptionButtonContainerViewTest() override = default;
@@ -52,13 +61,15 @@
   // Creates a widget which allows maximizing based on |maximize_allowed|.
   // The caller takes ownership of the returned widget.
   views::Widget* CreateTestWidget(MaximizeAllowed maximize_allowed,
-                                  MinimizeAllowed minimize_allowed)
+                                  MinimizeAllowed minimize_allowed,
+                                  CloseButtonVisible close_button_visible)
       WARN_UNUSED_RESULT {
     views::Widget* widget = new views::Widget;
     views::Widget::InitParams params;
     params.delegate =
         new TestWidgetDelegate(maximize_allowed == MAXIMIZE_ALLOWED,
-                               minimize_allowed == MINIMIZE_ALLOWED);
+                               minimize_allowed == MINIMIZE_ALLOWED,
+                               close_button_visible == CLOSE_BUTTON_VISIBLE);
     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
     params.context = CurrentContext();
     widget->Init(params);
@@ -106,8 +117,8 @@
 TEST_F(FrameCaptionButtonContainerViewTest, ButtonVisibility) {
   // All the buttons should be visible when minimizing and maximizing are
   // allowed.
-  FrameCaptionButtonContainerView container1(
-      CreateTestWidget(MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED));
+  FrameCaptionButtonContainerView container1(CreateTestWidget(
+      MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, CLOSE_BUTTON_VISIBLE));
   InitContainer(&container1);
   container1.Layout();
   FrameCaptionButtonContainerView::TestApi t1(&container1);
@@ -119,8 +130,8 @@
 
   // The minimize button should be visible when minimizing is allowed but
   // maximizing is disallowed.
-  FrameCaptionButtonContainerView container2(
-      CreateTestWidget(MAXIMIZE_DISALLOWED, MINIMIZE_ALLOWED));
+  FrameCaptionButtonContainerView container2(CreateTestWidget(
+      MAXIMIZE_DISALLOWED, MINIMIZE_ALLOWED, CLOSE_BUTTON_VISIBLE));
   InitContainer(&container2);
   container2.Layout();
   FrameCaptionButtonContainerView::TestApi t2(&container2);
@@ -132,8 +143,8 @@
 
   // Neither the minimize button nor the size button should be visible when
   // neither minimizing nor maximizing are allowed.
-  FrameCaptionButtonContainerView container3(
-      CreateTestWidget(MAXIMIZE_DISALLOWED, MINIMIZE_DISALLOWED));
+  FrameCaptionButtonContainerView container3(CreateTestWidget(
+      MAXIMIZE_DISALLOWED, MINIMIZE_DISALLOWED, CLOSE_BUTTON_VISIBLE));
   InitContainer(&container3);
   container3.Layout();
   FrameCaptionButtonContainerView::TestApi t3(&container3);
@@ -148,8 +159,8 @@
 // correct placement of the buttons.
 TEST_F(FrameCaptionButtonContainerViewTest,
        TestUpdateSizeButtonVisibilityAnimation) {
-  FrameCaptionButtonContainerView container(
-      CreateTestWidget(MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED));
+  FrameCaptionButtonContainerView container(CreateTestWidget(
+      MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, CLOSE_BUTTON_VISIBLE));
 
   // Add an extra button to the left of the size button to verify that it is
   // repositioned similarly to the minimize button. This simulates the PWA menu
@@ -213,4 +224,28 @@
             initial_container_bounds.width());
 }
 
+// Test that the close button is visible when
+// |WidgetDelegate::ShouldShowCloseButton()| returns true.
+TEST_F(FrameCaptionButtonContainerViewTest, ShouldShowCloseButtonTrue) {
+  FrameCaptionButtonContainerView container(CreateTestWidget(
+      MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, CLOSE_BUTTON_VISIBLE));
+  InitContainer(&container);
+  container.Layout();
+  FrameCaptionButtonContainerView::TestApi testApi(&container);
+  EXPECT_TRUE(testApi.close_button()->GetVisible());
+  EXPECT_TRUE(testApi.close_button()->GetEnabled());
+}
+
+// Test that the close button is not visible when
+// |WidgetDelegate::ShouldShowCloseButton()| returns false.
+TEST_F(FrameCaptionButtonContainerViewTest, ShouldShowCloseButtonFalse) {
+  FrameCaptionButtonContainerView container(CreateTestWidget(
+      MAXIMIZE_ALLOWED, MINIMIZE_ALLOWED, CLOSE_BUTTON_NOT_VISIBLE));
+  InitContainer(&container);
+  container.Layout();
+  FrameCaptionButtonContainerView::TestApi testApi(&container);
+  EXPECT_FALSE(testApi.close_button()->GetVisible());
+  EXPECT_TRUE(testApi.close_button()->GetEnabled());
+}
+
 }  // namespace ash
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc
index eb1d1a0..827a277 100644
--- a/ash/frame/non_client_frame_view_ash_unittest.cc
+++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -581,11 +581,15 @@
   FrameCaptionButtonContainerView::TestApi test_api(
       header_view->caption_button_container());
 
-  // CLOSE buttion is always visible and enabled.
+  // CLOSE button is always enabled.
   EXPECT_TRUE(test_api.close_button());
-  EXPECT_TRUE(test_api.close_button()->GetVisible());
+  EXPECT_FALSE(test_api.close_button()->GetVisible());
   EXPECT_TRUE(test_api.close_button()->GetEnabled());
 
+  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_CLOSE, true);
+  non_client_frame_view->SizeConstraintsChanged();
+  EXPECT_TRUE(test_api.close_button()->GetVisible());
+
   EXPECT_FALSE(test_api.minimize_button()->GetVisible());
   EXPECT_FALSE(test_api.size_button()->GetVisible());
   EXPECT_FALSE(test_api.menu_button()->GetVisible());
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc
index 6082a7d..4ff8cc8 100644
--- a/ash/login/ui/login_password_view.cc
+++ b/ash/login/ui/login_password_view.cc
@@ -494,7 +494,7 @@
 
 void LoginPasswordView::SetPlaceholderText(
     const base::string16& placeholder_text) {
-  textfield_->set_placeholder_text(placeholder_text);
+  textfield_->SetPlaceholderText(placeholder_text);
   SchedulePaint();
 }
 
diff --git a/ash/power/gatt_battery_poller.cc b/ash/power/gatt_battery_poller.cc
index caa613af..24644d0 100644
--- a/ash/power/gatt_battery_poller.cc
+++ b/ash/power/gatt_battery_poller.cc
@@ -76,7 +76,7 @@
   if (battery_percentage) {
     device::BluetoothDevice* device = adapter_->GetDevice(device_address_);
     if (device)
-      device->set_battery_percentage(*battery_percentage);
+      device->SetBatteryPercentage(*battery_percentage);
   }
 
   ScheduleNextAttempt(battery_percentage.has_value());
@@ -100,7 +100,7 @@
     StartNextAttemptTimer();
   } else {
     // Reset battery field after exceeding the retry count.
-    device->set_battery_percentage(base::nullopt);
+    device->SetBatteryPercentage(base::nullopt);
   }
 }
 
diff --git a/ash/power/gatt_battery_poller_unittest.cc b/ash/power/gatt_battery_poller_unittest.cc
index 33773b6d..ae944f9c 100644
--- a/ash/power/gatt_battery_poller_unittest.cc
+++ b/ash/power/gatt_battery_poller_unittest.cc
@@ -165,7 +165,7 @@
 }
 
 TEST_F(GattBatteryPollerTest, DoesNotModifyBatteryValueAfterAnError) {
-  mock_device_->set_battery_percentage(kBatteryPercentage);
+  mock_device_->SetBatteryPercentage(kBatteryPercentage);
 
   CreateGattBatteryPoller();
   EXPECT_EQ(1, fetchers_created_count());
@@ -180,7 +180,7 @@
 TEST_F(GattBatteryPollerTest, StopsRetryingAfterMaxRetryCount) {
   // Set a battery level to the device. Expect it resets after maximum retry
   // count is exceeded.
-  mock_device_->set_battery_percentage(kBatteryPercentage);
+  mock_device_->SetBatteryPercentage(kBatteryPercentage);
   CreateGattBatteryPoller();
 
   const int kMaxRetryCount = 3;
diff --git a/ash/public/cpp/accessibility_controller.h b/ash/public/cpp/accessibility_controller.h
index af54194..956563af 100644
--- a/ash/public/cpp/accessibility_controller.h
+++ b/ash/public/cpp/accessibility_controller.h
@@ -99,6 +99,12 @@
   // managed outside of this accessibility controller.
   virtual void NotifyAccessibilityStatusChanged() = 0;
 
+  // Returns true if the |path| pref is being controlled by a policy which
+  // enforces turning it on or its not being controlled by any type of policy
+  // and false otherwise.
+  virtual bool IsAccessibilityFeatureVisibleInTrayMenu(
+      const std::string& path) = 0;
+
  protected:
   AccessibilityController();
   virtual ~AccessibilityController();
diff --git a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
index 4abb310a..c38550c0 100644
--- a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
+++ b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
@@ -101,6 +101,19 @@
   return std::min(1.0, std::max(0.0, value));
 }
 
+// Returns a |views::BoxLayout| layout manager with the settings needed by
+// FrameCaptionButtonContainerView.
+std::unique_ptr<views::BoxLayout> MakeBoxLayoutManager(
+    int minimum_cross_axis_size) {
+  std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kHorizontal);
+  layout->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::kCenter);
+  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
+  layout->set_minimum_cross_axis_size(minimum_cross_axis_size);
+  return layout;
+}
+
 // A default CaptionButtonModel that uses the widget delegate's state
 // to determine if each button should be visible and enabled.
 class DefaultCaptionButtonModel : public CaptionButtonModel {
@@ -120,7 +133,7 @@
       case views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
         return frame_->widget_delegate()->CanResize();
       case views::CAPTION_BUTTON_ICON_CLOSE:
-        return true;
+        return frame_->widget_delegate()->ShouldShowCloseButton();
 
       // No back or menu button by default.
       case views::CAPTION_BUTTON_ICON_BACK:
@@ -154,12 +167,7 @@
     : views::AnimationDelegateViews(frame->GetRootView()),
       frame_(frame),
       model_(std::make_unique<DefaultCaptionButtonModel>(frame)) {
-  auto layout = std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal);
-  layout->set_cross_axis_alignment(
-      views::BoxLayout::CrossAxisAlignment::kCenter);
-  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
-  SetLayoutManager(std::move(layout));
+  SetLayoutManager(MakeBoxLayoutManager(/*minimum_cross_axis_size=*/0));
   tablet_mode_animation_.reset(new gfx::SlideAnimation(this));
   tablet_mode_animation_->SetTweenType(gfx::Tween::LINEAR);
 
@@ -262,6 +270,8 @@
       model_->IsEnabled(views::CAPTION_BUTTON_ICON_MINIMIZE));
   menu_button_->SetVisible(model_->IsVisible(views::CAPTION_BUTTON_ICON_MENU));
   menu_button_->SetEnabled(model_->IsEnabled(views::CAPTION_BUTTON_ICON_MENU));
+  close_button_->SetVisible(
+      model_->IsVisible(views::CAPTION_BUTTON_ICON_CLOSE));
 }
 
 void FrameCaptionButtonContainerView::SetButtonSize(const gfx::Size& size) {
@@ -269,6 +279,8 @@
   minimize_button_->SetPreferredSize(size);
   size_button_->SetPreferredSize(size);
   close_button_->SetPreferredSize(size);
+
+  SetLayoutManager(MakeBoxLayoutManager(size.height()));
 }
 
 void FrameCaptionButtonContainerView::SetModel(
@@ -284,10 +296,14 @@
   if (tablet_mode_animation_->is_animating())
     AnimationProgressed(tablet_mode_animation_.get());
 
-  // The top right corner must be occupied by the close button for easy mouse
-  // access. This check is agnostic to RTL layout.
-  DCHECK_EQ(close_button_->y(), 0);
-  DCHECK_EQ(close_button_->bounds().right(), width());
+#if DCHECK_IS_ON()
+  if (close_button_->GetVisible()) {
+    // The top right corner must be occupied by the close button for easy mouse
+    // access. This check is agnostic to RTL layout.
+    DCHECK_EQ(close_button_->y(), 0);
+    DCHECK_EQ(close_button_->bounds().right(), width());
+  }
+#endif  // DCHECK_IS_ON()
 }
 
 const char* FrameCaptionButtonContainerView::GetClassName() const {
diff --git a/ash/system/accessibility/tray_accessibility.cc b/ash/system/accessibility/tray_accessibility.cc
index 167f0e7..ec1c95a0 100644
--- a/ash/system/accessibility/tray_accessibility.cc
+++ b/ash/system/accessibility/tray_accessibility.cc
@@ -111,9 +111,12 @@
                                               switch_access_enabled_);
   }
 
-  large_cursor_enabled_ = controller->large_cursor_enabled();
-  TrayPopupUtils::UpdateCheckMarkVisibility(large_cursor_view_,
-                                            large_cursor_enabled_);
+  if (large_cursor_view_ &&
+      controller->GetTrayVisiblityOfLargeCursorSetting()) {
+    large_cursor_enabled_ = controller->large_cursor_enabled();
+    TrayPopupUtils::UpdateCheckMarkVisibility(large_cursor_view_,
+                                              large_cursor_enabled_);
+  }
 
   mono_audio_enabled_ = controller->mono_audio_enabled();
   TrayPopupUtils::UpdateCheckMarkVisibility(mono_audio_view_,
@@ -221,10 +224,13 @@
 
   AddScrollListSubHeader(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_ADDITIONAL_SETTINGS);
 
-  large_cursor_enabled_ = controller->large_cursor_enabled();
-  large_cursor_view_ = AddScrollListCheckableItem(
-      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LARGE_CURSOR),
-      large_cursor_enabled_);
+  if (controller->GetTrayVisiblityOfLargeCursorSetting()) {
+    large_cursor_enabled_ = controller->large_cursor_enabled();
+    large_cursor_view_ = AddScrollListCheckableItem(
+        l10n_util::GetStringUTF16(
+            IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LARGE_CURSOR),
+        large_cursor_enabled_);
+  }
 
   mono_audio_enabled_ = controller->mono_audio_enabled();
   mono_audio_view_ = AddScrollListCheckableItem(
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc
index db513db..03e9005 100644
--- a/ash/system/audio/unified_volume_view.cc
+++ b/ash/system/audio/unified_volume_view.cc
@@ -157,10 +157,15 @@
   // Indicate that the slider is inactive when it's muted.
   slider()->SetIsActive(!is_muted);
 
-  // The button should be gray whay muted and colored otherwise.
+  // The button should be gray when muted and colored otherwise.
   button()->SetToggled(!is_muted);
   button()->SetVectorIcon(is_muted ? kUnifiedMenuVolumeMuteIcon
                                    : GetVolumeIconForLevel(level));
+  base::string16 state_tooltip_text = l10n_util::GetStringUTF16(
+      is_muted ? IDS_ASH_STATUS_TRAY_VOLUME_STATE_MUTED
+               : IDS_ASH_STATUS_TRAY_VOLUME_STATE_ON);
+  button()->SetTooltipText(l10n_util::GetStringFUTF16(
+      IDS_ASH_STATUS_TRAY_VOLUME, state_tooltip_text));
 
   more_button_->SetVisible(CrasAudioHandler::Get()->has_alternative_input() ||
                            CrasAudioHandler::Get()->has_alternative_output());
diff --git a/ash/system/power/peripheral_battery_notifier.cc b/ash/system/power/peripheral_battery_notifier.cc
index 3024b10..0ff8951 100644
--- a/ash/system/power/peripheral_battery_notifier.cc
+++ b/ash/system/power/peripheral_battery_notifier.cc
@@ -11,12 +11,14 @@
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/bind.h"
+#include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/default_tick_clock.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "third_party/re2/src/re2/re2.h"
@@ -34,7 +36,7 @@
 
 // When a peripheral device's battery level is <= kLowBatteryLevel, consider
 // it to be in low battery condition.
-const int kLowBatteryLevel = 15;
+const uint8_t kLowBatteryLevel = 15;
 
 // Don't show 2 low battery notification within |kNotificationInterval|.
 constexpr base::TimeDelta kNotificationInterval =
@@ -54,6 +56,10 @@
 const char kHIDBatteryPathPrefix[] = "/sys/class/power_supply/hid-";
 const char kHIDBatteryPathSuffix[] = "-battery";
 
+// Prefix added to the address of a Bluetooth device to generate an unique ID
+// when posting a notification to the Message Center.
+const char kBluetoothDeviceIdPrefix[] = "battery_notification_bluetooth-";
+
 // Regex to check for valid bluetooth addresses.
 constexpr char kBluetoothAddressRegex[] =
     "^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$";
@@ -130,13 +136,13 @@
   const gfx::VectorIcon* icon;
 };
 
-NotificationParams GetNonStylusNotificationParams(const std::string& address,
-                                                  const std::string& name,
-                                                  int battery_level,
+NotificationParams GetNonStylusNotificationParams(const std::string& map_key,
+                                                  const base::string16& name,
+                                                  uint8_t battery_level,
                                                   bool is_bluetooth) {
   return NotificationParams{
-      address,
-      base::ASCIIToUTF16(name),
+      map_key,
+      name,
       l10n_util::GetStringFUTF16Int(
           IDS_ASH_LOW_PERIPHERAL_BATTERY_NOTIFICATION_TEXT, battery_level),
       kNotifierNonStylusBattery,
@@ -155,13 +161,55 @@
       &kNotificationStylusBatteryWarningIcon};
 }
 
+std::string GetMapKeyForBluetoothAddress(const std::string& bluetooth_address) {
+  return kBluetoothDeviceIdPrefix + base::ToLowerASCII(bluetooth_address);
+}
+
+// Returns the corresponding map key for a HID device.
+std::string GetBatteryMapKey(const std::string& path) {
+  // Check if the HID path corresponds to a Bluetooth device.
+  const std::string bluetooth_address = ExtractBluetoothAddressFromPath(path);
+  return bluetooth_address.empty()
+             ? path
+             : GetMapKeyForBluetoothAddress(bluetooth_address);
+}
+
+std::string GetBatteryMapKey(device::BluetoothDevice* device) {
+  return GetMapKeyForBluetoothAddress(device->GetAddress());
+}
+
 }  // namespace
 
 const char PeripheralBatteryNotifier::kStylusNotificationId[] =
     "stylus-battery";
 
+PeripheralBatteryNotifier::BatteryInfo::BatteryInfo() = default;
+
+PeripheralBatteryNotifier::BatteryInfo::BatteryInfo(
+    const base::string16& name,
+    base::Optional<uint8_t> level,
+    base::TimeTicks last_notification_timestamp,
+    bool is_stylus,
+    const std::string& bluetooth_address)
+    : name(name),
+      level(level),
+      last_notification_timestamp(last_notification_timestamp),
+      is_stylus(is_stylus),
+      bluetooth_address(bluetooth_address) {}
+
+PeripheralBatteryNotifier::BatteryInfo::~BatteryInfo() = default;
+
+PeripheralBatteryNotifier::BatteryInfo::BatteryInfo(const BatteryInfo& info) {
+  name = info.name;
+  level = info.level;
+  last_notification_timestamp = info.last_notification_timestamp;
+  is_stylus = info.is_stylus;
+  bluetooth_address = info.bluetooth_address;
+}
+
 PeripheralBatteryNotifier::PeripheralBatteryNotifier()
-    : weakptr_factory_(
+    : clock_(base::DefaultTickClock::GetInstance()),
+      weakptr_factory_(
           new base::WeakPtrFactory<PeripheralBatteryNotifier>(this)) {
   chromeos::PowerManagerClient::Get()->AddObserver(this);
   device::BluetoothAdapterFactory::GetAdapter(
@@ -194,44 +242,38 @@
 
   // If unknown battery level received, cancel any existing notification.
   if (level == -1) {
-    CancelNotification(path);
+    CancelNotification(GetBatteryMapKey(path));
     return;
   }
 
-  // Post the notification in 2 cases:
-  // 1. It's the first time the battery level is received, and it is below
-  //    kLowBatteryLevel.
-  // 2. The battery level is in record and it drops below kLowBatteryLevel.
-  if (batteries_.find(path) == batteries_.end()) {
-    BatteryInfo battery{name, level, base::TimeTicks(),
-                        IsStylusDevice(path, name),
-                        ExtractBluetoothAddressFromPath(path)};
-    if (level <= kLowBatteryLevel) {
-      if (PostNotification(path, battery)) {
-        battery.last_notification_timestamp = testing_clock_
-                                                  ? testing_clock_->NowTicks()
-                                                  : base::TimeTicks::Now();
-      }
-    }
-    batteries_[path] = battery;
-  } else {
-    BatteryInfo* battery = &batteries_[path];
-    battery->name = name;
-    int old_level = battery->level;
-    battery->level = level;
-    if (old_level > kLowBatteryLevel && level <= kLowBatteryLevel) {
-      if (PostNotification(path, *battery)) {
-        battery->last_notification_timestamp = testing_clock_
-                                                   ? testing_clock_->NowTicks()
-                                                   : base::TimeTicks::Now();
-      }
-    }
-  }
+  BatteryInfo battery{base::ASCIIToUTF16(name), level, base::TimeTicks(),
+                      IsStylusDevice(path, name),
+                      ExtractBluetoothAddressFromPath(path)};
+  UpdateBattery(GetBatteryMapKey(path), battery);
 }
 
-void PeripheralBatteryNotifier::DeviceChanged(device::BluetoothAdapter* adapter,
-                                              device::BluetoothDevice* device) {
-  if (!device->IsPaired())
+void PeripheralBatteryNotifier::DeviceBatteryChanged(
+    device::BluetoothAdapter* adapter,
+    device::BluetoothDevice* device,
+    base::Optional<uint8_t> new_battery_percentage) {
+  if (!new_battery_percentage) {
+    CancelNotification(kBluetoothDeviceIdPrefix +
+                       base::ToLowerASCII(device->GetAddress()));
+    return;
+  }
+
+  DCHECK_LE(new_battery_percentage.value(), 100);
+  BatteryInfo battery{device->GetNameForDisplay(),
+                      new_battery_percentage.value(), base::TimeTicks(),
+                      false /* is_stylus */, device->GetAddress()};
+  UpdateBattery(GetBatteryMapKey(device), battery);
+}
+
+void PeripheralBatteryNotifier::DeviceConnectedStateChanged(
+    device::BluetoothAdapter* adapter,
+    device::BluetoothDevice* device,
+    bool is_now_connected) {
+  if (!is_now_connected)
     RemoveBluetoothBattery(device->GetAddress());
 }
 
@@ -250,33 +292,72 @@
 void PeripheralBatteryNotifier::RemoveBluetoothBattery(
     const std::string& bluetooth_address) {
   std::string address_lowercase = base::ToLowerASCII(bluetooth_address);
-  for (auto it = batteries_.begin(); it != batteries_.end(); ++it) {
-    if (it->second.bluetooth_address == address_lowercase) {
-      CancelNotification(it->first);
-      batteries_.erase(it);
-      return;
-    }
+  auto it = batteries_.find(kBluetoothDeviceIdPrefix + address_lowercase);
+  if (it != batteries_.end()) {
+    CancelNotification(it->first);
+    batteries_.erase(it);
   }
 }
 
-bool PeripheralBatteryNotifier::PostNotification(const std::string& path,
+void PeripheralBatteryNotifier::UpdateBattery(const std::string& map_key,
+                                              const BatteryInfo& battery_info) {
+  bool was_old_battery_level_low = false;
+  auto it = batteries_.find(map_key);
+
+  if (it == batteries_.end()) {
+    batteries_[map_key] = battery_info;
+  } else {
+    BatteryInfo& existing_battery_info = it->second;
+    base::Optional<uint8_t> old_level = existing_battery_info.level;
+    was_old_battery_level_low = old_level && *old_level < kLowBatteryLevel;
+    existing_battery_info.name = battery_info.name;
+    existing_battery_info.level = battery_info.level;
+  }
+
+  const BatteryInfo& info = batteries_[map_key];
+  if (!info.level || *info.level > kLowBatteryLevel) {
+    CancelNotification(map_key);
+    return;
+  }
+
+  // If low battery was on record, check if there is a notification, otherwise
+  // the user dismissed it and we shouldn't create another one.
+  if (was_old_battery_level_low)
+    UpdateBatteryNotificationIfVisible(map_key, info);
+  else
+    ShowNotification(map_key, info);
+}
+
+void PeripheralBatteryNotifier::UpdateBatteryNotificationIfVisible(
+    const std::string& map_key,
+    const BatteryInfo& battery) {
+  message_center::Notification* notification =
+      message_center::MessageCenter::Get()->FindVisibleNotificationById(
+          map_key);
+  if (notification)
+    ShowOrUpdateNotification(map_key, battery);
+}
+
+void PeripheralBatteryNotifier::ShowNotification(const std::string& map_key,
                                                  const BatteryInfo& battery) {
-  // Only post notification if kNotificationInterval seconds have passed since
-  // last notification showed, avoiding the case where the battery level
-  // oscillates around the threshold level.
-  base::TimeTicks now =
-      testing_clock_ ? testing_clock_->NowTicks() : base::TimeTicks::Now();
-  if (now - battery.last_notification_timestamp < kNotificationInterval)
-    return false;
+  base::TimeTicks now = clock_->NowTicks();
+  if (now - battery.last_notification_timestamp >= kNotificationInterval) {
+    ShowOrUpdateNotification(map_key, battery);
+    batteries_[map_key].last_notification_timestamp = clock_->NowTicks();
+  }
+}
 
+void PeripheralBatteryNotifier::ShowOrUpdateNotification(
+    const std::string& map_key,
+    const BatteryInfo& battery) {
   // Stylus battery notifications differ slightly.
-  NotificationParams params =
-      battery.is_stylus
-          ? GetStylusNotificationParams()
-          : GetNonStylusNotificationParams(path, battery.name, battery.level,
-                                           !battery.bluetooth_address.empty());
+  NotificationParams params = battery.is_stylus
+                                  ? GetStylusNotificationParams()
+                                  : GetNonStylusNotificationParams(
+                                        map_key, battery.name, *battery.level,
+                                        !battery.bluetooth_address.empty());
 
-  auto notification = ash::CreateSystemNotification(
+  auto notification = CreateSystemNotification(
       message_center::NOTIFICATION_TYPE_SIMPLE, params.id, params.title,
       params.message, base::string16(), params.url,
       message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
@@ -287,16 +368,19 @@
 
   message_center::MessageCenter::Get()->AddNotification(
       std::move(notification));
-  return true;
 }
 
-void PeripheralBatteryNotifier::CancelNotification(const std::string& path) {
-  const auto it = batteries_.find(path);
+void PeripheralBatteryNotifier::CancelNotification(const std::string& map_key) {
+  const auto it = batteries_.find(map_key);
   if (it != batteries_.end()) {
-    std::string notification_id =
-        it->second.is_stylus ? kStylusNotificationId : path;
+    std::string notification_map_key =
+        it->second.is_stylus ? kStylusNotificationId : map_key;
     message_center::MessageCenter::Get()->RemoveNotification(
-        notification_id, false /* by_user */);
+        notification_map_key, false /* by_user */);
+
+    // Resetting this value allows a new low battery level to post a
+    // notification if the old one was also under the threshold.
+    it->second.level.reset();
   }
 }
 
diff --git a/ash/system/power/peripheral_battery_notifier.h b/ash/system/power/peripheral_battery_notifier.h
index 3df371c..7a18fd0 100644
--- a/ash/system/power/peripheral_battery_notifier.h
+++ b/ash/system/power/peripheral_battery_notifier.h
@@ -5,6 +5,7 @@
 #ifndef ASH_SYSTEM_POWER_PERIPHERAL_BATTERY_NOTIFIER_H_
 #define ASH_SYSTEM_POWER_PERIPHERAL_BATTERY_NOTIFIER_H_
 
+#include <cstdint>
 #include <map>
 
 #include "ash/ash_export.h"
@@ -12,6 +13,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/time/tick_clock.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -33,9 +35,6 @@
   PeripheralBatteryNotifier();
   ~PeripheralBatteryNotifier() override;
 
-  void set_testing_clock(const base::TickClock* clock) {
-    testing_clock_ = clock;
-  }
 
   // chromeos::PowerManagerClient::Observer:
   void PeripheralBatteryStatusReceived(const std::string& path,
@@ -43,8 +42,13 @@
                                        int level) override;
 
   // device::BluetoothAdapter::Observer:
-  void DeviceChanged(device::BluetoothAdapter* adapter,
-                     device::BluetoothDevice* device) override;
+  void DeviceBatteryChanged(
+      device::BluetoothAdapter* adapter,
+      device::BluetoothDevice* device,
+      base::Optional<uint8_t> new_battery_percentage) override;
+  void DeviceConnectedStateChanged(device::BluetoothAdapter* adapter,
+                                   device::BluetoothDevice* device,
+                                   bool is_now_connected) override;
   void DeviceRemoved(device::BluetoothAdapter* adapter,
                      device::BluetoothDevice* device) override;
 
@@ -57,10 +61,19 @@
   FRIEND_TEST_ALL_PREFIXES(PeripheralBatteryNotifierTest, DeviceRemove);
 
   struct BatteryInfo {
+    BatteryInfo();
+    BatteryInfo(const base::string16& name,
+                base::Optional<uint8_t> level,
+                base::TimeTicks last_notification_timestamp,
+                bool is_stylus,
+                const std::string& bluetooth_address);
+    ~BatteryInfo();
+    BatteryInfo(const BatteryInfo& info);
+
     // Human readable name for the device. It is changeable.
-    std::string name;
-    // Battery level within range [0, 100], and -1 for unknown level.
-    int level = -1;
+    base::string16 name;
+    // Battery level within range [0, 100].
+    base::Optional<uint8_t> level;
     base::TimeTicks last_notification_timestamp;
     bool is_stylus = false;
     // Peripheral's Bluetooth address. Empty for non-Bluetooth devices.
@@ -75,21 +88,39 @@
   // changed or removed.
   void RemoveBluetoothBattery(const std::string& bluetooth_address);
 
-  // Posts a low battery notification with unique id |path|. Returns true
-  // if the notification is posted, false if not.
-  bool PostNotification(const std::string& path, const BatteryInfo& battery);
+  // Updates the battery information of the peripheral with the corresponding
+  // |map_key|, and calls to post a notification if the battery level is under
+  // the threshold.
+  void UpdateBattery(const std::string& map_key,
+                     const BatteryInfo& battery_info);
 
-  void CancelNotification(const std::string& path);
+  // Updates the battery percentage in the corresponding notification.
+  void UpdateBatteryNotificationIfVisible(const std::string& map_key,
+                                          const BatteryInfo& battery);
 
-  // Record of existing battery infomation. The key is the device path.
+  // Calls to display a notification only if kNotificationInterval seconds have
+  // passed since the last notification showed, avoiding the case where the
+  // battery level oscillates around the threshold level.
+  void ShowNotification(const std::string& map_key, const BatteryInfo& battery);
+
+  // Posts a low battery notification with id as |map_key|. If a notification
+  // with the same id exists, its content gets updated.
+  void ShowOrUpdateNotification(const std::string& map_key,
+                                const BatteryInfo& battery);
+
+  void CancelNotification(const std::string& map_key);
+
+  // Record of existing battery information. For Bluetooth Devices, the key is
+  // kBluetoothDeviceIdPrefix + the device's address. For HID devices, the key
+  // is the device path. If a device uses HID over Bluetooth, it is indexed as a
+  // Bluetooth device.
   std::map<std::string, BatteryInfo> batteries_;
 
   // PeripheralBatteryNotifier is an observer of |bluetooth_adapter_| for
   // bluetooth device change/remove events.
   scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
 
-  // Used only for helping test. Not owned and can be nullptr.
-  const base::TickClock* testing_clock_ = nullptr;
+  const base::TickClock* clock_;
 
   std::unique_ptr<base::WeakPtrFactory<PeripheralBatteryNotifier>>
       weakptr_factory_;
diff --git a/ash/system/power/peripheral_battery_notifier_unittest.cc b/ash/system/power/peripheral_battery_notifier_unittest.cc
index bc83b95..c222ca3 100644
--- a/ash/system/power/peripheral_battery_notifier_unittest.cc
+++ b/ash/system/power/peripheral_battery_notifier_unittest.cc
@@ -9,40 +9,113 @@
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/macros.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/test/simple_test_tick_clock.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/test/mock_bluetooth_adapter.h"
+#include "device/bluetooth/test/mock_bluetooth_device.h"
 #include "ui/events/devices/device_data_manager_test_api.h"
 #include "ui/events/devices/touchscreen_device.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
 
+using testing::NiceMock;
+
 namespace {
 
+// HID device.
 const char kTestBatteryPath[] =
     "/sys/class/power_supply/hid-AA:BB:CC:DD:EE:FF-battery";
 const char kTestBatteryAddress[] = "ff:ee:dd:cc:bb:aa";
 const char kTestDeviceName[] = "test device";
+const char kTestBatteryId[] =
+    "battery_notification_bluetooth-ff:ee:dd:cc:bb:aa";
+
+// Bluetooth devices.
+const char kBluetoothDeviceAddress1[] = "aa:bb:cc:dd:ee:ff";
+const char kBluetoothDeviceAddress2[] = "11:22:33:44:55:66";
+const char kBluetoothDeviceId1[] =
+    "battery_notification_bluetooth-aa:bb:cc:dd:ee:ff";
+const char kBluetoothDeviceId2[] =
+    "battery_notification_bluetooth-11:22:33:44:55:66";
+
+const base::string16& NotificationMessagePrefix() {
+  static const base::string16 prefix(base::ASCIIToUTF16("Battery low ("));
+  return prefix;
+}
+
+const base::string16& NotificationMessageSuffix() {
+  static const base::string16 suffix(base::ASCIIToUTF16("%)"));
+  return suffix;
+}
 
 }  // namespace
 
 namespace ash {
 
-class PeripheralBatteryNotifierTest : public ash::AshTestBase {
+class PeripheralBatteryNotifierTest : public AshTestBase {
  public:
   PeripheralBatteryNotifierTest() = default;
   ~PeripheralBatteryNotifierTest() override = default;
 
   void SetUp() override {
-    ash::AshTestBase::SetUp();
-    observer_ = std::make_unique<PeripheralBatteryNotifier>();
+    AshTestBase::SetUp();
+
+    mock_adapter_ =
+        base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>();
+    mock_device_1_ = std::make_unique<NiceMock<device::MockBluetoothDevice>>(
+        mock_adapter_.get(), 0 /* bluetooth_class */, "device_name_1",
+        kBluetoothDeviceAddress1, true /* paired */, true /* connected */);
+    mock_device_2_ = std::make_unique<NiceMock<device::MockBluetoothDevice>>(
+        mock_adapter_.get(), 0 /* bluetooth_class */, "device_name_2",
+        kBluetoothDeviceAddress2, true /* paired */, true /* connected */);
+
+    message_center_ = message_center::MessageCenter::Get();
+
+    battery_notifier_ = std::make_unique<PeripheralBatteryNotifier>();
+    // No notifications should have been posted yet.
+    EXPECT_EQ(0u, message_center_->NotificationCount());
   }
 
   void TearDown() override {
-    observer_.reset();
-    ash::AshTestBase::TearDown();
+    battery_notifier_.reset();
+    AshTestBase::TearDown();
+  }
+
+  // Extracts the battery percentage from the message of a notification.
+  uint8_t ExtractBatteryPercentage(message_center::Notification* notification) {
+    const base::string16& message = notification->message();
+    EXPECT_TRUE(base::StartsWith(message, NotificationMessagePrefix(),
+                                 base::CompareCase::SENSITIVE));
+    EXPECT_TRUE(base::EndsWith(message, NotificationMessageSuffix(),
+                               base::CompareCase::SENSITIVE));
+
+    int prefix_size = NotificationMessagePrefix().size();
+    int suffix_size = NotificationMessageSuffix().size();
+    int key_len = message.size() - prefix_size - suffix_size;
+    EXPECT_GT(key_len, 0);
+
+    int battery_percentage;
+    EXPECT_TRUE(base::StringToInt(message.substr(prefix_size, key_len),
+                                  &battery_percentage));
+    EXPECT_GE(battery_percentage, 0);
+    EXPECT_LE(battery_percentage, 100);
+    return battery_percentage;
+  }
+
+  void SetTestingClock(base::SimpleTestTickClock* clock) {
+    battery_notifier_->clock_ = clock;
   }
 
  protected:
-  std::unique_ptr<PeripheralBatteryNotifier> observer_;
+  scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
+  std::unique_ptr<device::MockBluetoothDevice> mock_device_1_;
+  std::unique_ptr<device::MockBluetoothDevice> mock_device_2_;
+  message_center::MessageCenter* message_center_;
+  std::unique_ptr<PeripheralBatteryNotifier> battery_notifier_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PeripheralBatteryNotifierTest);
@@ -50,69 +123,66 @@
 
 TEST_F(PeripheralBatteryNotifierTest, Basic) {
   base::SimpleTestTickClock clock;
-  observer_->set_testing_clock(&clock);
-
-  message_center::MessageCenter* message_center =
-      message_center::MessageCenter::Get();
+  SetTestingClock(&clock);
 
   // Level 50 at time 100, no low-battery notification.
   clock.Advance(base::TimeDelta::FromSeconds(100));
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             50);
-  EXPECT_EQ(1u, observer_->batteries_.count(kTestBatteryPath));
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 50);
+  EXPECT_EQ(1u, battery_notifier_->batteries_.count(kTestBatteryId));
 
   const PeripheralBatteryNotifier::BatteryInfo& info =
-      observer_->batteries_[kTestBatteryPath];
+      battery_notifier_->batteries_[kTestBatteryId];
 
-  EXPECT_EQ(kTestDeviceName, info.name);
-  EXPECT_EQ(50, info.level);
+  EXPECT_EQ(base::ASCIIToUTF16(kTestDeviceName), info.name);
+  EXPECT_EQ(base::nullopt, info.level);
   EXPECT_EQ(base::TimeTicks(), info.last_notification_timestamp);
   EXPECT_EQ(kTestBatteryAddress, info.bluetooth_address);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) ==
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) ==
               nullptr);
 
   // Level 5 at time 110, low-battery notification.
   clock.Advance(base::TimeDelta::FromSeconds(10));
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             5);
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 5);
   EXPECT_EQ(5, info.level);
   EXPECT_EQ(clock.NowTicks(), info.last_notification_timestamp);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) !=
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) !=
               nullptr);
 
   // Verify that the low-battery notification for stylus does not show up.
-  EXPECT_FALSE(message_center->FindVisibleNotificationById(
+  EXPECT_FALSE(message_center_->FindVisibleNotificationById(
                    PeripheralBatteryNotifier::kStylusNotificationId) !=
                nullptr);
 
   // Level -1 at time 115, cancel previous notification
   clock.Advance(base::TimeDelta::FromSeconds(5));
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             -1);
-  EXPECT_EQ(5, info.level);
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, -1);
+  EXPECT_EQ(base::nullopt, info.level);
   EXPECT_EQ(clock.NowTicks() - base::TimeDelta::FromSeconds(5),
             info.last_notification_timestamp);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) ==
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) ==
               nullptr);
 
   // Level 50 at time 120, no low-battery notification.
   clock.Advance(base::TimeDelta::FromSeconds(5));
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             50);
-  EXPECT_EQ(50, info.level);
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 50);
+  EXPECT_EQ(base::nullopt, info.level);
   EXPECT_EQ(clock.NowTicks() - base::TimeDelta::FromSeconds(10),
             info.last_notification_timestamp);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) ==
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) ==
               nullptr);
 
   // Level 5 at time 130, no low-battery notification (throttling).
   clock.Advance(base::TimeDelta::FromSeconds(10));
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             5);
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 5);
   EXPECT_EQ(5, info.level);
   EXPECT_EQ(clock.NowTicks() - base::TimeDelta::FromSeconds(20),
             info.last_notification_timestamp);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) ==
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) ==
               nullptr);
 }
 
@@ -120,25 +190,25 @@
   const std::string invalid_path1 = "invalid-path";
   const std::string invalid_path2 = "/sys/class/power_supply/hid-battery";
 
-  observer_->PeripheralBatteryStatusReceived(invalid_path1, kTestDeviceName,
-                                             10);
-  EXPECT_TRUE(observer_->batteries_.empty());
+  battery_notifier_->PeripheralBatteryStatusReceived(invalid_path1,
+                                                     kTestDeviceName, 10);
+  EXPECT_TRUE(battery_notifier_->batteries_.empty());
 
-  observer_->PeripheralBatteryStatusReceived(invalid_path2, kTestDeviceName,
-                                             10);
-  EXPECT_TRUE(observer_->batteries_.empty());
+  battery_notifier_->PeripheralBatteryStatusReceived(invalid_path2,
+                                                     kTestDeviceName, 10);
+  EXPECT_TRUE(battery_notifier_->batteries_.empty());
 
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             -2);
-  EXPECT_TRUE(observer_->batteries_.empty());
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, -2);
+  EXPECT_TRUE(battery_notifier_->batteries_.empty());
 
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             101);
-  EXPECT_TRUE(observer_->batteries_.empty());
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 101);
+  EXPECT_TRUE(battery_notifier_->batteries_.empty());
 
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             -1);
-  EXPECT_TRUE(observer_->batteries_.empty());
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, -1);
+  EXPECT_TRUE(battery_notifier_->batteries_.empty());
 }
 
 // Verify that for Bluetooth devices, the correct address gets stored in the
@@ -148,37 +218,36 @@
   const std::string bluetooth_path =
       "/sys/class/power_supply/hid-A0:b1:C2:d3:E4:f5-battery";
   const std::string expected_bluetooth_address = "f5:e4:d3:c2:b1:a0";
+  const std::string expected_bluetooth_id =
+      "battery_notification_bluetooth-f5:e4:d3:c2:b1:a0";
   const std::string non_bluetooth_path =
       "/sys/class/power_supply/hid-notbluetooth-battery";
 
-  observer_->PeripheralBatteryStatusReceived(bluetooth_path, kTestDeviceName,
-                                             10);
-  observer_->PeripheralBatteryStatusReceived(non_bluetooth_path,
-                                             kTestDeviceName, 10);
-  EXPECT_EQ(2u, observer_->batteries_.size());
+  battery_notifier_->PeripheralBatteryStatusReceived(bluetooth_path,
+                                                     kTestDeviceName, 10);
+  battery_notifier_->PeripheralBatteryStatusReceived(non_bluetooth_path,
+                                                     kTestDeviceName, 10);
+  EXPECT_EQ(2u, battery_notifier_->batteries_.size());
 
   const PeripheralBatteryNotifier::BatteryInfo& bluetooth_device_info =
-      observer_->batteries_[bluetooth_path];
+      battery_notifier_->batteries_[expected_bluetooth_id];
   EXPECT_EQ(expected_bluetooth_address,
             bluetooth_device_info.bluetooth_address);
   const PeripheralBatteryNotifier::BatteryInfo& non_bluetooth_device_info =
-      observer_->batteries_[non_bluetooth_path];
+      battery_notifier_->batteries_[non_bluetooth_path];
   EXPECT_TRUE(non_bluetooth_device_info.bluetooth_address.empty());
 }
 
 // TODO(crbug.com/765794): Flaky on ash_unittests with mus.
 TEST_F(PeripheralBatteryNotifierTest, DISABLED_DeviceRemove) {
-  message_center::MessageCenter* message_center =
-      message_center::MessageCenter::Get();
-
-  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath, kTestDeviceName,
-                                             5);
-  EXPECT_EQ(1u, observer_->batteries_.count(kTestBatteryPath));
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) !=
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestBatteryPath,
+                                                     kTestDeviceName, 5);
+  EXPECT_EQ(1u, battery_notifier_->batteries_.count(kTestBatteryId));
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) !=
               nullptr);
 
-  observer_->RemoveBluetoothBattery(kTestBatteryAddress);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(kTestBatteryPath) ==
+  battery_notifier_->RemoveBluetoothBattery(kTestBatteryAddress);
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(kTestBatteryId) ==
               nullptr);
 }
 
@@ -196,32 +265,228 @@
 
   ui::DeviceDataManagerTestApi().SetTouchscreenDevices({stylus});
 
-  message_center::MessageCenter* message_center =
-      message_center::MessageCenter::Get();
-
   // Verify that when the battery level is 50, no stylus low battery
   // notification is shown.
-  observer_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
-                                             kTestStylusName, 50);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
+                                                     kTestStylusName, 50);
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(
                   PeripheralBatteryNotifier::kStylusNotificationId) == nullptr);
 
   // Verify that when the battery level is 5, a stylus low battery notification
   // is shown. Also check that a non stylus device low battery notification will
   // not show up.
-  observer_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
-                                             kTestStylusName, 5);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
+                                                     kTestStylusName, 5);
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(
                   PeripheralBatteryNotifier::kStylusNotificationId) != nullptr);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(
                   kTestBatteryAddress) == nullptr);
 
   // Verify that when the battery level is -1, the previous stylus low battery
   // notification is cancelled.
-  observer_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
-                                             kTestStylusName, -1);
-  EXPECT_TRUE(message_center->FindVisibleNotificationById(
+  battery_notifier_->PeripheralBatteryStatusReceived(kTestStylusBatteryPath,
+                                                     kTestStylusName, -1);
+  EXPECT_TRUE(message_center_->FindVisibleNotificationById(
                   PeripheralBatteryNotifier::kStylusNotificationId) == nullptr);
 }
 
+TEST_F(PeripheralBatteryNotifierTest,
+       Bluetooth_OnlyShowNotificationForLowBatteryLevels) {
+  // Should not create a notification for battery changes above the threshold.
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          80 /* new_battery_percentage */);
+  EXPECT_EQ(0u, message_center_->NotificationCount());
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          100 /* new_battery_percentage */);
+  EXPECT_EQ(0u, message_center_->NotificationCount());
+
+  // Should trigger notificaiton.
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          10 /* new_battery_percentage */);
+  EXPECT_EQ(1u, message_center_->NotificationCount());
+  message_center::Notification* notification =
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1);
+  EXPECT_EQ(mock_device_1_->GetNameForDisplay(), notification->title());
+  EXPECT_EQ(10, ExtractBatteryPercentage(notification));
+}
+
+TEST_F(PeripheralBatteryNotifierTest,
+       Bluetooth_CreatesANotificationForEachDevice) {
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          5 /* new_battery_percentage */);
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_2_.get(),
+                                          0 /* new_battery_percentage */);
+
+  // Verify 2 notifications were posted with the correct values.
+  EXPECT_EQ(2u, message_center_->NotificationCount());
+  message_center::Notification* notification_1 =
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1);
+  message_center::Notification* notification_2 =
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId2);
+
+  EXPECT_EQ(mock_device_1_->GetNameForDisplay(), notification_1->title());
+  EXPECT_EQ(5, ExtractBatteryPercentage(notification_1));
+  EXPECT_EQ(mock_device_2_->GetNameForDisplay(), notification_2->title());
+  EXPECT_EQ(0, ExtractBatteryPercentage(notification_2));
+}
+
+TEST_F(PeripheralBatteryNotifierTest,
+       Bluetooth_RemovesNotificationForDisconnectedDevices) {
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          5 /* new_battery_percentage */);
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_2_.get(),
+                                          0 /* new_battery_percentage */);
+
+  // Verify 2 notifications were posted.
+  EXPECT_EQ(2u, message_center_->NotificationCount());
+
+  // Verify only the notification for device 1 gets removed.
+  battery_notifier_->DeviceConnectedStateChanged(mock_adapter_.get(),
+                                                 mock_device_1_.get(), false);
+  EXPECT_EQ(1u, message_center_->NotificationCount());
+  EXPECT_TRUE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId2));
+
+  // Remove the second notification.
+  battery_notifier_->DeviceRemoved(mock_adapter_.get(), mock_device_2_.get());
+  EXPECT_EQ(0u, message_center_->NotificationCount());
+}
+
+TEST_F(PeripheralBatteryNotifierTest,
+       Bluetooth_CancelNotificationForInvalidBatteryLevel) {
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          1 /* new_battery_percentage */);
+  EXPECT_TRUE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+
+  // The notification should get canceled.
+  battery_notifier_->DeviceBatteryChanged(
+      mock_adapter_.get(), mock_device_1_.get(),
+      base::nullopt /* new_battery_percentage */);
+  EXPECT_FALSE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+}
+
+// Don't post a notification if the battery level drops again under the
+// threshold before kNotificationInterval is completed.
+TEST_F(PeripheralBatteryNotifierTest,
+       DontShowSecondNotificationWithinASmallTimeInterval) {
+  base::SimpleTestTickClock clock;
+  SetTestingClock(&clock);
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+
+  // Post a notification.
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          1 /* new_battery_percentage */);
+  EXPECT_TRUE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+
+  // Cancel the notification.
+  clock.Advance(base::TimeDelta::FromSeconds(1));
+  battery_notifier_->DeviceBatteryChanged(
+      mock_adapter_.get(), mock_device_1_.get(),
+      base::nullopt /* new_battery_percentage */);
+  EXPECT_FALSE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+
+  // The battery level falls below the threshold after a short time period. No
+  // notification should get posted.
+  clock.Advance(base::TimeDelta::FromSeconds(1));
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          1 /* new_battery_percentage */);
+  EXPECT_FALSE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+}
+
+// Post a notification if the battery is under threshold, then unknown level and
+// then is again under the threshold after kNotificationInterval is completed.
+TEST_F(PeripheralBatteryNotifierTest,
+       PostNotificationIfBatteryGoesFromUnknownLevelToBelowThreshold) {
+  base::SimpleTestTickClock clock;
+  SetTestingClock(&clock);
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+
+  // Post a notification.
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          1) /* new_battery_percentage */;
+  EXPECT_TRUE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+
+  // Cancel the notification.
+  clock.Advance(base::TimeDelta::FromSeconds(1));
+  battery_notifier_->DeviceBatteryChanged(
+      mock_adapter_.get(), mock_device_1_.get(),
+      base::nullopt /* new_battery_percentage */);
+  EXPECT_FALSE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+
+  // Post notification if we are out of the kNotificationInterval.
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          1 /* new_battery_percentage */);
+  EXPECT_TRUE(
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1));
+}
+
+// Don't Post another notification if the battery level keeps low and the user
+// dismissed the previous notification.
+TEST_F(PeripheralBatteryNotifierTest,
+       DontRepostNotificationIfUserDismissedPreviousOne) {
+  base::SimpleTestTickClock clock;
+  SetTestingClock(&clock);
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          5 /* new_battery_percentage */);
+  EXPECT_EQ(1u, message_center_->NotificationCount());
+
+  // Simulate the user clears the notification.
+  message_center_->RemoveAllNotifications(
+      true /* by_user */, message_center::MessageCenter::RemoveType::ALL);
+
+  // The battery level remains low, but shouldn't post a notificaiton.
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          3 /* new_battery_percentage */);
+  EXPECT_EQ(0u, message_center_->NotificationCount());
+}
+
+// If there is an existing notificaiton and the battery level remains low,
+// update its content.
+TEST_F(PeripheralBatteryNotifierTest, UpdateNotificationIfVisible) {
+  base::SimpleTestTickClock clock;
+  SetTestingClock(&clock);
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          5 /* new_battery_percentage */);
+  EXPECT_EQ(1u, message_center_->NotificationCount());
+
+  // The battery level remains low, should update the notification.
+  clock.Advance(base::TimeDelta::FromSeconds(100));
+  battery_notifier_->DeviceBatteryChanged(mock_adapter_.get(),
+                                          mock_device_1_.get(),
+                                          3 /* new_battery_percentage */);
+
+  message_center::Notification* notification =
+      message_center_->FindVisibleNotificationById(kBluetoothDeviceId1);
+  EXPECT_EQ(mock_device_1_->GetNameForDisplay(), notification->title());
+  EXPECT_EQ(3, ExtractBatteryPercentage(notification));
+}
+
 }  // namespace ash
diff --git a/ash/wm/test_child_modal_parent.cc b/ash/wm/test_child_modal_parent.cc
index e147be7a7..c607d43 100644
--- a/ash/wm/test_child_modal_parent.cc
+++ b/ash/wm/test_child_modal_parent.cc
@@ -53,7 +53,7 @@
     AddChildView(modal_child_textfield);
     modal_child_textfield->SetBounds(kTextfieldLeft, kTextfieldTop,
                                      kTextfieldWidth, kTextfieldHeight);
-    modal_child_textfield->set_placeholder_text(
+    modal_child_textfield->SetPlaceholderText(
         base::ASCIIToUTF16("modal child window"));
   }
   ~ChildModalWindow() override = default;
@@ -91,7 +91,7 @@
     : modal_parent_(std::make_unique<Widget>()),
       textfield_(new views::Textfield),
       host_(new views::NativeViewHost) {
-  textfield_->set_placeholder_text(base::ASCIIToUTF16("top level window"));
+  textfield_->SetPlaceholderText(base::ASCIIToUTF16("top level window"));
   Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   params.context = context;
@@ -102,7 +102,7 @@
   modal_parent_->GetRootView()->AddChildView(modal_parent_textfield);
   modal_parent_textfield->SetBounds(kTextfieldLeft, kTextfieldTop,
                                     kTextfieldWidth, kTextfieldHeight);
-  modal_parent_textfield->set_placeholder_text(
+  modal_parent_textfield->SetPlaceholderText(
       base::ASCIIToUTF16("modal parent window"));
   modal_parent_->GetNativeView()->SetName("ModalParent");
   auto button = views::MdTextButton::Create(
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 13ef9c5..4bc1db8 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1837,6 +1837,8 @@
       "CoreFoundation.framework",
       "IOKit.framework",
       "OpenDirectory.framework",
+      "pmenergy",
+      "pmsample",
       "Security.framework",
     ]
   }
@@ -3428,6 +3430,7 @@
       "test/android/javatests/src/org/chromium/base/test/util/parameter/CommandLineParameter.java",
       "test/android/javatests/src/org/chromium/base/test/util/parameter/SkipCommandLineParameterization.java",
     ]
+    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   }
 
   android_library("base_java_process_launcher_test_support") {
diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java
index d83db2f6..728a6bd 100644
--- a/base/android/java/src/org/chromium/base/ApplicationStatus.java
+++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
@@ -16,6 +16,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
@@ -579,7 +580,7 @@
                 sNativeApplicationStateListener = new ApplicationStateListener() {
                     @Override
                     public void onApplicationStateChange(int newState) {
-                        nativeOnApplicationStateChange(newState);
+                        ApplicationStatusJni.get().onApplicationStateChange(newState);
                     }
                 };
                 registerApplicationStateListener(sNativeApplicationStateListener);
@@ -619,7 +620,10 @@
         return ApplicationState.HAS_DESTROYED_ACTIVITIES;
     }
 
-    // Called to notify the native side of state changes.
-    // IMPORTANT: This is always called on the main thread!
-    private static native void nativeOnApplicationStateChange(@ApplicationState int newState);
+    @NativeMethods
+    interface Natives {
+        // Called to notify the native side of state changes.
+        // IMPORTANT: This is always called on the main thread!
+        void onApplicationStateChange(@ApplicationState int newState);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/CommandLine.java b/base/android/java/src/org/chromium/base/CommandLine.java
index 963b146..42392e6 100644
--- a/base/android/java/src/org/chromium/base/CommandLine.java
+++ b/base/android/java/src/org/chromium/base/CommandLine.java
@@ -9,6 +9,7 @@
 import android.util.Log;
 
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.io.File;
 import java.io.FileReader;
@@ -333,32 +334,32 @@
 
     private static class NativeCommandLine extends CommandLine {
         public NativeCommandLine(@Nullable String[] args) {
-            nativeInit(args);
+            CommandLineJni.get().init(args);
         }
 
         @Override
         public boolean hasSwitch(String switchString) {
-            return nativeHasSwitch(switchString);
+            return CommandLineJni.get().hasSwitch(switchString);
         }
 
         @Override
         public String getSwitchValue(String switchString) {
-            return nativeGetSwitchValue(switchString);
+            return CommandLineJni.get().getSwitchValue(switchString);
         }
 
         @Override
         public void appendSwitch(String switchString) {
-            nativeAppendSwitch(switchString);
+            CommandLineJni.get().appendSwitch(switchString);
         }
 
         @Override
         public void appendSwitchWithValue(String switchString, String value) {
-            nativeAppendSwitchWithValue(switchString, value);
+            CommandLineJni.get().appendSwitchWithValue(switchString, value);
         }
 
         @Override
         public void appendSwitchesAndArguments(String[] array) {
-            nativeAppendSwitchesAndArguments(array);
+            CommandLineJni.get().appendSwitchesAndArguments(array);
         }
 
         @Override
@@ -380,10 +381,13 @@
         }
     }
 
-    private static native void nativeInit(String[] args);
-    private static native boolean nativeHasSwitch(String switchString);
-    private static native String nativeGetSwitchValue(String switchString);
-    private static native void nativeAppendSwitch(String switchString);
-    private static native void nativeAppendSwitchWithValue(String switchString, String value);
-    private static native void nativeAppendSwitchesAndArguments(String[] array);
+    @NativeMethods
+    interface Natives {
+        void init(String[] args);
+        boolean hasSwitch(String switchString);
+        String getSwitchValue(String switchString);
+        void appendSwitch(String switchString);
+        void appendSwitchWithValue(String switchString, String value);
+        void appendSwitchesAndArguments(String[] array);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/CpuFeatures.java b/base/android/java/src/org/chromium/base/CpuFeatures.java
index ae4969c9..8b01221 100644
--- a/base/android/java/src/org/chromium/base/CpuFeatures.java
+++ b/base/android/java/src/org/chromium/base/CpuFeatures.java
@@ -5,6 +5,7 @@
 package org.chromium.base;
 
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 // The only purpose of this class is to allow sending CPU properties
 // from the browser process to sandboxed renderer processes. This is
@@ -25,7 +26,7 @@
      * Return the number of CPU Cores on the device.
      */
     public static int getCount() {
-        return nativeGetCoreCount();
+        return CpuFeaturesJni.get().getCoreCount();
     }
 
     /**
@@ -34,9 +35,12 @@
      * The value comes directly from android_getCpuFeatures().
      */
     public static long getMask() {
-        return nativeGetCpuFeatures();
+        return CpuFeaturesJni.get().getCpuFeatures();
     }
 
-    private static native int nativeGetCoreCount();
-    private static native long nativeGetCpuFeatures();
+    @NativeMethods
+    interface Natives {
+        int getCoreCount();
+        long getCpuFeatures();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/EarlyTraceEvent.java b/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
index 9c79586..c932d93 100644
--- a/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
+++ b/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
@@ -13,6 +13,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -313,7 +314,7 @@
     private static void dumpEvents(List<Event> events) {
         long offsetNanos = getOffsetNanos();
         for (Event e : events) {
-            nativeRecordEarlyEvent(e.mName, e.mBeginTimeNanos + offsetNanos,
+            EarlyTraceEventJni.get().recordEarlyEvent(e.mName, e.mBeginTimeNanos + offsetNanos,
                     e.mEndTimeNanos + offsetNanos, e.mThreadId,
                     e.mEndThreadTimeMillis - e.mBeginThreadTimeMillis);
         }
@@ -322,15 +323,17 @@
         long offsetNanos = getOffsetNanos();
         for (AsyncEvent e : events) {
             if (e.mIsStart) {
-                nativeRecordEarlyStartAsyncEvent(e.mName, e.mId, e.mTimestampNanos + offsetNanos);
+                EarlyTraceEventJni.get().recordEarlyStartAsyncEvent(
+                        e.mName, e.mId, e.mTimestampNanos + offsetNanos);
             } else {
-                nativeRecordEarlyFinishAsyncEvent(e.mName, e.mId, e.mTimestampNanos + offsetNanos);
+                EarlyTraceEventJni.get().recordEarlyFinishAsyncEvent(
+                        e.mName, e.mId, e.mTimestampNanos + offsetNanos);
             }
         }
     }
 
     private static long getOffsetNanos() {
-        long nativeNowNanos = TimeUtils.nativeGetTimeTicksNowUs() * 1000;
+        long nativeNowNanos = TimeUtilsJni.get().getTimeTicksNowUs() * 1000;
         long javaNowNanos = Event.elapsedRealtimeNanos();
         return nativeNowNanos - javaNowNanos;
     }
@@ -345,10 +348,11 @@
         return name + "@" + Process.myTid();
     }
 
-    private static native void nativeRecordEarlyEvent(String name, long beginTimNanos,
-            long endTimeNanos, int threadId, long threadDurationMillis);
-    private static native void nativeRecordEarlyStartAsyncEvent(
-            String name, long id, long timestamp);
-    private static native void nativeRecordEarlyFinishAsyncEvent(
-            String name, long id, long timestamp);
+    @NativeMethods
+    interface Natives {
+        void recordEarlyEvent(String name, long beginTimNanos, long endTimeNanos, int threadId,
+                long threadDurationMillis);
+        void recordEarlyStartAsyncEvent(String name, long id, long timestamp);
+        void recordEarlyFinishAsyncEvent(String name, long id, long timestamp);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/FieldTrialList.java b/base/android/java/src/org/chromium/base/FieldTrialList.java
index ea93a61..15b5a4ec 100644
--- a/base/android/java/src/org/chromium/base/FieldTrialList.java
+++ b/base/android/java/src/org/chromium/base/FieldTrialList.java
@@ -5,6 +5,7 @@
 package org.chromium.base;
 
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Helper to get field trial information.
@@ -20,7 +21,7 @@
      *         not exist.
      */
     public static String findFullName(String trialName) {
-        return nativeFindFullName(trialName);
+        return FieldTrialListJni.get().findFullName(trialName);
     }
 
     /**
@@ -28,7 +29,7 @@
      * @return Whether the trial exists or not.
      */
     public static boolean trialExists(String trialName) {
-        return nativeTrialExists(trialName);
+        return FieldTrialListJni.get().trialExists(trialName);
     }
 
     /**
@@ -37,7 +38,7 @@
      * @return The value of the parameter or an empty string if not found.
      */
     public static String getVariationParameter(String trialName, String parameterKey) {
-        return nativeGetVariationParameter(trialName, parameterKey);
+        return FieldTrialListJni.get().getVariationParameter(trialName, parameterKey);
     }
 
     /**
@@ -45,11 +46,14 @@
      * prtinting new trials as they become active. This should be called at most once.
      */
     public static void logActiveTrials() {
-        nativeLogActiveTrials();
+        FieldTrialListJni.get().logActiveTrials();
     }
 
-    private static native String nativeFindFullName(String trialName);
-    private static native boolean nativeTrialExists(String trialName);
-    private static native String nativeGetVariationParameter(String trialName, String parameterKey);
-    private static native void nativeLogActiveTrials();
+    @NativeMethods
+    interface Natives {
+        String findFullName(String trialName);
+        boolean trialExists(String trialName);
+        String getVariationParameter(String trialName, String parameterKey);
+        void logActiveTrials();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java b/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java
index cbaf7f7..2acd460 100644
--- a/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java
+++ b/base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java
@@ -5,6 +5,7 @@
 package org.chromium.base;
 
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * This class provides an interface to the native class for writing
@@ -23,9 +24,11 @@
      * @return true if the data was written to the file, false if not.
      */
     public static boolean writeFileAtomically(String fileName, byte[] data) {
-        return nativeWriteFileAtomically(fileName, data);
+        return ImportantFileWriterAndroidJni.get().writeFileAtomically(fileName, data);
     }
 
-    private static native boolean nativeWriteFileAtomically(
-            String fileName, byte[] data);
+    @NativeMethods
+    interface Natives {
+        boolean writeFileAtomically(String fileName, byte[] data);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/JavaExceptionReporter.java b/base/android/java/src/org/chromium/base/JavaExceptionReporter.java
index 91c491be..54e10c33 100644
--- a/base/android/java/src/org/chromium/base/JavaExceptionReporter.java
+++ b/base/android/java/src/org/chromium/base/JavaExceptionReporter.java
@@ -9,6 +9,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * This UncaughtExceptionHandler will create a breakpad minidump when there is an uncaught
@@ -34,7 +35,7 @@
     public void uncaughtException(Thread t, Throwable e) {
         if (!mHandlingException) {
             mHandlingException = true;
-            nativeReportJavaException(mCrashAfterReport, e);
+            JavaExceptionReporterJni.get().reportJavaException(mCrashAfterReport, e);
         }
         if (mParent != null) {
             mParent.uncaughtException(t, e);
@@ -51,7 +52,8 @@
     @UiThread
     public static void reportStackTrace(String stackTrace) {
         assert ThreadUtils.runningOnUiThread();
-        nativeReportJavaStackTrace(PiiElider.sanitizeStacktrace(stackTrace));
+        JavaExceptionReporterJni.get().reportJavaStackTrace(
+                PiiElider.sanitizeStacktrace(stackTrace));
     }
 
     @CalledByNative
@@ -60,6 +62,9 @@
                 Thread.getDefaultUncaughtExceptionHandler(), crashAfterReport));
     }
 
-    private static native void nativeReportJavaException(boolean crashAfterReport, Throwable e);
-    private static native void nativeReportJavaStackTrace(String stackTrace);
+    @NativeMethods
+    interface Natives {
+        void reportJavaException(boolean crashAfterReport, Throwable e);
+        void reportJavaStackTrace(String stackTrace);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/JavaHandlerThread.java b/base/android/java/src/org/chromium/base/JavaHandlerThread.java
index 9a1c924..7971074 100644
--- a/base/android/java/src/org/chromium/base/JavaHandlerThread.java
+++ b/base/android/java/src/org/chromium/base/JavaHandlerThread.java
@@ -12,6 +12,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.lang.Thread.UncaughtExceptionHandler;
 
@@ -54,7 +55,7 @@
         new Handler(mThread.getLooper()).post(new Runnable() {
             @Override
             public void run() {
-                nativeInitializeThread(nativeThread, nativeEvent);
+                JavaHandlerThreadJni.get().initializeThread(nativeThread, nativeEvent);
             }
         });
     }
@@ -66,7 +67,7 @@
             @Override
             public void run() {
                 mThread.quit();
-                nativeOnLooperStopped(nativeThread);
+                JavaHandlerThreadJni.get().onLooperStopped(nativeThread);
             }
         });
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
@@ -114,6 +115,9 @@
         return mUnhandledException;
     }
 
-    private native void nativeInitializeThread(long nativeJavaHandlerThread, long nativeEvent);
-    private native void nativeOnLooperStopped(long nativeJavaHandlerThread);
+    @NativeMethods
+    interface Natives {
+        void initializeThread(long nativeJavaHandlerThread, long nativeEvent);
+        void onLooperStopped(long nativeJavaHandlerThread);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/MemoryPressureListener.java b/base/android/java/src/org/chromium/base/MemoryPressureListener.java
index 6c80970..6e9dcac 100644
--- a/base/android/java/src/org/chromium/base/MemoryPressureListener.java
+++ b/base/android/java/src/org/chromium/base/MemoryPressureListener.java
@@ -9,6 +9,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.memory.MemoryPressureCallback;
 
 /**
@@ -59,7 +60,7 @@
      */
     @CalledByNative
     private static void addNativeCallback() {
-        addCallback(MemoryPressureListener::nativeOnMemoryPressure);
+        addCallback(MemoryPressureListenerJni.get()::onMemoryPressure);
     }
 
     /**
@@ -126,5 +127,8 @@
         activity.onTrimMemory(level);
     }
 
-    private static native void nativeOnMemoryPressure(@MemoryPressureLevel int pressure);
+    @NativeMethods
+    interface Natives {
+        void onMemoryPressure(@MemoryPressureLevel int pressure);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/PathService.java b/base/android/java/src/org/chromium/base/PathService.java
index 9807c2e..7f8546d 100644
--- a/base/android/java/src/org/chromium/base/PathService.java
+++ b/base/android/java/src/org/chromium/base/PathService.java
@@ -5,6 +5,7 @@
 package org.chromium.base;
 
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * This class provides java side access to the native PathService.
@@ -19,8 +20,11 @@
     private PathService() {}
 
     public static void override(int what, String path) {
-        nativeOverride(what, path);
+        PathServiceJni.get().override(what, path);
     }
 
-    private static native void nativeOverride(int what, String path);
+    @NativeMethods
+    interface Natives {
+        void override(int what, String path);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/PowerMonitor.java b/base/android/java/src/org/chromium/base/PowerMonitor.java
index ae36a75d..a6cc874 100644
--- a/base/android/java/src/org/chromium/base/PowerMonitor.java
+++ b/base/android/java/src/org/chromium/base/PowerMonitor.java
@@ -12,6 +12,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Integrates native PowerMonitor with the java side.
@@ -63,7 +64,7 @@
         // If we're not plugged, assume we're running on battery power.
         sInstance.mIsBatteryPower = chargePlug != BatteryManager.BATTERY_PLUGGED_USB
                 && chargePlug != BatteryManager.BATTERY_PLUGGED_AC;
-        nativeOnBatteryChargingChanged();
+        PowerMonitorJni.get().onBatteryChargingChanged();
     }
 
     @CalledByNative
@@ -76,5 +77,8 @@
         return sInstance.mIsBatteryPower;
     }
 
-    private static native void nativeOnBatteryChargingChanged();
+    @NativeMethods
+    interface Natives {
+        void onBatteryChargingChanged();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/SysUtils.java b/base/android/java/src/org/chromium/base/SysUtils.java
index c791d5b..a1d709e 100644
--- a/base/android/java/src/org/chromium/base/SysUtils.java
+++ b/base/android/java/src/org/chromium/base/SysUtils.java
@@ -16,6 +16,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.metrics.CachedMetrics;
 
 import java.io.BufferedReader;
@@ -200,11 +201,9 @@
      * enabled.
      */
     public static void logPageFaultCountToTracing() {
-        nativeLogPageFaultCountToTracing();
+        SysUtilsJni.get().logPageFaultCountToTracing();
     }
 
-    private static native void nativeLogPageFaultCountToTracing();
-
     /**
      * @return Whether or not this device should be considered a high end device from a disk
      *         capacity point of view.
@@ -226,4 +225,9 @@
         }
         return false;
     }
+
+    @NativeMethods
+    interface Natives {
+        void logPageFaultCountToTracing();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/TimeUtils.java b/base/android/java/src/org/chromium/base/TimeUtils.java
index 88d2c096..32f9b27c 100644
--- a/base/android/java/src/org/chromium/base/TimeUtils.java
+++ b/base/android/java/src/org/chromium/base/TimeUtils.java
@@ -6,6 +6,7 @@
 
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 /** Time-related utilities. */
 @JNINamespace("base::android")
@@ -17,8 +18,13 @@
     public static final int NANOSECONDS_PER_MILLISECOND = 1000000;
     public static final int SECONDS_PER_MINUTE = 60;
     public static final int SECONDS_PER_HOUR = 3600; // 60 sec * 60 min
-    public static final int SECONDS_PER_DAY = 86400; // 60 sec * 60 min * 24 h
+    public static final int SECONDS_PER_DAY = 86400;
 
-    /** Returns TimeTicks::Now() in microseconds. */
-    public static native long nativeGetTimeTicksNowUs();
+    @NativeMethods
+    public interface Natives {
+        // 60 sec * 60 min * 24 h
+
+        /** Returns TimeTicks::Now() in microseconds. */
+        long getTimeTicksNowUs();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/TraceEvent.java b/base/android/java/src/org/chromium/base/TraceEvent.java
index d7b83234..49c2c39a 100644
--- a/base/android/java/src/org/chromium/base/TraceEvent.java
+++ b/base/android/java/src/org/chromium/base/TraceEvent.java
@@ -13,6 +13,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 /**
  * Java mirror of Chrome trace event API. See base/trace_event/trace_event.h.
  *
@@ -57,7 +58,7 @@
             if (sEnabled || earlyTracingActive) {
                 mCurrentTarget = getTraceEventName(line);
                 if (sEnabled) {
-                    nativeBeginToplevel(mCurrentTarget);
+                    TraceEventJni.get().beginToplevel(mCurrentTarget);
                 } else {
                     EarlyTraceEvent.begin(mCurrentTarget);
                 }
@@ -68,7 +69,7 @@
             boolean earlyTracingActive = EarlyTraceEvent.isActive();
             if ((sEnabled || earlyTracingActive) && mCurrentTarget != null) {
                 if (sEnabled) {
-                    nativeEndToplevel(mCurrentTarget);
+                    TraceEventJni.get().endToplevel(mCurrentTarget);
                 } else {
                     EarlyTraceEvent.end(mCurrentTarget);
                 }
@@ -270,7 +271,7 @@
      * Register an enabled observer, such that java traces are always enabled with native.
      */
     public static void registerNativeEnabledObserver() {
-        nativeRegisterEnabledObserver();
+        TraceEventJni.get().registerEnabledObserver();
     }
 
     /**
@@ -314,11 +315,11 @@
         if (enabled) {
             // Calls TraceEvent.setEnabled(true) via
             // TraceLog::EnabledStateObserver::OnTraceLogEnabled
-            nativeStartATrace();
+            TraceEventJni.get().startATrace();
         } else {
             // Calls TraceEvent.setEnabled(false) via
             // TraceLog::EnabledStateObserver::OnTraceLogDisabled
-            nativeStopATrace();
+            TraceEventJni.get().stopATrace();
         }
     }
 
@@ -336,7 +337,7 @@
      * @param name The name of the event.
      */
     public static void instant(String name) {
-        if (sEnabled) nativeInstant(name, null);
+        if (sEnabled) TraceEventJni.get().instant(name, null);
     }
 
     /**
@@ -345,7 +346,7 @@
      * @param arg  The arguments of the event.
      */
     public static void instant(String name, String arg) {
-        if (sEnabled) nativeInstant(name, arg);
+        if (sEnabled) TraceEventJni.get().instant(name, arg);
     }
 
     /**
@@ -355,7 +356,7 @@
      */
     public static void startAsync(String name, long id) {
         EarlyTraceEvent.startAsync(name, id);
-        if (sEnabled) nativeStartAsync(name, id);
+        if (sEnabled) TraceEventJni.get().startAsync(name, id);
     }
 
     /**
@@ -365,7 +366,7 @@
      */
     public static void finishAsync(String name, long id) {
         EarlyTraceEvent.finishAsync(name, id);
-        if (sEnabled) nativeFinishAsync(name, id);
+        if (sEnabled) TraceEventJni.get().finishAsync(name, id);
     }
 
     /**
@@ -383,7 +384,7 @@
      */
     public static void begin(String name, String arg) {
         EarlyTraceEvent.begin(name);
-        if (sEnabled) nativeBegin(name, arg);
+        if (sEnabled) TraceEventJni.get().begin(name, arg);
     }
 
     /**
@@ -401,17 +402,20 @@
      */
     public static void end(String name, String arg) {
         EarlyTraceEvent.end(name);
-        if (sEnabled) nativeEnd(name, arg);
+        if (sEnabled) TraceEventJni.get().end(name, arg);
     }
 
-    private static native void nativeRegisterEnabledObserver();
-    private static native void nativeStartATrace();
-    private static native void nativeStopATrace();
-    private static native void nativeInstant(String name, String arg);
-    private static native void nativeBegin(String name, String arg);
-    private static native void nativeEnd(String name, String arg);
-    private static native void nativeBeginToplevel(String target);
-    private static native void nativeEndToplevel(String target);
-    private static native void nativeStartAsync(String name, long id);
-    private static native void nativeFinishAsync(String name, long id);
+    @NativeMethods
+    interface Natives {
+        void registerEnabledObserver();
+        void startATrace();
+        void stopATrace();
+        void instant(String name, String arg);
+        void begin(String name, String arg);
+        void end(String name, String arg);
+        void beginToplevel(String target);
+        void endToplevel(String target);
+        void startAsync(String name, long id);
+        void finishAsync(String name, long id);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index 40dd77fd..6b59e656 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -28,6 +28,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.compat.ApiHelperForM;
 import org.chromium.base.metrics.CachedMetrics;
 import org.chromium.base.metrics.RecordHistogram;
@@ -89,7 +90,7 @@
     private static LibraryLoader sInstance = new LibraryLoader();
 
     // One-way switch becomes true when the libraries are initialized (
-    // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
+    // by calling LibraryLoaderJni.get().libraryLoaded, which forwards to LibraryLoaded(...) in
     // library_loader_hooks.cc).
     // Note that this member should remain a one-way switch, since it accessed from multiple
     // threads without a lock.
@@ -513,16 +514,17 @@
 
         ensureCommandLineSwitchedAlreadyLocked();
 
-        if (!nativeLibraryLoaded(mLibraryProcessType)) {
-            Log.e(TAG, "error calling nativeLibraryLoaded");
+        if (!LibraryLoaderJni.get().libraryLoaded(mLibraryProcessType)) {
+            Log.e(TAG, "error calling LibraryLoaderJni.get().libraryLoaded");
             throw new ProcessInitException(LoaderErrors.LOADER_ERROR_FAILED_TO_REGISTER_JNI);
         }
 
         // Check that the version of the library we have loaded matches the version we expect
-        Log.i(TAG, String.format("Expected native library version number \"%s\", "
-                                   + "actual native library version number \"%s\"",
-                           NativeLibraries.sVersionNumber, nativeGetVersionNumber()));
-        if (!NativeLibraries.sVersionNumber.equals(nativeGetVersionNumber())) {
+        Log.i(TAG,
+                String.format("Expected native library version number \"%s\", "
+                                + "actual native library version number \"%s\"",
+                        NativeLibraries.sVersionNumber, LibraryLoaderJni.get().getVersionNumber()));
+        if (!NativeLibraries.sVersionNumber.equals(LibraryLoaderJni.get().getVersionNumber())) {
             throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_WRONG_VERSION);
         }
 
@@ -584,7 +586,7 @@
     public void registerRendererProcessHistogram() {
         synchronized (mLock) {
             if (useChromiumLinker()) {
-                nativeRecordRendererLibraryLoadTime(mLibraryLoadTimeMs);
+                LibraryLoaderJni.get().recordRendererLibraryLoadTime(mLibraryLoadTimeMs);
             }
         }
     }
@@ -685,18 +687,21 @@
                 ContextCompat.getCodeCacheDir(ContextUtils.getApplicationContext()), LIBRARY_DIR);
     }
 
-    // Only methods needed before or during normal JNI registration are during System.OnLoad.
-    // nativeLibraryLoaded is then called to register everything else.  This process is called
-    // "initialization".  This method will be mapped (by generated code) to the LibraryLoaded
-    // definition in base/android/library_loader/library_loader_hooks.cc.
-    //
-    // Return true on success and false on failure.
-    private native boolean nativeLibraryLoaded(@LibraryProcessType int processType);
+    @NativeMethods
+    interface Natives {
+        // Only methods needed before or during normal JNI registration are during System.OnLoad.
+        // nativeLibraryLoaded is then called to register everything else.  This process is called
+        // "initialization".  This method will be mapped (by generated code) to the LibraryLoaded
+        // definition in base/android/library_loader/library_loader_hooks.cc.
+        //
+        // Return true on success and false on failure.
+        boolean libraryLoaded(@LibraryProcessType int processType);
 
-    // Records the number of milliseconds it took to load the libraries in the renderer.
-    private native void nativeRecordRendererLibraryLoadTime(long libraryLoadTime);
+        // Records the number of milliseconds it took to load the libraries in the renderer.
+        void recordRendererLibraryLoadTime(long libraryLoadTime);
 
-    // Get the version of the native library. This is needed so that we can check we
-    // have the right version before initializing the (rest of the) JNI.
-    private native String nativeGetVersionNumber();
+        // Get the version of the native library. This is needed so that we can check we
+        // have the right version before initializing the (rest of the) JNI.
+        String getVersionNumber();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java b/base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java
index 2086e73a..04b5adf8 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java
@@ -15,6 +15,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
@@ -35,7 +36,7 @@
     /**
      * Used to pass ordered code info back from native.
      */
-    private final static class OrderedCodeInfo {
+    final static class OrderedCodeInfo {
         public final String filename;
         public final long startOffset;
         public final long length;
@@ -77,21 +78,21 @@
         // to be simultaneous with it. Also, don't prefetch in this case, as this would
         // skew the results.
         if (coldStart && CommandLine.getInstance().hasSwitch("log-native-library-residency")) {
-            // nativePeriodicallyCollectResidency() sleeps, run it on another thread,
-            // and not on the thread pool.
-            new Thread(LibraryPrefetcher::nativePeriodicallyCollectResidency).start();
+            // LibraryPrefetcherJni.get().periodicallyCollectResidency() sleeps, run it on another
+            // thread, and not on the thread pool.
+            new Thread(LibraryPrefetcherJni.get()::periodicallyCollectResidency).start();
             return;
         }
 
         PostTask.postTask(TaskTraits.USER_BLOCKING, () -> {
-            int percentage = nativePercentageOfResidentNativeLibraryCode();
+            int percentage = LibraryPrefetcherJni.get().percentageOfResidentNativeLibraryCode();
             try (TraceEvent e =
                             TraceEvent.scoped("LibraryPrefetcher.asyncPrefetchLibrariesToMemory",
                                     Integer.toString(percentage))) {
                 // Arbitrary percentage threshold. If most of the native library is already
                 // resident (likely with monochrome), don't bother creating a prefetch process.
                 boolean prefetch = coldStart && percentage < 90;
-                if (prefetch) nativeForkAndPrefetchNativeLibrary();
+                if (prefetch) LibraryPrefetcherJni.get().forkAndPrefetchNativeLibrary();
                 if (percentage != -1) {
                     String histogram = "LibraryLoader.PercentageOfResidentCodeBeforePrefetch"
                             + (coldStart ? ".ColdStartup" : ".WarmStartup");
@@ -107,7 +108,7 @@
     @SuppressLint("WrongConstant")
     public static void maybePinOrderedCodeInMemory() {
         try (TraceEvent e = TraceEvent.scoped("LibraryPrefetcher::maybePinOrderedCodeInMemory")) {
-            OrderedCodeInfo info = nativeGetOrderedCodeInfo();
+            OrderedCodeInfo info = LibraryPrefetcherJni.get().getOrderedCodeInfo();
             if (info == null) return;
             TraceEvent.instant("pinOrderedCodeInMemory", info.toString());
 
@@ -137,19 +138,22 @@
         }
     }
 
-    // Finds the ranges corresponding to the native library pages, forks a new
-    // process to prefetch these pages and waits for it. The new process then
-    // terminates. This is blocking.
-    private static native void nativeForkAndPrefetchNativeLibrary();
+    @NativeMethods
+    interface Natives {
+        // Finds the ranges corresponding to the native library pages, forks a new
+        // process to prefetch these pages and waits for it. The new process then
+        // terminates. This is blocking.
+        void forkAndPrefetchNativeLibrary();
 
-    // Returns the percentage of the native library code page that are currently reseident in
-    // memory.
-    private static native int nativePercentageOfResidentNativeLibraryCode();
+        // Returns the percentage of the native library code page that are currently reseident in
+        // memory.
+        int percentageOfResidentNativeLibraryCode();
 
-    // Periodically logs native library residency from this thread.
-    private static native void nativePeriodicallyCollectResidency();
+        // Periodically logs native library residency from this thread.
+        void periodicallyCollectResidency();
 
-    // Returns the range within a file of the ordered code section, or null if this is not
-    // available.
-    private static native OrderedCodeInfo nativeGetOrderedCodeInfo();
+        // Returns the range within a file of the ordered code section, or null if this is not
+        // available.
+        OrderedCodeInfo getOrderedCodeInfo();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
index c7a2a837f..445dc186 100644
--- a/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
+++ b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
@@ -9,6 +9,7 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -66,7 +67,7 @@
     public static void recordBooleanHistogram(String name, boolean sample) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordBooleanHistogram(name, key, sample);
+        long result = RecordHistogramJni.get().recordBooleanHistogram(name, key, sample);
         if (result != key) sCache.put(name, result);
     }
 
@@ -82,7 +83,8 @@
     public static void recordEnumeratedHistogram(String name, int sample, int boundary) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordEnumeratedHistogram(name, key, sample, boundary);
+        long result =
+                RecordHistogramJni.get().recordEnumeratedHistogram(name, key, sample, boundary);
         if (result != key) sCache.put(name, result);
     }
 
@@ -129,7 +131,8 @@
             String name, int sample, int min, int max, int numBuckets) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordCustomCountHistogram(name, key, sample, min, max, numBuckets);
+        long result = RecordHistogramJni.get().recordCustomCountHistogram(
+                name, key, sample, min, max, numBuckets);
         if (result != key) sCache.put(name, result);
     }
 
@@ -146,7 +149,8 @@
             String name, int sample, int min, int max, int numBuckets) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordLinearCountHistogram(name, key, sample, min, max, numBuckets);
+        long result = RecordHistogramJni.get().recordLinearCountHistogram(
+                name, key, sample, min, max, numBuckets);
         if (result != key) sCache.put(name, result);
     }
 
@@ -159,7 +163,7 @@
     public static void recordPercentageHistogram(String name, int sample) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordEnumeratedHistogram(name, key, sample, 101);
+        long result = RecordHistogramJni.get().recordEnumeratedHistogram(name, key, sample, 101);
         if (result != key) sCache.put(name, result);
     }
 
@@ -172,7 +176,7 @@
     public static void recordSparseHistogram(String name, int sample) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
-        long result = nativeRecordSparseHistogram(name, key, sample);
+        long result = RecordHistogramJni.get().recordSparseHistogram(name, key, sample);
         if (result != key) sCache.put(name, result);
     }
 
@@ -267,7 +271,7 @@
         // the types returned by TimeUnit and System.currentTimeMillis() APIs, from which these
         // values come.
         assert max == clampToInt(max);
-        long result = nativeRecordCustomTimesHistogramMilliseconds(
+        long result = RecordHistogramJni.get().recordCustomTimesHistogramMilliseconds(
                 name, key, clampToInt(duration), clampToInt(min), clampToInt(max), numBuckets);
         if (result != key) sCache.put(name, result);
     }
@@ -279,7 +283,7 @@
      */
     @VisibleForTesting
     public static int getHistogramValueCountForTesting(String name, int sample) {
-        return nativeGetHistogramValueCountForTesting(name, sample);
+        return RecordHistogramJni.get().getHistogramValueCountForTesting(name, sample);
     }
 
     /**
@@ -288,21 +292,21 @@
      */
     @VisibleForTesting
     public static int getHistogramTotalCountForTesting(String name) {
-        return nativeGetHistogramTotalCountForTesting(name);
+        return RecordHistogramJni.get().getHistogramTotalCountForTesting(name);
     }
 
-    private static native long nativeRecordCustomTimesHistogramMilliseconds(
-            String name, long key, int duration, int min, int max, int numBuckets);
-
-    private static native long nativeRecordBooleanHistogram(String name, long key, boolean sample);
-    private static native long nativeRecordEnumeratedHistogram(
-            String name, long key, int sample, int boundary);
-    private static native long nativeRecordCustomCountHistogram(
-            String name, long key, int sample, int min, int max, int numBuckets);
-    private static native long nativeRecordLinearCountHistogram(
-            String name, long key, int sample, int min, int max, int numBuckets);
-    private static native long nativeRecordSparseHistogram(String name, long key, int sample);
-
-    private static native int nativeGetHistogramValueCountForTesting(String name, int sample);
-    private static native int nativeGetHistogramTotalCountForTesting(String name);
+    @NativeMethods
+    public interface Natives {
+        long recordCustomTimesHistogramMilliseconds(
+                String name, long key, int duration, int min, int max, int numBuckets);
+        long recordBooleanHistogram(String name, long key, boolean sample);
+        long recordEnumeratedHistogram(String name, long key, int sample, int boundary);
+        long recordCustomCountHistogram(
+                String name, long key, int sample, int min, int max, int numBuckets);
+        long recordLinearCountHistogram(
+                String name, long key, int sample, int min, int max, int numBuckets);
+        long recordSparseHistogram(String name, long key, int sample);
+        int getHistogramValueCountForTesting(String name, int sample);
+        int getHistogramTotalCountForTesting(String name);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/metrics/RecordUserAction.java b/base/android/java/src/org/chromium/base/metrics/RecordUserAction.java
index 0d2ba54..74fbd5a 100644
--- a/base/android/java/src/org/chromium/base/metrics/RecordUserAction.java
+++ b/base/android/java/src/org/chromium/base/metrics/RecordUserAction.java
@@ -8,6 +8,7 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Java API for recording UMA actions.
@@ -38,14 +39,14 @@
         if (sDisabledBy != null) return;
 
         if (ThreadUtils.runningOnUiThread()) {
-            nativeRecordUserAction(action);
+            RecordUserActionJni.get().recordUserAction(action);
             return;
         }
 
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                nativeRecordUserAction(action);
+                RecordUserActionJni.get().recordUserAction(action);
             }
         });
     }
@@ -67,7 +68,7 @@
      */
     public static void setActionCallbackForTesting(UserActionCallback callback) {
         assert sNativeActionCallback == 0;
-        sNativeActionCallback = nativeAddActionCallbackForTesting(callback);
+        sNativeActionCallback = RecordUserActionJni.get().addActionCallbackForTesting(callback);
     }
 
     /**
@@ -75,11 +76,14 @@
      */
     public static void removeActionCallbackForTesting() {
         assert sNativeActionCallback != 0;
-        nativeRemoveActionCallbackForTesting(sNativeActionCallback);
+        RecordUserActionJni.get().removeActionCallbackForTesting(sNativeActionCallback);
         sNativeActionCallback = 0;
     }
 
-    private static native void nativeRecordUserAction(String action);
-    private static native long nativeAddActionCallbackForTesting(UserActionCallback callback);
-    private static native void nativeRemoveActionCallbackForTesting(long callbackId);
+    @NativeMethods
+    interface Natives {
+        void recordUserAction(String action);
+        long addActionCallbackForTesting(UserActionCallback callback);
+        void removeActionCallbackForTesting(long callbackId);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java b/base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java
index bff3fae7..6983257a8 100644
--- a/base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java
+++ b/base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java
@@ -5,6 +5,7 @@
 package org.chromium.base.metrics;
 
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Java API which exposes the registered histograms on the native side as
@@ -20,8 +21,11 @@
      * @return All the registered histograms as JSON text.
      */
     public static String toJson(@JSONVerbosityLevel int verbosityLevel) {
-        return nativeToJson(verbosityLevel);
+        return StatisticsRecorderAndroidJni.get().toJson(verbosityLevel);
     }
 
-    private static native String nativeToJson(@JSONVerbosityLevel int verbosityLevel);
+    @NativeMethods
+    interface Natives {
+        String toJson(@JSONVerbosityLevel int verbosityLevel);
+    }
 }
\ No newline at end of file
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
index 5d21c65a..ad100e5 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
@@ -24,6 +24,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.memory.MemoryPressureMonitor;
 
 import java.util.List;
@@ -172,7 +173,7 @@
                     return;
                 }
             }
-            nativeDumpProcessStack();
+            ChildProcessServiceJni.get().dumpProcessStack();
         }
 
     };
@@ -253,7 +254,8 @@
                         regionOffsets[i] = fdInfo.offset;
                         regionSizes[i] = fdInfo.size;
                     }
-                    nativeRegisterFileDescriptors(keys, fileIds, fds, regionOffsets, regionSizes);
+                    ChildProcessServiceJni.get().registerFileDescriptors(
+                            keys, fileIds, fds, regionOffsets, regionSizes);
 
                     mDelegate.onBeforeMain();
                     mDelegate.runMain();
@@ -262,7 +264,7 @@
                     } catch (RemoteException e) {
                         Log.e(TAG, "Failed to call clean exit callback.", e);
                     }
-                    nativeExitChildProcess();
+                    ChildProcessServiceJni.get().exitChildProcess();
                 } catch (InterruptedException e) {
                     Log.w(TAG, "%s startup failed: %s", MAIN_THREAD_NAME, e);
                 }
@@ -331,22 +333,24 @@
         }
     }
 
-    /**
-     * Helper for registering FileDescriptorInfo objects with GlobalFileDescriptors or
-     * FileDescriptorStore.
-     * This includes the IPC channel, the crash dump signals and resource related
-     * files.
-     */
-    private static native void nativeRegisterFileDescriptors(
-            String[] keys, int[] id, int[] fd, long[] offset, long[] size);
+    @NativeMethods
+    interface Natives {
+        /**
+         * Helper for registering FileDescriptorInfo objects with GlobalFileDescriptors or
+         * FileDescriptorStore.
+         * This includes the IPC channel, the crash dump signals and resource related
+         * files.
+         */
+        void registerFileDescriptors(String[] keys, int[] id, int[] fd, long[] offset, long[] size);
 
-    /**
-     * Force the child process to exit.
-     */
-    private static native void nativeExitChildProcess();
+        /**
+         * Force the child process to exit.
+         */
+        void exitChildProcess();
 
-    /**
-     * Dumps the child process stack without crashing it.
-     */
-    private static native void nativeDumpProcessStack();
+        /**
+         * Dumps the child process stack without crashing it.
+         */
+        void dumpProcessStack();
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/task/PostTask.java b/base/android/java/src/org/chromium/base/task/PostTask.java
index 00a3865..648eb05 100644
--- a/base/android/java/src/org/chromium/base/task/PostTask.java
+++ b/base/android/java/src/org/chromium/base/task/PostTask.java
@@ -6,6 +6,7 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.util.Collections;
 import java.util.Set;
@@ -85,9 +86,9 @@
             if (sPreNativeTaskRunners != null || taskTraits.mIsChoreographerFrame) {
                 getTaskExecutorForTraits(taskTraits).postDelayedTask(taskTraits, task, delay);
             } else {
-                nativePostDelayedTask(taskTraits.mPrioritySetExplicitly, taskTraits.mPriority,
-                        taskTraits.mMayBlock, taskTraits.mUseThreadPool, taskTraits.mExtensionId,
-                        taskTraits.mExtensionData, task, delay);
+                PostTaskJni.get().postDelayedTask(taskTraits.mPrioritySetExplicitly,
+                        taskTraits.mPriority, taskTraits.mMayBlock, taskTraits.mUseThreadPool,
+                        taskTraits.mExtensionId, taskTraits.mExtensionData, task, delay);
             }
         }
     }
@@ -256,7 +257,10 @@
         }
     }
 
-    private static native void nativePostDelayedTask(boolean prioritySetExplicitly, int priority,
-            boolean mayBlock, boolean useThreadPool, byte extensionId, byte[] extensionData,
-            Runnable task, long delay);
+    @NativeMethods
+    interface Natives {
+        void postDelayedTask(boolean prioritySetExplicitly, int priority, boolean mayBlock,
+                boolean useThreadPool, byte extensionId, byte[] extensionData, Runnable task,
+                long delay);
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java
index 2cffbef..6460811 100644
--- a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java
+++ b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java
@@ -47,7 +47,7 @@
     public boolean belongsToCurrentThread() {
         synchronized (mLock) {
             if (mNativeTaskRunnerAndroid != 0)
-                return nativeBelongsToCurrentThread(mNativeTaskRunnerAndroid);
+                return TaskRunnerImplJni.get().belongsToCurrentThread(mNativeTaskRunnerAndroid);
         }
         if (mHandler != null) return mHandler.getLooper().getThread() == Thread.currentThread();
         assert (false);
diff --git a/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java b/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java
index dc65ac6..0961d0d 100644
--- a/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java
+++ b/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java
@@ -11,6 +11,7 @@
 import org.chromium.base.LifetimeAssert;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -72,7 +73,8 @@
 
     @GuardedBy("mLock")
     protected void destroyInternal() {
-        if (mNativeTaskRunnerAndroid != 0) nativeDestroy(mNativeTaskRunnerAndroid);
+        if (mNativeTaskRunnerAndroid != 0)
+            TaskRunnerImplJni.get().destroy(mNativeTaskRunnerAndroid);
         mNativeTaskRunnerAndroid = 0;
     }
 
@@ -158,7 +160,7 @@
     @GuardedBy("mLock")
     protected void initNativeTaskRunnerInternal() {
         if (mNativeTaskRunnerAndroid == 0) {
-            mNativeTaskRunnerAndroid = nativeInit(mTaskRunnerType,
+            mNativeTaskRunnerAndroid = TaskRunnerImplJni.get().init(mTaskRunnerType,
                     mTaskTraits.mPrioritySetExplicitly, mTaskTraits.mPriority,
                     mTaskTraits.mMayBlock, mTaskTraits.mUseThreadPool, mTaskTraits.mExtensionId,
                     mTaskTraits.mExtensionData);
@@ -181,15 +183,17 @@
 
     @GuardedBy("mLock")
     protected void postDelayedTaskToNative(Runnable r, long delay) {
-        nativePostDelayedTask(mNativeTaskRunnerAndroid, r, delay);
+        TaskRunnerImplJni.get().postDelayedTask(mNativeTaskRunnerAndroid, r, delay);
     }
 
-    // NB due to Proguard obfuscation it's easiest to pass the traits via arguments.
-    private native long nativeInit(@TaskRunnerType int taskRunnerType,
-            boolean prioritySetExplicitly, int priority, boolean mayBlock, boolean useThreadPool,
-            byte extensionId, byte[] extensionData);
-    private native void nativeDestroy(long nativeTaskRunnerAndroid);
-    private native void nativePostDelayedTask(
-            long nativeTaskRunnerAndroid, Runnable task, long delay);
-    protected native boolean nativeBelongsToCurrentThread(long nativeTaskRunnerAndroid);
+    @NativeMethods
+    interface Natives {
+        // NB due to Proguard obfuscation it's easiest to pass the traits via arguments.
+        long init(@TaskRunnerType int taskRunnerType, boolean prioritySetExplicitly, int priority,
+                boolean mayBlock, boolean useThreadPool, byte extensionId, byte[] extensionData);
+
+        void destroy(long nativeTaskRunnerAndroid);
+        void postDelayedTask(long nativeTaskRunnerAndroid, Runnable task, long delay);
+        boolean belongsToCurrentThread(long nativeTaskRunnerAndroid);
+    }
 }
diff --git a/base/android/java_handler_thread.cc b/base/android/java_handler_thread.cc
index c26f130..2d5d011 100644
--- a/base/android/java_handler_thread.cc
+++ b/base/android/java_handler_thread.cc
@@ -81,7 +81,6 @@
 }
 
 void JavaHandlerThread::InitializeThread(JNIEnv* env,
-                                         const JavaParamRef<jobject>& obj,
                                          jlong event) {
   base::ThreadIdNameManager::GetInstance()->RegisterThread(
       base::PlatformThread::CurrentHandle().platform_handle(),
@@ -95,8 +94,7 @@
   reinterpret_cast<base::WaitableEvent*>(event)->Signal();
 }
 
-void JavaHandlerThread::OnLooperStopped(JNIEnv* env,
-                                        const JavaParamRef<jobject>& obj) {
+void JavaHandlerThread::OnLooperStopped(JNIEnv* env) {
   DCHECK(task_runner()->BelongsToCurrentThread());
   task_environment_.reset();
 
diff --git a/base/android/java_handler_thread.h b/base/android/java_handler_thread.h
index a21ff27..5e8b865 100644
--- a/base/android/java_handler_thread.h
+++ b/base/android/java_handler_thread.h
@@ -54,10 +54,9 @@
   // Called from java on the newly created thread.
   // Start() will not return before this methods has finished.
   void InitializeThread(JNIEnv* env,
-                        const JavaParamRef<jobject>& obj,
                         jlong event);
   // Called from java on this thread.
-  void OnLooperStopped(JNIEnv* env, const JavaParamRef<jobject>& obj);
+  void OnLooperStopped(JNIEnv* env);
 
   // Called from this thread.
   void StopSequenceManagerForTesting();
diff --git a/base/android/library_loader/library_loader_hooks.cc b/base/android/library_loader/library_loader_hooks.cc
index 7d49e13..38642c7 100644
--- a/base/android/library_loader/library_loader_hooks.cc
+++ b/base/android/library_loader/library_loader_hooks.cc
@@ -49,7 +49,6 @@
 
 static void JNI_LibraryLoader_RecordRendererLibraryLoadTime(
     JNIEnv* env,
-    const JavaParamRef<jobject>& jcaller,
     jlong library_load_time_ms) {
   g_renderer_library_load_time_ms = library_load_time_ms;
 }
@@ -75,7 +74,6 @@
 
 static jboolean JNI_LibraryLoader_LibraryLoaded(
     JNIEnv* env,
-    const JavaParamRef<jobject>& jcaller,
     jint library_process_type) {
 #if BUILDFLAG(ORDERFILE_INSTRUMENTATION)
   orderfile::StartDelayedDump();
@@ -114,9 +112,7 @@
   g_library_version_number = strdup(version_number);
 }
 
-ScopedJavaLocalRef<jstring> JNI_LibraryLoader_GetVersionNumber(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& jcaller) {
+ScopedJavaLocalRef<jstring> JNI_LibraryLoader_GetVersionNumber(JNIEnv* env) {
   return ConvertUTF8ToJavaString(env, g_library_version_number);
 }
 
diff --git a/base/android/task_scheduler/task_runner_android.cc b/base/android/task_scheduler/task_runner_android.cc
index 5cfa3838..18730e17 100644
--- a/base/android/task_scheduler/task_runner_android.cc
+++ b/base/android/task_scheduler/task_runner_android.cc
@@ -15,7 +15,6 @@
 
 jlong JNI_TaskRunnerImpl_Init(
     JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& jcaller,
     jint task_runner_type,
     jboolean priority_set_explicitly,
     jint priority,
@@ -46,15 +45,13 @@
 
 TaskRunnerAndroid::~TaskRunnerAndroid() = default;
 
-void TaskRunnerAndroid::Destroy(JNIEnv* env,
-                                const base::android::JavaRef<jobject>& caller) {
+void TaskRunnerAndroid::Destroy(JNIEnv* env) {
   // This could happen on any thread.
   delete this;
 }
 
 void TaskRunnerAndroid::PostDelayedTask(
     JNIEnv* env,
-    const base::android::JavaRef<jobject>& caller,
     const base::android::JavaRef<jobject>& task,
     jlong delay) {
   task_runner_->PostDelayedTask(
@@ -64,9 +61,7 @@
       TimeDelta::FromMilliseconds(delay));
 }
 
-bool TaskRunnerAndroid::BelongsToCurrentThread(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& caller) {
+bool TaskRunnerAndroid::BelongsToCurrentThread(JNIEnv* env) {
   return task_runner_->RunsTasksInCurrentSequence();
 }
 
diff --git a/base/android/task_scheduler/task_runner_android.h b/base/android/task_scheduler/task_runner_android.h
index 00ead774..94f22c5 100644
--- a/base/android/task_scheduler/task_runner_android.h
+++ b/base/android/task_scheduler/task_runner_android.h
@@ -20,15 +20,13 @@
   explicit TaskRunnerAndroid(scoped_refptr<TaskRunner> task_runner);
   ~TaskRunnerAndroid();
 
-  void Destroy(JNIEnv* env, const base::android::JavaRef<jobject>& caller);
+  void Destroy(JNIEnv* env);
 
   void PostDelayedTask(JNIEnv* env,
-                       const base::android::JavaRef<jobject>& caller,
                        const base::android::JavaRef<jobject>& task,
                        jlong delay);
 
-  bool BelongsToCurrentThread(JNIEnv* env,
-                              const base::android::JavaRef<jobject>& caller);
+  bool BelongsToCurrentThread(JNIEnv* env);
 
  private:
   const scoped_refptr<TaskRunner> task_runner_;
diff --git a/base/memory/memory_pressure_monitor_chromeos.cc b/base/memory/memory_pressure_monitor_chromeos.cc
index c85ea9a..e7a68b6f 100644
--- a/base/memory/memory_pressure_monitor_chromeos.cc
+++ b/base/memory/memory_pressure_monitor_chromeos.cc
@@ -293,7 +293,7 @@
 void MemoryPressureMonitor::ScheduleWaitForKernelNotification() {
   base::PostTaskAndReplyWithResult(
       FROM_HERE,
-      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+      {ThreadPool(), MayBlock(), TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       kernel_waiting_callback_,
       base::BindRepeating(&MemoryPressureMonitor::HandleKernelNotification,
                           weak_ptr_factory_.GetWeakPtr()));
diff --git a/base/process/kill.cc b/base/process/kill.cc
index 54b99beb..1f9322a5 100644
--- a/base/process/kill.cc
+++ b/base/process/kill.cc
@@ -42,7 +42,8 @@
 
   PostDelayedTask(
       FROM_HERE,
-      {TaskPriority::BEST_EFFORT, TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+      {ThreadPool(), TaskPriority::BEST_EFFORT,
+       TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       BindOnce(
           [](Process process) {
             if (process.WaitForExitWithTimeout(TimeDelta(), nullptr))
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h
index 2599109..2b7cfe1 100644
--- a/base/process/process_metrics.h
+++ b/base/process/process_metrics.h
@@ -137,6 +137,10 @@
   // measures such as placing DRAM in to self-refresh (also referred to as
   // auto-refresh), place interconnects into lower-power states etc"
   int GetPackageIdleWakeupsPerSecond();
+
+  // Returns "Energy Impact", a synthetic power estimation metric displayed by
+  // macOS in Activity Monitor and the battery menu.
+  int GetEnergyImpact();
 #endif
 
   // Retrieves accounting information for all I/O operations performed by the
@@ -226,6 +230,9 @@
   // And same thing for package idle exit wakeups.
   TimeTicks last_package_idle_wakeups_time_;
   uint64_t last_absolute_package_idle_wakeups_;
+  double last_energy_impact_;
+  // In mach_absolute_time units.
+  uint64_t last_energy_impact_time_;
 #endif
 
 #if !defined(OS_IOS)
diff --git a/base/process/process_metrics_mac.cc b/base/process/process_metrics_mac.cc
index d05e1228..d0f35471 100644
--- a/base/process/process_metrics_mac.cc
+++ b/base/process/process_metrics_mac.cc
@@ -6,6 +6,7 @@
 
 #include <libproc.h>
 #include <mach/mach.h>
+#include <mach/mach_time.h>
 #include <mach/mach_vm.h>
 #include <mach/shared_region.h>
 #include <stddef.h>
@@ -20,6 +21,34 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/numerics/safe_math.h"
 #include "base/process/process_metrics_iocounters.h"
+#include "base/time/time.h"
+
+namespace {
+
+// This is a standin for the private pm_task_energy_data_t struct.
+struct OpaquePMTaskEnergyData {
+  // Empirical size of the private struct.
+  uint8_t data[384];
+};
+
+// Sample everything but network usage, since fetching network
+// usage can hang.
+static constexpr uint8_t kPMSampleFlags = 0xff & ~0x8;
+
+}  // namespace
+
+extern "C" {
+
+// From libpmsample.dylib
+int pm_sample_task(mach_port_t task,
+                   OpaquePMTaskEnergyData* pm_energy,
+                   uint64_t mach_time,
+                   uint8_t flags);
+
+// From libpmenergy.dylib
+double pm_energy_impact(OpaquePMTaskEnergyData* pm_energy);
+
+}  // extern "C"
 
 namespace base {
 
@@ -59,6 +88,14 @@
   return kr == KERN_SUCCESS;
 }
 
+double GetEnergyImpactInternal(mach_port_t task, uint64_t mach_time) {
+  OpaquePMTaskEnergyData energy_info{};
+
+  if (pm_sample_task(task, &energy_info, mach_time, kPMSampleFlags) != 0)
+    return 0.0;
+  return pm_energy_impact(&energy_info);
+}
+
 }  // namespace
 
 // Getting a mach task from a pid for another process requires permissions in
@@ -146,6 +183,31 @@
   return CalculateIdleWakeupsPerSecond(power_info_data.task_interrupt_wakeups);
 }
 
+int ProcessMetrics::GetEnergyImpact() {
+  uint64_t now = mach_absolute_time();
+  if (last_energy_impact_ == 0) {
+    last_energy_impact_ = GetEnergyImpactInternal(TaskForPid(process_), now);
+    last_energy_impact_time_ = now;
+    return 0;
+  }
+
+  double total_energy_impact =
+      GetEnergyImpactInternal(TaskForPid(process_), now);
+  uint64_t delta = now - last_energy_impact_time_;
+  if (delta == 0)
+    return 0;
+
+  // Scale by 100 since the histogram is integral.
+  double seconds_since_last_measurement =
+      base::TimeTicks::FromMachAbsoluteTime(delta).since_origin().InSecondsF();
+  int energy_impact = 100 * (total_energy_impact - last_energy_impact_) /
+                      seconds_since_last_measurement;
+  last_energy_impact_ = total_energy_impact;
+  last_energy_impact_time_ = now;
+
+  return energy_impact;
+}
+
 int ProcessMetrics::GetOpenFdCount() const {
   // In order to get a true count of the open number of FDs, PROC_PIDLISTFDS
   // is used. This is done twice: first to get the appropriate size of a
@@ -183,6 +245,7 @@
     : process_(process),
       last_absolute_idle_wakeups_(0),
       last_absolute_package_idle_wakeups_(0),
+      last_energy_impact_(0),
       port_provider_(port_provider) {}
 
 mach_port_t ProcessMetrics::TaskForPid(ProcessHandle process) const {
diff --git a/base/sequence_checker_unittest.cc b/base/sequence_checker_unittest.cc
index 09e272d..b3a55ff4 100644
--- a/base/sequence_checker_unittest.cc
+++ b/base/sequence_checker_unittest.cc
@@ -272,9 +272,9 @@
   ThreadLocalOwnedPointer<SequenceCheckerOwner> thread_local_owner;
   {
     test::ScopedTaskEnvironment task_environment;
-    auto task_runner = CreateSequencedTaskRunner({});
+    auto task_runner = CreateSequencedTaskRunner({ThreadPool()});
     task_runner->PostTask(
-        FROM_HERE, base::BindLambdaForTesting([&]() {
+        FROM_HERE, BindLambdaForTesting([&]() {
           thread_local_owner.Set(std::make_unique<SequenceCheckerOwner>());
         }));
     task_runner = nullptr;
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc
index 64e6a8a0..21ddf7ca 100644
--- a/base/system/sys_info.cc
+++ b/base/system/sys_info.cc
@@ -107,7 +107,7 @@
 void SysInfo::GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback) {
 #if defined(OS_WIN)
   base::PostTaskAndReplyWithResult(
-      base::CreateCOMSTATaskRunner({}).get(), FROM_HERE,
+      base::CreateCOMSTATaskRunner({ThreadPool()}).get(), FROM_HERE,
       base::BindOnce(&GetHardwareInfoSync), std::move(callback));
 #elif defined(OS_ANDROID) || defined(OS_MACOSX)
   base::PostTaskAndReplyWithResult(
diff --git a/base/task/post_task_unittest.cc b/base/task/post_task_unittest.cc
index 35d1f0d..052041cf 100644
--- a/base/task/post_task_unittest.cc
+++ b/base/task/post_task_unittest.cc
@@ -114,7 +114,7 @@
   auto single_thread_task_runner = CreateSingleThreadTaskRunner({ThreadPool()});
   EXPECT_NE(executor_.runner(), single_thread_task_runner);
 #if defined(OS_WIN)
-  auto comsta_task_runner = CreateCOMSTATaskRunner({});
+  auto comsta_task_runner = CreateCOMSTATaskRunner({ThreadPool()});
   EXPECT_NE(executor_.runner(), comsta_task_runner);
 #endif  // defined(OS_WIN)
 
diff --git a/base/task/promise/abstract_promise_unittest.cc b/base/task/promise/abstract_promise_unittest.cc
index ebee591e..b558041 100644
--- a/base/task/promise/abstract_promise_unittest.cc
+++ b/base/task/promise/abstract_promise_unittest.cc
@@ -2425,8 +2425,8 @@
               p->OnRejected();
             }));
 
-    base::PostTaskWithTraits(
-        FROM_HERE, {},
+    base::PostTask(
+        FROM_HERE, {base::ThreadPool()},
         base::Bind([](scoped_refptr<AbstractPromise> p2) { p2->OnRejected(); },
                    p2));
 
diff --git a/base/task/promise/promise_unittest.cc b/base/task/promise/promise_unittest.cc
index a892f16..a8a6454 100644
--- a/base/task/promise/promise_unittest.cc
+++ b/base/task/promise/promise_unittest.cc
@@ -1136,11 +1136,10 @@
                                    promise_resolver->promise()))
         .ThenHere(FROM_HERE, base::BindOnce([](int v) { EXPECT_EQ(v, 42); }))
         .ThenHere(FROM_HERE, run_loop.QuitClosure());
-    PostTaskWithTraits(FROM_HERE, {ThreadPool()},
-                       base::BindLambdaForTesting([&]() {
-                         promise_resolver->Resolve(42);
-                         promise_resolver.reset();
-                       }));
+    PostTask(FROM_HERE, {ThreadPool()}, BindLambdaForTesting([&]() {
+               promise_resolver->Resolve(42);
+               promise_resolver.reset();
+             }));
     run_loop.Run();
     scoped_task_environment_.RunUntilIdle();
   }
diff --git a/base/task/sequence_manager/sequence_manager_perftest.cc b/base/task/sequence_manager/sequence_manager_perftest.cc
index 5673405..79fa69d 100644
--- a/base/task/sequence_manager/sequence_manager_perftest.cc
+++ b/base/task/sequence_manager/sequence_manager_perftest.cc
@@ -64,15 +64,7 @@
   DISALLOW_COPY_AND_ASSIGN(PerfTestTimeDomain);
 };
 
-// TODO(crbug.com/891670): This can be simplified after the transition away from
-// the old base::MessageLoop.
 enum class PerfTestType {
-  // A SequenceManager on top of a MessageLoop (which is SequenceManager based).
-  // This configuration is now strictly overkill.
-  kUseSequenceManagerWithMessageLoop,
-  kUseSequenceManagerWithUIMessageLoop,
-  kUseSequenceManagerWithIOMessageLoop,
-
   // A SequenceManager with a ThreadControllerWithMessagePumpImpl driving the
   // thread.
   kUseSequenceManagerWithMessagePump,
@@ -80,12 +72,6 @@
   kUseSequenceManagerWithIOMessagePump,
   kUseSequenceManagerWithMessagePumpAndRandomSampling,
 
-  // A SequenceManager backed base::MessageLoop (now the default and only
-  // base::MessageLoop configuration).
-  kUseMessageLoop,
-  kUseUIMessageLoop,
-  kUseIOMessageLoop,
-
   // A SingleThreadTaskRunner in the thread pool.
   kUseSingleThreadInThreadPool,
 };
@@ -594,21 +580,6 @@
 
   std::unique_ptr<PerfTestDelegate> CreateDelegate() {
     switch (GetParam()) {
-      case PerfTestType::kUseSequenceManagerWithMessageLoop:
-        return std::make_unique<
-            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoop>>(
-            " SequenceManager with MessageLoop ");
-
-      case PerfTestType::kUseSequenceManagerWithUIMessageLoop:
-        return std::make_unique<
-            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoopForUI>>(
-            " SequenceManager with MessageLoopForUI ");
-
-      case PerfTestType::kUseSequenceManagerWithIOMessageLoop:
-        return std::make_unique<
-            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoopForIO>>(
-            " SequenceManager with MessageLoopForIO ");
-
       case PerfTestType::kUseSequenceManagerWithMessagePump:
         return std::make_unique<SequenceManagerWithMessagePumpPerfTestDelegate>(
             " SequenceManager with MessagePumpDefault ",
@@ -627,18 +598,6 @@
             " SequenceManager with MessagePumpDefault and random sampling ",
             MessagePump::Type::DEFAULT, true);
 
-      case PerfTestType::kUseMessageLoop:
-        return std::make_unique<MessageLoopPerfTestDelegate>(
-            " MessageLoop ", std::make_unique<MessageLoop>());
-
-      case PerfTestType::kUseUIMessageLoop:
-        return std::make_unique<MessageLoopPerfTestDelegate>(
-            " MessageLoopForUI ", std::make_unique<MessageLoopForUI>());
-
-      case PerfTestType::kUseIOMessageLoop:
-        return std::make_unique<MessageLoopPerfTestDelegate>(
-            " MessageLoopForIO ", std::make_unique<MessageLoopForIO>());
-
       case PerfTestType::kUseSingleThreadInThreadPool:
         return std::make_unique<SingleThreadInThreadPoolPerfTestDelegate>();
 
@@ -687,15 +646,9 @@
     ,
     SequenceManagerPerfTest,
     testing::Values(
-        PerfTestType::kUseSequenceManagerWithMessageLoop,
         PerfTestType::kUseSequenceManagerWithMessagePump,
-        PerfTestType::kUseSequenceManagerWithUIMessageLoop,
         PerfTestType::kUseSequenceManagerWithUIMessagePump,
-        PerfTestType::kUseSequenceManagerWithIOMessageLoop,
         PerfTestType::kUseSequenceManagerWithIOMessagePump,
-        PerfTestType::kUseMessageLoop,
-        PerfTestType::kUseUIMessageLoop,
-        PerfTestType::kUseIOMessageLoop,
         PerfTestType::kUseSingleThreadInThreadPool,
         PerfTestType::kUseSequenceManagerWithMessagePumpAndRandomSampling));
 TEST_P(SequenceManagerPerfTest, PostDelayedTasks_OneQueue) {
diff --git a/base/task/task_traits_extension_unittest.cc b/base/task/task_traits_extension_unittest.cc
index ac54144..54c30fd 100644
--- a/base/task/task_traits_extension_unittest.cc
+++ b/base/task/task_traits_extension_unittest.cc
@@ -17,7 +17,7 @@
 }
 
 TEST(TaskTraitsExtensionTest, CreateWithOneExtensionTrait) {
-  constexpr TaskTraits traits = {ThreadPool(), TestExtensionEnumTrait::kB};
+  constexpr TaskTraits traits = {TestExtensionEnumTrait::kB};
 
   EXPECT_EQ(traits.GetExtension<TestTaskTraitsExtension>().enum_trait(),
             TestExtensionEnumTrait::kB);
@@ -25,7 +25,7 @@
 }
 
 TEST(TaskTraitsExtensionTest, CreateWithMultipleExtensionTraits) {
-  constexpr TaskTraits traits = {ThreadPool(), TestExtensionEnumTrait::kB,
+  constexpr TaskTraits traits = {TestExtensionEnumTrait::kB,
                                  TestExtensionBoolTrait()};
 
   EXPECT_EQ(traits.GetExtension<TestTaskTraitsExtension>().enum_trait(),
@@ -34,7 +34,7 @@
 }
 
 TEST(TaskTraitsExtensionTest, CreateWithBaseAndExtensionTraits) {
-  constexpr TaskTraits traits = {ThreadPool(), TaskPriority::USER_BLOCKING,
+  constexpr TaskTraits traits = {TaskPriority::USER_BLOCKING,
                                  TestExtensionEnumTrait::kC,
                                  TestExtensionBoolTrait()};
 
diff --git a/base/task/thread_pool/job_task_source_unittest.cc b/base/task/thread_pool/job_task_source_unittest.cc
index fe1a87d..cd428b86 100644
--- a/base/task/thread_pool/job_task_source_unittest.cc
+++ b/base/task/thread_pool/job_task_source_unittest.cc
@@ -20,8 +20,8 @@
 TEST(ThreadPoolJobTaskSourceTest, RunTasks) {
   auto job_task = base::MakeRefCounted<test::MockJobTask>(
       DoNothing(), /* num_tasks_to_run */ 2);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
 
   TaskSource::Transaction task_source_transaction(
       task_source->BeginTransaction());
@@ -55,8 +55,8 @@
 TEST(ThreadPoolJobTaskSourceTest, SkipTask) {
   auto job_task = base::MakeRefCounted<test::MockJobTask>(
       DoNothing(), /* num_tasks_to_run */ 1);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
 
   TaskSource::Transaction task_source_transaction(
       task_source->BeginTransaction());
@@ -73,8 +73,8 @@
 TEST(ThreadPoolJobTaskSourceTest, RunTasksInParallel) {
   auto job_task = base::MakeRefCounted<test::MockJobTask>(
       DoNothing(), /* num_tasks_to_run */ 2);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
 
   TaskSource::Transaction task_source_transaction(
       task_source->BeginTransaction());
@@ -115,8 +115,8 @@
   auto job_task =
       base::MakeRefCounted<test::MockJobTask>(DoNothing(),
                                               /* num_tasks_to_run */ 1);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
   TaskSource::Transaction task_source_transaction(
       task_source->BeginTransaction());
 
@@ -135,8 +135,8 @@
   auto job_task =
       base::MakeRefCounted<test::MockJobTask>(DoNothing(),
                                               /* num_tasks_to_run */ 1);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
   TaskSource::Transaction task_source_transaction(
       task_source->BeginTransaction());
 
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
index 5b680bd6..e33235f 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
@@ -361,7 +361,7 @@
 
   bool get_work_first_ = true;
   const scoped_refptr<Sequence> message_pump_sequence_ =
-      MakeRefCounted<Sequence>(TaskTraits(MayBlock()),
+      MakeRefCounted<Sequence>(TaskTraits{ThreadPool(), MayBlock()},
                                nullptr,
                                TaskSourceExecutionMode::kParallel);
   std::unique_ptr<win::ScopedCOMInitializer> scoped_com_initializer_;
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
index 1559b65..1d1aafe2 100644
--- a/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
+++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager_unittest.cc
@@ -560,7 +560,7 @@
 TEST_P(PooledSingleThreadTaskRunnerManagerCommonTest, COMSTAInitialized) {
   scoped_refptr<SingleThreadTaskRunner> com_task_runner =
       single_thread_task_runner_manager_->CreateCOMSTATaskRunner(
-          {TaskShutdownBehavior::BLOCK_SHUTDOWN}, GetParam());
+          {ThreadPool(), TaskShutdownBehavior::BLOCK_SHUTDOWN}, GetParam());
 
   com_task_runner->PostTask(FROM_HERE, BindOnce(&win::AssertComApartmentType,
                                                 win::ComApartmentType::STA));
@@ -571,11 +571,11 @@
 TEST_F(PooledSingleThreadTaskRunnerManagerTest, COMSTASameThreadUsed) {
   scoped_refptr<SingleThreadTaskRunner> task_runner_1 =
       single_thread_task_runner_manager_->CreateCOMSTATaskRunner(
-          {TaskShutdownBehavior::BLOCK_SHUTDOWN},
+          {ThreadPool(), TaskShutdownBehavior::BLOCK_SHUTDOWN},
           SingleThreadTaskRunnerThreadMode::SHARED);
   scoped_refptr<SingleThreadTaskRunner> task_runner_2 =
       single_thread_task_runner_manager_->CreateCOMSTATaskRunner(
-          {TaskShutdownBehavior::BLOCK_SHUTDOWN},
+          {ThreadPool(), TaskShutdownBehavior::BLOCK_SHUTDOWN},
           SingleThreadTaskRunnerThreadMode::SHARED);
 
   PlatformThreadRef thread_ref_1;
@@ -640,7 +640,7 @@
 TEST_F(PooledSingleThreadTaskRunnerManagerTestWin, PumpsMessages) {
   scoped_refptr<SingleThreadTaskRunner> com_task_runner =
       single_thread_task_runner_manager_->CreateCOMSTATaskRunner(
-          {TaskShutdownBehavior::BLOCK_SHUTDOWN},
+          {ThreadPool(), TaskShutdownBehavior::BLOCK_SHUTDOWN},
           SingleThreadTaskRunnerThreadMode::DEDICATED);
   HWND hwnd = nullptr;
   // HWNDs process messages on the thread that created them, so we have to
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc
index fcb269b..1b1c3b1 100644
--- a/base/task/thread_pool/thread_group_impl_unittest.cc
+++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -310,8 +310,8 @@
         test::WaitWithoutBlockingObserver(&threads_continue);
       }),
       /* num_tasks_to_run */ kMaxTasks);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::USER_VISIBLE);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::USER_VISIBLE});
 
   auto registered_task_source = task_tracker_.WillQueueTaskSource(task_source);
   ASSERT_TRUE(registered_task_source);
@@ -327,7 +327,7 @@
   // Note: This is only true because this test is using a single ThreadGroup.
   //       Under the ThreadPool this wouldn't be racy because BEST_EFFORT tasks
   //       run in an independent ThreadGroup.
-  test::CreateTaskRunner(TaskPriority::BEST_EFFORT,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::BEST_EFFORT},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(
           FROM_HERE, BindLambdaForTesting([&]() {
@@ -338,7 +338,7 @@
   EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_BLOCKING));
 
   // Posting a USER_VISIBLE task should cause BEST_EFFORT tasks to yield.
-  test::CreateTaskRunner(TaskPriority::USER_VISIBLE,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::USER_VISIBLE},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                    EXPECT_FALSE(
@@ -350,7 +350,7 @@
 
   // Posting a USER_BLOCKING task should cause BEST_EFFORT and USER_VISIBLE
   // tasks to yield.
-  test::CreateTaskRunner(TaskPriority::USER_BLOCKING,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::USER_BLOCKING},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                    // Once this task got to start, no other task needs to yield.
@@ -1340,7 +1340,7 @@
 
   // Post a USER_VISIBLE task that can't run since workers are saturated. This
   // should cause BEST_EFFORT tasks to yield.
-  test::CreateTaskRunner(TaskPriority::USER_VISIBLE,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::USER_VISIBLE},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(
           FROM_HERE, BindLambdaForTesting([&]() {
@@ -1350,7 +1350,7 @@
 
   // Post a USER_BLOCKING task that can't run since workers are saturated. This
   // should cause USER_VISIBLE tasks to yield.
-  test::CreateTaskRunner(TaskPriority::USER_BLOCKING,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::USER_BLOCKING},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                    EXPECT_FALSE(
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc
index 357712aa..799558a 100644
--- a/base/task/thread_pool/thread_group_unittest.cc
+++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -564,7 +564,7 @@
 TEST_P(ThreadGroupTest, ShouldYieldSingleTask) {
   StartThreadGroup();
 
-  test::CreateTaskRunner(TaskPriority::USER_BLOCKING,
+  test::CreateTaskRunner({ThreadPool(), TaskPriority::USER_BLOCKING},
                          &mock_pooled_task_runner_delegate_)
       ->PostTask(
           FROM_HERE, BindLambdaForTesting([&]() {
@@ -597,7 +597,7 @@
       }),
       /* num_tasks_to_run */ kMaxTasks);
   scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskTraits());
+      job_task->GetJobTaskSource(FROM_HERE, {ThreadPool()});
 
   auto registered_task_source =
       task_tracker_.WillQueueTaskSource(std::move(task_source));
@@ -643,8 +643,8 @@
         }
       }),
       /* num_tasks_to_run */ kMaxTasks);
-  scoped_refptr<JobTaskSource> task_source =
-      job_task->GetJobTaskSource(FROM_HERE, TaskPriority::BEST_EFFORT);
+  scoped_refptr<JobTaskSource> task_source = job_task->GetJobTaskSource(
+      FROM_HERE, {ThreadPool(), TaskPriority::BEST_EFFORT});
 
   auto registered_task_source = task_tracker_.WillQueueTaskSource(task_source);
   EXPECT_TRUE(registered_task_source);
diff --git a/base/task/thread_pool/thread_pool.h b/base/task/thread_pool/thread_pool.h
index 637f8c75..e42e33a 100644
--- a/base/task/thread_pool/thread_pool.h
+++ b/base/task/thread_pool/thread_pool.h
@@ -59,8 +59,8 @@
       // Place the pool's *foreground* workers in a COM STA. This exists to
       // mimic the behavior of SequencedWorkerPool and BrowserThreadImpl that
       // ThreadPool has replaced. Tasks that need a COM STA should use
-      // CreateCOMSTATaskRunner() instead of
-      // Create(Sequenced)TaskRunnerWithTraits() + this init param.
+      // CreateCOMSTATaskRunner() instead of Create(Sequenced)TaskRunner() +
+      // this init param.
       DEPRECATED_COM_STA_IN_FOREGROUND_GROUP,
 #endif  // defined(OS_WIN)
     };
diff --git a/base/task/thread_pool/thread_pool_impl_unittest.cc b/base/task/thread_pool/thread_pool_impl_unittest.cc
index 7df882c..101d8d2c 100644
--- a/base/task/thread_pool/thread_pool_impl_unittest.cc
+++ b/base/task/thread_pool/thread_pool_impl_unittest.cc
@@ -1030,27 +1030,29 @@
 
 #if defined(OS_WIN)
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::BEST_EFFORT}, SingleThreadTaskRunnerThreadMode::SHARED));
-  task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::BEST_EFFORT, MayBlock()},
+      {ThreadPool(), TaskPriority::BEST_EFFORT},
       SingleThreadTaskRunnerThreadMode::SHARED));
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::USER_BLOCKING}, SingleThreadTaskRunnerThreadMode::SHARED));
+      {ThreadPool(), TaskPriority::BEST_EFFORT, MayBlock()},
+      SingleThreadTaskRunnerThreadMode::SHARED));
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::USER_BLOCKING, MayBlock()},
+      {ThreadPool(), TaskPriority::USER_BLOCKING},
+      SingleThreadTaskRunnerThreadMode::SHARED));
+  task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
+      {ThreadPool(), TaskPriority::USER_BLOCKING, MayBlock()},
       SingleThreadTaskRunnerThreadMode::SHARED));
 
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::BEST_EFFORT},
+      {ThreadPool(), TaskPriority::BEST_EFFORT},
       SingleThreadTaskRunnerThreadMode::DEDICATED));
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::BEST_EFFORT, MayBlock()},
+      {ThreadPool(), TaskPriority::BEST_EFFORT, MayBlock()},
       SingleThreadTaskRunnerThreadMode::DEDICATED));
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::USER_BLOCKING},
+      {ThreadPool(), TaskPriority::USER_BLOCKING},
       SingleThreadTaskRunnerThreadMode::DEDICATED));
   task_runners.push_back(thread_pool_->CreateCOMSTATaskRunner(
-      {TaskPriority::USER_BLOCKING, MayBlock()},
+      {ThreadPool(), TaskPriority::USER_BLOCKING, MayBlock()},
       SingleThreadTaskRunnerThreadMode::DEDICATED));
 #endif
 
@@ -1164,7 +1166,7 @@
   // Its task is expected to run after the USER_BLOCKING task runner's task.
   task_runners_and_events.push_back(std::make_unique<TaskRunnerAndEvents>(
       thread_pool->CreateUpdateableSequencedTaskRunner(
-          TaskTraits({ThreadPool(), TaskPriority::BEST_EFFORT, thread_policy})),
+          {ThreadPool(), TaskPriority::BEST_EFFORT, thread_policy}),
       TaskPriority::USER_VISIBLE, &task_runners_and_events.back()->task_ran));
 
   // -----
diff --git a/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java b/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java
index 1b1a5c0e..31c84c5 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java
@@ -5,6 +5,7 @@
 package org.chromium.base.test;
 
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Class containing only static methods for querying the status of the reached code profiler.
@@ -17,7 +18,7 @@
      * @return Whether the reached code profiler is enabled.
      */
     public static boolean isEnabled() {
-        return nativeIsReachedCodeProfilerEnabled();
+        return ReachedCodeProfilerJni.get().isReachedCodeProfilerEnabled();
     }
 
     /**
@@ -25,9 +26,12 @@
      *         profiler.
      */
     public static boolean isSupported() {
-        return nativeIsReachedCodeProfilerSupported();
+        return ReachedCodeProfilerJni.get().isReachedCodeProfilerSupported();
     }
 
-    private static native boolean nativeIsReachedCodeProfilerEnabled();
-    private static native boolean nativeIsReachedCodeProfilerSupported();
+    @NativeMethods
+    interface Natives {
+        boolean isReachedCodeProfilerEnabled();
+        boolean isReachedCodeProfilerSupported();
+    }
 }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/task/ThreadPoolTestHelpers.java b/base/test/android/javatests/src/org/chromium/base/test/task/ThreadPoolTestHelpers.java
index e90eaf9..aeb69e6 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/task/ThreadPoolTestHelpers.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/task/ThreadPoolTestHelpers.java
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 package org.chromium.base.test.task;
+import org.chromium.base.annotations.NativeMethods;
 
 /** Helpers that allow base::ThreadPoolInstance to be initialized or shutdown for testing. */
 public class ThreadPoolTestHelpers {
@@ -10,16 +11,19 @@
      * Initializes base::ThreadPoolInstance with default params.
      */
     public static void enableThreadPoolExecutionForTesting() {
-        nativeEnableThreadPoolExecutionForTesting();
+        ThreadPoolTestHelpersJni.get().enableThreadPoolExecutionForTesting();
     }
 
     /**
      * Shuts down base::ThreadPoolInstance.
      */
     public static void disableThreadPoolExecutionForTesting() {
-        nativeDisableThreadPoolExecutionForTesting();
+        ThreadPoolTestHelpersJni.get().disableThreadPoolExecutionForTesting();
     }
 
-    private static native void nativeEnableThreadPoolExecutionForTesting();
-    private static native void nativeDisableThreadPoolExecutionForTesting();
+    @NativeMethods
+    interface Natives {
+        void enableThreadPoolExecutionForTesting();
+        void disableThreadPoolExecutionForTesting();
+    }
 }
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc
index f8967d7..250c0ff 100644
--- a/base/test/scoped_task_environment.cc
+++ b/base/test/scoped_task_environment.cc
@@ -444,6 +444,8 @@
 }
 
 void ScopedTaskEnvironment::CompleteInitialization() {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
   if (main_thread_type() == MainThreadType::IO) {
     file_descriptor_watcher_ =
@@ -456,6 +458,8 @@
     default;
 
 ScopedTaskEnvironment::~ScopedTaskEnvironment() {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   // If we've been moved then bail out.
   if (!owns_instance_)
     return;
@@ -465,6 +469,8 @@
 }
 
 void ScopedTaskEnvironment::DestroyThreadPool() {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   if (threading_mode_ == ThreadingMode::MAIN_THREAD_ONLY)
     return;
 
@@ -499,6 +505,8 @@
 
 void ScopedTaskEnvironment::DeferredInitFromSubclass(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   task_runner_ = std::move(task_runner);
   sequence_manager_->SetDefaultTaskRunner(task_runner_);
   CompleteInitialization();
@@ -506,6 +514,8 @@
 
 void ScopedTaskEnvironment::
     NotifyDestructionObserversAndReleaseSequenceManager() {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   // A derived classes may call this method early.
   if (!sequence_manager_)
     return;
@@ -523,6 +533,8 @@
 }
 
 bool ScopedTaskEnvironment::MainThreadIsIdle() const {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   sequence_manager::internal::SequenceManagerImpl* sequence_manager_impl =
       static_cast<sequence_manager::internal::SequenceManagerImpl*>(
           sequence_manager_.get());
@@ -532,6 +544,8 @@
 }
 
 void ScopedTaskEnvironment::RunUntilIdle() {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   // TODO(gab): This can be heavily simplified to essentially:
   //     bool HasMainThreadTasks() {
   //      if (message_loop_)
@@ -616,6 +630,7 @@
 }
 
 void ScopedTaskEnvironment::FastForwardBy(TimeDelta delta) {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
   DCHECK(mock_time_domain_);
   DCHECK_GE(delta, TimeDelta());
 
@@ -653,12 +668,16 @@
 }
 
 size_t ScopedTaskEnvironment::GetPendingMainThreadTaskCount() const {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   // ReclaimMemory sweeps canceled delayed tasks.
   sequence_manager_->ReclaimMemory();
   return sequence_manager_->GetPendingTaskCountForTesting();
 }
 
 TimeDelta ScopedTaskEnvironment::NextMainThreadPendingTaskDelay() const {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   // ReclaimMemory sweeps canceled delayed tasks.
   sequence_manager_->ReclaimMemory();
   DCHECK(mock_time_domain_);
@@ -669,11 +688,14 @@
 }
 
 bool ScopedTaskEnvironment::NextTaskIsDelayed() const {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+
   TimeDelta delay = NextMainThreadPendingTaskDelay();
   return !delay.is_zero() && !delay.is_max();
 }
 
 void ScopedTaskEnvironment::DescribePendingMainThreadTasks() const {
+  DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
   LOG(INFO) << sequence_manager_->DescribeAllPendingTasks();
 }
 
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h
index 7722b4ee..bb226e4 100644
--- a/base/test/scoped_task_environment.h
+++ b/base/test/scoped_task_environment.h
@@ -14,6 +14,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/task/lazy_task_runner.h"
 #include "base/task/sequence_manager/sequence_manager.h"
+#include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "base/traits_bag.h"
 #include "build/build_config.h"
@@ -336,6 +337,11 @@
 
   std::unique_ptr<bool> owns_instance_ = std::make_unique<bool>(true);
 
+  // Used to verify thread-affinity of operations that must occur on the main
+  // thread. This is the case for anything that modifies or drives the
+  // |sequence_manager_|.
+  THREAD_CHECKER(main_thread_checker_);
+
   DISALLOW_COPY_AND_ASSIGN(ScopedTaskEnvironment);
 };
 
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc
index 50423a32..4f2366f 100644
--- a/base/test/scoped_task_environment_unittest.cc
+++ b/base/test/scoped_task_environment_unittest.cc
@@ -675,7 +675,7 @@
 
   ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, post_main_thread_delayed_task, kOneMs);
-  CreateSequencedTaskRunnerWithTraits({ThreadPool()})
+  CreateSequencedTaskRunner({ThreadPool()})
       ->PostDelayedTask(FROM_HERE, post_thread_pool_delayed_task, kOneMs);
 
   scoped_task_environment.FastForwardUntilNoTasksRemain();
diff --git a/build/android/pylib/base/environment_factory.py b/build/android/pylib/base/environment_factory.py
index fdca803..4d37274 100644
--- a/build/android/pylib/base/environment_factory.py
+++ b/build/android/pylib/base/environment_factory.py
@@ -4,12 +4,16 @@
 
 from pylib import constants
 from pylib.local.device import local_device_environment
+from pylib.local.emulator import local_emulator_environment
 from pylib.local.machine import local_machine_environment
 
 def CreateEnvironment(args, output_manager, error_func):
 
   if args.environment == 'local':
     if args.command not in constants.LOCAL_MACHINE_TESTS:
+      if args.avd_name:
+        return local_emulator_environment.LocalEmulatorEnvironment(
+            args, output_manager, error_func)
       return local_device_environment.LocalDeviceEnvironment(
           args, output_manager, error_func)
     else:
diff --git a/build/android/pylib/local/emulator/__init__.py b/build/android/pylib/local/emulator/__init__.py
new file mode 100644
index 0000000..4a12e35
--- /dev/null
+++ b/build/android/pylib/local/emulator/__init__.py
@@ -0,0 +1,3 @@
+# 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.
diff --git a/build/android/pylib/local/emulator/local_emulator_environment.py b/build/android/pylib/local/emulator/local_emulator_environment.py
new file mode 100644
index 0000000..cd81cf9c3
--- /dev/null
+++ b/build/android/pylib/local/emulator/local_emulator_environment.py
@@ -0,0 +1,121 @@
+# 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 contextlib
+import logging
+import os
+import socket
+import stat
+
+from py_utils import tempfile_ext
+
+from devil.android.sdk import adb_wrapper
+from devil.utils import cmd_helper
+from devil.utils import timeout_retry
+
+from pylib import constants
+from pylib.local.device import local_device_environment
+
+
+class LocalEmulatorEnvironment(local_device_environment.LocalDeviceEnvironment):
+
+  def __init__(self, args, output_manager, error_func):
+    super(LocalEmulatorEnvironment, self).__init__(args, output_manager,
+                                                   error_func)
+    self._avd_name = args.avd_name
+    self._emulator_home = (args.emulator_home
+                           or os.path.expanduser(os.path.join('~', '.android')))
+
+    root_ini = os.path.join(self._emulator_home, 'avd',
+                            '%s.ini' % self._avd_name)
+    if not os.path.exists(root_ini):
+      error_func('Unable to find configuration for AVD %s at %s' %
+                 (self._avd_name, root_ini))
+
+    self._emulator_path = os.path.join(constants.ANDROID_SDK_ROOT, 'emulator',
+                                       'emulator')
+    if not os.path.exists(self._emulator_path):
+      error_func('%s does not exist.' % self._emulator_path)
+
+    self._emulator_proc = None
+    self._emulator_serial = None
+
+  #override
+  def SetUp(self):
+    # Emulator start-up looks for the adb daemon. Make sure it's running.
+    adb_wrapper.AdbWrapper.StartServer()
+
+    # Emulator start-up tries to check for the SDK root by looking for
+    # platforms/ and platform-tools/. Ensure they exist.
+    # See http://bit.ly/2YAkyFE for context.
+    required_dirs = [
+        os.path.join(constants.ANDROID_SDK_ROOT, 'platforms'),
+        os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools'),
+    ]
+    for d in required_dirs:
+      if not os.path.exists(d):
+        os.makedirs(d)
+
+    # The emulator requires that some files are writable.
+    for dirname, _, filenames in os.walk(self._emulator_home):
+      for f in filenames:
+        path = os.path.join(dirname, f)
+        if (os.lstat(path).st_mode &
+            (stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) == stat.S_IRUSR):
+          os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
+
+    self._emulator_proc, self._emulator_serial = self._StartInstance()
+
+    logging.info('Emulator serial: %s', self._emulator_serial)
+    self._device_serials = [self._emulator_serial]
+    super(LocalEmulatorEnvironment, self).SetUp()
+
+  def _StartInstance(self):
+    """Starts an AVD instance.
+
+    Returns:
+      A (Popen, str) 2-tuple that includes the process and serial.
+    """
+    # Start up the AVD.
+    with tempfile_ext.TemporaryFileName() as socket_path, (contextlib.closing(
+        socket.socket(socket.AF_UNIX))) as sock:
+      sock.bind(socket_path)
+      emulator_cmd = [
+          self._emulator_path,
+          '-avd',
+          self._avd_name,
+          '-report-console',
+          'unix:%s' % socket_path,
+          '-read-only',
+          '-no-window',
+      ]
+      emulator_env = {}
+      if self._emulator_home:
+        emulator_env['ANDROID_EMULATOR_HOME'] = self._emulator_home
+      sock.listen(1)
+      emulator_proc = cmd_helper.Popen(emulator_cmd, env=emulator_env)
+
+      def listen_for_serial(s):
+        logging.info('Waiting for connection from emulator.')
+        with contextlib.closing(s.accept()[0]) as conn:
+          val = conn.recv(1024)
+          return 'emulator-%d' % int(val)
+
+      try:
+        emulator_serial = timeout_retry.Run(
+            listen_for_serial, timeout=30, retries=0, args=[sock])
+      except Exception:
+        emulator_proc.terminate()
+        raise
+
+      return (emulator_proc, emulator_serial)
+
+  #override
+  def TearDown(self):
+    try:
+      super(LocalEmulatorEnvironment, self).TearDown()
+    finally:
+      if self._emulator_proc:
+        self._emulator_proc.terminate()
+        self._emulator_proc.wait()
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 043a53a5e..443eb26 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -305,6 +305,20 @@
            'to the specified file.')
 
 
+def AddEmulatorOptions(parser):
+  """Adds emulator-specific options to |parser|."""
+  parser = parser.add_argument_group('emulator arguments')
+
+  parser.add_argument(
+      '--avd-name',
+      help='Run and manage the lifetime of an AVD with the given name.')
+  parser.add_argument(
+      '--emulator-home',
+      type=os.path.realpath,
+      help='Emulator home directory '
+      '(see ANDROID_EMULATOR_HOME: http://bit.ly/2K32oEy)')
+
+
 def AddGTestOptions(parser):
   """Adds gtest options to |parser|."""
 
@@ -877,6 +891,7 @@
       help='googletest-based C++ tests')
   AddCommonOptions(subp)
   AddDeviceOptions(subp)
+  AddEmulatorOptions(subp)
   AddGTestOptions(subp)
   AddTracingOptions(subp)
   AddCommandLineOptions(subp)
@@ -886,6 +901,7 @@
       help='InstrumentationTestCase-based Java tests')
   AddCommonOptions(subp)
   AddDeviceOptions(subp)
+  AddEmulatorOptions(subp)
   AddInstrumentationTestOptions(subp)
   AddTracingOptions(subp)
   AddCommandLineOptions(subp)
@@ -901,6 +917,7 @@
       help='linker tests')
   AddCommonOptions(subp)
   AddDeviceOptions(subp)
+  AddEmulatorOptions(subp)
   AddLinkerTestOptions(subp)
 
   subp = command_parsers.add_parser(
@@ -908,6 +925,7 @@
       help="tests based on Android's monkey command")
   AddCommonOptions(subp)
   AddDeviceOptions(subp)
+  AddEmulatorOptions(subp)
   AddMonkeyTestOptions(subp)
 
   subp = command_parsers.add_parser(
diff --git a/build/android/test_runner.pydeps b/build/android/test_runner.pydeps
index 572cc3a..9b722c40 100644
--- a/build/android/test_runner.pydeps
+++ b/build/android/test_runner.pydeps
@@ -167,6 +167,8 @@
 pylib/local/device/local_device_linker_test_run.py
 pylib/local/device/local_device_monkey_test_run.py
 pylib/local/device/local_device_test_run.py
+pylib/local/emulator/__init__.py
+pylib/local/emulator/local_emulator_environment.py
 pylib/local/local_test_server_spawner.py
 pylib/local/machine/__init__.py
 pylib/local/machine/local_machine_environment.py
diff --git a/build/fuchsia/fidlgen_js/test/fidlgen_js_unittest.cc b/build/fuchsia/fidlgen_js/test/fidlgen_js_unittest.cc
index ed8e24b7..b3b958d 100644
--- a/build/fuchsia/fidlgen_js/test/fidlgen_js_unittest.cc
+++ b/build/fuchsia/fidlgen_js/test/fidlgen_js_unittest.cc
@@ -288,11 +288,11 @@
     for (uint64_t i = 0; i < fidljstest::ARRRR_SIZE; ++i) {
       sat.arrrr[i] = static_cast<int32_t>(i * 5) - 10;
     }
-    sat.nullable_vector_of_string0 = nullptr;
+    sat.nullable_vector_of_string0.reset();
     std::vector<std::string> vector_of_str;
     vector_of_str.push_back("passed_str0");
     vector_of_str.push_back("passed_str1");
-    sat.nullable_vector_of_string1.reset(std::move(vector_of_str));
+    sat.nullable_vector_of_string1 = std::move(vector_of_str);
     std::vector<fidljstest::Blorp> vector_of_blorp;
     vector_of_blorp.push_back(fidljstest::Blorp::GAMMA);
     vector_of_blorp.push_back(fidljstest::Blorp::BETA);
@@ -352,9 +352,9 @@
 
     ASSERT_EQ(nullable.size(), 5u);
     EXPECT_EQ(nullable[0], "str3");
-    EXPECT_TRUE(nullable[1].is_null());
-    EXPECT_TRUE(nullable[2].is_null());
-    EXPECT_TRUE(nullable[3].is_null());
+    EXPECT_FALSE(nullable[1].has_value());
+    EXPECT_FALSE(nullable[2].has_value());
+    EXPECT_FALSE(nullable[3].has_value());
     EXPECT_EQ(nullable[4], "str4");
 
     ASSERT_EQ(max_strlen.size(), 1u);
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 198a898f..2ee91c4c 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8906467105259660928
\ No newline at end of file
+8906436983136519744
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index e1d72ed..5de9776f 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8906464930627119904
\ No newline at end of file
+8906436981559617696
\ No newline at end of file
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 0da4873..e87aef895 100644
--- a/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -238,7 +238,9 @@
 using LayerTreeHostTilesTestPartialInvalidationLowBitDepth =
     LayerTreeHostTilesTestPartialInvalidation;
 
-// TODO(crbug.com/963446): Enable these tests for Vulkan.
+// This test doesn't work on Vulkan because on our hardware we can't render to
+// RGBA4444 format using either SwiftShader or native Vulkan. See
+// crbug.com/987278 for details
 INSTANTIATE_TEST_SUITE_P(
     ,
     LayerTreeHostTilesTestPartialInvalidationLowBitDepth,
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestSection.java
index da23572..c262d95 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestSection.java
@@ -142,6 +142,7 @@
             for (int i = 0; i < options.size(); i++) {
                 if (options.get(i).isComplete()) {
                     selectedItemIndex = i;
+                    break;
                 }
             }
             // Fallback: if there are no complete items, select the first (incomplete) one.
@@ -227,16 +228,20 @@
     }
 
     private void updatePaddings() {
+        View titleView = mSectionExpander.getTitleView();
         if (isEmpty()) {
             // Section is empty, i.e., the title is the bottom-most widget.
-            mSectionExpander.setTitlePadding(mTopPadding, mBottomPadding);
+            titleView.setPadding(titleView.getPaddingLeft(), mTopPadding,
+                    titleView.getPaddingRight(), mBottomPadding);
         } else if (mSectionExpander.isExpanded()) {
             // Section is expanded, i.e., the expanded widget is the bottom-most widget.
-            mSectionExpander.setTitlePadding(mTopPadding, mTitleToContentPadding);
+            titleView.setPadding(titleView.getPaddingLeft(), mTopPadding,
+                    titleView.getPaddingRight(), mTitleToContentPadding);
             // No need to set additional bottom padding, expanded sections have enough already.
         } else {
             // Section is non-empty and collapsed -> collapsed widget is the bottom-most widget.
-            mSectionExpander.setTitlePadding(mTopPadding, mTitleToContentPadding);
+            titleView.setPadding(titleView.getPaddingLeft(), mTopPadding,
+                    titleView.getPaddingRight(), mTitleToContentPadding);
             setBottomPadding(mSectionExpander.getCollapsedView(), mBottomPadding);
         }
     }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestTermsSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestTermsSection.java
index f230638..d614651 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestTermsSection.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestTermsSection.java
@@ -47,6 +47,7 @@
     @Nullable
     private final TextView mTermsRequiresReview;
     private final TextView mThirdPartyPrivacyNotice;
+    @Nullable
     private Delegate mDelegate;
 
     private final SpanInfo mBoldSpanInfo =
@@ -143,10 +144,9 @@
     }
 
     private void onTermsAndConditionsLinkClicked(int link) {
-        // Ignore first click if the option is not selected yet.
-        if (!mTermsList.isChecked(mTermsAgree) || mDelegate == null) return;
-
-        mDelegate.onLinkClicked(link);
+        if (mDelegate != null) {
+            mDelegate.onLinkClicked(link);
+        }
     }
 
     public void setTermsStatus(@AssistantTermsAndConditionsState int status) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantVerticalExpander.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantVerticalExpander.java
index 0ffef1d..8e683b3c 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantVerticalExpander.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantVerticalExpander.java
@@ -146,18 +146,6 @@
         mExpandedContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 
-    /**
-     * Sets the top/bottom padding of the title bar. This method should be used instead of manually
-     * setting a padding on the title view, because that would result in misalignment between title
-     * view and the expand chevron.
-     */
-    public void setTitlePadding(int topPadding, int bottomPadding) {
-        mTitleContainer.setPadding(mTitleContainer.getPaddingLeft(), topPadding,
-                mTitleContainer.getPaddingRight(), bottomPadding);
-        mChevronButton.setPadding(mChevronButton.getPaddingLeft(), topPadding,
-                mChevronButton.getPaddingRight(), bottomPadding);
-    }
-
     public View getChevronButton() {
         return mChevronButton;
     }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java
index c6ac163..d070b3e3 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java
@@ -590,14 +590,7 @@
                                 acceptTermsText2));
         acceptMatcher = allOf(withText(acceptTermsText), isDisplayed());
 
-        assertThat(delegate.mLastLinkClicked, nullValue());
-
-        // First click marks the terms as accepted and ignores the link.
-        onView(acceptMatcher).perform(click());
-        assertThat(delegate.mTermsStatus, is(AssistantTermsAndConditionsState.ACCEPTED));
-        assertThat(delegate.mLastLinkClicked, nullValue());
-
-        // Second click will trigger the link.
+        // Clicking the text will trigger the link.
         onView(acceptMatcher).perform(click());
         assertThat(delegate.mLastLinkClicked, is(42));
     }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
index 8e9cd6d..be4af9d 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
@@ -25,6 +25,7 @@
 import android.support.design.widget.TabLayout;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -32,9 +33,11 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.RecordHistogramJni;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.task.test.CustomShadowAsyncTask;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction;
 import org.chromium.chrome.browser.keyboard_accessory.AccessoryBarContents;
@@ -64,6 +67,9 @@
 @Config(manifest = Config.NONE,
         shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
 public class KeyboardAccessoryControllerTest {
+    @Rule
+    public JniMocker mocker = new JniMocker();
+
     @Mock
     private PropertyObserver<PropertyKey> mMockPropertyObserver;
     @Mock
@@ -78,6 +84,8 @@
     private KeyboardAccessoryCoordinator.TabSwitchingDelegate mMockTabSwitchingDelegate;
     @Mock
     private AutofillDelegate mMockAutofillDelegate;
+    @Mock
+    private RecordHistogram.Natives mMockRecordHistogram;
 
     private final KeyboardAccessoryData.Tab mTestTab =
             new KeyboardAccessoryData.Tab("Passwords", null, null, 0, 0, null);
@@ -91,7 +99,7 @@
         ShadowRecordHistogram.reset();
         MockitoAnnotations.initMocks(this);
         setAutofillFeature(false);
-
+        mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogram);
         when(mMockView.getTabLayout()).thenReturn(mock(TabLayout.class));
         when(mMockTabLayout.getTabSwitchingDelegate()).thenReturn(mMockTabSwitchingDelegate);
         mCoordinator = new KeyboardAccessoryCoordinator(
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetControllerTest.java
index f552a620..c04b6f27 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetControllerTest.java
@@ -22,6 +22,7 @@
 import android.view.ViewGroup;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -29,9 +30,11 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.RecordHistogramJni;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.task.test.CustomShadowAsyncTask;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.keyboard_accessory.AccessorySheetTrigger;
 import org.chromium.chrome.browser.keyboard_accessory.ManualFillingMetricsRecorder;
 import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.Tab;
@@ -48,6 +51,8 @@
 @Config(manifest = Config.NONE,
         shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
 public class AccessorySheetControllerTest {
+    @Rule
+    public JniMocker mocker = new JniMocker();
     @Mock
     private PropertyObservable.PropertyObserver<PropertyKey> mMockPropertyObserver;
     @Mock
@@ -56,6 +61,8 @@
     private AccessorySheetView mMockView;
     @Mock
     private RecyclerView mMockRecyclerView;
+    @Mock
+    private RecordHistogram.Natives mMockRecordHistogramNatives;
 
     private final Tab[] mTabs = new Tab[] {new Tab("Passwords", null, null, 0, 0, null),
             new Tab("Passwords", null, null, 0, 0, null),
@@ -70,6 +77,7 @@
     public void setUp() {
         ShadowRecordHistogram.reset();
         MockitoAnnotations.initMocks(this);
+        mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
         when(mMockView.getLayoutParams()).thenReturn(new ViewGroup.LayoutParams(0, 0));
         mCoordinator = new AccessorySheetCoordinator(new FakeViewProvider<>(mMockView));
         mMediator = mCoordinator.getMediatorForTesting();
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetControllerTest.java
index 85ce466..15778db91 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetControllerTest.java
@@ -22,6 +22,7 @@
 import android.support.v7.widget.RecyclerView;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -30,9 +31,11 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.RecordHistogramJni;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.task.test.CustomShadowAsyncTask;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType;
 import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData;
@@ -51,10 +54,14 @@
 @Config(manifest = Config.NONE,
         shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
 public class AddressAccessorySheetControllerTest {
+    @Rule
+    public JniMocker mocker = new JniMocker();
     @Mock
     private RecyclerView mMockView;
     @Mock
     private ListObservable.ListObserver<Void> mMockItemListObserver;
+    @Mock
+    private RecordHistogram.Natives mMockRecordHistogramNatives;
 
     private AddressAccessorySheetCoordinator mCoordinator;
     private AccessorySheetTabModel mSheetDataPieces;
@@ -63,6 +70,7 @@
     public void setUp() {
         ShadowRecordHistogram.reset();
         MockitoAnnotations.initMocks(this);
+        mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
         setAutofillFeature(true);
         mCoordinator = new AddressAccessorySheetCoordinator(RuntimeEnvironment.application, null);
         assertNotNull(mCoordinator);
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java
index b8f4fe7..9494ca8 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java
@@ -24,6 +24,7 @@
 import android.support.v7.widget.RecyclerView;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -32,9 +33,11 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.RecordHistogramJni;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.task.test.CustomShadowAsyncTask;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction;
 import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType;
@@ -55,10 +58,14 @@
 @Config(manifest = Config.NONE,
         shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class})
 public class PasswordAccessorySheetControllerTest {
+    @Rule
+    public JniMocker mocker = new JniMocker();
     @Mock
     private RecyclerView mMockView;
     @Mock
     private ListObservable.ListObserver<Void> mMockItemListObserver;
+    @Mock
+    private RecordHistogram.Natives mMockRecordHistogramNatives;
 
     private PasswordAccessorySheetCoordinator mCoordinator;
     private AccessorySheetTabModel mSheetDataPieces;
@@ -67,6 +74,7 @@
     public void setUp() {
         ShadowRecordHistogram.reset();
         MockitoAnnotations.initMocks(this);
+        mocker.mock(RecordHistogramJni.TEST_HOOKS, mMockRecordHistogramNatives);
         mCoordinator = new PasswordAccessorySheetCoordinator(RuntimeEnvironment.application, null);
         assertNotNull(mCoordinator);
         mSheetDataPieces = mCoordinator.getSheetDataPiecesForTesting();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java
index b9259d3..271e278e 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediator.java
@@ -309,7 +309,10 @@
      *               in TabModel.
      */
     private void recordUserSwitchedTab(Tab tab, int lastId) {
-        if (tab == null) return;
+        if (tab == null) {
+            assert false : "New selected tab cannot be null when recording tab switch.";
+            return;
+        }
 
         Tab fromTab = TabModelUtils.getTabById(mTabModelSelector.getCurrentModel(), lastId);
         assert fromTab != null;
@@ -444,10 +447,12 @@
     public boolean onBackPressed() {
         if (!mContainerViewModel.get(IS_VISIBLE)) return false;
         if (mTabSelectionEditorController.handleBackPressed()) return true;
+        if (mTabModelSelector.getCurrentTab() == null) return false;
 
         recordUserSwitchedTab(
                 mTabModelSelector.getCurrentTab(), mTabModelSelector.getCurrentTabId());
         onTabSelecting(mTabModelSelector.getCurrentTabId());
+
         return true;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
index 32269d2..d2627638 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -17,7 +17,7 @@
 import android.view.View.OnCreateContextMenuListener;
 
 import org.chromium.base.Callback;
-import org.chromium.base.TimeUtils;
+import org.chromium.base.TimeUtilsJni;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.metrics.RecordHistogram;
@@ -113,7 +113,8 @@
         };
         mOnMenuShown = () -> {
             mSelectedItemBeforeDismiss = false;
-            mMenuShownTimeMs = TimeUnit.MICROSECONDS.toMillis(TimeUtils.nativeGetTimeTicksNowUs());
+            mMenuShownTimeMs =
+                    TimeUnit.MICROSECONDS.toMillis(TimeUtilsJni.get().getTimeTicksNowUs());
             RecordHistogram.recordBooleanHistogram("ContextMenu.Shown", mWebContents != null);
         };
         mOnMenuClosed = (notAbandoned) -> {
@@ -258,7 +259,7 @@
     private void recordTimeToTakeActionHistogram(boolean selectedItem) {
         final String action = selectedItem ? "SelectedItem" : "Abandoned";
         RecordHistogram.recordTimesHistogram("ContextMenu.TimeToTakeAction." + action,
-                TimeUnit.MICROSECONDS.toMillis(TimeUtils.nativeGetTimeTicksNowUs())
+                TimeUnit.MICROSECONDS.toMillis(TimeUtilsJni.get().getTimeTicksNowUs())
                         - mMenuShownTimeMs);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
index 1a0f1ba..2c602ec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -37,7 +37,7 @@
 import org.chromium.base.StrictModeContext;
 import org.chromium.base.SysUtils;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.TimeUtils;
+import org.chromium.base.TimeUtilsJni;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
@@ -53,10 +53,10 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.WarmupManager;
-import org.chromium.chrome.browser.browserservices.SessionHandler;
-import org.chromium.chrome.browser.browserservices.SessionDataHolder;
 import org.chromium.chrome.browser.browserservices.Origin;
 import org.chromium.chrome.browser.browserservices.PostMessageHandler;
+import org.chromium.chrome.browser.browserservices.SessionDataHolder;
+import org.chromium.chrome.browser.browserservices.SessionHandler;
 import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleLoader;
 import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics;
 import org.chromium.chrome.browser.device.DeviceClassManager;
@@ -1153,7 +1153,7 @@
         if (!mNativeTickOffsetUsComputed) {
             // Compute offset from time ticks to uptimeMillis.
             mNativeTickOffsetUsComputed = true;
-            long nativeNowUs = TimeUtils.nativeGetTimeTicksNowUs();
+            long nativeNowUs = TimeUtilsJni.get().getTimeTicksNowUs();
             long javaNowUs = SystemClock.uptimeMillis() * 1000;
             mNativeTickOffsetUs = nativeNowUs - javaNowUs;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java
index b0b9cb73..e065d934 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java
@@ -7,7 +7,7 @@
 import android.os.SystemClock;
 import android.support.annotation.Nullable;
 
-import org.chromium.base.TimeUtils;
+import org.chromium.base.TimeUtilsJni;
 import org.chromium.chrome.browser.ActivityTabProvider;
 import org.chromium.chrome.browser.metrics.PageLoadMetrics;
 import org.chromium.content_public.browser.WebContents;
@@ -51,7 +51,7 @@
     public DynamicModulePageLoadObserver(ActivityTabProvider activityTabProvider) {
         mActivityTabProvider = activityTabProvider;
 
-        long nativeNowUs = TimeUtils.nativeGetTimeTicksNowUs();
+        long nativeNowUs = TimeUtilsJni.get().getTimeTicksNowUs();
         long javaNowUs = SystemClock.uptimeMillis() * 1000;
         mNativeTickOffsetUs = nativeNowUs - javaNowUs;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
index 0a2ad62..bfcdac3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
@@ -13,6 +13,7 @@
 import org.chromium.base.Log;
 import org.chromium.base.SysUtils;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.GlobalDiscardableReferencePool;
 import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
@@ -49,6 +50,14 @@
     private static final int LOW_MEMORY_THRESHOLD_KB =
             (int) (1.5 * ConversionUtils.KILOBYTES_PER_GIGABYTE);
 
+    // These values are used with UMA to report Omnibox.RichEntity.DecorationType histograms, and
+    // should therefore be treated as append-only.
+    // See http://cs.chromium.org/Omnibox.RichEntity.DecorationType.
+    private static final int DECORATION_TYPE_ICON = 0;
+    private static final int DECORATION_TYPE_COLOR = 1;
+    private static final int DECORATION_TYPE_IMAGE = 2;
+    private static final int DECORATION_TYPE_TOTAL_COUNT = 3;
+
     /**
      * @param context An Android context.
      * @param suggestionHost A handle to the object using the suggestions.
@@ -89,7 +98,17 @@
 
     @Override
     public void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model) {
-        // Not used.
+        int decorationType = DECORATION_TYPE_ICON;
+
+        if (model.get(EntitySuggestionViewProperties.IMAGE_BITMAP) != null) {
+            decorationType = DECORATION_TYPE_IMAGE;
+        } else if (model.get(EntitySuggestionViewProperties.IMAGE_DOMINANT_COLOR)
+                != EntitySuggestionViewBinder.NO_DOMINANT_COLOR) {
+            decorationType = DECORATION_TYPE_COLOR;
+        }
+
+        RecordHistogram.recordEnumeratedHistogram(
+                "Omnibox.RichEntity.DecorationType", decorationType, DECORATION_TYPE_TOTAL_COUNT);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/EngagementTimeUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/EngagementTimeUtil.java
index a0cb8711..6aa5e11 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/EngagementTimeUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/EngagementTimeUtil.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.tasks;
 
-import org.chromium.base.TimeUtils;
+import org.chromium.base.TimeUtilsJni;
 
 import java.util.concurrent.TimeUnit;
 
@@ -61,7 +61,7 @@
     public long timeSinceLastEngagementFromTimeTicksMs(
             final long lastEngagementMs, final long currentEngagementTicksMs) {
         final long currentTimeMs = currentTime();
-        final long currentTimeTicksUs = TimeUtils.nativeGetTimeTicksNowUs();
+        final long currentTimeTicksUs = TimeUtilsJni.get().getTimeTicksNowUs();
         final long currentTimeTicksMs = TimeUnit.MICROSECONDS.toMillis(currentTimeTicksUs);
         final long offsetMs = currentTimeTicksMs - currentEngagementTicksMs;
         final long currentEngagementTimeMs = currentTimeMs - offsetMs;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
index d08dee2..8e8f821 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderUnitTest.java
@@ -27,7 +27,9 @@
 
 import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.RecordHistogramJni;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.ContentSettingsType;
 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeaderUnitTest.ShadowRecordHistogram;
 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeaderUnitTest.ShadowUrlUtilities;
@@ -48,8 +50,7 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE,
-        shadows = {ShadowUrlUtilities.class, ShadowRecordHistogram.class,
-                ShadowWebsitePreferenceBridge.class})
+        shadows = {ShadowUrlUtilities.class, ShadowWebsitePreferenceBridge.class})
 public class GeolocationHeaderUnitTest {
     private static final String SEARCH_URL = "https://www.google.com/search?q=potatoes";
 
@@ -98,12 +99,19 @@
     @Rule
     public TestRule mFeatureProcessor = new Features.JUnitProcessor();
 
+    @Rule
+    public JniMocker mocker = new JniMocker();
+
+    @Mock
+    RecordHistogram.Natives mRecordHistogramMock;
+
     @Mock
     private Tab mTab;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mocker.mock(RecordHistogramJni.TEST_HOOKS, mRecordHistogramMock);
         GeolocationTracker.setLocationAgeForTesting(null);
         GeolocationHeader.setLocationSourceForTesting(
                 GeolocationHeader.LocationSource.HIGH_ACCURACY);
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index fcb67c0..821d1752 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -423,7 +423,7 @@
     "//chrome/common:mojo_bindings",
     "//chrome/common:offline_page_auto_fetcher_mojom",
     "//chrome/common:page_load_metrics_mojom",
-    "//chrome/common/media_router/mojo:media_router",
+    "//chrome/common/media_router/mojom:media_router",
     "//chrome/test/data:web_ui_test_bindings",
     "//components/autofill/content/common/mojom",
     "//components/contextual_search/content/common/mojom",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index df6bad12..6da905b 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.h"
 #include "chrome/common/available_offline_content.mojom.h"
 #include "chrome/common/cache_stats_recorder.mojom.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/net_benchmarking.mojom.h"
 #include "chrome/common/offline_page_auto_fetcher.mojom.h"
 #include "chrome/common/page_load_metrics/page_load_metrics.mojom.h"
diff --git a/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.cc b/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.cc
index 8f8302b..0229c75f 100644
--- a/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.cc
+++ b/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.cc
@@ -71,7 +71,6 @@
               ->IsOffTheRecord()),
       file_selected_callback_(file_selected_callback) {
   download_item_->AddObserver(this);
-  RecordDuplicateInfobarType(INFOBAR_SHOWN);
 }
 
 infobars::InfoBarDelegate::InfoBarIdentifier
@@ -81,13 +80,11 @@
 
 bool ChromeDuplicateDownloadInfoBarDelegate::Accept() {
   if (!download_item_) {
-    RecordDuplicateInfobarType(INFOBAR_DOWNLOAD_CANCELED);
     return true;
   }
 
   base::FilePath download_dir;
   if (!base::android::GetDownloadsDirectory(&download_dir)) {
-    RecordDuplicateInfobarType(INFOBAR_NO_DOWNLOAD_DIR);
     return true;
   }
 
@@ -96,7 +93,6 @@
       base::FilePath(), /* fallback_directory */
       true, download::DownloadPathReservationTracker::UNIQUIFY,
       base::Bind(&CreateNewFileDone, file_selected_callback_));
-  RecordDuplicateInfobarType(INFOBAR_CREATE_NEW_FILE);
   return true;
 }
 
@@ -106,9 +102,6 @@
 
   file_selected_callback_.Run(DownloadConfirmationResult::CANCELED,
                               base::FilePath());
-  // TODO(qinmin): rename this histogram enum.
-  DownloadController::RecordDownloadCancelReason(
-      DownloadController::CANCEL_REASON_OVERWRITE_INFOBAR_DISMISSED);
   return true;
 }
 
@@ -124,10 +117,4 @@
   return is_off_the_record_;
 }
 
-void ChromeDuplicateDownloadInfoBarDelegate::RecordDuplicateInfobarType(
-    DuplicateInfobarType type) {
-  UMA_HISTOGRAM_ENUMERATION("MobileDownload.DuplicateInfobar", type,
-                            INFOBAR_MAX);
-}
-
 }  // namespace android
diff --git a/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h b/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h
index d165271..463b9dfa 100644
--- a/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h
+++ b/chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h
@@ -40,18 +40,6 @@
       const base::FilePath& file_path,
       const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback);
 
-  // UMA histogram enum for duplicate infobar. Keep this in sync with
-  // MobileDownloadDuplcaiteInfobar in histograms.xml. This should be
-  // append only.
-  enum DuplicateInfobarType {
-    INFOBAR_SHOWN = 0,
-    INFOBAR_DOWNLOAD_CANCELED,
-    INFOBAR_NO_DOWNLOAD_DIR,
-    INFOBAR_CREATE_NEW_FILE,
-    INFOBAR_MAX
-  };
-  void RecordDuplicateInfobarType(DuplicateInfobarType type);
-
   // DownloadOverwriteInfoBarDelegate:
   infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
   bool Accept() override;
diff --git a/chrome/browser/android/download/download_controller.cc b/chrome/browser/android/download/download_controller.cc
index 042aa84..4565c25 100644
--- a/chrome/browser/android/download/download_controller.cc
+++ b/chrome/browser/android/download/download_controller.cc
@@ -167,10 +167,6 @@
     return;
   }
 
-  if (!granted) {
-    DownloadController::RecordDownloadCancelReason(
-        DownloadController::CANCEL_REASON_NO_STORAGE_PERMISSION);
-  }
   std::move(cb).Run(granted);
 }
 
@@ -228,13 +224,6 @@
 }
 
 // static
-void DownloadController::RecordDownloadCancelReason(
-    DownloadCancelReason reason) {
-  UMA_HISTOGRAM_ENUMERATION(
-      "MobileDownload.CancelReason", reason, CANCEL_REASON_MAX);
-}
-
-// static
 void DownloadController::RecordStoragePermission(StoragePermissionType type) {
   UMA_HISTOGRAM_ENUMERATION("MobileDownload.StoragePermission", type,
                             STORAGE_PERMISSION_MAX);
@@ -429,14 +418,10 @@
 
       // Call onDownloadCompleted
       Java_DownloadController_onDownloadCompleted(env, j_item);
-      DownloadController::RecordDownloadCancelReason(
-             DownloadController::CANCEL_REASON_NOT_CANCELED);
       break;
     case DownloadItem::CANCELLED:
       strong_validators_map_.erase(item->GetGuid());
       Java_DownloadController_onDownloadCancelled(env, j_item);
-      DownloadController::RecordDownloadCancelReason(
-          DownloadController::CANCEL_REASON_OTHER_NATIVE_RESONS);
       break;
     case DownloadItem::INTERRUPTED:
       if (item->IsDone())
diff --git a/chrome/browser/android/download/download_controller.h b/chrome/browser/android/download/download_controller.h
index 0b71533..171dbf1 100644
--- a/chrome/browser/android/download/download_controller.h
+++ b/chrome/browser/android/download/download_controller.h
@@ -39,24 +39,6 @@
                              const DownloadInfo& info) override;
   void AboutToResumeDownload(download::DownloadItem* download_item) override;
 
-  // UMA histogram enum for download cancellation reasons. Keep this
-  // in sync with MobileDownloadCancelReason in histograms.xml. This should be
-  // append only.
-  enum DownloadCancelReason {
-    CANCEL_REASON_NOT_CANCELED = 0,
-    CANCEL_REASON_ACTION_BUTTON,
-    CANCEL_REASON_NOTIFICATION_DISMISSED,
-    CANCEL_REASON_OVERWRITE_INFOBAR_DISMISSED,
-    CANCEL_REASON_NO_STORAGE_PERMISSION,
-    CANCEL_REASON_DANGEROUS_DOWNLOAD_INFOBAR_DISMISSED,
-    CANCEL_REASON_NO_EXTERNAL_STORAGE,
-    CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET,
-    CANCEL_REASON_OTHER_NATIVE_RESONS,
-    CANCEL_REASON_USER_CANCELED,
-    CANCEL_REASON_MAX
-  };
-  static void RecordDownloadCancelReason(DownloadCancelReason reason);
-
   // UMA histogram enum for download storage permission requests. Keep this
   // in sync with MobileDownloadStoragePermission in histograms.xml. This should
   // be append only.
diff --git a/chrome/browser/android/download/download_location_dialog_bridge_impl.cc b/chrome/browser/android/download/download_location_dialog_bridge_impl.cc
index 2b2015b..db0fab51 100644
--- a/chrome/browser/android/download/download_location_dialog_bridge_impl.cc
+++ b/chrome/browser/android/download/download_location_dialog_bridge_impl.cc
@@ -79,8 +79,6 @@
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& obj) {
   if (location_callback_) {
-    DownloadController::RecordDownloadCancelReason(
-        DownloadController::CANCEL_REASON_USER_CANCELED);
     CompleteLocationSelection(DownloadLocationDialogResult::USER_CANCELED,
                               base::FilePath());
   }
diff --git a/chrome/browser/android/download/download_manager_service.cc b/chrome/browser/android/download/download_manager_service.cc
index 5aca12b..d3faa382 100644
--- a/chrome/browser/android/download/download_manager_service.cc
+++ b/chrome/browser/android/download/download_manager_service.cc
@@ -106,22 +106,19 @@
 // static
 void DownloadManagerService::OnDownloadCanceled(
     download::DownloadItem* download,
-    DownloadController::DownloadCancelReason reason) {
+    bool has_no_external_storage) {
   if (download->IsTransient()) {
     LOG(WARNING) << "Transient download should not have user interaction!";
     return;
   }
 
   // Inform the user in Java UI about file writing failures.
-  bool has_no_external_storage =
-      (reason == DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
   JNIEnv* env = base::android::AttachCurrentThread();
 
   ScopedJavaLocalRef<jobject> j_item =
       JNI_DownloadManagerService_CreateJavaDownloadItem(env, download);
   Java_DownloadManagerService_onDownloadItemCanceled(env, j_item,
                                                      has_no_external_storage);
-  DownloadController::RecordDownloadCancelReason(reason);
 }
 
 // static
@@ -408,8 +405,6 @@
     const JavaParamRef<jstring>& jdownload_guid,
     bool is_off_the_record) {
   std::string download_guid = ConvertJavaStringToUTF8(env, jdownload_guid);
-  DownloadController::RecordDownloadCancelReason(
-      DownloadController::CANCEL_REASON_ACTION_BUTTON);
   if (is_pending_downloads_loaded_ || is_off_the_record)
     CancelDownloadInternal(download_guid, is_off_the_record);
   else
@@ -629,8 +624,6 @@
       FROM_HERE,
       base::BindOnce(&DownloadManagerService::OnResumptionFailedInternal,
                      base::Unretained(this), download_guid));
-  DownloadController::RecordDownloadCancelReason(
-      DownloadController::CANCEL_REASON_NOT_CANCELED);
 }
 
 void DownloadManagerService::OnResumptionFailedInternal(
diff --git a/chrome/browser/android/download/download_manager_service.h b/chrome/browser/android/download/download_manager_service.h
index 6aeed39..5b715a04 100644
--- a/chrome/browser/android/download/download_manager_service.h
+++ b/chrome/browser/android/download/download_manager_service.h
@@ -13,7 +13,6 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/singleton.h"
-#include "chrome/browser/android/download/download_controller.h"
 #include "chrome/browser/download/download_manager_utils.h"
 #include "components/download/public/common/all_download_event_notifier.h"
 #include "components/download/public/common/in_progress_download_manager.h"
@@ -38,9 +37,8 @@
  public:
   static void CreateAutoResumptionHandler();
 
-  static void OnDownloadCanceled(
-      download::DownloadItem* download,
-      DownloadController::DownloadCancelReason reason);
+  static void OnDownloadCanceled(download::DownloadItem* download,
+                                 bool has_no_external_storage);
 
   static DownloadManagerService* GetInstance();
 
diff --git a/chrome/browser/browsing_data/browsing_data_appcache_helper.cc b/chrome/browser/browsing_data/browsing_data_appcache_helper.cc
index 8aded4c2..c36a096 100644
--- a/chrome/browser/browsing_data/browsing_data_appcache_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_appcache_helper.cc
@@ -60,9 +60,8 @@
   if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
     std::move(callback).Run(std::move(result));
   } else {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), std::move(result)));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), std::move(result)));
   }
 }
 
@@ -79,7 +78,7 @@
   if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
     StartFetchingOnLoaderThread(std::move(callback));
   } else {
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::IO},
         base::BindOnce(&BrowsingDataAppCacheHelper::StartFetchingOnLoaderThread,
                        this, std::move(callback)));
@@ -91,7 +90,7 @@
   if (base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI)) {
     DeleteAppCachesOnLoaderThread(origin);
   } else {
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::IO},
         base::BindOnce(
             &BrowsingDataAppCacheHelper::DeleteAppCachesOnLoaderThread, this,
@@ -156,8 +155,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin, 0, base::Time());
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataAppCacheHelper::DeleteAppCaches(
diff --git a/chrome/browser/browsing_data/browsing_data_cache_storage_helper.cc b/chrome/browser/browsing_data/browsing_data_cache_storage_helper.cc
index 63921f2..06bfda9 100644
--- a/chrome/browser/browsing_data/browsing_data_cache_storage_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_cache_storage_helper.cc
@@ -99,8 +99,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin, 0, base::Time());
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataCacheStorageHelper::DeleteCacheStorage(
diff --git a/chrome/browser/browsing_data/browsing_data_database_helper.cc b/chrome/browser/browsing_data/browsing_data_database_helper.cc
index 7e4024f..ba2c14e 100644
--- a/chrome/browser/browsing_data/browsing_data_database_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_database_helper.cc
@@ -113,8 +113,8 @@
     result.emplace_back(origin, 0, base::Time());
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataDatabaseHelper::DeleteDatabase(
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
index 0f28272..516a57e 100644
--- a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
@@ -98,8 +98,8 @@
   for (const auto& iter : file_system_info_map)
     result.push_back(iter.second);
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void BrowsingDataFileSystemHelper::DeleteFileSystemOriginInFileThread(
@@ -157,8 +157,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin);
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataFileSystemHelper::DeleteFileSystemOrigin(
diff --git a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
index 7f33f56..c634aa7 100644
--- a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
@@ -63,8 +63,8 @@
       continue;  // Non-websafe state is not considered browsing data.
     result.push_back(origin);
   }
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void BrowsingDataIndexedDBHelper::DeleteIndexedDBInIndexedDBThread(
@@ -112,8 +112,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin, 0, base::Time());
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataIndexedDBHelper::DeleteIndexedDB(
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
index 3fae278..e43cc4b 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
@@ -44,8 +44,8 @@
     result.push_back(info);
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 }  // namespace
@@ -111,8 +111,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin, 0, base::Time());
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataLocalStorageHelper::DeleteOrigin(
diff --git a/chrome/browser/browsing_data/browsing_data_media_license_helper.cc b/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
index 4c6419f2..1bb7657 100644
--- a/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
@@ -112,8 +112,8 @@
     result.push_back(MediaLicenseInfo(origin, size, last_modified_time));
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void BrowsingDataMediaLicenseHelperImpl::
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
index d51af64..801d520 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
@@ -35,7 +35,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!callback.is_null());
 
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&BrowsingDataQuotaHelperImpl::FetchQuotaInfoOnIOThread,
                      this, std::move(callback)));
@@ -43,7 +43,7 @@
 
 void BrowsingDataQuotaHelperImpl::RevokeHostQuota(const std::string& host) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&BrowsingDataQuotaHelperImpl::RevokeHostQuotaOnIOThread,
                      this, host));
@@ -159,8 +159,8 @@
     result.push_back(info);
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void BrowsingDataQuotaHelperImpl::RevokeHostQuotaOnIOThread(
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
index 377b4e3b..8b410d5 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
@@ -39,8 +39,8 @@
     EXPECT_TRUE(dir_.CreateUniqueTempDir());
     quota_manager_ = new storage::QuotaManager(
         false, dir_.GetPath(),
-        base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}).get(),
-        nullptr, storage::GetQuotaSettingsFunc());
+        base::CreateSingleThreadTaskRunner({BrowserThread::IO}).get(), nullptr,
+        storage::GetQuotaSettingsFunc());
     helper_ = new BrowsingDataQuotaHelperImpl(quota_manager_.get());
   }
 
diff --git a/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc b/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
index bb1a3ed1..ccf37aa 100644
--- a/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_service_worker_helper.cc
@@ -37,8 +37,8 @@
     result.push_back(origin);
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 }  // namespace
@@ -54,16 +54,15 @@
 void BrowsingDataServiceWorkerHelper::StartFetching(FetchCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!callback.is_null());
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::IO},
-      base::BindOnce(&BrowsingDataServiceWorkerHelper::
-                         FetchServiceWorkerUsageInfoOnIOThread,
-                     this, std::move(callback)));
+  base::PostTask(FROM_HERE, {BrowserThread::IO},
+                 base::BindOnce(&BrowsingDataServiceWorkerHelper::
+                                    FetchServiceWorkerUsageInfoOnIOThread,
+                                this, std::move(callback)));
 }
 
 void BrowsingDataServiceWorkerHelper::DeleteServiceWorkers(const GURL& origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
           &BrowsingDataServiceWorkerHelper::DeleteServiceWorkersOnIOThread,
@@ -127,8 +126,8 @@
   for (const auto& origin : pending_origins_)
     result.emplace_back(origin, 0, base::Time());
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataServiceWorkerHelper::DeleteServiceWorkers(
diff --git a/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc b/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
index 7c9371d1..89f0dad2 100644
--- a/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
@@ -48,8 +48,8 @@
   // We always return an empty list, as there are no "persistent" shared
   // workers.
   std::list<SharedWorkerInfo> result;
-  base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 void BrowsingDataSharedWorkerHelper::DeleteSharedWorker(
     const GURL& worker,
@@ -104,8 +104,8 @@
   std::list<SharedWorkerInfo> result;
   for (auto& it : pending_shared_worker_info_)
     result.push_back(it);
-  base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
-                           base::BindOnce(std::move(callback), result));
+  base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+                 base::BindOnce(std::move(callback), result));
 }
 
 void CannedBrowsingDataSharedWorkerHelper::DeleteSharedWorker(
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index ebcb59e..ad1a474 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -154,13 +154,13 @@
 // Generic functions but currently only used when ENABLE_NACL.
 #if BUILDFLAG(ENABLE_NACL)
 void UIThreadTrampolineHelper(base::OnceClosure callback) {
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(callback));
+  base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(callback));
 }
 
 // Convenience method to create a callback that can be run on any thread and
 // will post the given |callback| back to the UI thread.
 base::OnceClosure UIThreadTrampoline(base::OnceClosure callback) {
-  // We could directly bind &base::PostTaskWithTraits, but that would require
+  // We could directly bind &base::PostTask, but that would require
   // evaluating FROM_HERE when this method is called, as opposed to when the
   // task is actually posted.
   return base::BindOnce(&UIThreadTrampolineHelper, std::move(callback));
@@ -325,9 +325,9 @@
   slow_pending_tasks_closure_.Reset(base::BindRepeating(
       &ChromeBrowsingDataRemoverDelegate::RecordUnfinishedSubTasks,
       weak_ptr_factory_.GetWeakPtr()));
-  base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                                  slow_pending_tasks_closure_.callback(),
-                                  kSlowTaskTimeout);
+  base::PostDelayedTask(FROM_HERE, {BrowserThread::UI},
+                        slow_pending_tasks_closure_.callback(),
+                        kSlowTaskTimeout);
 
   // Embedder-defined DOM-accessible storage currently contains only
   // one datatype, which is the durable storage permission.
@@ -517,8 +517,10 @@
         data_manager->Refresh();
     }
 
-    base::PostTaskWithTraitsAndReply(
-        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+    base::PostTaskAndReply(
+        FROM_HERE,
+        {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
+         base::MayBlock()},
         base::BindOnce(
             &webrtc_logging::DeleteOldAndRecentWebRtcLogFiles,
             webrtc_logging::TextLogList::
@@ -527,8 +529,10 @@
         CreateTaskCompletionClosure(TracingDataType::kWebrtcLogs));
 
 #if defined(OS_ANDROID)
-    base::PostTaskWithTraitsAndReply(
-        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+    base::PostTaskAndReply(
+        FROM_HERE,
+        {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
+         base::MayBlock()},
         base::BindOnce(&ClearPrecacheInBackground, profile_),
         CreateTaskCompletionClosure(TracingDataType::kPrecache));
 
@@ -878,12 +882,12 @@
     web_cache::WebCacheManager::GetInstance()->ClearCache();
 
 #if BUILDFLAG(ENABLE_NACL)
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::IO},
         base::BindOnce(&ClearNaClCacheOnIOThread,
                        UIThreadTrampoline(CreateTaskCompletionClosure(
                            TracingDataType::kNaclCache))));
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::IO},
         base::BindOnce(&ClearPnaclCacheOnIOThread, delete_begin_, delete_end_,
                        UIThreadTrampoline(CreateTaskCompletionClosure(
diff --git a/chrome/browser/browsing_data/counters/site_data_counting_helper.cc b/chrome/browser/browsing_data/counters/site_data_counting_helper.cc
index 86d73cb7..f9b6c9b 100644
--- a/chrome/browser/browsing_data/counters/site_data_counting_helper.cc
+++ b/chrome/browser/browsing_data/counters/site_data_counting_helper.cc
@@ -72,7 +72,7 @@
         blink::mojom::StorageType::kSyncable};
     for (auto type : types) {
       tasks_ += 1;
-      base::PostTaskWithTraits(
+      base::PostTask(
           FROM_HERE, {BrowserThread::IO},
           base::BindOnce(&storage::QuotaManager::GetOriginsModifiedSince,
                          quota_manager, type, begin_, origins_callback));
@@ -158,9 +158,9 @@
       origins.push_back(url);
     }
   }
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(&SiteDataCountingHelper::Done,
-                                          base::Unretained(this), origins));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(&SiteDataCountingHelper::Done,
+                                base::Unretained(this), origins));
 }
 
 void SiteDataCountingHelper::GetQuotaOriginsCallback(
@@ -171,10 +171,9 @@
   urls.resize(origins.size());
   for (const url::Origin& origin : origins)
     urls.push_back(origin.GetURL());
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&SiteDataCountingHelper::Done, base::Unretained(this),
-                     std::move(urls)));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(&SiteDataCountingHelper::Done,
+                                base::Unretained(this), std::move(urls)));
 }
 
 void SiteDataCountingHelper::GetLocalStorageUsageInfoCallback(
diff --git a/chrome/browser/browsing_data/site_data_size_collector.cc b/chrome/browser/browsing_data/site_data_size_collector.cc
index e32835a..5e94565b 100644
--- a/chrome/browser/browsing_data/site_data_size_collector.cc
+++ b/chrome/browser/browsing_data/site_data_size_collector.cc
@@ -137,8 +137,9 @@
   }
   base::FilePath cookie_file_path = default_storage_partition_path_
       .Append(chrome::kCookieFilename);
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+  base::PostTaskAndReplyWithResult(
+      FROM_HERE,
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
       base::BindOnce(&GetFileSizeBlocking, cookie_file_path),
       base::BindOnce(&SiteDataSizeCollector::OnStorageSizeFetched,
                      weak_ptr_factory_.GetWeakPtr()));
@@ -212,8 +213,9 @@
   }
   base::FilePath pepper_data_dir_path = default_storage_partition_path_
       .Append(content::kPepperDataDirname);
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+  base::PostTaskAndReplyWithResult(
+      FROM_HERE,
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
       base::BindOnce(&base::ComputeDirectorySize, pepper_data_dir_path),
       base::BindOnce(&SiteDataSizeCollector::OnStorageSizeFetched,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc
index fbcaa4eb..d6c7e155 100644
--- a/chrome/browser/chrome_navigation_browsertest.cc
+++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -954,8 +954,7 @@
   process->Shutdown(-1);
   crash_observer.Wait();
 
-  // Attempt to navigate to a chrome://... URL.  This used to hang and never
-  // commit in PlzNavigate mode.
+  // Attempt to navigate to a chrome://... URL.
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL));
 }
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 96edd6c..82cceba 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1410,8 +1410,12 @@
     "login/ui/login_display_webui.h",
     "login/ui/login_feedback.cc",
     "login/ui/login_feedback.h",
+    "login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.cc",
+    "login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h",
     "login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.cc",
     "login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h",
+    "login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.cc",
+    "login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h",
     "login/ui/login_screen_extension_ui/login_screen_extension_ui_window.cc",
     "login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h",
     "login/ui/login_web_dialog.cc",
@@ -2544,6 +2548,7 @@
     "login/signin_partition_manager_unittest.cc",
     "login/supervised/supervised_user_authentication_unittest.cc",
     "login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate_unittest.cc",
+    "login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view_unittest.cc",
     "login/users/affiliation_unittest.cc",
     "login/users/multi_profile_user_controller_unittest.cc",
     "login/users/user_manager_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.cc b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.cc
index 10c9708..8232021 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.cc
@@ -7,6 +7,7 @@
 #include "ash/public/cpp/login_screen.h"
 #include "ash/public/cpp/login_screen_model.h"
 #include "ash/public/cpp/login_types.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
 #include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
@@ -90,7 +91,7 @@
         ash::OobeDialogState::EXTENSION_LOGIN);
   }
 
-  LoginScreenExtensionUiWindow::CreateOptions create_options(
+  LoginScreenExtensionUiCreateOptions create_options(
       extension->short_name(), extension->GetResourceURL(resource_path),
       can_be_closed_by_user,
       base::BindOnce(
@@ -166,4 +167,14 @@
   RemoveWindowForExtension(extension->id());
 }
 
+LoginScreenExtensionUiWindow*
+LoginScreenExtensionUiHandler::GetWindowForTesting(
+    const std::string& extension_id) {
+  WindowMap::iterator it = windows_.find(extension_id);
+  if (it == windows_.end())
+    return nullptr;
+
+  return it->second.get();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h
index bab8657..9e7891a 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h
+++ b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h
@@ -67,6 +67,9 @@
   // session_manager::SessionManagerObserver
   void OnSessionStateChanged() override;
 
+  LoginScreenExtensionUiWindow* GetWindowForTesting(
+      const std::string& extension_id);
+
  private:
   using WindowMap =
       std::map<std::string, std::unique_ptr<LoginScreenExtensionUiWindow>>;
diff --git a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler_unittest.cc b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler_unittest.cc
index 5abaa946..3a8296d 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler_unittest.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/test/gtest_util.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
 #include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
 #include "chrome/browser/ui/ash/test_login_screen.h"
 #include "chrome/common/chrome_constants.h"
@@ -50,7 +51,7 @@
   ~FakeLoginScreenExtensionUiWindowFactory() override = default;
 
   std::unique_ptr<LoginScreenExtensionUiWindow> Create(
-      LoginScreenExtensionUiWindow::CreateOptions* create_options) override {
+      LoginScreenExtensionUiCreateOptions* create_options) override {
     create_was_called_ = true;
     last_extension_name_ = create_options->extension_name;
     last_content_url_ = create_options->content_url;
diff --git a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_ui_apitest.cc b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_ui_apitest.cc
index e823b68..3598289d 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_ui_apitest.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_ui_apitest.cc
@@ -7,16 +7,22 @@
 
 #include "chrome/browser/chromeos/extensions/login_screen/login_screen_apitest_base.h"
 #include "chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
 #include "chrome/browser/chromeos/policy/signin_profile_extensions_policy_test_base.h"
 #include "components/version_info/version_info.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
 
 namespace {
 
-const char kCanOpenWindow[] = "LoginScreenUiCanOpenWindow";
-const char kCannotOpenMultipleWindows[] =
+constexpr char kCanOpenWindow[] = "LoginScreenUiCanOpenWindow";
+constexpr char kCannotOpenMultipleWindows[] =
     "LoginScreenUiCannotOpenMultipleWindows";
-const char kCanOpenAndCloseWindow[] = "LoginScreenUiCanOpenAndCloseWindow";
-const char kCannotCloseNoWindow[] = "LoginScreenUiCannotCloseNoWindow";
+constexpr char kCanOpenAndCloseWindow[] = "LoginScreenUiCanOpenAndCloseWindow";
+constexpr char kCannotCloseNoWindow[] = "LoginScreenUiCannotCloseNoWindow";
+constexpr char kUserCanCloseWindow[] = "LoginScreenUiUserCanCloseWindow";
+constexpr char kUserCannotCloseWindow[] = "LoginScreenUiUserCannotCloseWindow";
 
 }  // namespace
 
@@ -28,11 +34,31 @@
 
   ~LoginScreenUiApitest() override = default;
 
-  bool HasOpenWindow() {
-    LoginScreenExtensionUiHandler* ui_handler =
-        LoginScreenExtensionUiHandler::Get(false);
-    CHECK(ui_handler);
-    return ui_handler->HasOpenWindow(extension_id_);
+  bool HasOpenWindow() const {
+    return LoginScreenExtensionUiHandler::Get(false)->HasOpenWindow(
+        extension_id_);
+  }
+
+  bool CanCloseDialog() const {
+    return LoginScreenExtensionUiHandler::Get(false)
+        ->GetWindowForTesting(extension_id_)
+        ->GetDialogDelegateForTesting()
+        ->CanCloseDialog();
+  }
+
+  bool ShouldShowCloseButton() const {
+    return LoginScreenExtensionUiHandler::Get(false)
+        ->GetWindowForTesting(extension_id_)
+        ->GetDialogWidgetForTesting()
+        ->widget_delegate()
+        ->ShouldShowCloseButton();
+  }
+
+  bool IsMovementDisabled() const {
+    return LoginScreenExtensionUiHandler::Get(false)
+        ->GetWindowForTesting(extension_id_)
+        ->GetDialogWidgetForTesting()
+        ->movement_disabled();
   }
 
  private:
@@ -41,7 +67,11 @@
 
 IN_PROC_BROWSER_TEST_F(LoginScreenUiApitest, ExtensionCanOpenWindow) {
   SetUpExtensionAndRunTest(kCanOpenWindow);
-  EXPECT_TRUE(HasOpenWindow());
+  ASSERT_TRUE(HasOpenWindow());
+  // userCanClose defaults to false
+  EXPECT_TRUE(IsMovementDisabled());
+  EXPECT_FALSE(CanCloseDialog());
+  EXPECT_FALSE(ShouldShowCloseButton());
 }
 
 IN_PROC_BROWSER_TEST_F(LoginScreenUiApitest,
@@ -60,4 +90,20 @@
   EXPECT_FALSE(HasOpenWindow());
 }
 
+IN_PROC_BROWSER_TEST_F(LoginScreenUiApitest, UserCanCloseWindow) {
+  SetUpExtensionAndRunTest(kUserCanCloseWindow);
+  ASSERT_TRUE(HasOpenWindow());
+  EXPECT_TRUE(IsMovementDisabled());
+  EXPECT_TRUE(CanCloseDialog());
+  EXPECT_TRUE(ShouldShowCloseButton());
+}
+
+IN_PROC_BROWSER_TEST_F(LoginScreenUiApitest, UserCannotCloseWindow) {
+  SetUpExtensionAndRunTest(kUserCannotCloseWindow);
+  ASSERT_TRUE(HasOpenWindow());
+  EXPECT_TRUE(IsMovementDisabled());
+  EXPECT_FALSE(CanCloseDialog());
+  EXPECT_FALSE(ShouldShowCloseButton());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.cc
new file mode 100644
index 0000000..2ea4bca7
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.cc
@@ -0,0 +1,24 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
+
+#include <memory>
+
+namespace chromeos {
+
+LoginScreenExtensionUiCreateOptions::LoginScreenExtensionUiCreateOptions(
+    const std::string& extension_name,
+    const GURL& content_url,
+    bool can_be_closed_by_user,
+    base::OnceClosure close_callback)
+    : extension_name(extension_name),
+      content_url(content_url),
+      can_be_closed_by_user(can_be_closed_by_user),
+      close_callback(std::move(close_callback)) {}
+
+LoginScreenExtensionUiCreateOptions::~LoginScreenExtensionUiCreateOptions() =
+    default;
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h
new file mode 100644
index 0000000..0b282e1
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h
@@ -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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_CREATE_OPTIONS_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_CREATE_OPTIONS_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "url/gurl.h"
+
+namespace chromeos {
+
+struct LoginScreenExtensionUiCreateOptions {
+  LoginScreenExtensionUiCreateOptions(const std::string& extension_name,
+                                      const GURL& content_url,
+                                      bool can_be_closed_by_user,
+                                      base::OnceClosure close_callback);
+  ~LoginScreenExtensionUiCreateOptions();
+
+  const std::string extension_name;
+  const GURL content_url;
+  bool can_be_closed_by_user;
+  base::OnceClosure close_callback;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_CREATE_OPTIONS_H_
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.cc
index 2399783..69c1b23 100644
--- a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.cc
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.cc
@@ -5,10 +5,14 @@
 #include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
 #include "chrome/grit/generated_resources.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui_message_handler.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace chromeos {
 
@@ -18,7 +22,7 @@
 }  // namespace
 
 LoginScreenExtensionUiDialogDelegate::LoginScreenExtensionUiDialogDelegate(
-    LoginScreenExtensionUiWindow::CreateOptions* create_options)
+    LoginScreenExtensionUiCreateOptions* create_options)
     : extension_name_(create_options->extension_name),
       content_url_(create_options->content_url),
       can_close_(create_options->can_be_closed_by_user),
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h
index 130aa7f..11dd36f 100644
--- a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h
@@ -6,19 +6,34 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_DIALOG_DELEGATE_H_
 
 #include <string>
+#include <vector>
 
-#include "base/callback_forward.h"
-#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
+#include "base/callback.h"
+#include "base/strings/string16.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
+#include "url/gurl.h"
+
+namespace content {
+class WebContents;
+class WebUIMessageHandler;
+}  // namespace content
+
+namespace gfx {
+class Size;
+}  // namespace gfx
 
 namespace chromeos {
 
+struct LoginScreenExtensionUiCreateOptions;
+
 // This class is used to provide data from a chrome.loginScreenUi API call to
 // the WebDialog.
 class LoginScreenExtensionUiDialogDelegate : public ui::WebDialogDelegate {
  public:
   explicit LoginScreenExtensionUiDialogDelegate(
-      LoginScreenExtensionUiWindow::CreateOptions* create_options);
+      LoginScreenExtensionUiCreateOptions* create_options);
   ~LoginScreenExtensionUiDialogDelegate() override;
 
   void set_can_close(bool can_close) { can_close_ = can_close; }
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate_unittest.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate_unittest.cc
index e858548..20a9477 100644
--- a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate_unittest.cc
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/extensions/login_screen/login_screen_ui/login_screen_extension_ui_handler.h"
-#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -41,7 +41,7 @@
 
   base::RunLoop close_callback_wait;
 
-  LoginScreenExtensionUiWindow::CreateOptions create_options(
+  LoginScreenExtensionUiCreateOptions create_options(
       extension->short_name(), extension->GetResourceURL(kResourcePath),
       false /*can_be_closed_by_user*/, close_callback_wait.QuitClosure());
 
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.cc
new file mode 100644
index 0000000..75140df
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.cc
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h"
+
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h"
+#include "content/public/browser/browser_context.h"
+
+namespace chromeos {
+
+LoginScreenExtensionUiWebDialogView::LoginScreenExtensionUiWebDialogView(
+    content::BrowserContext* context,
+    LoginScreenExtensionUiDialogDelegate* delegate,
+    std::unique_ptr<ui::WebDialogWebContentsDelegate::WebContentsHandler>
+        handler)
+    : views::WebDialogView(context, delegate, std::move(handler)),
+      delegate_(delegate) {}
+
+LoginScreenExtensionUiWebDialogView::~LoginScreenExtensionUiWebDialogView() =
+    default;
+
+bool LoginScreenExtensionUiWebDialogView::ShouldShowCloseButton() const {
+  return !delegate_ || delegate_->CanCloseDialog();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h
new file mode 100644
index 0000000..825fba9
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_WEB_DIALOG_VIEW_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_WEB_DIALOG_VIEW_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "ui/views/controls/webview/web_dialog_view.h"
+#include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace chromeos {
+
+class LoginScreenExtensionUiDialogDelegate;
+
+// A WebDialogView used by chrome.loginScreenUi API calls. It hides the close
+// button if |LoginScreenExtensionUiDialogDelegate::CanCloseDialog()| is false.
+class LoginScreenExtensionUiWebDialogView : public views::WebDialogView {
+ public:
+  explicit LoginScreenExtensionUiWebDialogView(
+      content::BrowserContext* context,
+      LoginScreenExtensionUiDialogDelegate* delegate,
+      std::unique_ptr<ui::WebDialogWebContentsDelegate::WebContentsHandler>
+          handler);
+  ~LoginScreenExtensionUiWebDialogView() override;
+
+  bool ShouldShowCloseButton() const override;
+
+ private:
+  LoginScreenExtensionUiDialogDelegate* delegate_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(LoginScreenExtensionUiWebDialogView);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_WEB_DIALOG_VIEW_H_
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view_unittest.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view_unittest.cc
new file mode 100644
index 0000000..312cea9
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h"
+
+#include <memory>
+
+#include "base/bind_helpers.h"
+#include "base/macros.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h"
+#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace chromeos {
+
+class LoginScreenExtensionUiWebDialogViewUnittest : public testing::Test {
+ public:
+  LoginScreenExtensionUiWebDialogViewUnittest() = default;
+  ~LoginScreenExtensionUiWebDialogViewUnittest() override = default;
+
+ protected:
+  content::TestBrowserThreadBundle thread_bundle_;
+  TestingProfile profile;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LoginScreenExtensionUiWebDialogViewUnittest);
+};
+
+TEST_F(LoginScreenExtensionUiWebDialogViewUnittest, ShouldShowCloseButton) {
+  LoginScreenExtensionUiCreateOptions create_options(
+      "extension_name", GURL(),
+      /*can_be_closed_by_user=*/true, base::DoNothing());
+
+  std::unique_ptr<LoginScreenExtensionUiDialogDelegate> dialog_delegate =
+      std::make_unique<LoginScreenExtensionUiDialogDelegate>(&create_options);
+
+  std::unique_ptr<LoginScreenExtensionUiWebDialogView> dialog_view =
+      std::make_unique<LoginScreenExtensionUiWebDialogView>(
+          &profile, dialog_delegate.get(),
+          std::make_unique<ChromeWebContentsHandler>());
+
+  ASSERT_TRUE(dialog_view->ShouldShowCloseButton());
+}
+
+TEST_F(LoginScreenExtensionUiWebDialogViewUnittest, ShouldNotShowCloseButton) {
+  LoginScreenExtensionUiCreateOptions create_options(
+      "extension_name", GURL(),
+      /*can_be_closed_by_user=*/false, base::DoNothing());
+
+  std::unique_ptr<LoginScreenExtensionUiDialogDelegate> dialog_delegate =
+      std::make_unique<LoginScreenExtensionUiDialogDelegate>(&create_options);
+
+  std::unique_ptr<LoginScreenExtensionUiWebDialogView> dialog_view =
+      std::make_unique<LoginScreenExtensionUiWebDialogView>(
+          &profile, dialog_delegate.get(),
+          std::make_unique<ChromeWebContentsHandler>());
+
+  ASSERT_FALSE(dialog_view->ShouldShowCloseButton());
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.cc b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.cc
index 68d9b83..e20a8e4 100644
--- a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.cc
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h"
 
 #include "ash/public/cpp/shell_window_ids.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_create_options.h"
 #include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_dialog_delegate.h"
+#include "chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_web_dialog_view.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
@@ -14,18 +16,6 @@
 
 namespace chromeos {
 
-LoginScreenExtensionUiWindow::CreateOptions::CreateOptions(
-    const std::string& extension_name,
-    const GURL& content_url,
-    bool can_be_closed_by_user,
-    base::OnceClosure close_callback)
-    : extension_name(extension_name),
-      content_url(content_url),
-      can_be_closed_by_user(can_be_closed_by_user),
-      close_callback(std::move(close_callback)) {}
-
-LoginScreenExtensionUiWindow::CreateOptions::~CreateOptions() = default;
-
 LoginScreenExtensionUiWindowFactory::LoginScreenExtensionUiWindowFactory() =
     default;
 LoginScreenExtensionUiWindowFactory::~LoginScreenExtensionUiWindowFactory() =
@@ -33,24 +23,25 @@
 
 std::unique_ptr<LoginScreenExtensionUiWindow>
 LoginScreenExtensionUiWindowFactory::Create(
-    LoginScreenExtensionUiWindow::CreateOptions* create_options) {
+    LoginScreenExtensionUiCreateOptions* create_options) {
   return std::make_unique<LoginScreenExtensionUiWindow>(create_options);
 }
 
 LoginScreenExtensionUiWindow::LoginScreenExtensionUiWindow(
-    CreateOptions* create_options) {
-  dialog_delegate_ = new LoginScreenExtensionUiDialogDelegate(create_options);
-
-  dialog_view_ = new views::WebDialogView(
-      ProfileHelper::GetSigninProfile(), dialog_delegate_,
-      std::make_unique<ChromeWebContentsHandler>());
-
+    LoginScreenExtensionUiCreateOptions* create_options)
+    : dialog_delegate_(
+          new LoginScreenExtensionUiDialogDelegate(create_options)),
+      dialog_view_(new LoginScreenExtensionUiWebDialogView(
+          ProfileHelper::GetSigninProfile(),
+          dialog_delegate_,
+          std::make_unique<ChromeWebContentsHandler>())) {
   dialog_widget_ = new views::Widget;
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   params.delegate = dialog_view_;
   ash_util::SetupWidgetInitParamsForContainer(
       &params, ash::kShellWindowId_LockScreenContainer);
   dialog_widget_->Init(params);
+  dialog_widget_->set_movement_disabled(true);
   dialog_delegate_->set_native_window(dialog_widget_->GetNativeWindow());
   dialog_widget_->Show();
 }
@@ -60,4 +51,13 @@
   dialog_widget_->Close();
 }
 
+LoginScreenExtensionUiDialogDelegate*
+LoginScreenExtensionUiWindow::GetDialogDelegateForTesting() {
+  return dialog_delegate_;
+}
+
+views::Widget* LoginScreenExtensionUiWindow::GetDialogWidgetForTesting() {
+  return dialog_widget_;
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h
index 1142e37..170dffc9 100644
--- a/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h
+++ b/chrome/browser/chromeos/login/ui/login_screen_extension_ui/login_screen_extension_ui_window.h
@@ -5,44 +5,37 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_WINDOW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_SCREEN_EXTENSION_UI_LOGIN_SCREEN_EXTENSION_UI_WINDOW_H_
 
-#include <string>
+#include <memory>
 
-#include "base/callback_forward.h"
-#include "ui/web_dialogs/web_dialog_delegate.h"
+#include "base/macros.h"
 
 namespace views {
-class WebDialogView;
 class Widget;
 }  // namespace views
 
 namespace chromeos {
 
+struct LoginScreenExtensionUiCreateOptions;
 class LoginScreenExtensionUiDialogDelegate;
+class LoginScreenExtensionUiWebDialogView;
 
 // This class represents the window that can be created by the
 // chrome.loginScreenUi API. It manages the window's widget, view and delegate,
 // which are all automatically deleted when the widget closes.
+// The window is not draggable, and has a close button which is not visible
+// if |create_options.can_be_closed_by_user| is false.
 class LoginScreenExtensionUiWindow {
  public:
-  struct CreateOptions {
-    CreateOptions(const std::string& extension_name,
-                  const GURL& content_url,
-                  bool can_be_closed_by_user,
-                  base::OnceClosure close_callback);
-    ~CreateOptions();
-
-    const std::string extension_name;
-    const GURL content_url;
-    bool can_be_closed_by_user;
-    base::OnceClosure close_callback;
-  };
-
-  explicit LoginScreenExtensionUiWindow(CreateOptions* create_options);
+  explicit LoginScreenExtensionUiWindow(
+      LoginScreenExtensionUiCreateOptions* create_options);
   ~LoginScreenExtensionUiWindow();
 
+  LoginScreenExtensionUiDialogDelegate* GetDialogDelegateForTesting();
+  views::Widget* GetDialogWidgetForTesting();
+
  private:
   LoginScreenExtensionUiDialogDelegate* dialog_delegate_ = nullptr;
-  views::WebDialogView* dialog_view_ = nullptr;
+  LoginScreenExtensionUiWebDialogView* dialog_view_ = nullptr;
   views::Widget* dialog_widget_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(LoginScreenExtensionUiWindow);
@@ -54,7 +47,7 @@
   virtual ~LoginScreenExtensionUiWindowFactory();
 
   virtual std::unique_ptr<LoginScreenExtensionUiWindow> Create(
-      LoginScreenExtensionUiWindow::CreateOptions* create_options);
+      LoginScreenExtensionUiCreateOptions* create_options);
 
   DISALLOW_COPY_AND_ASSIGN(LoginScreenExtensionUiWindowFactory);
 };
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 51b4ed82..1cf3fa3 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -242,7 +242,8 @@
 
   device_scheduled_update_checker_ =
       std::make_unique<DeviceScheduledUpdateChecker>(
-          chromeos::CrosSettings::Get());
+          chromeos::CrosSettings::Get(),
+          chromeos::NetworkHandler::Get()->network_state_handler());
 
   device_cloud_external_data_policy_handlers_.emplace_back(
       std::make_unique<policy::DeviceNativePrintersExternalDataHandler>(
@@ -284,6 +285,8 @@
   if (device_cloud_policy_manager_)
     device_cloud_policy_manager_->RemoveDeviceCloudPolicyManagerObserver(this);
 
+  device_scheduled_update_checker_.reset();
+
   if (hostname_handler_)
     hostname_handler_->Shutdown();
 
diff --git a/chrome/browser/chromeos/policy/device_scheduled_update_checker.cc b/chrome/browser/chromeos/policy/device_scheduled_update_checker.cc
index d364b8f0..5c60f6d 100644
--- a/chrome/browser/chromeos/policy/device_scheduled_update_checker.cc
+++ b/chrome/browser/chromeos/policy/device_scheduled_update_checker.cc
@@ -207,9 +207,6 @@
       }
 
       // Validated by schema validation at higher layers.
-      // TODO(crbug.com/924762): Currently |day_of_month| is restricted to 28 to
-      // make month rollover calculations easier. Fix it to be smart enough to
-      // handle all 31 days and month and year rollovers.
       result.day_of_month = day_of_month.value();
       break;
     }
@@ -270,7 +267,8 @@
 // |os_and_policies_update_checker_| will be destroyed as part of this object,
 // so it's safe to use "this" with any callbacks.
 DeviceScheduledUpdateChecker::DeviceScheduledUpdateChecker(
-    chromeos::CrosSettings* cros_settings)
+    chromeos::CrosSettings* cros_settings,
+    chromeos::NetworkStateHandler* network_state_handler)
     : cros_settings_(cros_settings),
       cros_settings_observer_(cros_settings_->AddSettingsObserver(
           chromeos::kDeviceScheduledUpdateCheck,
@@ -284,6 +282,7 @@
           update_checker_internal::kMaxStartUpdateCheckTimerRetryIterations,
           update_checker_internal::kStartUpdateCheckTimerRetryTime),
       os_and_policies_update_checker_(
+          network_state_handler,
           base::BindRepeating(&DeviceScheduledUpdateChecker::GetTicksSinceBoot,
                               base::Unretained(this))) {
   chromeos::system::TimezoneSettings::GetInstance()->AddObserver(this);
@@ -309,8 +308,7 @@
 
   // Following things needs to be done on every update check event. These will
   // be done serially to make state management easier -
-  // - Check for download any updates.
-  // - TODO(crbug.com/924762)  Refresh policies.
+  // - Download updates and refresh policies.
   // - Calculate and start the next update check timer.
   //
   // |os_and_policies_update_checker_| will be destroyed as part of this object,
diff --git a/chrome/browser/chromeos/policy/device_scheduled_update_checker.h b/chrome/browser/chromeos/policy/device_scheduled_update_checker.h
index 1a87f056..12aeee7 100644
--- a/chrome/browser/chromeos/policy/device_scheduled_update_checker.h
+++ b/chrome/browser/chromeos/policy/device_scheduled_update_checker.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/chromeos/policy/task_executor_with_retries.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chromeos/dbus/power/native_timer.h"
+#include "chromeos/network/network_state_handler.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "third_party/icu/source/i18n/unicode/calendar.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
@@ -27,7 +28,9 @@
 class DeviceScheduledUpdateChecker
     : public chromeos::system::TimezoneSettings::Observer {
  public:
-  explicit DeviceScheduledUpdateChecker(chromeos::CrosSettings* cros_settings);
+  DeviceScheduledUpdateChecker(
+      chromeos::CrosSettings* cros_settings,
+      chromeos::NetworkStateHandler* network_state_handler);
   ~DeviceScheduledUpdateChecker() override;
 
   // Frequency at which the update check should occur.
diff --git a/chrome/browser/chromeos/policy/device_scheduled_update_checker_unittest.cc b/chrome/browser/chromeos/policy/device_scheduled_update_checker_unittest.cc
index 4ae97ea..9e71d5b 100644
--- a/chrome/browser/chromeos/policy/device_scheduled_update_checker_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_scheduled_update_checker_unittest.cc
@@ -26,11 +26,16 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_update_engine_client.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
+#include "chromeos/dbus/shill/shill_clients.h"
 #include "chromeos/dbus/update_engine_client.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_test_helper.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "chromeos/tpm/stub_install_attributes.h"
 #include "components/policy/core/common/policy_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
 
 namespace policy {
 
@@ -199,15 +204,23 @@
   return true;
 }
 
+std::string CreateConnectedWifiConfigurationJsonString(
+    const std::string& guid) {
+  return base::StringPrintf(R"({ "GUID": "%s", "Type": "%s", "State": "%s" })",
+                            guid.data(), shill::kTypeWifi, shill::kStateOnline);
+}
+
 }  // namespace
 
 class DeviceScheduledUpdateCheckerForTest
     : public DeviceScheduledUpdateChecker {
  public:
-  DeviceScheduledUpdateCheckerForTest(chromeos::CrosSettings* cros_settings,
-                                      const base::Clock* clock,
-                                      const base::TickClock* tick_clock)
-      : DeviceScheduledUpdateChecker(cros_settings),
+  DeviceScheduledUpdateCheckerForTest(
+      chromeos::CrosSettings* cros_settings,
+      chromeos::NetworkStateHandler* network_state_handler,
+      const base::Clock* clock,
+      const base::TickClock* tick_clock)
+      : DeviceScheduledUpdateChecker(cros_settings, network_state_handler),
         clock_(clock),
         tick_clock_(tick_clock) {
     // Set time zone so that tests are deterministic across different
@@ -300,9 +313,14 @@
     chromeos::FakePowerManagerClient::Get()->set_tick_clock(
         scoped_task_environment_.GetMockTickClock());
 
+    network_state_test_helper_ =
+        std::make_unique<chromeos::NetworkStateTestHelper>(
+            true /* use_default_devices_and_services */);
+
     device_scheduled_update_checker_ =
         std::make_unique<DeviceScheduledUpdateCheckerForTest>(
             chromeos::CrosSettings::Get(),
+            network_state_test_helper_->network_state_handler(),
             scoped_task_environment_.GetMockClock(),
             scoped_task_environment_.GetMockTickClock());
   }
@@ -310,6 +328,8 @@
   ~DeviceScheduledUpdateCheckerTest() override {
     device_scheduled_update_checker_.reset();
     chromeos::PowerManagerClient::Shutdown();
+    chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
+        nullptr);
   }
 
  protected:
@@ -563,6 +583,7 @@
       device_scheduled_update_checker_;
   chromeos::ScopedTestingCrosSettings cros_settings_;
   chromeos::FakeUpdateEngineClient* fake_update_engine_client_;
+  std::unique_ptr<chromeos::NetworkStateTestHelper> network_state_test_helper_;
 
  private:
   chromeos::ScopedStubInstallAttributes test_install_attributes_{
@@ -1030,4 +1051,99 @@
   EXPECT_TRUE(CheckRecalculationOnTimezoneChange(kPSTTimeZoneID));
 }
 
+// Check if no network is present for more than |kWaitForNetworkTimeout|, an
+// update check fails. When the network comes back again, the next update check
+// succeeds.
+TEST_F(DeviceScheduledUpdateCheckerTest, CheckNoNetworkTimeoutScenario) {
+  // Go offline to cause update check failures.
+  network_state_test_helper_->ClearServices();
+
+  // Create and set daily policy starting from one hour from now.
+  base::TimeDelta delay_from_now = base::TimeDelta::FromHours(1);
+  auto policy_and_next_update_check_time = CreatePolicy(
+      delay_from_now, DeviceScheduledUpdateChecker::Frequency::kDaily);
+  cros_settings_.device_settings()->Set(
+      chromeos::kDeviceScheduledUpdateCheck,
+      std::move(policy_and_next_update_check_time.first));
+
+  // Fast forward to right before the expected update and then check if an
+  // update check is not scheduled.
+  const base::TimeDelta small_delay = base::TimeDelta::FromMilliseconds(1);
+  int expected_update_checks = 0;
+  int expected_update_check_requests = 0;
+  int expected_update_check_completions = 0;
+  device_scheduled_update_checker_->GetUpdateCheckCompletions();
+  scoped_task_environment_.FastForwardBy(delay_from_now - small_delay);
+  EXPECT_TRUE(CheckStats(expected_update_checks, expected_update_check_requests,
+                         expected_update_check_completions));
+
+  // Fast forward to the expected update check time + |kMaxNetworkTimeout|. Due
+  // to no network being connected but no update check requests or completions
+  // should happens.
+  expected_update_checks += 1;
+  scoped_task_environment_.FastForwardBy(
+      small_delay + update_checker_internal::kWaitForNetworkTimeout);
+
+  // Go online again. This time the next scheduled update check should complete.
+  network_state_test_helper_->ConfigureService(
+      CreateConnectedWifiConfigurationJsonString("fake-wifi-network"));
+  expected_update_checks += 1;
+  expected_update_check_requests += 1;
+  expected_update_check_completions += 1;
+  scoped_task_environment_.FastForwardBy(
+      base::TimeDelta::FromDays(1) -
+      update_checker_internal::kWaitForNetworkTimeout);
+  // Simulate update check succeeding.
+  NotifyUpdateCheckStatus(chromeos::UpdateEngineClient::UpdateStatusOperation::
+                              UPDATE_STATUS_UPDATED_NEED_REBOOT);
+  EXPECT_TRUE(CheckStats(expected_update_checks, expected_update_check_requests,
+                         expected_update_check_completions));
+}
+
+// Check if no network is present for < than |kWaitForNetworkTimeout|, and then
+// there is a valid network present, update check will succeed.
+TEST_F(DeviceScheduledUpdateCheckerTest, CheckNoNetworkDelayScenario) {
+  // Go offline to cause update check failures.
+  network_state_test_helper_->ClearServices();
+
+  // Create and set daily policy starting from one hour from now.
+  base::TimeDelta delay_from_now = base::TimeDelta::FromHours(1);
+  auto policy_and_next_update_check_time = CreatePolicy(
+      delay_from_now, DeviceScheduledUpdateChecker::Frequency::kDaily);
+  cros_settings_.device_settings()->Set(
+      chromeos::kDeviceScheduledUpdateCheck,
+      std::move(policy_and_next_update_check_time.first));
+
+  // Fast forward to right before the expected update and then check if an
+  // update check is not scheduled.
+  const base::TimeDelta small_delay = base::TimeDelta::FromMilliseconds(1);
+  int expected_update_checks = 0;
+  int expected_update_check_requests = 0;
+  int expected_update_check_completions = 0;
+  device_scheduled_update_checker_->GetUpdateCheckCompletions();
+  scoped_task_environment_.FastForwardBy(delay_from_now - small_delay);
+  EXPECT_TRUE(CheckStats(expected_update_checks, expected_update_check_requests,
+                         expected_update_check_completions));
+
+  // Fast forward to the expected update check time + |kMaxNetworkTimeout| -
+  // |small_delay|. Due to no network being connected no update check requests
+  // or completions should happen.
+  const base::TimeDelta network_not_present_delay =
+      update_checker_internal::kWaitForNetworkTimeout - small_delay;
+  expected_update_checks += 1;
+  scoped_task_environment_.FastForwardBy(small_delay +
+                                         network_not_present_delay);
+
+  // Go online again. The existing update check should complete.
+  network_state_test_helper_->ConfigureService(
+      CreateConnectedWifiConfigurationJsonString("fake-wifi-network"));
+  expected_update_check_requests += 1;
+  expected_update_check_completions += 1;
+  // Simulate update check succeeding.
+  NotifyUpdateCheckStatus(chromeos::UpdateEngineClient::UpdateStatusOperation::
+                              UPDATE_STATUS_UPDATED_NEED_REBOOT);
+  EXPECT_TRUE(CheckStats(expected_update_checks, expected_update_check_requests,
+                         expected_update_check_completions));
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/os_and_policies_update_checker.cc b/chrome/browser/chromeos/policy/os_and_policies_update_checker.cc
index 95f3f24..9fae635 100644
--- a/chrome/browser/chromeos/policy/os_and_policies_update_checker.cc
+++ b/chrome/browser/chromeos/policy/os_and_policies_update_checker.cc
@@ -10,6 +10,8 @@
 #include "chrome/browser/chromeos/policy/task_executor_with_retries.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/update_engine_client.h"
+#include "chromeos/network/network_handler.h"
+#include "components/device_event_log/device_event_log.h"
 #include "components/policy/core/common/policy_service.h"
 
 namespace policy {
@@ -22,22 +24,66 @@
 }  // namespace
 
 OsAndPoliciesUpdateChecker::OsAndPoliciesUpdateChecker(
+    chromeos::NetworkStateHandler* network_state_handler,
     TaskExecutorWithRetries::GetTicksSinceBootFn get_ticks_since_boot_fn)
-    : update_check_task_executor_(
+    : network_state_handler_(network_state_handler),
+      update_check_task_executor_(
           kUpdateCheckTaskExecutorTag,
           std::move(get_ticks_since_boot_fn),
           update_checker_internal::
               kMaxOsAndPoliciesUpdateCheckerRetryIterations,
           update_checker_internal::kOsAndPoliciesUpdateCheckerRetryTime) {}
 
-OsAndPoliciesUpdateChecker::~OsAndPoliciesUpdateChecker() = default;
+OsAndPoliciesUpdateChecker::~OsAndPoliciesUpdateChecker() {
+  // Called to remove any observers.
+  ResetState();
+}
 
 void OsAndPoliciesUpdateChecker::Start(UpdateCheckCompletionCallback cb) {
   // Override any previous calls by resetting state.
   ResetState();
+
   // Must be set before starting the task runner, as callbacks may be called
   // synchronously.
   update_check_completion_cb_ = std::move(cb);
+
+  // If there is no network then wait for a network connection before starting
+  // an update check. If then network isn't found for a maximum time then report
+  // failure. It's safe to use |this| because |wait_for_network_timer_| is a
+  // member of this object.
+  if (!network_state_handler_->DefaultNetwork()) {
+    LOGIN_LOG(EVENT) << "Unable to start update check: no network";
+    wait_for_network_timer_.Start(
+        FROM_HERE, update_checker_internal::kWaitForNetworkTimeout,
+        base::BindOnce(&OsAndPoliciesUpdateChecker::OnUpdateCheckFailure,
+                       base::Unretained(this)));
+    network_state_handler_->AddObserver(this, FROM_HERE);
+    return;
+  }
+
+  ScheduleUpdateCheck();
+}
+
+void OsAndPoliciesUpdateChecker::Stop() {
+  ResetState();
+}
+
+void OsAndPoliciesUpdateChecker::DefaultNetworkChanged(
+    const chromeos::NetworkState* network) {
+  // If a network is found, it's okay to start an update check. Stop observing
+  // for more network changes, any network flakiness will now be handled by
+  // timeouts and retries.
+  // If no network is found, continue observing for network changes.
+  if (network) {
+    wait_for_network_timer_.Stop();
+    // At this point, there is guaranteed to be an observer. This should always
+    // remove it.
+    MaybeRemoveNetworkStateHandlerObserver();
+    ScheduleUpdateCheck();
+  }
+}
+
+void OsAndPoliciesUpdateChecker::ScheduleUpdateCheck() {
   // Safe to use "this" as |update_check_task_executor_| is a member of this
   // class.
   update_check_task_executor_.Start(
@@ -47,10 +93,6 @@
                      base::Unretained(this)));
 }
 
-void OsAndPoliciesUpdateChecker::Stop() {
-  ResetState();
-}
-
 void OsAndPoliciesUpdateChecker::OnUpdateCheckFailure() {
   // Refresh policies after the update check is finished successfully or
   // unsuccessfully.
@@ -72,12 +114,12 @@
 
   // This could be a retry, reset observer state as adding observers is not
   // idempotent.
-  chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(
-      this);
+  MaybeRemoveUpdateEngineClientObserver();
 
   // Register observer to keep track of different stages of the update check.
   chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(
       this);
+
   chromeos::DBusThreadManager::Get()
       ->GetUpdateEngineClient()
       ->RequestUpdateCheck(
@@ -170,10 +212,24 @@
 
 void OsAndPoliciesUpdateChecker::ResetState() {
   weak_factory_.InvalidateWeakPtrs();
-  chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(
-      this);
+  MaybeRemoveUpdateEngineClientObserver();
+  MaybeRemoveNetworkStateHandlerObserver();
   update_check_task_executor_.Stop();
   ignore_idle_status_ = true;
+  wait_for_network_timer_.Stop();
+}
+
+void OsAndPoliciesUpdateChecker::MaybeRemoveUpdateEngineClientObserver() {
+  if (chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->HasObserver(
+          this)) {
+    chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(
+        this);
+  }
+}
+
+void OsAndPoliciesUpdateChecker::MaybeRemoveNetworkStateHandlerObserver() {
+  if (network_state_handler_->HasObserver(this))
+    network_state_handler_->RemoveObserver(this, FROM_HERE);
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/os_and_policies_update_checker.h b/chrome/browser/chromeos/policy/os_and_policies_update_checker.h
index 1bb9718..4916072 100644
--- a/chrome/browser/chromeos/policy/os_and_policies_update_checker.h
+++ b/chrome/browser/chromeos/policy/os_and_policies_update_checker.h
@@ -11,9 +11,12 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "chrome/browser/chromeos/policy/task_executor_with_retries.h"
 #include "chromeos/dbus/power/native_timer.h"
 #include "chromeos/dbus/update_engine_client.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_handler_observer.h"
 
 namespace policy {
 
@@ -28,14 +31,22 @@
 constexpr base::TimeDelta kOsAndPoliciesUpdateCheckerRetryTime =
     base::TimeDelta::FromMinutes(30);
 
+// Time for which |OsAndPoliciesUpdateChecker| will wait for a valid network
+// before querying the update server for updates. After this time it will return
+// a failure.
+constexpr base::TimeDelta kWaitForNetworkTimeout =
+    base::TimeDelta::FromMinutes(1);
+
 }  // namespace update_checker_internal
 
 // This class is used by the scheduled update check policy to perform the actual
 // device update check.
 class OsAndPoliciesUpdateChecker
-    : public chromeos::UpdateEngineClient::Observer {
+    : public chromeos::UpdateEngineClient::Observer,
+      public chromeos::NetworkStateHandlerObserver {
  public:
   OsAndPoliciesUpdateChecker(
+      chromeos::NetworkStateHandler* network_state_handler,
       TaskExecutorWithRetries::GetTicksSinceBootFn get_ticks_since_boot_fn);
   ~OsAndPoliciesUpdateChecker() override;
 
@@ -52,7 +63,13 @@
   // this.
   void Stop();
 
+  // chromeos::NetworkStateHandlerObserver overrides.
+  void DefaultNetworkChanged(const chromeos::NetworkState* network) override;
+
  private:
+  // Schedules update check by using |update_check_task_executor_|.
+  void ScheduleUpdateCheck();
+
   // Runs |update_check_completion_cb_| with |result| and runs |ResetState|.
   void RunCompletionCallbackAndResetState(bool result);
 
@@ -78,6 +95,12 @@
   // Resets all state and cancels any pending update checks.
   void ResetState();
 
+  // If present, removes observer from update engine client.
+  void MaybeRemoveUpdateEngineClientObserver();
+
+  // If present, removes observer from |network_state_handler_|.
+  void MaybeRemoveNetworkStateHandlerObserver();
+
   // Ignore fist IDLE status that is sent when the update check is initiated.
   bool ignore_idle_status_ = true;
 
@@ -85,9 +108,15 @@
   // after retries or when an update check finishes successfully.
   UpdateCheckCompletionCallback update_check_completion_cb_;
 
+  // Not owned.
+  chromeos::NetworkStateHandler* const network_state_handler_;
+
   // Scheduled and retries |StartUpdateCheck|.
   TaskExecutorWithRetries update_check_task_executor_;
 
+  // Timer to wait for a valid network after |Start| is called.
+  base::OneShotTimer wait_for_network_timer_;
+
   base::WeakPtrFactory<OsAndPoliciesUpdateChecker> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(OsAndPoliciesUpdateChecker);
diff --git a/chrome/browser/devtools/protocol/cast_handler.cc b/chrome/browser/devtools/protocol/cast_handler.cc
index a437d4b..bccebb6 100644
--- a/chrome/browser/devtools/protocol/cast_handler.cc
+++ b/chrome/browser/devtools/protocol/cast_handler.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/media_router/media_router_ui_helper.h"
 #include "chrome/common/media_router/media_source.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
 
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index ce30a64..a3db31d 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -862,8 +862,7 @@
       }
 
       if (reason == DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE) {
-        OnDownloadCanceled(
-            download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
+        OnDownloadCanceled(download, true /* has_no_external_storage */);
         callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
         return;
       }
@@ -872,9 +871,7 @@
       // is no way to prompt user for a dialog. This could happen after chrome
       // gets killed, and user tries to resume a download while another app has
       // created the target file (not the temporary .crdownload file).
-      OnDownloadCanceled(
-          download,
-          DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET);
+      OnDownloadCanceled(download, false /* has_no_external_storage */);
       callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
     } else if (reason == DownloadConfirmationReason::TARGET_CONFLICT) {
       // If there is a file that already has the same name, try to generate a
@@ -935,8 +932,7 @@
         return;
 
       case DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE:
-        OnDownloadCanceled(
-            download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
+        OnDownloadCanceled(download, true /* has_no_external_storage */);
         callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
         return;
 
@@ -970,9 +966,7 @@
       // gets killed, and user tries to resume a download while another app has
       // created the target file (not the temporary .crdownload file).
       case DownloadConfirmationReason::UNEXPECTED:
-        OnDownloadCanceled(
-            download,
-            DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET);
+        OnDownloadCanceled(download, false /* has_no_external_storage */);
         callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
         return;
     }
@@ -1063,8 +1057,8 @@
 
 void ChromeDownloadManagerDelegate::OnDownloadCanceled(
     download::DownloadItem* download,
-    DownloadController::DownloadCancelReason reason) {
-  DownloadManagerService::OnDownloadCanceled(download, reason);
+    bool has_no_external_storage) {
+  DownloadManagerService::OnDownloadCanceled(download, has_no_external_storage);
 }
 #endif  // defined(OS_ANDROID)
 
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index c5b7b53..fdbfe4aa 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -33,7 +33,6 @@
 #include "ui/gfx/native_widget_types.h"
 
 #if defined(OS_ANDROID)
-#include "chrome/browser/android/download/download_controller.h"
 #include "chrome/browser/android/download/download_location_dialog_bridge.h"
 #endif
 
@@ -172,9 +171,8 @@
                        const GetFileMimeTypeCallback& callback) override;
 
 #if defined(OS_ANDROID)
-  virtual void OnDownloadCanceled(
-      download::DownloadItem* download,
-      DownloadController::DownloadCancelReason reason);
+  virtual void OnDownloadCanceled(download::DownloadItem* download,
+                                  bool has_no_external_storage);
 #endif
 
   // Called when the file picker returns the confirmation result.
diff --git a/chrome/browser/download/chrome_download_manager_delegate_unittest.cc b/chrome/browser/download/chrome_download_manager_delegate_unittest.cc
index b0984b50..cc4e914 100644
--- a/chrome/browser/download/chrome_download_manager_delegate_unittest.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate_unittest.cc
@@ -180,9 +180,8 @@
   }
 
 #if defined(OS_ANDROID)
-  void OnDownloadCanceled(
-      download::DownloadItem* download,
-      DownloadController::DownloadCancelReason reason) override {}
+  void OnDownloadCanceled(download::DownloadItem* download,
+                          bool has_no_external_storage) override {}
 #endif
 
   MOCK_METHOD5(
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index 2575f45..ec08b6cc 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -4165,7 +4165,7 @@
 
 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
 // Also flaky on Linux. http://crbug.com/700382
-// Also flaky on Mac ASAN with PlzNavigate.
+// Also flaky on Mac ASAN.
 // Test download interruption while extensions determining filename. Should not
 // re-dispatch onDeterminingFilename.
 IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.h b/chrome/browser/extensions/api/streams_private/streams_private_api.h
index 5506ae5e9..01197a0 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_api.h
+++ b/chrome/browser/extensions/api/streams_private/streams_private_api.h
@@ -20,12 +20,11 @@
   // Send the onExecuteMimeTypeHandler event to |extension_id|. If the viewer is
   // being opened in a BrowserPlugin, specify a non-empty |view_id| of the
   // plugin. |embedded| should be set to whether the document is embedded
-  // within another document. The |frame_tree_node_id| parameter is used for
-  // PlzNavigate for the top level plugins case. (PDF, etc). If this parameter
-  // has a valid value then it overrides the |render_process_id| and
-  // |render_frame_id| parameters. The |render_process_id| is the id of the
-  // renderer process. The |render_frame_id| is the routing id of the
-  // RenderFrameHost.
+  // within another document. The |frame_tree_node_id| parameter is used for the
+  // top level plugins case. (PDF, etc). If this parameter has a valid value
+  // then it overrides the |render_process_id| and |render_frame_id| parameters.
+  // The |render_process_id| is the id of the renderer process. The
+  // |render_frame_id| is the routing id of the RenderFrameHost.
   //
   // If the network service is not enabled, |stream| is used; otherwise,
   // |transferrable_loader| and |original_url| are used instead.
diff --git a/chrome/browser/extensions/extension_navigation_throttle_unittest.cc b/chrome/browser/extensions/extension_navigation_throttle_unittest.cc
index 86aa59f..e9e37ae 100644
--- a/chrome/browser/extensions/extension_navigation_throttle_unittest.cc
+++ b/chrome/browser/extensions/extension_navigation_throttle_unittest.cc
@@ -86,9 +86,9 @@
     GURL http_url("https://example.com");
     test_handle.set_url(http_url);
 
-    // TODO(nick): https://crbug.com/695421 Once PlzNavigate is enabled 100%, it
-    // should be possible to support return values other than PROCEED and CANCEL
-    // from ExtensionNavigationThrottle::WillRedirectRequest.
+    // TODO(nick): https://crbug.com/695421 It should be possible to support
+    // return values other than PROCEED and CANCEL from
+    // ExtensionNavigationThrottle::WillRedirectRequest.
     NavigationThrottle::ThrottleAction expected_will_redirect_result =
         (expected_will_start_result == NavigationThrottle::PROCEED)
             ? NavigationThrottle::PROCEED
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn
index 29707ed..cdc6e272 100644
--- a/chrome/browser/media/router/BUILD.gn
+++ b/chrome/browser/media/router/BUILD.gn
@@ -25,7 +25,7 @@
   ]
   public_deps = [
     "//chrome/common/media_router:router",
-    "//chrome/common/media_router/mojo:media_router",
+    "//chrome/common/media_router/mojom:media_router",
   ]
   sources = [
     "issue_manager.cc",
@@ -191,8 +191,8 @@
   if (enable_extensions) {
     deps += [
       "discovery",
-      "//chrome/common/media_router/mojo:media_router",
-      "//chrome/common/media_router/mojo:media_router_test_interfaces",
+      "//chrome/common/media_router/mojom:media_router",
+      "//chrome/common/media_router/mojom:media_router_test_interfaces",
       "//extensions/browser",
       "//extensions/common",
     ]
diff --git a/chrome/browser/media/router/media_router.h b/chrome/browser/media/router/media_router.h
index ec1e174f..50d954a 100644
--- a/chrome/browser/media/router/media_router.h
+++ b/chrome/browser/media/router/media_router.h
@@ -20,7 +20,7 @@
 #include "chrome/common/media_router/media_route.h"
 #include "chrome/common/media_router/media_sink.h"
 #include "chrome/common/media_router/media_source.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/sessions/core/session_id.h"
 #include "content/public/browser/presentation_service_delegate.h"
diff --git a/chrome/browser/media/router/media_router_dialog_controller.h b/chrome/browser/media/router/media_router_dialog_controller.h
index 8b0266c..0bc8cdd 100644
--- a/chrome/browser/media/router/media_router_dialog_controller.h
+++ b/chrome/browser/media/router/media_router_dialog_controller.h
@@ -10,7 +10,7 @@
 
 #include "base/macros.h"
 #include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "content/public/browser/presentation_request.h"
 #include "content/public/browser/presentation_service_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
diff --git a/chrome/browser/media/router/mojo/media_route_controller.h b/chrome/browser/media/router/mojo/media_route_controller.h
index d956875..8ce9c8b 100644
--- a/chrome/browser/media/router/mojo/media_route_controller.h
+++ b/chrome/browser/media/router/mojo/media_route_controller.h
@@ -11,8 +11,8 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "chrome/common/media_router/media_route.h"
-#include "chrome/common/media_router/mojo/media_controller.mojom.h"
-#include "chrome/common/media_router/mojo/media_status.mojom.h"
+#include "chrome/common/media_router/mojom/media_controller.mojom.h"
+#include "chrome/common/media_router/mojom/media_status.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 class PrefService;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.h b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
index 9f56e22..ffdd121 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.h
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
@@ -24,7 +24,7 @@
 #include "chrome/browser/media/router/media_router_base.h"
 #include "chrome/browser/media/router/media_routes_observer.h"
 #include "chrome/common/media_router/issue.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/route_request_result.h"
 #include "content/public/browser/browser_thread.h"
 #include "mojo/public/cpp/bindings/binding.h"
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
index 4ccd3905..e9cd3a7d6 100644
--- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
@@ -20,7 +20,7 @@
 #include "chrome/browser/media/router/media_router.h"
 #include "chrome/browser/media/router/presentation/presentation_service_delegate_observers.h"
 #include "chrome/common/media_router/media_source.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "content/public/browser/presentation_request.h"
 #include "content/public/browser/presentation_service_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
diff --git a/chrome/browser/media/router/providers/cast/activity_record.h b/chrome/browser/media/router/providers/cast/activity_record.h
index cb8031c7..45760b4c 100644
--- a/chrome/browser/media/router/providers/cast/activity_record.h
+++ b/chrome/browser/media/router/providers/cast/activity_record.h
@@ -15,7 +15,7 @@
 #include "chrome/browser/media/router/providers/cast/cast_session_tracker.h"
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
 #include "chrome/common/media_router/media_route.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/providers/cast/cast_media_source.h"
 
 namespace cast_channel {
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
index efd6469..b0d90b0 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/media/router/providers/cast/cast_session_client.h"
 #include "chrome/browser/media/router/providers/cast/mirroring_activity_record.h"
 #include "chrome/common/media_router/media_source.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "url/origin.h"
 
 using blink::mojom::PresentationConnectionCloseReason;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.h b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
index 230d23b..d73b414 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager.h
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
@@ -19,7 +19,7 @@
 #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h"
 #include "chrome/browser/media/router/providers/cast/cast_session_tracker.h"
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/providers/cast/cast_media_source.h"
 #include "url/origin.h"
 
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_record.h b/chrome/browser/media/router/providers/cast/cast_activity_record.h
index ceed9f2..3d91e0e6 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_record.h
+++ b/chrome/browser/media/router/providers/cast/cast_activity_record.h
@@ -11,7 +11,7 @@
 #include "base/containers/flat_map.h"
 #include "base/optional.h"
 #include "chrome/browser/media/router/providers/cast/activity_record.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/providers/cast/cast_media_source.h"
 #include "components/cast_channel/cast_message_handler.h"
 
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
index 4f84842..2953c56 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/media/router/data_decoder_util.h"
 #include "chrome/browser/media/router/providers/cast/cast_activity_manager.h"
 #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/providers/cast/cast_media_source.h"
 #include "components/cast_channel/cast_message_handler.h"
 #include "url/origin.h"
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
index 14d594c..357ffc1 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "chrome/browser/media/router/providers/cast/cast_app_discovery_service.h"
 #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace cast_channel {
diff --git a/chrome/browser/media/router/providers/cast/cast_session_client.h b/chrome/browser/media/router/providers/cast/cast_session_client.h
index 8d37a4e..0f004e2e 100644
--- a/chrome/browser/media/router/providers/cast/cast_session_client.h
+++ b/chrome/browser/media/router/providers/cast/cast_session_client.h
@@ -14,7 +14,7 @@
 #include "base/optional.h"
 #include "base/values.h"
 #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/providers/cast/cast_media_source.h"
 #include "components/cast_channel/cast_message_handler.h"
 #include "mojo/public/cpp/bindings/binding.h"
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc
index e96d74e..6cf7042b 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/media/router/data_decoder_util.h"
 #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h"
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/route_request_result.h"
 #include "components/cast_channel/cast_message_util.h"
 #include "components/cast_channel/cast_socket.h"
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h
index 6f560c29..5d8af993 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h
@@ -12,7 +12,7 @@
 #include "chrome/browser/media/router/providers/cast/activity_record.h"
 #include "chrome/browser/media/router/providers/cast/cast_session_tracker.h"
 #include "chrome/common/media_router/media_route.h"
-#include "chrome/common/media_router/mojo/media_router.mojom-forward.h"
+#include "chrome/common/media_router/mojom/media_router.mojom-forward.h"
 #include "components/cast_channel/cast_message_handler.h"
 #include "components/mirroring/mojom/cast_message_channel.mojom.h"
 #include "components/mirroring/mojom/mirroring_service_host.mojom.h"
diff --git a/chrome/browser/media/router/providers/common/buffered_message_sender.h b/chrome/browser/media/router/providers/common/buffered_message_sender.h
index e37dfa58..0218f5e 100644
--- a/chrome/browser/media/router/providers/common/buffered_message_sender.h
+++ b/chrome/browser/media/router/providers/common/buffered_message_sender.h
@@ -11,7 +11,7 @@
 #include "base/containers/flat_set.h"
 #include "base/macros.h"
 #include "chrome/common/media_router/media_route.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 
 namespace media_router {
 
diff --git a/chrome/browser/media/router/providers/dial/dial_activity_manager.h b/chrome/browser/media/router/providers/dial/dial_activity_manager.h
index 1349c1d..0bed4db 100644
--- a/chrome/browser/media/router/providers/dial/dial_activity_manager.h
+++ b/chrome/browser/media/router/providers/dial/dial_activity_manager.h
@@ -14,7 +14,7 @@
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
 #include "chrome/common/media_router/media_route.h"
 #include "chrome/common/media_router/media_source.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/route_request_result.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/media/router/providers/dial/dial_internal_message_util.h b/chrome/browser/media/router/providers/dial/dial_internal_message_util.h
index 161eb68..6b75a41 100644
--- a/chrome/browser/media/router/providers/dial/dial_internal_message_util.h
+++ b/chrome/browser/media/router/providers/dial/dial_internal_message_util.h
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/values.h"
 #include "chrome/browser/media/router/discovery/dial/parsed_dial_app_info.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 
 namespace media_router {
 
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
index 389dc03..54728df 100644
--- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
+++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
@@ -19,7 +19,7 @@
 #include "chrome/browser/media/router/providers/common/buffered_message_sender.h"
 #include "chrome/browser/media/router/providers/dial/dial_activity_manager.h"
 #include "chrome/browser/media/router/providers/dial/dial_internal_message_util.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace url {
diff --git a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
index b0048e4..4d48929 100644
--- a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
+++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_EXTENSION_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
 
 #include "base/memory/weak_ptr.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace content {
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
index a85e187..a322711f0 100644
--- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
@@ -18,7 +18,7 @@
 #include "chrome/browser/media/router/providers/wired_display/wired_display_presentation_receiver.h"
 #include "chrome/common/media_router/media_route_provider_helper.h"
 #include "chrome/common/media_router/media_status.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/display/display.h"
 #include "ui/display/display_observer.h"
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
index 1b43d8c..062ab7f 100644
--- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/media/router/providers/wired_display/wired_display_presentation_receiver_factory.h"
 #include "chrome/browser/media/router/test/media_router_mojo_test.h"
 #include "chrome/browser/media/router/test/mock_mojo_media_router.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/route_message_observer.h b/chrome/browser/media/router/route_message_observer.h
index 3a9448b..f5193751 100644
--- a/chrome/browser/media/router/route_message_observer.h
+++ b/chrome/browser/media/router/route_message_observer.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "chrome/common/media_router/media_route.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 
 namespace media_router {
 
diff --git a/chrome/browser/media/router/route_message_util.h b/chrome/browser/media/router/route_message_util.h
index ecdfb3f6..ed681e11 100644
--- a/chrome/browser/media/router/route_message_util.h
+++ b/chrome/browser/media/router/route_message_util.h
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "third_party/blink/public/mojom/presentation/presentation.mojom.h"
 
 namespace media_router {
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.h b/chrome/browser/media/router/test/media_router_mojo_test.h
index 44718923..b6ac450 100644
--- a/chrome/browser/media/router/test/media_router_mojo_test.h
+++ b/chrome/browser/media/router/test/media_router_mojo_test.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
 #include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/browser/media/router/test/test_helper.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "extensions/browser/event_page_tracker.h"
diff --git a/chrome/browser/media/router/test/mock_mojo_media_router.h b/chrome/browser/media/router/test/mock_mojo_media_router.h
index 8499e5f1..0391a30 100644
--- a/chrome/browser/media/router/test/mock_mojo_media_router.h
+++ b/chrome/browser/media/router/test/mock_mojo_media_router.h
@@ -7,7 +7,7 @@
 
 #include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/common/media_router/media_route_provider_helper.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace media_router {
diff --git a/chrome/browser/media/unified_autoplay_browsertest.cc b/chrome/browser/media/unified_autoplay_browsertest.cc
index 893b99b..b391ecb 100644
--- a/chrome/browser/media/unified_autoplay_browsertest.cc
+++ b/chrome/browser/media/unified_autoplay_browsertest.cc
@@ -283,7 +283,7 @@
   const GURL kTestPageUrl = embedded_test_server()->GetURL(kTestPagePath);
 
   NavigateParams params(browser(), kTestPageUrl, ui::PAGE_TRANSITION_LINK);
-  params.was_activated = content::WasActivatedOption::kYes;
+  params.was_activated = content::mojom::WasActivatedOption::kYes;
   ui_test_utils::NavigateToURL(&params);
 
   EXPECT_TRUE(AttemptPlay(GetWebContents()));
@@ -296,7 +296,7 @@
   const GURL kTestPageUrl = embedded_test_server()->GetURL(kTestPagePath);
 
   NavigateParams params(browser(), kRedirectPageUrl, ui::PAGE_TRANSITION_LINK);
-  params.was_activated = content::WasActivatedOption::kYes;
+  params.was_activated = content::mojom::WasActivatedOption::kYes;
   ui_test_utils::NavigateToURL(&params);
 
   EXPECT_TRUE(NavigateInRenderer(GetWebContents(), kTestPageUrl));
@@ -326,7 +326,7 @@
       embedded_test_server()->GetURL("foo.example.com", kTestPagePath);
 
   NavigateParams params(browser(), kRedirectPageUrl, ui::PAGE_TRANSITION_LINK);
-  params.was_activated = content::WasActivatedOption::kYes;
+  params.was_activated = content::mojom::WasActivatedOption::kYes;
   ui_test_utils::NavigateToURL(&params);
 
   EXPECT_TRUE(NavigateInRenderer(GetWebContents(), kTestPageUrl));
diff --git a/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
index 861ee79f..3aa1f0f 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
@@ -32,7 +32,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
-#include "content/public/browser/resource_request_info.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_system.h"
 #include "net/url_request/url_request.h"
@@ -205,18 +204,8 @@
                         base::CompareCase::SENSITIVE))
     return false;
 
-  content::WebContents::Getter web_contents_getter;
-  if (request_info.content_id) {
-    web_contents_getter = base::BindRepeating(
-        &GetWebContentsFromFrameTreeNodeID, request_info.content_id);
-  } else {
-    content::ResourceRequestInfo* resource_request_info =
-        content::ResourceRequestInfo::ForRequest(request_info.request);
-    if (!resource_request_info)
-      return false;
-    web_contents_getter =
-        resource_request_info->GetWebContentsGetterForRequest();
-  }
+  content::WebContents::Getter web_contents_getter = base::BindRepeating(
+      &GetWebContentsFromFrameTreeNodeID, request_info.content_id);
 
   base::PostTaskWithTraits(
       FROM_HERE, {content::BrowserThread::UI},
diff --git a/chrome/browser/net/network_request_metrics_browsertest.cc b/chrome/browser/net/network_request_metrics_browsertest.cc
index d2ff138..5b112c8 100644
--- a/chrome/browser/net/network_request_metrics_browsertest.cc
+++ b/chrome/browser/net/network_request_metrics_browsertest.cc
@@ -356,8 +356,8 @@
 };
 
 // Testing before headers / during body is most interesting in the frame case,
-// as it checks the before and after commit case, which with browser-side
-// navigations / PlzNavigate, follow very different paths.
+// as it checks the before and after commit case, which follow very different
+// paths.
 IN_PROC_BROWSER_TEST_P(NetworkRequestMetricsBrowserTest,
                        NetErrorBeforeHeaders) {
   TestNavigationObserver navigation_observer(active_web_contents(), 1);
diff --git a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
index befb4bd..1c92432b 100644
--- a/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
+++ b/chrome/browser/offline_pages/android/downloads/offline_page_download_bridge.cc
@@ -257,7 +257,7 @@
 
 content::WebContents::Getter GetWebContentsGetter(
     content::WebContents* web_contents) {
-  // PlzNavigate: The FrameTreeNode ID should be used to access the WebContents.
+  // The FrameTreeNode ID should be used to access the WebContents.
   int frame_tree_node_id = web_contents->GetMainFrame()->GetFrameTreeNodeId();
   if (frame_tree_node_id != -1) {
     return base::Bind(content::WebContents::FromFrameTreeNodeId,
diff --git a/chrome/browser/offline_pages/offline_page_utils.cc b/chrome/browser/offline_pages/offline_page_utils.cc
index 29742f0f..9ac53ed 100644
--- a/chrome/browser/offline_pages/offline_page_utils.cc
+++ b/chrome/browser/offline_pages/offline_page_utils.cc
@@ -130,7 +130,7 @@
 
 content::WebContents::Getter GetWebContentsGetter(
     content::WebContents* web_contents) {
-  // PlzNavigate: The FrameTreeNode ID should be used to access the WebContents.
+  // The FrameTreeNode ID should be used to access the WebContents.
   int frame_tree_node_id = web_contents->GetMainFrame()->GetFrameTreeNodeId();
   if (frame_tree_node_id != -1) {
     return base::Bind(content::WebContents::FromFrameTreeNodeId,
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
index 787788a..a28f8567 100644
--- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
+++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
@@ -477,9 +477,8 @@
   const net::Error error = navigation_handle->GetNetErrorCode();
 
   // net::OK: This case occurs when the NavigationHandle finishes and reports
-  // !HasCommitted(), but reports no net::Error. This should not occur
-  // pre-PlzNavigate, but afterwards it should represent the navigation stopped
-  // by the user before it was ready to commit.
+  // !HasCommitted(), but reports no net::Error. This represents the navigation
+  // being stopped by the user before it was ready to commit.
   // net::ERR_ABORTED: An aborted provisional load has error net::ERR_ABORTED.
   const bool is_aborted_provisional_load =
       error == net::OK || error == net::ERR_ABORTED;
diff --git a/chrome/browser/performance_monitor/process_metrics_history.cc b/chrome/browser/performance_monitor/process_metrics_history.cc
index dd25eeb..b259bc6 100644
--- a/chrome/browser/performance_monitor/process_metrics_history.cc
+++ b/chrome/browser/performance_monitor/process_metrics_history.cc
@@ -52,6 +52,7 @@
 #endif
 #if defined(OS_MACOSX)
   package_idle_wakeups_ = process_metrics_->GetPackageIdleWakeupsPerSecond();
+  energy_impact_ = process_metrics_->GetEnergyImpact();
 #endif
 }
 
@@ -95,6 +96,9 @@
       UMA_HISTOGRAM_COUNTS_1000(
           "PerformanceMonitor.PackageExitIdleWakeups.BrowserProcess",
           package_idle_wakeups_);
+      UMA_HISTOGRAM_COUNTS_100000(
+          "PerformanceMonitor.EnergyImpact.BrowserProcess", energy_impact_);
+
 #endif
       break;
     case content::PROCESS_TYPE_RENDERER:
@@ -113,6 +117,9 @@
       UMA_HISTOGRAM_COUNTS_1000(
           "PerformanceMonitor.PackageExitIdleWakeups.RendererProcess",
           package_idle_wakeups_);
+      UMA_HISTOGRAM_COUNTS_100000(
+          "PerformanceMonitor.EnergyImpact.RendererProcess", energy_impact_);
+
 #endif
 
       break;
@@ -130,6 +137,9 @@
       UMA_HISTOGRAM_COUNTS_1000(
           "PerformanceMonitor.PackageExitIdleWakeups.GPUProcess",
           package_idle_wakeups_);
+      UMA_HISTOGRAM_COUNTS_100000("PerformanceMonitor.EnergyImpact.GPUProcess",
+                                  energy_impact_);
+
 #endif
 
       break;
diff --git a/chrome/browser/performance_monitor/process_metrics_history.h b/chrome/browser/performance_monitor/process_metrics_history.h
index e36e124..b5bb6e1 100644
--- a/chrome/browser/performance_monitor/process_metrics_history.h
+++ b/chrome/browser/performance_monitor/process_metrics_history.h
@@ -77,6 +77,7 @@
 #endif
 #if defined(OS_MACOSX)
   int package_idle_wakeups_ = 0;
+  double energy_impact_ = 0.0;
 #endif
 
   DISALLOW_ASSIGN(ProcessMetricsHistory);
diff --git a/chrome/browser/policy/e2e_test/tests/__init__.py b/chrome/browser/policy/e2e_test/tests/__init__.py
index 4194621..db8f8df 100644
--- a/chrome/browser/policy/e2e_test/tests/__init__.py
+++ b/chrome/browser/policy/e2e_test/tests/__init__.py
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 from apps_shortcut.apps_shortcut import *
+from default_search_provider.default_search_provider import *
 from force_google_safe_search.force_google_safe_search import *
 from homepage.homepage import *
 from restore_on_startup.restore_on_startup import *
@@ -14,6 +15,7 @@
 from extension_forcelist.extension_forcelist import *
 from extension_whitelist.extension_whitelist import *
 from bookmarkbar_enabled.bookmarkbar_enabled import *
+from user_data_dir.user_data_dir import *
 # TODO(mbinette): Fix TranslateEnabledTest on LUCI bots.
 # from translate_enabled.translate_enabled import *
 from youtube_restrict.youtube_restrict import *
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/default_search_provider/__init__.py
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py
new file mode 100644
index 0000000..c436b30b
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider.py
@@ -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.
+
+import os
+from chrome_ent_test.ent_tests import ChromeEnterpriseTestCase
+from chrome_ent_test.infra.core import environment, before_all, test
+
+
+@environment(file="../policy_test.asset.textpb")
+class DefaultSearchProviderTest(ChromeEnterpriseTestCase):
+  """Test the DefaultSearchProviderEnabled,
+              DefaultSearchProviderName,
+              DefaultSearchProviderSearchURL
+
+    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderEnabled
+    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderName
+    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=DefaultSearchProviderSearchURL
+
+    """
+
+  @before_all
+  def setup(self):
+    self.InstallChrome('client2012')
+    self.EnableUITest('client2012')
+
+  def _get_search_url(self, instance_name):
+    local_dir = os.path.dirname(os.path.abspath(__file__))
+    output = self.RunUITest(
+        instance_name,
+        os.path.join(local_dir, 'default_search_provider_webdriver.py'))
+    return output
+
+  @test
+  def test_default_search_provider_bing(self):
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 1, 'DWORD')
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderName', 'Bing', 'String')
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderSearchURL',
+                   '"https://www.bing.com/search?q={searchTerms}"', 'String')
+    self.RunCommand('client2012', 'gpupdate /force')
+
+    output = self._get_search_url('client2012')
+    self.assertIn('www.bing.com', output)
+
+  @test
+  def test_default_search_provider_yahoo(self):
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 1, 'DWORD')
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderName', 'Yahoo', 'String')
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderSearchURL',
+                   '"https://search.yahoo.com/search?p={searchTerms}"',
+                   'String')
+    self.RunCommand('client2012', 'gpupdate /force')
+
+    output = self._get_search_url('client2012')
+    self.assertIn('search.yahoo.com', output)
+
+  @test
+  def test_default_search_provider_disabled(self):
+    self.SetPolicy('win2012-dc', 'DefaultSearchProviderEnabled', 0, 'DWORD')
+    self.RunCommand('client2012', 'gpupdate /force')
+
+    output = self._get_search_url('client2012')
+    self.assertIn('http://anything', output)
diff --git a/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py
new file mode 100644
index 0000000..aa0bbda
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/default_search_provider/default_search_provider_webdriver.py
@@ -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.
+
+from selenium import webdriver
+from pywinauto.application import Application
+import os
+
+# Set up ChromeDriver
+options = webdriver.ChromeOptions()
+options.add_argument("--force-renderer-accessibility")
+
+os.environ["CHROME_LOG_FILE"] = r"c:\temp\chrome_log.txt"
+
+driver = webdriver.Chrome(
+    "C:/ProgramData/chocolatey/lib/chromedriver/tools/chromedriver.exe",
+    chrome_options=options,
+    service_args=["--verbose", r"--log-path=c:\temp\chromedriver.log"])
+
+try:
+  app = Application(backend="uia")
+  app.connect(title_re='.*Chrome|.*Chromium')
+  omnibox = app.top_window() \
+            .child_window(title="Address and search bar", control_type="Edit")
+  omnibox.set_edit_text('anything').type_keys('{ENTER}')
+  print driver.current_url
+except Exception as error:
+  print error
+finally:
+  driver.quit()
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/user_data_dir/__init__.py
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py
new file mode 100644
index 0000000..6cdc1dc4
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir.py
@@ -0,0 +1,46 @@
+# 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 logging
+import os
+
+from chrome_ent_test.ent_tests import ChromeEnterpriseTestCase
+from chrome_ent_test.infra.core import environment, before_all, test
+
+
+@environment(file="../policy_test.asset.textpb")
+class UserDataDirTest(ChromeEnterpriseTestCase):
+  """Test the UserDataDir
+
+    https://cloud.google.com/docs/chrome-enterprise/policies/?policy=UserDataDir.
+
+    """
+
+  @before_all
+  def setup(self):
+    self.InstallChrome('client2012')
+    self.InstallWebDriver('client2012')
+
+  @test
+  def test_user_data_dir(self):
+    user_data_dir = r'C:\Temp\Browser\Google\Chrome\UserData'
+    self.SetPolicy('win2012-dc', r'UserDataDir', user_data_dir, 'String')
+    self.RunCommand('client2012', 'gpupdate /force')
+    logging.info('Updated User data dir to: ' + user_data_dir)
+
+    local_dir = os.path.dirname(os.path.abspath(__file__))
+    args = ['--user_data_dir', user_data_dir]
+    output = self.RunWebDriverTest(
+        'client2012', os.path.join(local_dir, 'user_data_dir_webdriver.py'),
+        args)
+
+    # Verify user data dir not exsiting before chrome launch
+    self.assertIn('User data before running chrome is False', output)
+    # Verify policy in chrome://policy page
+    self.assertIn('UserDataDir', output)
+    self.assertIn(user_data_dir, output)
+    # Verify profile path in chrome:// version
+    self.assertIn("Profile path is " + user_data_dir, output)
+    # Verify user data dir folder creation
+    self.assertIn('User data dir creation is True', output)
diff --git a/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py
new file mode 100644
index 0000000..756b27a
--- /dev/null
+++ b/chrome/browser/policy/e2e_test/tests/user_data_dir/user_data_dir_webdriver.py
@@ -0,0 +1,54 @@
+# 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.
+
+from selenium import webdriver
+import os
+from absl import app, flags
+
+FLAGS = flags.FLAGS
+flags.DEFINE_string('user_data_dir', None, 'Need specify user data dir to test')
+flags.mark_flag_as_required('user_data_dir')
+
+
+def main(argv):
+  policy_url = "chrome://policy"
+  version_url = "chrome://version"
+
+  # Verify the user data dir is not exsiting before launch the Chrome
+  print "User data before running chrome is " + str(
+      os.path.isdir(FLAGS.user_data_dir))
+
+  # Launch real Chrome
+  os.system('start chrome --remote-debugging-port=9222')
+
+  options = webdriver.ChromeOptions()
+  # Add option for connecting chromedriver with Chrome
+  options.add_experimental_option("debuggerAddress", "localhost:9222")
+  os.environ["CHROME_LOG_FILE"] = r"c:\temp\chrome_log.txt"
+
+  driver = webdriver.Chrome(
+      "C:/ProgramData/chocolatey/lib/chromedriver/tools/chromedriver.exe",
+      chrome_options=options,
+      service_args=["--verbose", r"--log-path=c:\temp\chromedriver.log"])
+
+  try:
+    # Verify User Data Dir in chrome://policy page
+    driver.get(policy_url)
+    print driver.find_element_by_css_selector('html').text.encode('utf-8')
+
+    # Verfiy User Data Dir used in chrome://version
+    driver.get(version_url)
+    print "Profile path is " + driver.find_element_by_id("profile_path").text
+
+    # Verify if UserDataDir folder is created
+    print "User data dir creation is " + str(os.path.isdir(FLAGS.user_data_dir))
+  except Exception as error:
+    print error
+  finally:
+    driver.quit()
+    os.system('taskkill /f /im chrome.exe')
+
+
+if __name__ == '__main__':
+  app.run(main)
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 456ae85..162772a 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -3634,9 +3634,8 @@
   // Verify that the window is not in fullscreen mode.
   EXPECT_FALSE(window->GetBaseWindow()->IsFullscreen());
 
-  // For PlzNavigate case, we have to wait for the navigation to commit since
-  // the JS object registration is delayed (see
-  // AppWindowCreateFunction::RunAsync).
+  // We have to wait for the navigation to commit since the JS object
+  // registration is delayed (see AppWindowCreateFunction::RunAsync).
   content::WaitForLoadStop(window->web_contents());
 
   // Verify that the window cannot be toggled into fullscreen mode via apps
diff --git a/chrome/browser/predictors/loading_predictor.cc b/chrome/browser/predictors/loading_predictor.cc
index 706044d..0c97c6d 100644
--- a/chrome/browser/predictors/loading_predictor.cc
+++ b/chrome/browser/predictors/loading_predictor.cc
@@ -13,6 +13,8 @@
 #include "chrome/browser/predictors/navigation_id.h"
 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/base/network_isolation_key.h"
+#include "url/origin.h"
 
 namespace predictors {
 
@@ -39,8 +41,10 @@
         std::max(prediction->requests.front().num_sockets, kMinSockets);
   } else if (initial_origin.is_valid() &&
              initial_origin.SchemeIsHTTPOrHTTPS()) {
+    url::Origin origin = url::Origin::Create(initial_origin);
     prediction->requests.emplace(prediction->requests.begin(), initial_origin,
-                                 kMinSockets);
+                                 kMinSockets,
+                                 net::NetworkIsolationKey(origin, origin));
   }
 
   return !prediction->requests.empty();
@@ -231,7 +235,10 @@
     if (is_new_origin || now - last_omnibox_preconnect_time_ >=
                              kMinDelayBetweenPreconnectRequests) {
       last_omnibox_preconnect_time_ = now;
-      preconnect_manager()->StartPreconnectUrl(url, true);
+      // Not to be confused with |origin|.
+      url::Origin url_origin = url::Origin::Create(url);
+      preconnect_manager()->StartPreconnectUrl(
+          url, true, net::NetworkIsolationKey(url_origin, url_origin));
     }
     return;
   }
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc
index 65d3e4d8..a1c33559 100644
--- a/chrome/browser/predictors/loading_predictor_browsertest.cc
+++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/browser_features.h"
 #include "chrome/browser/predictors/loading_predictor.h"
@@ -28,6 +29,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/page_navigator.h"
@@ -36,16 +38,24 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/referrer.h"
 #include "content/public/test/browser_test_utils.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
 #include "net/base/features.h"
+#include "net/base/network_isolation_key.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
 #include "net/test/embedded_test_server/request_handler_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request_filter.h"
 #include "net/url_request/url_request_interceptor.h"
 #include "net/url_request/url_request_test_job.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 using content::BrowserThread;
 
@@ -384,6 +394,8 @@
 
   void SetUp() override {
     ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+        &LoadingPredictorBrowserTest::HandleFaviconRequest));
     InProcessBrowserTest::SetUp();
   }
 
@@ -462,12 +474,25 @@
 
   ConnectionTracker* connection_tracker() { return connection_tracker_.get(); }
 
+  static std::unique_ptr<net::test_server::HttpResponse> HandleFaviconRequest(
+      const net::test_server::HttpRequest& request) {
+    if (request.relative_url != "/favicon.ico")
+      return std::unique_ptr<net::test_server::HttpResponse>();
+
+    auto http_response =
+        std::make_unique<net::test_server::BasicHttpResponse>();
+    http_response->set_code(net::HTTP_OK);
+    http_response->AddCustomHeader("Cache-Control", "max-age=6000");
+    return http_response;
+  }
+
  private:
   LoadingPredictor* loading_predictor_ = nullptr;
   std::unique_ptr<ConnectionListener> connection_listener_;
   std::unique_ptr<ConnectionTracker> connection_tracker_;
   std::unique_ptr<TestPreconnectManagerObserver> preconnect_manager_observer_;
   base::test::ScopedFeatureList scoped_feature_list_;
+
   DISALLOW_COPY_AND_ASSIGN(LoadingPredictorBrowserTest);
 };
 
@@ -595,9 +620,12 @@
   GURL url = embedded_test_server()->GetURL(
       "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath,
                                              embedded_test_server()->port()));
+  url::Origin origin = url::Origin::Create(url);
   std::vector<PreconnectRequest> requests;
-  for (auto* const host : kHtmlSubresourcesHosts)
-    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1);
+  for (auto* const host : kHtmlSubresourcesHosts) {
+    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1,
+                          net::NetworkIsolationKey(origin, origin));
+  }
 
   ui_test_utils::NavigateToURL(browser(), url);
   auto prediction = GetPreconnectPrediction(url);
@@ -620,14 +648,18 @@
   GURL url = embedded_test_server()->GetURL(
       "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath,
                                              embedded_test_server()->port()));
+  url::Origin origin = url::Origin::Create(url);
   std::vector<PreconnectRequest> requests;
-  for (auto* const host : kHtmlSubresourcesHosts)
-    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1);
+  for (auto* const host : kHtmlSubresourcesHosts) {
+    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1,
+                          net::NetworkIsolationKey(origin, origin));
+  }
 
   // When kLoadingOnlyLearnHighPriorityResources is disabled, loading data
   // collector should learn the loading of low priority resources hosted on
   // bar.com as well.
-  requests.emplace_back(embedded_test_server()->GetURL("bar.com", "/"), 1);
+  requests.emplace_back(embedded_test_server()->GetURL("bar.com", "/"), 1,
+                        net::NetworkIsolationKey(origin, origin));
 
   ui_test_utils::NavigateToURL(browser(), url);
   auto prediction = GetPreconnectPrediction(url);
@@ -648,9 +680,12 @@
   GURL original_url = embedded_test_server()->GetURL(
       "redirect.com",
       base::StringPrintf("/server-redirect?%s", redirect_url.spec().c_str()));
+  url::Origin origin = url::Origin::Create(redirect_url);
   std::vector<PreconnectRequest> requests;
-  for (auto* const host : kHtmlSubresourcesHosts)
-    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1);
+  for (auto* const host : kHtmlSubresourcesHosts) {
+    requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1,
+                          net::NetworkIsolationKey(origin, origin));
+  }
 
   ui_test_utils::NavigateToURL(browser(), original_url);
   // The predictor can correctly predict hosts by |redirect_url|
@@ -665,6 +700,16 @@
   prediction = GetPreconnectPrediction(original_url);
   EXPECT_FALSE(prediction);
 
+  // TODO(https://crbug.com/987735): These predictions should match |requests|
+  // should use |redirect_url|'s origin.
+  url::Origin original_origin = url::Origin::Create(original_url);
+  std::vector<PreconnectRequest> requests2;
+  for (auto* const host : kHtmlSubresourcesHosts) {
+    requests2.emplace_back(
+        embedded_test_server()->GetURL(host, "/"), 1,
+        net::NetworkIsolationKey(original_origin, original_origin));
+  }
+
   // The predictor will start predict a redirect after the second navigation.
   ui_test_utils::NavigateToURL(browser(), original_url);
   prediction = GetPreconnectPrediction(original_url);
@@ -672,7 +717,7 @@
   EXPECT_EQ(prediction->is_redirected, true);
   EXPECT_EQ(prediction->host, redirect_url.host());
   EXPECT_THAT(prediction->requests,
-              testing::UnorderedElementsAreArray(requests));
+              testing::UnorderedElementsAreArray(requests2));
 }
 
 // Tests that the LoadingPredictor performs preresolving/preconnecting for a
@@ -849,7 +894,12 @@
       case NetworkIsolationKeyMode::kTopFrameOrigin:
         scoped_feature_list2_.InitWithFeatures(
             // enabled_features
-            {net::features::kPartitionConnectionsByNetworkIsolationKey},
+            {net::features::kPartitionConnectionsByNetworkIsolationKey,
+             // While these tests are focusing on partitioning the socket pools,
+             // some depend on cache behavior, and it would be
+             // unfortunate if splitting the cache by the key as well broke
+             // them.
+             net::features::kSplitCacheByNetworkIsolationKey},
             // disabled_features
             {net::features::kAppendFrameOriginToNetworkIsolationKey});
         break;
@@ -857,6 +907,7 @@
         scoped_feature_list2_.InitWithFeatures(
             // enabled_features
             {net::features::kPartitionConnectionsByNetworkIsolationKey,
+             net::features::kSplitCacheByNetworkIsolationKey,
              net::features::kAppendFrameOriginToNetworkIsolationKey},
             // disabled_features
             {});
@@ -873,6 +924,37 @@
     return &preconnecting_test_server_;
   }
 
+  // Load the favicon into the cache, so that favicon requests won't create any
+  // new connections. Can't just wait for it normally, because there's no easy
+  // way to be sure that the favicon request associated with a page load has
+  // completed, since it doesn't block navigation complete events.
+  void CacheFavIcon() {
+    CacheUrl(embedded_test_server()->GetURL("/favicon.ico"));
+  }
+
+  // Drives a request for the provided URL to completion, which will then be
+  // stored in the HTTP cache, headers permitting.
+  void CacheUrl(const GURL& url) {
+    std::unique_ptr<network::ResourceRequest> request =
+        std::make_unique<network::ResourceRequest>();
+    request->url = url;
+    content::SimpleURLLoaderTestHelper simple_loader_helper;
+    url::Origin origin = url::Origin::Create(url);
+    request->trusted_network_isolation_key =
+        net::NetworkIsolationKey(origin, origin);
+    std::unique_ptr<network::SimpleURLLoader> simple_loader =
+        network::SimpleURLLoader::Create(std::move(request),
+                                         TRAFFIC_ANNOTATION_FOR_TESTS);
+    simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+        browser()->profile()->GetURLLoaderFactory().get(),
+        simple_loader_helper.GetCallback());
+    simple_loader_helper.WaitForCallback();
+    ASSERT_TRUE(simple_loader_helper.response_body());
+    EXPECT_EQ(1u, connection_tracker()->GetAcceptedSocketCount());
+    EXPECT_EQ(1u, connection_tracker()->GetReadSocketCount());
+    connection_tracker()->ResetCounts();
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list2_;
 
@@ -888,6 +970,48 @@
                       NetworkIsolationKeyMode::kTopFrameOrigin,
                       NetworkIsolationKeyMode::kTopFrameAndFrameOrigins));
 
+// Make sure that the right NetworkIsolationKey is used by the LoadingPredictor,
+// both when the predictor is populated and when it isn't.
+IN_PROC_BROWSER_TEST_P(LoadingPredictorNetworkIsolationKeyBrowserTest,
+                       LoadingPredictorNoRedirects) {
+  // Cache resources needed by navigations, so so the only sockets created
+  // during navigations should be for the two preconnects.
+  CacheFavIcon();
+  GURL cacheable_url = embedded_test_server()->GetURL("/cachetime");
+  CacheUrl(cacheable_url);
+
+  // For the first loop iteration, the predictor has no state, and for the
+  // second one it does.
+  for (bool predictor_has_state : {false, true}) {
+    SCOPED_TRACE(predictor_has_state);
+
+    auto observer = NavigateToURLAsync(cacheable_url);
+    observer->WaitForNavigationFinished();
+    connection_tracker()->WaitForAcceptedConnections(2);
+    EXPECT_EQ(0u, connection_tracker()->GetReadSocketCount());
+
+    // Have the page fetch a subresource, which should use one of the
+    // preconnects triggered by the above navigation, due to the matching
+    // NetworkIsolationKey. Do this instead of a navigation to a non-cached URL
+    // to avoid triggering more preconnects.
+    std::string fetch_resource = base::StringPrintf(
+        "(async () => {"
+        "  var resp = (await fetch('%s'));"
+        "  return resp.status; })();",
+        embedded_test_server()->GetURL("/echo").spec().c_str());
+    EXPECT_EQ(200, EvalJs(browser()
+                              ->tab_strip_model()
+                              ->GetActiveWebContents()
+                              ->GetMainFrame(),
+                          fetch_resource));
+
+    EXPECT_EQ(2u, connection_tracker()->GetAcceptedSocketCount());
+    EXPECT_EQ(1u, connection_tracker()->GetReadSocketCount());
+
+    ResetNetworkState();
+  }
+}
+
 IN_PROC_BROWSER_TEST_P(LoadingPredictorNetworkIsolationKeyBrowserTest,
                        LinkRelPreconnectMainFrame) {
   const char kHost1[] = "host1.test";
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc
index 75cfada..8a635ab 100644
--- a/chrome/browser/predictors/loading_predictor_unittest.cc
+++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -18,9 +18,11 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "net/base/network_isolation_key.h"
 #include "net/url_request/url_request_context.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
 
 using testing::_;
 using testing::Return;
@@ -71,6 +73,12 @@
   return config;
 }
 
+// Creates a NetworkIsolationKey for a main frame navigation to URL.
+net::NetworkIsolationKey CreateNetworkIsolationKey(const GURL& main_frame_url) {
+  url::Origin origin = url::Origin::Create(main_frame_url);
+  return net::NetworkIsolationKey(origin, origin);
+}
+
 }  // namespace
 
 class LoadingPredictorTest : public testing::Test {
@@ -304,9 +312,10 @@
 
 TEST_F(LoadingPredictorPreconnectTest, TestHandleOmniboxHint) {
   const GURL preconnect_suggestion = GURL("http://search.com/kittens");
-  EXPECT_CALL(*mock_preconnect_manager_,
-              StartPreconnectUrl(preconnect_suggestion, true,
-                                 net::NetworkIsolationKey()));
+  EXPECT_CALL(
+      *mock_preconnect_manager_,
+      StartPreconnectUrl(preconnect_suggestion, true,
+                         CreateNetworkIsolationKey(preconnect_suggestion)));
   predictor_->PrepareForPageLoad(preconnect_suggestion, HintOrigin::OMNIBOX,
                                  true);
   // The second suggestion for the same host should be filtered out.
@@ -332,10 +341,11 @@
   GURL main_frame_url("http://search.com/kittens");
   EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
       .WillOnce(Return(false));
-  EXPECT_CALL(
-      *mock_preconnect_manager_,
-      StartProxy(main_frame_url, std::vector<PreconnectRequest>(
-                                     {{GURL("http://search.com"), 2}})));
+  EXPECT_CALL(*mock_preconnect_manager_,
+              StartProxy(main_frame_url,
+                         std::vector<PreconnectRequest>(
+                             {{GURL("http://search.com"), 2,
+                               CreateNetworkIsolationKey(main_frame_url)}})));
   predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::NAVIGATION);
 }
 
@@ -343,19 +353,23 @@
 // if the list already containts the origin.
 TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlMatchesPrediction) {
   GURL main_frame_url("http://search.com/kittens");
-  PreconnectPrediction prediction =
-      CreatePreconnectPrediction("search.com", true,
-                                 {{GURL("http://search.com"), 1},
-                                  {GURL("http://cdn.search.com"), 1},
-                                  {GURL("http://ads.search.com"), 0}});
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
+  PreconnectPrediction prediction = CreatePreconnectPrediction(
+      "search.com", true,
+      {{GURL("http://search.com"), 1, network_isolation_key},
+       {GURL("http://cdn.search.com"), 1, network_isolation_key},
+       {GURL("http://ads.search.com"), 0, network_isolation_key}});
   EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
       .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
   EXPECT_CALL(
       *mock_preconnect_manager_,
-      StartProxy(main_frame_url, std::vector<PreconnectRequest>(
-                                     {{GURL("http://search.com"), 2},
-                                      {GURL("http://cdn.search.com"), 1},
-                                      {GURL("http://ads.search.com"), 0}})));
+      StartProxy(
+          main_frame_url,
+          std::vector<PreconnectRequest>(
+              {{GURL("http://search.com"), 2, network_isolation_key},
+               {GURL("http://cdn.search.com"), 1, network_isolation_key},
+               {GURL("http://ads.search.com"), 0, network_isolation_key}})));
   predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL);
 }
 
@@ -364,20 +378,24 @@
 // url redirects to another host.
 TEST_F(LoadingPredictorPreconnectTest, TestAddInitialUrlDoesntMatchPrediction) {
   GURL main_frame_url("http://search.com/kittens");
-  PreconnectPrediction prediction =
-      CreatePreconnectPrediction("search.com", true,
-                                 {{GURL("http://en.search.com"), 1},
-                                  {GURL("http://cdn.search.com"), 1},
-                                  {GURL("http://ads.search.com"), 0}});
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
+  PreconnectPrediction prediction = CreatePreconnectPrediction(
+      "search.com", true,
+      {{GURL("http://en.search.com"), 1, network_isolation_key},
+       {GURL("http://cdn.search.com"), 1, network_isolation_key},
+       {GURL("http://ads.search.com"), 0, network_isolation_key}});
   EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(main_frame_url, _))
       .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
   EXPECT_CALL(
       *mock_preconnect_manager_,
-      StartProxy(main_frame_url, std::vector<PreconnectRequest>(
-                                     {{GURL("http://search.com"), 2},
-                                      {GURL("http://en.search.com"), 1},
-                                      {GURL("http://cdn.search.com"), 1},
-                                      {GURL("http://ads.search.com"), 0}})));
+      StartProxy(
+          main_frame_url,
+          std::vector<PreconnectRequest>(
+              {{GURL("http://search.com"), 2, network_isolation_key},
+               {GURL("http://en.search.com"), 1, network_isolation_key},
+               {GURL("http://cdn.search.com"), 1, network_isolation_key},
+               {GURL("http://ads.search.com"), 0, network_isolation_key}})));
   predictor_->PrepareForPageLoad(main_frame_url, HintOrigin::EXTERNAL);
 }
 
diff --git a/chrome/browser/predictors/loading_stats_collector_unittest.cc b/chrome/browser/predictors/loading_stats_collector_unittest.cc
index b2094bb..5b2ffe6 100644
--- a/chrome/browser/predictors/loading_stats_collector_unittest.cc
+++ b/chrome/browser/predictors/loading_stats_collector_unittest.cc
@@ -13,6 +13,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "net/base/network_isolation_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::_;
@@ -77,7 +78,7 @@
   const std::string& script_url = "https://cdn.google.com/script.js";
   PreconnectPrediction prediction = CreatePreconnectPrediction(
       GURL(prediction_url).host(), initial_url != prediction_url,
-      {{GURL(script_url).GetOrigin(), 1}});
+      {{GURL(script_url).GetOrigin(), 1, net::NetworkIsolationKey()}});
   EXPECT_CALL(*mock_predictor_, PredictPreconnectOrigins(GURL(initial_url), _))
       .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
 
@@ -105,12 +106,12 @@
   };
 
   // Predicts 4 origins: 2 useful, 2 useless.
-  PreconnectPrediction prediction =
-      CreatePreconnectPrediction(GURL(main_frame_url).host(), false,
-                                 {{GURL(main_frame_url).GetOrigin(), 1},
-                                  {GURL(gen(1)).GetOrigin(), 1},
-                                  {GURL(gen(2)).GetOrigin(), 1},
-                                  {GURL(gen(3)).GetOrigin(), 0}});
+  PreconnectPrediction prediction = CreatePreconnectPrediction(
+      GURL(main_frame_url).host(), false,
+      {{GURL(main_frame_url).GetOrigin(), 1, net::NetworkIsolationKey()},
+       {GURL(gen(1)).GetOrigin(), 1, net::NetworkIsolationKey()},
+       {GURL(gen(2)).GetOrigin(), 1, net::NetworkIsolationKey()},
+       {GURL(gen(3)).GetOrigin(), 0, net::NetworkIsolationKey()}});
   EXPECT_CALL(*mock_predictor_,
               PredictPreconnectOrigins(GURL(main_frame_url), _))
       .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true)));
diff --git a/chrome/browser/predictors/loading_test_util.cc b/chrome/browser/predictors/loading_test_util.cc
index 326def7..9c9d6c9 100644
--- a/chrome/browser/predictors/loading_test_util.cc
+++ b/chrome/browser/predictors/loading_test_util.cc
@@ -211,7 +211,8 @@
 
 std::ostream& operator<<(std::ostream& os, const PreconnectRequest& request) {
   return os << "[" << request.origin << "," << request.num_sockets << ","
-            << request.allow_credentials << "]";
+            << request.allow_credentials << ","
+            << request.network_isolation_key.ToDebugString() << "]";
 }
 
 std::ostream& operator<<(std::ostream& os,
@@ -284,7 +285,8 @@
 
 bool operator==(const PreconnectRequest& lhs, const PreconnectRequest& rhs) {
   return lhs.origin == rhs.origin && lhs.num_sockets == rhs.num_sockets &&
-         lhs.allow_credentials == rhs.allow_credentials;
+         lhs.allow_credentials == rhs.allow_credentials &&
+         lhs.network_isolation_key == rhs.network_isolation_key;
 }
 
 bool operator==(const PreconnectPrediction& lhs,
diff --git a/chrome/browser/predictors/preconnect_manager_unittest.cc b/chrome/browser/predictors/preconnect_manager_unittest.cc
index c9161f8..5420498 100644
--- a/chrome/browser/predictors/preconnect_manager_unittest.cc
+++ b/chrome/browser/predictors/preconnect_manager_unittest.cc
@@ -24,6 +24,7 @@
 #include "services/network/test/test_network_context.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
 
 using testing::_;
 using testing::Mock;
@@ -32,6 +33,8 @@
 
 namespace predictors {
 
+namespace {
+
 constexpr int kNormalLoadFlags = net::LOAD_NORMAL;
 constexpr int kPrivateLoadFlags = net::LOAD_DO_NOT_SEND_COOKIES |
                                   net::LOAD_DO_NOT_SAVE_COOKIES |
@@ -154,6 +157,14 @@
   std::vector<std::string> hanging_hosts_;
 };
 
+// Creates a NetworkIsolationKey for a main frame navigation to URL.
+net::NetworkIsolationKey CreateNetworkIsolationKey(const GURL& main_frame_url) {
+  url::Origin origin = url::Origin::Create(main_frame_url);
+  return net::NetworkIsolationKey(origin, origin);
+}
+
+}  // namespace
+
 class PreconnectManagerTest : public testing::Test {
  public:
   PreconnectManagerTest();
@@ -198,23 +209,28 @@
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preresolve.host()));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preresolve, 0)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preresolve, 0,
+                         CreateNetworkIsolationKey(main_frame_url))});
   mock_network_context_->CompleteHostLookup(url_to_preresolve.host(), net::OK);
 }
 
 TEST_F(PreconnectManagerTest, TestStartOneUrlPreconnect) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
 
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key)});
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
   mock_network_context_->CompleteHostLookup(url_to_preconnect.host(), net::OK);
 }
@@ -222,10 +238,9 @@
 TEST_F(PreconnectManagerTest,
        TestStartOneUrlPreconnectWithNetworkIsolationKey) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
-  url::Origin requesting_origin = url::Origin::Create(GURL("http://foo.test"));
-  net::NetworkIsolationKey network_isolation_key(requesting_origin,
-                                                 requesting_origin);
 
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
@@ -246,12 +261,15 @@
 // related to the second request are dispatched on the network.
 TEST_F(PreconnectManagerTest, TestStartOneUrlPreconnect_MultipleTimes) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   size_t count = PreconnectManager::kMaxInflightPreresolves;
   std::vector<PreconnectRequest> requests;
   for (size_t i = 0; i < count + 1; ++i) {
     // Exactly PreconnectManager::kMaxInflightPreresolves should be preresolved.
     requests.emplace_back(
-        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1);
+        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1,
+        network_isolation_key);
   }
   for (size_t i = 0; i < count; ++i) {
     // Exactly PreconnectManager::kMaxInflightPreresolves should be preresolved.
@@ -271,14 +289,14 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, requests.back().origin, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(requests.back().origin.host()));
   for (size_t i = 0; i < count; ++i) {
     EXPECT_CALL(*mock_network_context_,
                 PreconnectSockets(1, requests[i].origin, kNormalLoadFlags,
                                   false /* privacy_mode_enabled */,
-                                  net::NetworkIsolationKey()));
+                                  network_isolation_key));
     EXPECT_CALL(*mock_network_context_,
                 ResolveHostProxy(requests[i].origin.host()));
   }
@@ -298,14 +316,19 @@
 // related to the second request are dispatched on the network.
 TEST_F(PreconnectManagerTest, TestTwoConcurrentMainFrameUrls_MultipleTimes) {
   GURL main_frame_url_1("http://google.com");
+  net::NetworkIsolationKey network_isolation_key_1 =
+      CreateNetworkIsolationKey(main_frame_url_1);
   size_t count = PreconnectManager::kMaxInflightPreresolves;
   std::vector<PreconnectRequest> requests;
   for (size_t i = 0; i < count + 1; ++i) {
     requests.emplace_back(
-        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1);
+        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1,
+        network_isolation_key_1);
   }
 
   GURL main_frame_url_2("http://google2.com");
+  net::NetworkIsolationKey network_isolation_key_2 =
+      CreateNetworkIsolationKey(main_frame_url_1);
 
   for (size_t i = 0; i < count; ++i) {
     EXPECT_CALL(*mock_network_context_,
@@ -316,7 +339,7 @@
     EXPECT_CALL(*mock_network_context_,
                 PreconnectSockets(1, requests[i].origin, kNormalLoadFlags,
                                   false /* privacy_mode_enabled */,
-                                  net::NetworkIsolationKey()));
+                                  network_isolation_key_1));
   }
 
   preconnect_manager_->Start(
@@ -355,11 +378,11 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, requests[count - 1].origin, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key_2));
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, requests[count].origin, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key_2));
 
   mock_network_context_->CompleteHostLookup(requests[count - 1].origin.host(),
                                             net::OK);
@@ -377,12 +400,14 @@
 TEST_F(PreconnectManagerTest,
        TestStartOneUrlPreconnect_MultipleTimes_CancelledAfterInFlight) {
   GURL main_frame_url_1("http://google1.com");
+  net::NetworkIsolationKey network_isolation_key_1 =
+      CreateNetworkIsolationKey(main_frame_url_1);
   size_t count = PreconnectManager::kMaxInflightPreresolves;
   std::vector<PreconnectRequest> requests;
   for (size_t i = 0; i < count - 1; ++i) {
     requests.emplace_back(
         GURL(base::StringPrintf("http://hanging.cdn%" PRIuS ".google.com", i)),
-        1);
+        1, network_isolation_key_1);
   }
   mock_network_context_->SetHangingHostsFromPreconnectRequests(requests);
 
@@ -390,6 +415,8 @@
   preconnect_manager_->Start(main_frame_url_1, requests);
 
   GURL main_frame_url_2("http://google2.com");
+  net::NetworkIsolationKey network_isolation_key_2 =
+      CreateNetworkIsolationKey(main_frame_url_2);
   GURL url_to_preconnect_1("http://cdn.google1.com");
   GURL url_to_preconnect_2("http://cdn.google2.com");
 
@@ -398,9 +425,10 @@
   // Starting and stopping preconnect request for |main_frame_url_2|
   // should still dispatch the request for |url_to_preconnect_1| on the
   // network.
-  preconnect_manager_->Start(main_frame_url_2,
-                             {PreconnectRequest(url_to_preconnect_1, 1),
-                              PreconnectRequest(url_to_preconnect_2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url_2,
+      {PreconnectRequest(url_to_preconnect_1, 1, network_isolation_key_2),
+       PreconnectRequest(url_to_preconnect_2, 1, network_isolation_key_2)});
   // preconnect request for |url_to_preconnect_1| is still in-flight and
   // Stop() is called on the associated webpage.
   preconnect_manager_->Stop(main_frame_url_2);
@@ -420,14 +448,15 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key_2));
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
-  preconnect_manager_->Start(main_frame_url_2,
-                             {PreconnectRequest(url_to_preconnect_1, 1),
-                              PreconnectRequest(url_to_preconnect_2, 1)});
+                                network_isolation_key_2));
+  preconnect_manager_->Start(
+      main_frame_url_2,
+      {PreconnectRequest(url_to_preconnect_1, 1, network_isolation_key_2),
+       PreconnectRequest(url_to_preconnect_2, 1, network_isolation_key_2)});
 
   mock_network_context_->CompleteHostLookup(url_to_preconnect_1.host(),
                                             net::OK);
@@ -440,6 +469,8 @@
 TEST_F(PreconnectManagerTest,
        TestStartOneUrlPreconnect_MultipleTimes_LessThanThree) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect_1("http://cdn.google1.com");
   GURL url_to_preconnect_2("http://cdn.google2.com");
 
@@ -448,9 +479,10 @@
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect_2.host()));
 
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect_1, 1),
-                              PreconnectRequest(url_to_preconnect_2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect_1, 1, network_isolation_key),
+       PreconnectRequest(url_to_preconnect_2, 1, network_isolation_key)});
   preconnect_manager_->Stop(main_frame_url);
 
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
@@ -468,15 +500,16 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect_1, 1),
-                              PreconnectRequest(url_to_preconnect_2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect_1, 1, network_isolation_key),
+       PreconnectRequest(url_to_preconnect_2, 1, network_isolation_key)});
   mock_network_context_->CompleteHostLookup(url_to_preconnect_1.host(),
                                             net::OK);
   mock_network_context_->CompleteHostLookup(url_to_preconnect_2.host(),
@@ -485,13 +518,16 @@
 
 TEST_F(PreconnectManagerTest, TestStopOneUrlBeforePreconnect) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
 
   // Preconnect job isn't started before preresolve is completed asynchronously.
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key)});
 
   // Stop all jobs for |main_frame_url| before we get the callback.
   preconnect_manager_->Stop(main_frame_url);
@@ -501,11 +537,14 @@
 
 TEST_F(PreconnectManagerTest, TestGetCallbackAfterDestruction) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key)});
 
   // Callback may outlive PreconnectManager but it shouldn't cause a crash.
   preconnect_manager_ = nullptr;
@@ -514,17 +553,21 @@
 
 TEST_F(PreconnectManagerTest, TestUnqueuedPreresolvesCanceled) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   size_t count = PreconnectManager::kMaxInflightPreresolves;
   std::vector<PreconnectRequest> requests;
   for (size_t i = 0; i < count; ++i) {
     // Exactly PreconnectManager::kMaxInflightPreresolves should be preresolved.
     requests.emplace_back(
-        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1);
+        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 1,
+        network_isolation_key);
     EXPECT_CALL(*mock_network_context_,
                 ResolveHostProxy(requests.back().origin.host()));
   }
   // This url shouldn't be preresolved.
-  requests.emplace_back(GURL("http://no.preresolve.com"), 1);
+  requests.emplace_back(GURL("http://no.preresolve.com"), 1,
+                        network_isolation_key);
   preconnect_manager_->Start(main_frame_url, requests);
 
   preconnect_manager_->Stop(main_frame_url);
@@ -536,18 +579,24 @@
 
 TEST_F(PreconnectManagerTest, TestTwoConcurrentMainFrameUrls) {
   GURL main_frame_url1("http://google.com");
+  net::NetworkIsolationKey network_isolation_key1 =
+      CreateNetworkIsolationKey(main_frame_url1);
   GURL url_to_preconnect1("http://cdn.google.com");
   GURL main_frame_url2("http://facebook.com");
+  net::NetworkIsolationKey network_isolation_key2 =
+      CreateNetworkIsolationKey(main_frame_url2);
   GURL url_to_preconnect2("http://cdn.facebook.com");
 
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect1.host()));
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect2.host()));
-  preconnect_manager_->Start(main_frame_url1,
-                             {PreconnectRequest(url_to_preconnect1, 1)});
-  preconnect_manager_->Start(main_frame_url2,
-                             {PreconnectRequest(url_to_preconnect2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url1,
+      {PreconnectRequest(url_to_preconnect1, 1, network_isolation_key1)});
+  preconnect_manager_->Start(
+      main_frame_url2,
+      {PreconnectRequest(url_to_preconnect2, 1, network_isolation_key2)});
   // Check that the first url didn't block the second one.
   Mock::VerifyAndClearExpectations(preconnect_manager_.get());
 
@@ -556,7 +605,7 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key1));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url1));
   mock_network_context_->CompleteHostLookup(url_to_preconnect1.host(), net::OK);
   // No preconnect for the second url.
@@ -568,23 +617,29 @@
 // simultaneously.
 TEST_F(PreconnectManagerTest, TestTwoConcurrentSameHostMainFrameUrls) {
   GURL main_frame_url1("http://google.com/search?query=cats");
+  net::NetworkIsolationKey network_isolation_key1 =
+      CreateNetworkIsolationKey(main_frame_url1);
   GURL url_to_preconnect1("http://cats.google.com");
   GURL main_frame_url2("http://google.com/search?query=dogs");
+  net::NetworkIsolationKey network_isolation_key2 =
+      CreateNetworkIsolationKey(main_frame_url2);
   GURL url_to_preconnect2("http://dogs.google.com");
 
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect1.host()));
-  preconnect_manager_->Start(main_frame_url1,
-                             {PreconnectRequest(url_to_preconnect1, 1)});
+  preconnect_manager_->Start(
+      main_frame_url1,
+      {PreconnectRequest(url_to_preconnect1, 1, network_isolation_key1)});
   // This suggestion should be dropped because the PreconnectManager already has
   // a job for the "google.com" host.
-  preconnect_manager_->Start(main_frame_url2,
-                             {PreconnectRequest(url_to_preconnect2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url2,
+      {PreconnectRequest(url_to_preconnect2, 1, network_isolation_key2)});
 
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key1));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url1));
   mock_network_context_->CompleteHostLookup(url_to_preconnect1.host(), net::OK);
 }
@@ -616,23 +671,24 @@
 
 TEST_F(PreconnectManagerTest, TestStartPreconnectUrl) {
   GURL url("http://cdn.google.com/script.js");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(url);
   GURL origin("http://cdn.google.com");
   bool allow_credentials = false;
 
   EXPECT_CALL(*mock_network_context_, ResolveHostProxy(origin.host()));
   preconnect_manager_->StartPreconnectUrl(url, allow_credentials,
-                                          net::NetworkIsolationKey());
+                                          network_isolation_key);
 
-  EXPECT_CALL(
-      *mock_network_context_,
-      PreconnectSockets(1, origin, kPrivateLoadFlags, !allow_credentials,
-                        net::NetworkIsolationKey()));
+  EXPECT_CALL(*mock_network_context_,
+              PreconnectSockets(1, origin, kPrivateLoadFlags,
+                                !allow_credentials, network_isolation_key));
   mock_network_context_->CompleteHostLookup(origin.host(), net::OK);
 
   // Non http url shouldn't be preconnected.
   GURL non_http_url("file:///tmp/index.html");
   preconnect_manager_->StartPreconnectUrl(non_http_url, allow_credentials,
-                                          net::NetworkIsolationKey());
+                                          network_isolation_key);
 }
 
 TEST_F(PreconnectManagerTest, TestStartPreconnectUrlWithNetworkIsolationKey) {
@@ -655,18 +711,21 @@
 
 TEST_F(PreconnectManagerTest, TestDetachedRequestHasHigherPriority) {
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   size_t count = PreconnectManager::kMaxInflightPreresolves;
   std::vector<PreconnectRequest> requests;
   // Create enough asynchronous jobs to leave the last one in the queue.
   for (size_t i = 0; i < count; ++i) {
     requests.emplace_back(
-        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 0);
+        GURL(base::StringPrintf("http://cdn%" PRIuS ".google.com", i)), 0,
+        network_isolation_key);
     EXPECT_CALL(*mock_network_context_,
                 ResolveHostProxy(requests.back().origin.host()));
   }
   // This url will wait in the queue.
   GURL queued_url("http://fonts.google.com");
-  requests.emplace_back(queued_url, 0);
+  requests.emplace_back(queued_url, 0, network_isolation_key);
   preconnect_manager_->Start(main_frame_url, requests);
 
   // This url should come to the front of the queue.
@@ -693,15 +752,18 @@
 TEST_F(PreconnectManagerTest, TestSuccessfulProxyLookup) {
   mock_network_context_->EnableProxyTesting();
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
 
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key)});
 
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
   mock_network_context_->CompleteProxyLookup(url_to_preconnect,
                                              GetIndirectProxyInfo());
@@ -710,12 +772,15 @@
 TEST_F(PreconnectManagerTest, TestSuccessfulHostLookupAfterProxyLookupFailure) {
   mock_network_context_->EnableProxyTesting();
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
   GURL url_to_preconnect2("http://ads.google.com");
 
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1),
-                              PreconnectRequest(url_to_preconnect2, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key),
+       PreconnectRequest(url_to_preconnect2, 1, network_isolation_key)});
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
   EXPECT_CALL(*mock_network_context_,
@@ -730,11 +795,11 @@
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_network_context_,
               PreconnectSockets(1, url_to_preconnect2, kNormalLoadFlags,
                                 false /* privacy_mode_enabled */,
-                                net::NetworkIsolationKey()));
+                                network_isolation_key));
   EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url));
   mock_network_context_->CompleteHostLookup(url_to_preconnect.host(), net::OK);
   mock_network_context_->CompleteHostLookup(url_to_preconnect2.host(), net::OK);
@@ -743,10 +808,13 @@
 TEST_F(PreconnectManagerTest, TestBothProxyAndHostLookupFailed) {
   mock_network_context_->EnableProxyTesting();
   GURL main_frame_url("http://google.com");
+  net::NetworkIsolationKey network_isolation_key =
+      CreateNetworkIsolationKey(main_frame_url);
   GURL url_to_preconnect("http://cdn.google.com");
 
-  preconnect_manager_->Start(main_frame_url,
-                             {PreconnectRequest(url_to_preconnect, 1)});
+  preconnect_manager_->Start(
+      main_frame_url,
+      {PreconnectRequest(url_to_preconnect, 1, network_isolation_key)});
 
   EXPECT_CALL(*mock_network_context_,
               ResolveHostProxy(url_to_preconnect.host()));
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
index 8d1c505..c0f50e42 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -24,6 +24,7 @@
 #include "components/history/core/browser/url_utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
+#include "url/origin.h"
 
 using content::BrowserThread;
 
@@ -61,10 +62,10 @@
 PreconnectRequest::PreconnectRequest(
     const GURL& origin,
     int num_sockets,
-    net::NetworkIsolationKey network_isolation_key)
+    const net::NetworkIsolationKey& network_isolation_key)
     : origin(origin),
       num_sockets(num_sockets),
-      network_isolation_key(std::move(network_isolation_key)) {
+      network_isolation_key(network_isolation_key) {
   DCHECK_GE(num_sockets, 0);
 }
 
@@ -224,6 +225,16 @@
   }
 
   bool has_any_prediction = false;
+
+  // TODO(https://crbug.com/987735): Use the NetworkIsolationKey of the final
+  // destination in the case of redirects. This will require recording the port,
+  // which is not currently logged. That will not result in using the correct
+  // NetworkIsolationKey in the case of intermediary redirects, but given the
+  // relatively low accurace of redirect predictions, seems likely not worth
+  // fixing.
+  url::Origin origin = url::Origin::Create(url);
+  net::NetworkIsolationKey network_isolation_key(origin, origin);
+
   for (const OriginStat& origin : data.origins()) {
     float confidence = static_cast<float>(origin.number_of_hits()) /
                        (origin.number_of_hits() + origin.number_of_misses());
@@ -232,10 +243,13 @@
 
     has_any_prediction = true;
     if (prediction) {
-      if (confidence > kMinOriginConfidenceToTriggerPreconnect)
-        prediction->requests.emplace_back(GURL(origin.origin()), 1);
-      else
-        prediction->requests.emplace_back(GURL(origin.origin()), 0);
+      if (confidence > kMinOriginConfidenceToTriggerPreconnect) {
+        prediction->requests.emplace_back(GURL(origin.origin()), 1,
+                                          network_isolation_key);
+      } else {
+        prediction->requests.emplace_back(GURL(origin.origin()), 0,
+                                          network_isolation_key);
+      }
     }
   }
 
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h
index c43d5ed..9edc2df3 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -60,13 +60,9 @@
   // preconnected URL are expected to use. If a request is issued with a
   // different key, it may not use the preconnected socket. It has no effect
   // when |num_sockets| == 0.
-  //
-  // TODO(https://crbug.com/966896): Update consumers and make
-  // |network_isolation_key| a mandatory argument.
   PreconnectRequest(const GURL& origin,
                     int num_sockets,
-                    net::NetworkIsolationKey network_isolation_key =
-                        net::NetworkIsolationKey());
+                    const net::NetworkIsolationKey& network_isolation_key);
 
   GURL origin;
   // A zero-value means that we need to preresolve a host only.
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
index 724bd8a..43b7c9c 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -25,8 +25,11 @@
 #include "components/sessions/core/session_id.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "net/base/network_isolation_key.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
 
 using testing::StrictMock;
 using testing::UnorderedElementsAre;
@@ -676,6 +679,8 @@
 
 TEST_F(ResourcePrefetchPredictorTest, TestPredictPreconnectOrigins) {
   const GURL main_frame_url("http://google.com/?query=cats");
+  const url::Origin origin = url::Origin::Create(main_frame_url);
+  const net::NetworkIsolationKey network_isolation_key(origin, origin);
   auto prediction = std::make_unique<PreconnectPrediction>();
   // No prefetch data.
   EXPECT_FALSE(predictor_->IsUrlPreconnectable(main_frame_url));
@@ -704,7 +709,8 @@
   EXPECT_EQ(*prediction,
             CreatePreconnectPrediction(
                 "google.com", false,
-                {{GURL(gen_origin(1)), 1}, {GURL(gen_origin(2)), 0}}));
+                {{GURL(gen_origin(1)), 1, network_isolation_key},
+                 {GURL(gen_origin(2)), 0, network_isolation_key}}));
 
   // Add a redirect.
   RedirectData redirect = CreateRedirectData("google.com", 3);
@@ -729,9 +735,9 @@
   EXPECT_TRUE(predictor_->IsUrlPreconnectable(main_frame_url));
   EXPECT_TRUE(
       predictor_->PredictPreconnectOrigins(main_frame_url, prediction.get()));
-  EXPECT_EQ(*prediction,
-            CreatePreconnectPrediction("www.google.com", true,
-                                       {{GURL(gen_origin(4)), 1}}));
+  EXPECT_EQ(*prediction, CreatePreconnectPrediction("www.google.com", true,
+                                                    {{GURL(gen_origin(4)), 1,
+                                                      network_isolation_key}}));
 }
 
 }  // namespace predictors
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
index b03ff9c02..1585e08 100644
--- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
+++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -227,13 +227,23 @@
 
 class NoStatePrefetchBrowserTestHttpCache
     : public NoStatePrefetchBrowserTest,
-      public testing::WithParamInterface<bool> {
+      public testing::WithParamInterface<std::tuple<bool, bool>> {
  protected:
   void SetUp() override {
-    if (GetParam()) {
-      feature_list_.InitAndEnableFeature(
-          net::features::kSplitCacheByNetworkIsolationKey);
-    }
+    bool split_cache_by_network_isolation_key;
+    bool append_frame_origin_to_network_isolation_key;
+    std::tie(split_cache_by_network_isolation_key,
+             append_frame_origin_to_network_isolation_key) = GetParam();
+
+    std::vector<base::Feature> disabled_and_enabled_features[2];
+
+    disabled_and_enabled_features[split_cache_by_network_isolation_key]
+        .push_back(net::features::kSplitCacheByNetworkIsolationKey);
+    disabled_and_enabled_features[append_frame_origin_to_network_isolation_key]
+        .push_back(net::features::kAppendFrameOriginToNetworkIsolationKey);
+
+    feature_list_.InitWithFeatures(disabled_and_enabled_features[true],
+                                   disabled_and_enabled_features[false]);
     NoStatePrefetchBrowserTest::SetUp();
   }
 
@@ -241,12 +251,48 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(DefaultKeyedHttpCache,
-                         NoStatePrefetchBrowserTestHttpCache,
-                         ::testing::Values(false));
-INSTANTIATE_TEST_SUITE_P(DoubleKeyedHttpCache,
-                         NoStatePrefetchBrowserTestHttpCache,
-                         ::testing::Values(true));
+using NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin =
+    NoStatePrefetchBrowserTestHttpCache;
+
+// Test that the network isolation key is correctly populated during a prefetch,
+// with feature kAppendFrameOriginToNetworkIsolationKey disabled and enabled
+// respectively.
+IN_PROC_BROWSER_TEST_P(
+    NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin,
+    PrefetchTwoCrossOriginFrames) {
+  bool append_frame_origin_to_network_isolation_key;
+  std::tie(std::ignore, append_frame_origin_to_network_isolation_key) =
+      GetParam();
+
+  GURL image_src =
+      embedded_test_server()->GetURL("/prerender/cacheable_image.png");
+  base::StringPairs replacement_text_img_src;
+  replacement_text_img_src.push_back(
+      std::make_pair("IMAGE_SRC", image_src.spec()));
+  std::string iframe_path = net::test_server::GetFilePathWithReplacements(
+      "/prerender/one_image.html", replacement_text_img_src);
+
+  GURL iframe_src_1 = embedded_test_server()->GetURL("www.a.com", iframe_path);
+  GURL iframe_src_2 = embedded_test_server()->GetURL("www.b.com", iframe_path);
+
+  base::StringPairs replacement_text_iframe_src;
+  replacement_text_iframe_src.push_back(
+      std::make_pair("IFRAME_1_SRC", iframe_src_1.spec()));
+  replacement_text_iframe_src.push_back(
+      std::make_pair("IFRAME_2_SRC", iframe_src_2.spec()));
+  std::string prerender_path = net::test_server::GetFilePathWithReplacements(
+      "/prerender/two_iframes.html", replacement_text_iframe_src);
+  ui_test_utils::NavigateToURL(current_browser(),
+                               src_server()->GetURL(prerender_path));
+
+  WaitForRequestCount(image_src,
+                      append_frame_origin_to_network_isolation_key ? 2 : 1);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    /* no prefix */,
+    NoStatePrefetchBrowserTestHttpCache_DefaultAndAppendFrameOrigin,
+    ::testing::Combine(::testing::Values(true), ::testing::Bool()));
 
 // Checks that a page is correctly prefetched in the case of a
 // <link rel=prerender> tag and the JavaScript on the page is not executed.
@@ -276,10 +322,15 @@
   WaitForRequestCount(src_server()->GetURL(kPrefetchPngRedirect), 1);
 }
 
+using NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache =
+    NoStatePrefetchBrowserTestHttpCache;
+
 // Checks that a page load following a prefetch reuses preload-scanned resources
 // and link rel 'prerender' main resource from cache without failing over to
 // network.
-IN_PROC_BROWSER_TEST_P(NoStatePrefetchBrowserTestHttpCache, LoadAfterPrefetch) {
+IN_PROC_BROWSER_TEST_P(
+    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
+    LoadAfterPrefetch) {
   {
     std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(
         kPrefetchPageBigger, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
@@ -298,8 +349,9 @@
 // Checks that a page load following a cross origin prefetch reuses
 // preload-scanned resources and link rel 'prerender' main resource
 // from cache without failing over to network.
-IN_PROC_BROWSER_TEST_P(NoStatePrefetchBrowserTestHttpCache,
-                       LoadAfterPrefetchCrossOrigin) {
+IN_PROC_BROWSER_TEST_P(
+    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
+    LoadAfterPrefetchCrossOrigin) {
   static const std::string kSecondaryDomain = "www.foo.com";
   GURL cross_domain_url =
       embedded_test_server()->GetURL(kSecondaryDomain, kPrefetchPageBigger);
@@ -316,6 +368,11 @@
   WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1);
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    /* no prefix */,
+    NoStatePrefetchBrowserTestHttpCache_DefaultAndDoubleKeyedHttpCache,
+    ::testing::Combine(::testing::Bool(), ::testing::Values(false)));
+
 // Checks that the expected resource types are fetched via NoState Prefetch.
 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchAllResourceTypes) {
   std::unique_ptr<TestPrerender> test_prerender =
diff --git a/chrome/browser/renderer_host/chrome_navigation_ui_data.h b/chrome/browser/renderer_host/chrome_navigation_ui_data.h
index 5bbb115..81b9b8d 100644
--- a/chrome/browser/renderer_host/chrome_navigation_ui_data.h
+++ b/chrome/browser/renderer_host/chrome_navigation_ui_data.h
@@ -21,7 +21,6 @@
 
 enum class WindowOpenDisposition;
 
-// PlzNavigate
 // Contains data that is passed from the UI thread to the IO thread at the
 // beginning of each navigation. The class is instantiated on the UI thread,
 // then a copy created using Clone is passed to the content::ResourceRequestInfo
diff --git a/chrome/browser/resources/omnibox/omnibox.html b/chrome/browser/resources/omnibox/omnibox.html
index 1f9f1f8..3a692fc 100644
--- a/chrome/browser/resources/omnibox/omnibox.html
+++ b/chrome/browser/resources/omnibox/omnibox.html
@@ -6,6 +6,7 @@
   <title>Omnibox Debug Page</title>
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
   <link rel="stylesheet" href="omnibox.css">
+  <script src="chrome://resources/js/promise_resolver.js"></script>
   <script src="chrome://resources/js/cr.js"></script>
   <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js
index e2f4e0115..c5d0e722 100644
--- a/chrome/browser/resources/omnibox/omnibox.js
+++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -242,18 +242,29 @@
       };
       batchExports.push(exportData);
     }
+    const variationInfo =
+        await cr.sendWithPromise('requestVariationInfo', true);
+    const pathInfo = await cr.sendWithPromise('requestPathInfo');
+    const loadTimeDataKeys = ['cl', 'command_line', 'executable_path',
+        'language', 'official', 'os_type', 'profile_path', 'useragent',
+        'version', 'version_bitsize', 'version_modifier'];
+    const versionDetails = Object.fromEntries(
+        loadTimeDataKeys.map(key => [key, window.loadTimeData.getValue(key)]));
+
     const now = new Date();
     const fileName = `omnibox_batch_${ExportDelegate.getTimeStamp(now)}.json`;
     // If this data format changes, please roll schemaVersion.
     const batchData = {
       schemaKind: 'Omnibox Batch Export',
-      schemaVersion: 2,
+      schemaVersion: 3,
       dateCreated: now.toISOString(),
       author: '',
       description: '',
       authorTool: 'chrome://omnibox',
       batchName,
-      versionDetails: window.loadTimeData.data_,
+      versionDetails,
+      variationInfo,
+      pathInfo,
       appVersion: navigator.appVersion,
       batchExports
     };
@@ -330,7 +341,7 @@
     a.click();
   }
 
-  /** 
+  /**
     * @param {Date=} date
     * @return {string} A sortable timestamp string for use in filenames.
     */
diff --git a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.cc b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.cc
index 25883e9..36098398 100644
--- a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.cc
@@ -16,7 +16,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
-#include "content/public/browser/resource_request_info.h"
 #include "content/public/browser/site_instance.h"
 #include "crypto/sha2.h"
 #include "net/url_request/url_request.h"
@@ -128,19 +127,6 @@
 
 }  // namespace
 
-// static
-ResourceRequestInfo ResourceRequestDetector::GetRequestInfo(
-    const net::URLRequest* request) {
-  ResourceRequestInfo info;
-  info.url = request->url();
-  content::ResourceRequestInfo* request_info =
-      content::ResourceRequestInfo::ForRequest(request);
-  info.resource_type = request_info->GetResourceType();
-  content::ResourceRequestInfo::GetRenderFrameForRequest(
-      request, &info.render_process_id, &info.render_frame_id);
-  return info;
-}
-
 ResourceRequestDetector::ResourceRequestDetector(
     scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
     std::unique_ptr<IncidentReceiver> incident_receiver)
diff --git a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h
index 69f4536..9a27556 100644
--- a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h
+++ b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h
@@ -12,10 +12,6 @@
 #include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h"
 #include "components/safe_browsing/db/database_manager.h"
 
-namespace net {
-class URLRequest;
-}
-
 namespace safe_browsing {
 
 class ClientIncidentReport_IncidentData_ResourceRequestIncident;
@@ -30,8 +26,6 @@
 // Observes network requests and reports suspicious activity.
 class ResourceRequestDetector {
  public:
-  static ResourceRequestInfo GetRequestInfo(const net::URLRequest* request);
-
   ResourceRequestDetector(
       scoped_refptr<SafeBrowsingDatabaseManager> sb_database_manager,
       std::unique_ptr<IncidentReceiver> incident_receiver);
diff --git a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
index 3469c01..d26c527 100644
--- a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h"
 #include "components/safe_browsing/db/test_database_manager.h"
 #include "components/safe_browsing/proto/csd.pb.h"
-#include "content/public/browser/resource_request_info.h"
 #include "content/public/common/previews_state.h"
 #include "content/public/common/resource_type.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -22,8 +21,6 @@
 #include "ipc/ipc_message.h"
 #include "net/base/request_priority.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -91,25 +88,6 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  std::unique_ptr<net::URLRequest> GetTestURLRequest(
-      const std::string& url,
-      content::ResourceType resource_type) const {
-    std::unique_ptr<net::URLRequest> url_request(context_.CreateRequest(
-        GURL(url), net::DEFAULT_PRIORITY, NULL, TRAFFIC_ANNOTATION_FOR_TESTS));
-
-    content::ResourceRequestInfo::AllocateForTesting(
-        url_request.get(), resource_type,
-        /*resource_context=*/NULL,
-        /*render_process_id=*/0,
-        /*render_view_id=*/0,
-        /*render_frame_id=*/MSG_ROUTING_NONE,
-        /*is_main_frame=*/true, content::ResourceInterceptPolicy::kAllowAll,
-        /*is_async=*/false, content::PREVIEWS_OFF,
-        /*navigation_ui_data*/ nullptr);
-
-    return url_request;
-  }
-
   void ExpectNoDatabaseCheck() {
     EXPECT_CALL(*mock_database_manager_, CheckResourceUrl(_, _))
         .Times(0);
@@ -133,14 +111,12 @@
 
   void ExpectNoIncident(const std::string& url,
                         content::ResourceType resource_type) {
-    std::unique_ptr<net::URLRequest> request(
-        GetTestURLRequest(url, resource_type));
-
     EXPECT_CALL(*mock_incident_receiver_, DoAddIncidentForProfile(IsNull(), _))
         .Times(0);
 
-    ResourceRequestInfo info =
-        ResourceRequestDetector::GetRequestInfo(request.get());
+    ResourceRequestInfo info;
+    info.url = GURL(url);
+    info.resource_type = resource_type;
     fake_resource_request_detector_->ProcessResourceRequest(&info);
     base::RunLoop().RunUntilIdle();
   }
@@ -150,14 +126,13 @@
       content::ResourceType resource_type,
       ResourceRequestIncidentMessage::Type expected_type,
       const std::string& expected_digest) {
-    std::unique_ptr<net::URLRequest> request(
-        GetTestURLRequest(url, resource_type));
     std::unique_ptr<Incident> incident;
     EXPECT_CALL(*mock_incident_receiver_, DoAddIncidentForProfile(IsNull(), _))
         .WillOnce(WithArg<1>(TakeIncident(&incident)));
 
-    ResourceRequestInfo info =
-        ResourceRequestDetector::GetRequestInfo(request.get());
+    ResourceRequestInfo info;
+    info.url = GURL(url);
+    info.resource_type = resource_type;
     fake_resource_request_detector_->ProcessResourceRequest(&info);
     base::RunLoop().RunUntilIdle();
 
@@ -181,7 +156,6 @@
   std::unique_ptr<FakeResourceRequestDetector> fake_resource_request_detector_;
 
  private:
-  net::TestURLRequestContext context_;
 };
 
 TEST_F(ResourceRequestDetectorTest, NoDbCheckForIgnoredResourceTypes) {
diff --git a/chrome/browser/search/instant_io_context.cc b/chrome/browser/search/instant_io_context.cc
index c994fb3..35439f5 100644
--- a/chrome/browser/search/instant_io_context.cc
+++ b/chrome/browser/search/instant_io_context.cc
@@ -82,7 +82,7 @@
   if (!instant_io_context)
     return false;
 
-  // For PlzNavigate, the process_id for the navigation request will be -1. If
+  // The process_id for the navigation request will be -1. If
   // so, allow this request since it's not going to another renderer.
   return render_process_id == -1 ||
          instant_io_context->IsInstantProcess(render_process_id);
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 1013697..09831c1 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -1126,16 +1126,16 @@
   ui_test_utils::NavigateToURL(browser(), webui_url);
   content::WebContents* old_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
-            old_tab->GetMainFrame()->GetEnabledBindings());
+  EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
+              old_tab->GetMainFrame()->GetEnabledBindings());
 
   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   ASSERT_EQ(1u, active_browser_list_->size());
   content::WebContents* new_tab =
       new_browser->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(webui_url, new_tab->GetURL());
-  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
-            new_tab->GetMainFrame()->GetEnabledBindings());
+  EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
+              new_tab->GetMainFrame()->GetEnabledBindings());
 }
 
 // http://crbug.com/803510 : Flaky on dbg and ASan bots.
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc
index aa29f94..882cd92 100644
--- a/chrome/browser/signin/chrome_signin_helper.cc
+++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -38,7 +38,6 @@
 #include "components/signin/public/base/signin_buildflags.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_request_info.h"
 #include "content/public/common/resource_type.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "net/http/http_response_headers.h"
@@ -433,73 +432,14 @@
 
 }  // namespace
 
-ChromeRequestAdapter::ChromeRequestAdapter(net::URLRequest* request)
-    : RequestAdapter(request) {}
+ChromeRequestAdapter::ChromeRequestAdapter() : RequestAdapter(nullptr) {}
 
 ChromeRequestAdapter::~ChromeRequestAdapter() = default;
 
-content::WebContents::Getter ChromeRequestAdapter::GetWebContentsGetter()
-    const {
-  auto* info = content::ResourceRequestInfo::ForRequest(request_);
-  return info->GetWebContentsGetterForRequest();
-}
-
-content::ResourceType ChromeRequestAdapter::GetResourceType() const {
-  auto* info = content::ResourceRequestInfo::ForRequest(request_);
-  return info->GetResourceType();
-}
-
-GURL ChromeRequestAdapter::GetReferrerOrigin() const {
-  return GURL(request_->referrer()).GetOrigin();
-}
-
-void ChromeRequestAdapter::SetDestructionCallback(base::OnceClosure closure) {
-  if (request_->GetUserData(kRequestDestructionObserverUserDataKey))
-    return;
-
-  request_->SetUserData(
-      kRequestDestructionObserverUserDataKey,
-      std::make_unique<RequestDestructionObserverUserData>(std::move(closure)));
-}
-
-ResponseAdapter::ResponseAdapter(net::URLRequest* request)
-    : request_(request) {}
+ResponseAdapter::ResponseAdapter() = default;
 
 ResponseAdapter::~ResponseAdapter() = default;
 
-content::WebContents::Getter ResponseAdapter::GetWebContentsGetter() const {
-  auto* info = content::ResourceRequestInfo::ForRequest(request_);
-  return info->GetWebContentsGetterForRequest();
-}
-
-bool ResponseAdapter::IsMainFrame() const {
-  auto* info = content::ResourceRequestInfo::ForRequest(request_);
-  return info && (info->GetResourceType() == content::ResourceType::kMainFrame);
-}
-
-GURL ResponseAdapter::GetOrigin() const {
-  return request_->url().GetOrigin();
-}
-
-const net::HttpResponseHeaders* ResponseAdapter::GetHeaders() const {
-  return request_->response_headers();
-}
-
-void ResponseAdapter::RemoveHeader(const std::string& name) {
-  request_->response_headers()->RemoveHeader(name);
-}
-
-base::SupportsUserData::Data* ResponseAdapter::GetUserData(
-    const void* key) const {
-  return request_->GetUserData(key);
-}
-
-void ResponseAdapter::SetUserData(
-    const void* key,
-    std::unique_ptr<base::SupportsUserData::Data> data) {
-  request_->SetUserData(key, std::move(data));
-}
-
 void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms) {
   g_dice_account_reconcilor_blocked_delay_ms = delay_ms;
 }
diff --git a/chrome/browser/signin/chrome_signin_helper.h b/chrome/browser/signin/chrome_signin_helper.h
index a008f5b..988ec13 100644
--- a/chrome/browser/signin/chrome_signin_helper.h
+++ b/chrome/browser/signin/chrome_signin_helper.h
@@ -21,7 +21,6 @@
 
 namespace net {
 class HttpResponseHeaders;
-class URLRequest;
 }
 
 class GURL;
@@ -38,17 +37,19 @@
 
 class ChromeRequestAdapter : public RequestAdapter {
  public:
-  explicit ChromeRequestAdapter(net::URLRequest* request);
+  ChromeRequestAdapter();
   ~ChromeRequestAdapter() override;
 
-  virtual content::WebContents::Getter GetWebContentsGetter() const;
-  virtual content::ResourceType GetResourceType() const;
-  virtual GURL GetReferrerOrigin() const;
+  virtual content::WebContents::Getter GetWebContentsGetter() const = 0;
+
+  virtual content::ResourceType GetResourceType() const = 0;
+
+  virtual GURL GetReferrerOrigin() const = 0;
 
   // Associate a callback with this request which will be executed when the
   // request is complete (including any redirects). If a callback was already
   // registered this function does nothing.
-  virtual void SetDestructionCallback(base::OnceClosure closure);
+  virtual void SetDestructionCallback(base::OnceClosure closure) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeRequestAdapter);
@@ -56,22 +57,21 @@
 
 class ResponseAdapter {
  public:
-  explicit ResponseAdapter(net::URLRequest* request);
+  ResponseAdapter();
   virtual ~ResponseAdapter();
 
-  virtual content::WebContents::Getter GetWebContentsGetter() const;
-  virtual bool IsMainFrame() const;
-  virtual GURL GetOrigin() const;
-  virtual const net::HttpResponseHeaders* GetHeaders() const;
-  virtual void RemoveHeader(const std::string& name);
+  virtual content::WebContents::Getter GetWebContentsGetter() const = 0;
+  virtual bool IsMainFrame() const = 0;
+  virtual GURL GetOrigin() const = 0;
+  virtual const net::HttpResponseHeaders* GetHeaders() const = 0;
+  virtual void RemoveHeader(const std::string& name) = 0;
 
-  virtual base::SupportsUserData::Data* GetUserData(const void* key) const;
-  virtual void SetUserData(const void* key,
-                           std::unique_ptr<base::SupportsUserData::Data> data);
+  virtual base::SupportsUserData::Data* GetUserData(const void* key) const = 0;
+  virtual void SetUserData(
+      const void* key,
+      std::unique_ptr<base::SupportsUserData::Data> data) = 0;
 
  private:
-  net::URLRequest* const request_;
-
   DISALLOW_COPY_AND_ASSIGN(ResponseAdapter);
 };
 
diff --git a/chrome/browser/signin/chrome_signin_helper_unittest.cc b/chrome/browser/signin/chrome_signin_helper_unittest.cc
index d803a9b..f51b4113 100644
--- a/chrome/browser/signin/chrome_signin_helper_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_helper_unittest.cc
@@ -55,6 +55,49 @@
   const std::string header_value_;
 };
 
+class TestResponseAdapter : public signin::ResponseAdapter,
+                            public base::SupportsUserData {
+ public:
+  TestResponseAdapter(const std::string& header_name,
+                      const std::string& header_value,
+                      bool is_main_frame)
+      : is_main_frame_(is_main_frame),
+        headers_(new net::HttpResponseHeaders(std::string())) {
+    headers_->AddHeader(header_name + ": " + header_value);
+  }
+
+  ~TestResponseAdapter() override {}
+
+  content::WebContents::Getter GetWebContentsGetter() const override {
+    return base::BindRepeating(
+        []() -> content::WebContents* { return nullptr; });
+  }
+  bool IsMainFrame() const override { return is_main_frame_; }
+  GURL GetOrigin() const override { return GURL(kGaiaUrl); }
+  const net::HttpResponseHeaders* GetHeaders() const override {
+    return headers_.get();
+  }
+
+  void RemoveHeader(const std::string& name) override {
+    headers_->RemoveHeader(name);
+  }
+
+  base::SupportsUserData::Data* GetUserData(const void* key) const override {
+    return base::SupportsUserData::GetUserData(key);
+  }
+
+  void SetUserData(
+      const void* key,
+      std::unique_ptr<base::SupportsUserData::Data> data) override {
+    return base::SupportsUserData::SetUserData(key, std::move(data));
+  }
+
+ private:
+  bool is_main_frame_;
+  scoped_refptr<net::HttpResponseHeaders> headers_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestResponseAdapter);
+};
 
 }  // namespace
 
@@ -65,36 +108,8 @@
 
   ~ChromeSigninHelperTest() override {}
 
-  void SetupRequest(const std::string& header_name,
-                    const std::string& header_value,
-                    bool is_main_frame) {
-    test_request_delegate_ = std::make_unique<net::TestDelegate>();
-    request_ = url_request_context_.CreateRequest(
-        kGaiaUrl, net::DEFAULT_PRIORITY, test_request_delegate_.get(),
-        TRAFFIC_ANNOTATION_FOR_TESTS);
-    content::ResourceRequestInfo::AllocateForTesting(
-        request_.get(),
-        is_main_frame ? content::ResourceType::kMainFrame
-                      : content::ResourceType::kSubFrame,
-        nullptr, -1, -1, -1, true, content::ResourceInterceptPolicy::kAllowNone,
-        true, content::PREVIEWS_OFF, nullptr);
-    net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
-        kGaiaUrl,
-        std::make_unique<TestRequestInterceptor>(header_name, header_value));
-    request_->Start();
-    base::RunLoop().RunUntilIdle();
-    net::URLRequestFilter::GetInstance()->RemoveUrlHandler(kGaiaUrl);
-
-    // Check that the response header is correctly set.
-    net::HttpResponseHeaders* response_headers = request_->response_headers();
-    ASSERT_TRUE(response_headers);
-    ASSERT_TRUE(request_->response_headers()->HasHeader(header_name));
-  }
-
   content::TestBrowserThreadBundle thread_bundle_;
-  net::TestURLRequestContext url_request_context_;
   std::unique_ptr<net::TestDelegate> test_request_delegate_;
-  std::unique_ptr<net::URLRequest> request_;
 };
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
@@ -102,17 +117,14 @@
 TEST_F(ChromeSigninHelperTest, RemoveDiceSigninHeader) {
   ScopedAccountConsistencyDiceMigration scoped_dice_migration;
 
-  // Create a response with the Dice header.
-  SetupRequest(signin::kDiceResponseHeader, "Foo", /*is_main_frame=*/false);
-
   // Process the header.
-  signin::ResponseAdapter response_adapter(request_.get());
-  signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(),
+  TestResponseAdapter adapter(signin::kDiceResponseHeader, "Foo",
+                              /*is_main_frame=*/false);
+  signin::ProcessAccountConsistencyResponseHeaders(&adapter, GURL(),
                                                    false /* is_incognito */);
 
   // Check that the header has been removed.
-  EXPECT_FALSE(
-      request_->response_headers()->HasHeader(signin::kDiceResponseHeader));
+  EXPECT_FALSE(adapter.GetHeaders()->HasHeader(signin::kDiceResponseHeader));
 }
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
@@ -120,35 +132,31 @@
 TEST_F(ChromeSigninHelperTest, MirrorMainFrame) {
   ScopedAccountConsistencyMirror scoped_mirror;
 
-  // Create a response with the Mirror header.
-  SetupRequest(kChromeManageAccountsHeader, kMirrorAction,
-               /*is_main_frame=*/true);
-
   // Process the header.
-  signin::ResponseAdapter response_adapter(request_.get());
+  TestResponseAdapter response_adapter(kChromeManageAccountsHeader,
+                                       kMirrorAction,
+                                       /*is_main_frame=*/true);
   signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(),
                                                    false /* is_incognito */);
   // Check that the header has not been removed.
   EXPECT_TRUE(
-      request_->response_headers()->HasHeader(kChromeManageAccountsHeader));
+      response_adapter.GetHeaders()->HasHeader(kChromeManageAccountsHeader));
   // Request was flagged with the user data.
-  EXPECT_TRUE(
-      request_->GetUserData(signin::kManageAccountsHeaderReceivedUserDataKey));
+  EXPECT_TRUE(response_adapter.GetUserData(
+      signin::kManageAccountsHeaderReceivedUserDataKey));
 }
 
 // Tests that user data is not set on Mirror requests for sub frames.
 TEST_F(ChromeSigninHelperTest, MirrorSubFrame) {
   ScopedAccountConsistencyMirror scoped_mirror;
 
-  // Create a response with the Mirror header.
-  SetupRequest(kChromeManageAccountsHeader, kMirrorAction,
-               /*is_main_frame=*/false);
-
   // Process the header.
-  signin::ResponseAdapter response_adapter(request_.get());
+  TestResponseAdapter response_adapter(kChromeManageAccountsHeader,
+                                       kMirrorAction,
+                                       /*is_main_frame=*/false);
   signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(),
                                                    false /* is_incognito */);
   // Request was not flagged with the user data.
-  EXPECT_FALSE(
-      request_->GetUserData(signin::kManageAccountsHeaderReceivedUserDataKey));
+  EXPECT_FALSE(response_adapter.GetUserData(
+      signin::kManageAccountsHeaderReceivedUserDataKey));
 }
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
index b8774958..68c54ab 100644
--- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
+++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
@@ -190,8 +190,7 @@
                       const net::HttpRequestHeaders& original_headers,
                       net::HttpRequestHeaders* modified_headers,
                       std::vector<std::string>* removed_headers)
-      : ChromeRequestAdapter(nullptr),
-        in_progress_request_(in_progress_request),
+      : in_progress_request_(in_progress_request),
         original_headers_(original_headers),
         modified_headers_(modified_headers),
         removed_headers_(removed_headers) {
@@ -257,9 +256,7 @@
  public:
   ProxyResponseAdapter(InProgressRequest* in_progress_request,
                        net::HttpResponseHeaders* headers)
-      : ResponseAdapter(nullptr),
-        in_progress_request_(in_progress_request),
-        headers_(headers) {
+      : in_progress_request_(in_progress_request), headers_(headers) {
     DCHECK(in_progress_request_);
     DCHECK(headers_);
   }
diff --git a/chrome/browser/signin/chrome_signin_url_loader_throttle.cc b/chrome/browser/signin/chrome_signin_url_loader_throttle.cc
index 177c7fd..7bcc217 100644
--- a/chrome/browser/signin/chrome_signin_url_loader_throttle.cc
+++ b/chrome/browser/signin/chrome_signin_url_loader_throttle.cc
@@ -16,8 +16,7 @@
                          const net::HttpRequestHeaders& original_headers,
                          net::HttpRequestHeaders* modified_headers,
                          std::vector<std::string>* headers_to_remove)
-      : ChromeRequestAdapter(nullptr),
-        throttle_(throttle),
+      : throttle_(throttle),
         original_headers_(original_headers),
         modified_headers_(modified_headers),
         headers_to_remove_(headers_to_remove) {}
@@ -79,7 +78,7 @@
  public:
   ThrottleResponseAdapter(URLLoaderThrottle* throttle,
                           net::HttpResponseHeaders* headers)
-      : ResponseAdapter(nullptr), throttle_(throttle), headers_(headers) {}
+      : throttle_(throttle), headers_(headers) {}
 
   ~ThrottleResponseAdapter() override = default;
 
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index c0baaa7..75fe2cb 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -3312,8 +3312,8 @@
   // SetUpOnMainThread adds this hostname to the resolver so that it's not
   // blocked (browser_test_base.cc has a resolver that blocks all non-local
   // hostnames by default to ensure tests don't hit the network). This is
-  // critical to do because for PlzNavigate the request would otherwise get
-  // cancelled in the browser before the renderer sees it.
+  // critical to do because the request would otherwise get cancelled in the
+  // browser before the renderer sees it.
 
   std::string top_frame_path = GetTopFramePath(
       *embedded_test_server(), https_server_, https_server_expired_);
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
index c9f1039f..42f80407 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -84,14 +84,6 @@
 // Names of DocumentLoad histograms.
 constexpr const char kDocumentLoadActivationLevel[] =
     "SubresourceFilter.DocumentLoad.ActivationState";
-constexpr const char kSubresourceLoadsTotal[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Total";
-constexpr const char kSubresourceLoadsEvaluated[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Evaluated";
-constexpr const char kSubresourceLoadsMatchedRules[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules";
-constexpr const char kSubresourceLoadsDisallowed[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Disallowed";
 
 constexpr const char kSubresourceLoadsTotalForPage[] =
     "SubresourceFilter.PageLoad.NumSubresourceLoads.Total";
@@ -111,10 +103,6 @@
     "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalWallDuration";
 constexpr const char kEvaluationTotalCPUDurationForPage[] =
     "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalCPUDuration";
-constexpr const char kEvaluationTotalWallDurationForDocument[] =
-    "SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalWallDuration";
-constexpr const char kEvaluationTotalCPUDurationForDocument[] =
-    "SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration";
 constexpr const char kEvaluationWallDuration[] =
     "SubresourceFilter.SubresourceLoad.Evaluation.WallDuration";
 constexpr const char kEvaluationCPUDuration[] =
@@ -410,10 +398,8 @@
   NavigateFrame(kSubframeNames[0], allowed_empty_subdocument_url);
 
   // Finally, navigate the first subframe to an allowed URL that redirects to a
-  // disallowed URL, and verify that:
-  //  -- The navigation gets blocked and the frame collapsed (with PlzNavigate).
-  //  -- The navigation is cancelled, but the frame is not collapsed (without
-  //  PlzNavigate, where BLOCK_REQUEST_AND_COLLAPSE is not supported).
+  // disallowed URL, and verify that the navigation gets blocked and the frame
+  // collapsed.
   GURL disallowed_subdocument_url(
       GetTestUrl("subresource_filter/frame_with_included_script.html"));
   GURL redirect_to_disallowed_subdocument_url(embedded_test_server()->GetURL(
@@ -699,11 +685,6 @@
   content::FetchHistogramsFromChildProcesses();
   SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
 
-  tester.ExpectTotalCount(kEvaluationTotalWallDurationForDocument,
-                          time_recorded ? 6 : 0);
-  tester.ExpectTotalCount(kEvaluationTotalCPUDurationForDocument,
-                          time_recorded ? 6 : 0);
-
   // 5 subframes, each with an include.js, plus a top level include.js.
   int num_subresource_checks = 5 + 5 + 1;
   tester.ExpectTotalCount(kEvaluationWallDuration,
@@ -723,16 +704,6 @@
       kDocumentLoadActivationLevel,
       static_cast<base::Histogram::Sample>(mojom::ActivationLevel::kEnabled),
       6);
-
-  EXPECT_THAT(tester.GetAllSamples(kSubresourceLoadsTotal),
-              ::testing::ElementsAre(base::Bucket(0, 3), base::Bucket(2, 3)));
-  EXPECT_THAT(tester.GetAllSamples(kSubresourceLoadsEvaluated),
-              ::testing::ElementsAre(base::Bucket(0, 3), base::Bucket(2, 3)));
-
-  EXPECT_THAT(tester.GetAllSamples(kSubresourceLoadsMatchedRules),
-              ::testing::ElementsAre(base::Bucket(0, 4), base::Bucket(2, 2)));
-  EXPECT_THAT(tester.GetAllSamples(kSubresourceLoadsDisallowed),
-              ::testing::ElementsAre(base::Bucket(0, 4), base::Bucket(2, 2)));
 }
 
 }  // namespace
@@ -780,19 +751,12 @@
   SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
 
   // But they still should not be recorded as the filtering is not activated.
-  tester.ExpectTotalCount(kEvaluationTotalWallDurationForDocument, 0);
-  tester.ExpectTotalCount(kEvaluationTotalCPUDurationForDocument, 0);
   tester.ExpectTotalCount(kEvaluationWallDuration, 0);
   tester.ExpectTotalCount(kEvaluationCPUDuration, 0);
 
   tester.ExpectTotalCount(kActivationWallDuration, 0);
   tester.ExpectTotalCount(kActivationCPUDuration, 0);
 
-  tester.ExpectTotalCount(kSubresourceLoadsTotal, 0);
-  tester.ExpectTotalCount(kSubresourceLoadsEvaluated, 0);
-  tester.ExpectTotalCount(kSubresourceLoadsMatchedRules, 0);
-  tester.ExpectTotalCount(kSubresourceLoadsDisallowed, 0);
-
   // Although SubresourceFilterAgents still record the activation decision.
   tester.ExpectUniqueSample(
       kDocumentLoadActivationLevel,
diff --git a/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
index d33a061..7d9d654 100644
--- a/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_special_subframe_navigations_browsertest.cc
@@ -51,9 +51,7 @@
 }
 
 // Navigate to a site with site hierarchy a(b(c)). Let a navigate c to a data
-// URL, and expect that the resulting frame has activation. We expect to fail in
-// --site-per-process with PlzNavigate disabled because c is navigated to a's
-// process. Therefore we can't sniff b's activation state from c.
+// URL, and expect that the resulting frame has activation.
 // See crbug.com/739777.
 IN_PROC_BROWSER_TEST_F(SubresourceFilterSpecialSubframeNavigationsBrowserTest,
                        NavigateCrossProcessDataUrl_MaintainsActivation) {
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
index e5030da..771dd37 100644
--- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -514,8 +514,9 @@
   ExpectNavigationChain({first_url, second_url});
 }
 
+// TODO(crbug.com/972871): Fails or crashes on all platforms flakily.
 IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest,
-                       NavigationChainAlteredDestructively) {
+                       DISABLED_NavigationChainAlteredDestructively) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
   ASSERT_TRUE(CheckInitialState(0));
 
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
index 6538ed0..8d49887 100644
--- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -44,7 +44,9 @@
   DISALLOW_COPY_AND_ASSIGN(TwoClientPreferencesSyncTest);
 };
 
-IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, E2E_ENABLED(Sanity)) {
+// TODO(crbug.com/988404): Enable once not flaky anymore.
+IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest,
+                       E2E_ENABLED(DISABLED_Sanity)) {
   DisableVerifier();
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
   // Wait until sync settles before we override the prefs below.
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
index 1967cfc..284461d3 100644
--- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
+++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
@@ -60,3 +60,8 @@
 void FakeAccessibilityController::SetVirtualKeyboardVisible(bool is_visible) {}
 
 void FakeAccessibilityController::NotifyAccessibilityStatusChanged() {}
+
+bool FakeAccessibilityController::IsAccessibilityFeatureVisibleInTrayMenu(
+    const std::string& path) {
+  return true;
+}
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
index 029346f..c4ff5aab 100644
--- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
+++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
@@ -45,6 +45,8 @@
   base::string16 GetBatteryDescription() const override;
   void SetVirtualKeyboardVisible(bool is_visible) override;
   void NotifyAccessibilityStatusChanged() override;
+  bool IsAccessibilityFeatureVisibleInTrayMenu(
+      const std::string& path) override;
 
  private:
   bool was_client_set_ = false;
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index 181f4c6..e49888c2 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -57,7 +57,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/user_agent.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/constants.h"
@@ -611,7 +611,7 @@
                                 ui::PAGE_TRANSITION_FROM_API));
 
   if (from_user_interaction)
-    navigate_params.was_activated = content::WasActivatedOption::kYes;
+    navigate_params.was_activated = content::mojom::WasActivatedOption::kYes;
 
   Navigate(&navigate_params);
 
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index 4e3ab2d..09826398 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -1813,8 +1813,8 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   content::RenderViewHost* webui_rvh = popup->GetRenderViewHost();
   content::RenderFrameHost* webui_rfh = popup->GetMainFrame();
-  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
-            webui_rfh->GetEnabledBindings());
+  EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
+              webui_rfh->GetEnabledBindings());
 
   // Navigate to another page in the popup.
   GURL nonwebui_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
@@ -1828,8 +1828,8 @@
   back_load_observer.Wait();
   EXPECT_EQ(webui_rvh, popup->GetRenderViewHost());
   EXPECT_TRUE(webui_rvh->IsRenderViewLive());
-  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
-            webui_rvh->GetMainFrame()->GetEnabledBindings());
+  EXPECT_TRUE(content::BINDINGS_POLICY_MOJO_WEB_UI &
+              webui_rvh->GetMainFrame()->GetEnabledBindings());
 }
 
 // Test that main frame navigations generate a NavigationUIData with the
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h
index d2954c8..042bc79 100644
--- a/chrome/browser/ui/browser_navigator_params.h
+++ b/chrome/browser/ui/browser_navigator_params.h
@@ -16,7 +16,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/common/referrer.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "ui/base/page_transition_types.h"
@@ -276,8 +276,8 @@
   // outside of the page and pass it to the page as if it happened on a prior
   // page. For example, if the assistant opens a page we should treat the
   // user's interaction with the assistant as a previous user activation.
-  content::WasActivatedOption was_activated =
-      content::WasActivatedOption::kUnknown;
+  content::mojom::WasActivatedOption was_activated =
+      content::mojom::WasActivatedOption::kUnknown;
 
   // If this navigation was initiated from a link that specified the
   // hrefTranslate attribute, this contains the attribute's value (a BCP47
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
index 81e83ab..bf661a8 100644
--- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
+++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.cc
@@ -412,10 +412,6 @@
   }
 }
 
-// This function handles the case where browser-side navigation (PlzNavigate) is
-// enabled. DidStartNavigationToPendingEntry, below, handles the case where
-// PlzNavigate is not enabled. TODO(avi): When the non-PlzNavigate code is
-// removed, remove DidStartNavigationToPendingEntry.
 void JavaScriptDialogTabHelper::DidStartNavigation(
     content::NavigationHandle* navigation_handle) {
   // Close the dialog if the user started a new navigation. This allows reloads
@@ -423,10 +419,8 @@
   CloseDialog(DismissalCause::kTabNavigated, false, base::string16());
 }
 
-// This function handles the case where browser-side navigation (PlzNavigate) is
-// not enabled. DidStartNavigation, above, handles the case where PlzNavigate is
-// enabled. TODO(avi): When the non-PlzNavigate code is removed, remove
-// DidStartNavigationToPendingEntry.
+// TODO(avi): Remove this function since it is deprecated at the
+// WebContentsObserver level.
 void JavaScriptDialogTabHelper::DidStartNavigationToPendingEntry(
     const GURL& url,
     content::ReloadType reload_type) {
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
index de84fe2..202685e 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc
@@ -434,7 +434,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     CredentialProviderSigninDialogWinIntegrationDesktopVerificationTest,
-    DialogFailsToLoadOnIncorrectDesktop) {
+    DISABLED_DialogFailsToLoadOnIncorrectDesktop) {
   // Normally the GCPW signin dialog should only run on "winlogon" desktops. If
   // we are just running the test, we should not be under this desktop and the
   // dialog should fail to load.
diff --git a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc
index 640d123..1876f6bc 100644
--- a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc
+++ b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc
@@ -120,7 +120,7 @@
 
 std::unique_ptr<views::Textfield> CreateCvcTextfield() {
   auto textfield = std::make_unique<views::Textfield>();
-  textfield->set_placeholder_text(
+  textfield->SetPlaceholderText(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC));
   textfield->SetDefaultWidthInChars(8);
   textfield->SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_NUMBER);
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc
index 0c36685..6b0bf5cb 100644
--- a/chrome/browser/ui/views/find_bar_view.cc
+++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -255,7 +255,7 @@
     const base::string16& find_text,
     const gfx::Range& selected_range) {
   find_text_->SetText(find_text);
-  find_text_->SelectRange(selected_range);
+  find_text_->SetSelectedRange(selected_range);
 }
 
 base::string16 FindBarView::GetFindText() const {
diff --git a/chrome/browser/ui/views/hats/OWNERS b/chrome/browser/ui/views/hats/OWNERS
new file mode 100644
index 0000000..bbdb9fd
--- /dev/null
+++ b/chrome/browser/ui/views/hats/OWNERS
@@ -0,0 +1 @@
+file://chrome/browser/ui/hats/OWNERS
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 79b15c0..cfeebdf 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -289,7 +289,7 @@
       SelectAll(true);
       saved_selection_for_focus_change_ = gfx::Range();
     } else {
-      SelectRange(state->selection);
+      SetSelectedRange(state->selection);
       saved_selection_for_focus_change_ =
           state->saved_selection_for_focus_change;
     }
@@ -310,10 +310,10 @@
   const TemplateURL* const default_provider =
       model()->client()->GetTemplateURLService()->GetDefaultSearchProvider();
   if (default_provider) {
-    set_placeholder_text(l10n_util::GetStringFUTF16(
+    SetPlaceholderText(l10n_util::GetStringFUTF16(
         IDS_OMNIBOX_PLACEHOLDER_TEXT, default_provider->short_name()));
   } else {
-    set_placeholder_text(base::string16());
+    SetPlaceholderText(base::string16());
   }
 }
 
@@ -583,17 +583,17 @@
 
   SetText(text);
   // Select all the text to prioritize showing unselected text.
-  SelectRange(gfx::Range(range.start(), 0));
+  SetSelectedRange(gfx::Range(range.start(), 0));
   // Scroll selection right, to ensure |kPadRight| chars of selected text are
   // shown.
-  SelectRange(gfx::Range(range.start(),
-                         std::min(range.end() + kPadRight, range.start())));
+  SetSelectedRange(gfx::Range(
+      range.start(), std::min(range.end() + kPadRight, range.start())));
   // Scroll selection left, to ensure |kPadLeft| chars of unselected text are
   // shown.
-  SelectRange(
+  SetSelectedRange(
       gfx::Range(range.start(), range.end() - std::min(kPadLeft, range.end())));
   // Select the specified selection.
-  SelectRange(range);
+  SetSelectedRange(range);
 }
 
 base::string16 OmniboxViewViews::GetSelectedText() const {
@@ -740,7 +740,7 @@
 }
 
 void OmniboxViewViews::SetCaretPos(size_t caret_pos) {
-  SelectRange(gfx::Range(caret_pos, caret_pos));
+  SetSelectedRange(gfx::Range(caret_pos, caret_pos));
 }
 
 bool OmniboxViewViews::IsSelectAll() const {
@@ -803,7 +803,7 @@
 void OmniboxViewViews::OnRevertTemporaryText(const base::string16& display_text,
                                              const AutocompleteMatch& match) {
   SetAccessibilityLabel(display_text, match);
-  SelectRange(saved_temporary_selection_);
+  SetSelectedRange(saved_temporary_selection_);
   // We got here because the user hit the Escape key. We explicitly don't call
   // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
   // been called by now, and it would've called TextChanged() if it was
@@ -891,7 +891,7 @@
     OffsetDoubleClickWord(offset);
   }
 
-  SelectRange(gfx::Range(start, end));
+  SetSelectedRange(gfx::Range(start, end));
   return true;
 }
 
@@ -1249,7 +1249,7 @@
   } else if (action_data.action == ax::mojom::Action::kReplaceSelectedText) {
     model()->SetInputInProgress(true);
     if (saved_selection_for_focus_change_.IsValid()) {
-      SelectRange(saved_selection_for_focus_change_);
+      SetSelectedRange(saved_selection_for_focus_change_);
       saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
     }
     InsertOrReplaceText(base::UTF8ToUTF16(action_data.value));
@@ -1281,7 +1281,7 @@
 
   // Restore the selection we saved in OnBlur() if it's still valid.
   if (saved_selection_for_focus_change_.IsValid()) {
-    SelectRange(saved_selection_for_focus_change_);
+    SetSelectedRange(saved_selection_for_focus_change_);
     saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
   }
 
@@ -1363,7 +1363,7 @@
   model()->OnKillFocus();
 
   // Deselect the text. Ensures the cursor is an I-beam.
-  SelectRange(gfx::Range(0));
+  SetSelectedRange(gfx::Range(0));
 
   // When deselected, elide and reset scroll position. After eliding, the old
   // scroll offset is meaningless (since the string is guaranteed to fit within
@@ -1659,7 +1659,7 @@
           // to the beginning of the full unelided URL.
           size_t start, end;
           GetSelectionBounds(&start, &end);
-          SelectRange(gfx::Range(start, 0));
+          SetSelectedRange(gfx::Range(start, 0));
         } else {
           // After uneliding, move the caret to the beginning of the full
           // unelided URL.
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
index fee070f4..5435ca1 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -747,7 +747,7 @@
       static_cast<ValidatingTextfield*>(delegate_->dialog_view()->GetViewByID(
           EditorViewController::GetInputFieldViewId(type)));
   DCHECK(textfield);
-  return textfield->invalid();
+  return textfield->GetInvalid();
 }
 
 bool PaymentRequestBrowserTestBase::IsEditorComboboxInvalid(
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
index 14f5431..5b625f8 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
@@ -623,7 +623,7 @@
   DCHECK(textfield);
   EXPECT_TRUE(textfield->GetText().empty());
   // Field is not invalid because there is nothing in it.
-  EXPECT_FALSE(textfield->invalid());
+  EXPECT_FALSE(textfield->GetInvalid());
   EXPECT_TRUE(textfield->HasFocus());
 }
 
@@ -648,7 +648,7 @@
           EditorViewController::GetInputFieldViewId(autofill::NAME_FULL)));
   DCHECK(textfield);
   EXPECT_FALSE(textfield->GetText().empty());
-  EXPECT_FALSE(textfield->invalid());
+  EXPECT_FALSE(textfield->GetInvalid());
   EXPECT_FALSE(textfield->HasFocus());
 
   // Since we can't easily tell which field is after name, let's just make sure
diff --git a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc
index 5d328f2..cf57f85 100644
--- a/chrome/browser/ui/views/payments/validating_textfield_unittest.cc
+++ b/chrome/browser/ui/views/payments/validating_textfield_unittest.cc
@@ -69,11 +69,11 @@
   textfield->OnContentsChanged();
 
   // Not marked as invalid.
-  EXPECT_FALSE(textfield->invalid());
+  EXPECT_FALSE(textfield->GetInvalid());
 
   // On blur though, there is a first validation.
   textfield->OnBlur();
-  EXPECT_TRUE(textfield->invalid());
+  EXPECT_TRUE(textfield->GetInvalid());
 
   // On further text adjustements, the validation runs now. Set a valid string
   // (<=5 characters).
@@ -81,7 +81,7 @@
   textfield->OnContentsChanged();
 
   // No longer invalid.
-  EXPECT_FALSE(textfield->invalid());
+  EXPECT_FALSE(textfield->GetInvalid());
 }
 
 }  // namespace payments
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
index af3ee72..380fe00 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/omnibox/omnibox_page_handler.h"
+#include "chrome/browser/ui/webui/version_handler.h"
 #include "chrome/browser/ui/webui/version_ui.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/browser_resources.h"
@@ -16,7 +17,8 @@
 #include "content/public/browser/web_ui_controller.h"
 #include "content/public/browser/web_ui_data_source.h"
 
-OmniboxUI::OmniboxUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui) {
+OmniboxUI::OmniboxUI(content::WebUI* web_ui)
+    : ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {
   // Set up the chrome://omnibox/ source.
   content::WebUIDataSource* source =
       content::WebUIDataSource::Create(chrome::kChromeUIOmniboxHost);
@@ -43,6 +45,7 @@
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source);
   AddHandlerToRegistry(base::BindRepeating(&OmniboxUI::BindOmniboxPageHandler,
                                            base::Unretained(this)));
+  web_ui->AddMessageHandler(std::make_unique<VersionHandler>());
 }
 
 OmniboxUI::~OmniboxUI() {}
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 4bf988f..5c4620a 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -587,7 +587,7 @@
 
 // Enables Load image context menu item for broken images.
 const base::Feature kLoadBrokenImagesFromContextMenu{
-    "LoadBrokenImagesFromContextMenu", base::FEATURE_DISABLED_BY_DEFAULT};
+    "LoadBrokenImagesFromContextMenu", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls whether to show Safety Tip warnings on low-reputation sites.
 const base::Feature kSafetyTipUI{"SafetyTip",
diff --git a/chrome/common/media_router/mojo/typemaps.gni b/chrome/common/media_router/mojo/typemaps.gni
deleted file mode 100644
index 7d134e8..0000000
--- a/chrome/common/media_router/mojo/typemaps.gni
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-typemaps = [
-  "//chrome/common/media_router/mojo/media_router.typemap",
-  "//chrome/common/media_router/mojo/media_status.typemap",
-]
diff --git a/chrome/common/media_router/mojo/BUILD.gn b/chrome/common/media_router/mojom/BUILD.gn
similarity index 100%
rename from chrome/common/media_router/mojo/BUILD.gn
rename to chrome/common/media_router/mojom/BUILD.gn
diff --git a/chrome/common/media_router/mojo/OWNERS b/chrome/common/media_router/mojom/OWNERS
similarity index 61%
rename from chrome/common/media_router/mojo/OWNERS
rename to chrome/common/media_router/mojom/OWNERS
index 2c44a46..ae29a36aa 100644
--- a/chrome/common/media_router/mojo/OWNERS
+++ b/chrome/common/media_router/mojom/OWNERS
@@ -1,6 +1,6 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chrome/common/media_router/mojo/media_controller.mojom b/chrome/common/media_router/mojom/media_controller.mojom
similarity index 95%
rename from chrome/common/media_router/mojo/media_controller.mojom
rename to chrome/common/media_router/mojom/media_controller.mojom
index 80ad5f4a..b169e6a 100644
--- a/chrome/common/media_router/mojo/media_controller.mojom
+++ b/chrome/common/media_router/mojom/media_controller.mojom
@@ -4,7 +4,7 @@
 
 module media_router.mojom;
 
-import "chrome/common/media_router/mojo/media_status.mojom";
+import "chrome/common/media_router/mojom/media_status.mojom";
 import "mojo/public/mojom/base/time.mojom";
 
 // Interface for a controller to change the current state of a media content.
diff --git a/chrome/common/media_router/mojo/media_router.mojom b/chrome/common/media_router/mojom/media_router.mojom
similarity index 99%
rename from chrome/common/media_router/mojo/media_router.mojom
rename to chrome/common/media_router/mojom/media_router.mojom
index fe08d5b..a4b24493 100644
--- a/chrome/common/media_router/mojo/media_router.mojom
+++ b/chrome/common/media_router/mojom/media_router.mojom
@@ -4,8 +4,8 @@
 
 module media_router.mojom;
 
-import "chrome/common/media_router/mojo/media_controller.mojom";
-import "chrome/common/media_router/mojo/media_status.mojom";
+import "chrome/common/media_router/mojom/media_controller.mojom";
+import "chrome/common/media_router/mojom/media_status.mojom";
 import "components/mirroring/mojom/mirroring_service_host.mojom";
 import "media/mojo/interfaces/mirror_service_remoting.mojom";
 import "mojo/public/mojom/base/time.mojom";
@@ -205,7 +205,7 @@
 // - RouteRequestResult::ResultCode in route_request_result.h
 // - MediaRouteProviderResult enum in tools/metrics/histograms.xml.
 // - mr.RouteRequestResultCode in route_request_error.js
-// - media_router_struct_traits.h
+// - media_router_mojom_traits.h
 enum RouteRequestResultCode {
   UNKNOWN_ERROR,
   OK,
diff --git a/chrome/common/media_router/mojo/media_router.typemap b/chrome/common/media_router/mojom/media_router.typemap
similarity index 86%
rename from chrome/common/media_router/mojo/media_router.typemap
rename to chrome/common/media_router/mojom/media_router.typemap
index 57e6e3b5..5f835cc 100644
--- a/chrome/common/media_router/mojo/media_router.typemap
+++ b/chrome/common/media_router/mojom/media_router.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//chrome/common/media_router/mojo/media_router.mojom"
+mojom = "//chrome/common/media_router/mojom/media_router.mojom"
 public_headers = [
   "//chrome/common/media_router/discovery/media_sink_internal.h",
   "//chrome/common/media_router/issue.h",
@@ -22,9 +22,9 @@
   "//url",
 ]
 traits_headers =
-    [ "//chrome/common/media_router/mojo/media_router_struct_traits.h" ]
+    [ "//chrome/common/media_router/mojom/media_router_mojom_traits.h" ]
 sources = [
-  "//chrome/common/media_router/mojo/media_router_struct_traits.cc",
+  "//chrome/common/media_router/mojom/media_router_mojom_traits.cc",
 ]
 type_mappings = [
   "media_router.mojom.Issue=media_router::IssueInfo",
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits.cc b/chrome/common/media_router/mojom/media_router_mojom_traits.cc
similarity index 98%
rename from chrome/common/media_router/mojo/media_router_struct_traits.cc
rename to chrome/common/media_router/mojom/media_router_mojom_traits.cc
index 48b0d9e..d6b4a10 100644
--- a/chrome/common/media_router/mojo/media_router_struct_traits.cc
+++ b/chrome/common/media_router/mojom/media_router_mojom_traits.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/common/media_router/mojo/media_router_struct_traits.h"
+#include "chrome/common/media_router/mojom/media_router_mojom_traits.h"
 
 #include "chrome/common/media_router/media_source.h"
 #include "services/network/public/cpp/ip_address_mojom_traits.h"
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits.h b/chrome/common/media_router/mojom/media_router_mojom_traits.h
similarity index 98%
rename from chrome/common/media_router/mojo/media_router_struct_traits.h
rename to chrome/common/media_router/mojom/media_router_mojom_traits.h
index 2f2005b..21e06d7 100644
--- a/chrome/common/media_router/mojo/media_router_struct_traits.h
+++ b/chrome/common/media_router/mojom/media_router_mojom_traits.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 CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_STRUCT_TRAITS_H_
-#define CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_STRUCT_TRAITS_H_
+#ifndef CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_ROUTER_MOJOM_TRAITS_H_
+#define CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_ROUTER_MOJOM_TRAITS_H_
 
 #include <string>
 
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
 #include "chrome/common/media_router/issue.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
 #include "chrome/common/media_router/route_request_result.h"
 #include "net/base/ip_endpoint.h"
 
@@ -522,4 +522,4 @@
 
 }  // namespace mojo
 
-#endif  // CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_STRUCT_TRAITS_H_
+#endif  // CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_ROUTER_MOJOM_TRAITS_H_
diff --git a/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc b/chrome/common/media_router/mojom/media_router_mojom_traits_unittest.cc
similarity index 93%
rename from chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc
rename to chrome/common/media_router/mojom/media_router_mojom_traits_unittest.cc
index b6acc67..6b0d182 100644
--- a/chrome/common/media_router/mojo/media_router_struct_traits_unittest.cc
+++ b/chrome/common/media_router/mojom/media_router_mojom_traits_unittest.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 "chrome/common/media_router/mojo/media_router_struct_traits.h"
+#include "chrome/common/media_router/mojom/media_router_mojom_traits.h"
 
 #include <utility>
 
 #include "base/test/scoped_task_environment.h"
 #include "chrome/common/media_router/discovery/media_sink_internal.h"
-#include "chrome/common/media_router/mojo/media_router.mojom.h"
-#include "chrome/common/media_router/mojo/media_router_traits_test_service.mojom.h"
+#include "chrome/common/media_router/mojom/media_router.mojom.h"
+#include "chrome/common/media_router/mojom/media_router_traits_test_service.mojom.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/common/media_router/mojo/media_router_traits_test_service.mojom b/chrome/common/media_router/mojom/media_router_traits_test_service.mojom
similarity index 86%
rename from chrome/common/media_router/mojo/media_router_traits_test_service.mojom
rename to chrome/common/media_router/mojom/media_router_traits_test_service.mojom
index 8431ff6..9b8b61f 100644
--- a/chrome/common/media_router/mojo/media_router_traits_test_service.mojom
+++ b/chrome/common/media_router/mojom/media_router_traits_test_service.mojom
@@ -4,7 +4,7 @@
 
 module media_router.mojom;
 
-import "chrome/common/media_router/mojo/media_router.mojom";
+import "chrome/common/media_router/mojom/media_router.mojom";
 
 // All functions on this interface echo their arguments to test StructTraits
 // serialization and deserialization.
diff --git a/chrome/common/media_router/mojo/media_status.mojom b/chrome/common/media_router/mojom/media_status.mojom
similarity index 100%
rename from chrome/common/media_router/mojo/media_status.mojom
rename to chrome/common/media_router/mojom/media_status.mojom
diff --git a/chrome/common/media_router/mojo/media_status.typemap b/chrome/common/media_router/mojom/media_status.typemap
similarity index 64%
rename from chrome/common/media_router/mojo/media_status.typemap
rename to chrome/common/media_router/mojom/media_status.typemap
index 81ce6ec5..c718e72 100644
--- a/chrome/common/media_router/mojo/media_status.typemap
+++ b/chrome/common/media_router/mojom/media_status.typemap
@@ -2,11 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//chrome/common/media_router/mojo/media_status.mojom"
+mojom = "//chrome/common/media_router/mojom/media_status.mojom"
 public_headers = [ "//chrome/common/media_router/media_status.h" ]
 traits_headers =
-    [ "//chrome/common/media_router/mojo/media_status_struct_traits.h" ]
+    [ "//chrome/common/media_router/mojom/media_status_mojom_traits.h" ]
 sources = [
-  "//chrome/common/media_router/mojo/media_status_struct_traits.cc",
+  "//chrome/common/media_router/mojom/media_status_mojom_traits.cc",
 ]
 type_mappings = [ "media_router.mojom.MediaStatus=media_router::MediaStatus" ]
diff --git a/chrome/common/media_router/mojo/media_status_struct_traits.cc b/chrome/common/media_router/mojom/media_status_mojom_traits.cc
similarity index 93%
rename from chrome/common/media_router/mojo/media_status_struct_traits.cc
rename to chrome/common/media_router/mojom/media_status_mojom_traits.cc
index ec7e515..29ba90b 100644
--- a/chrome/common/media_router/mojo/media_status_struct_traits.cc
+++ b/chrome/common/media_router/mojom/media_status_mojom_traits.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/common/media_router/mojo/media_status_struct_traits.h"
+#include "chrome/common/media_router/mojom/media_status_mojom_traits.h"
 
 #include "base/strings/string_util.h"
 #include "mojo/public/cpp/base/time_mojom_traits.h"
diff --git a/chrome/common/media_router/mojo/media_status_struct_traits.h b/chrome/common/media_router/mojom/media_status_mojom_traits.h
similarity index 91%
rename from chrome/common/media_router/mojo/media_status_struct_traits.h
rename to chrome/common/media_router/mojom/media_status_mojom_traits.h
index dc10a82..e755f44 100644
--- a/chrome/common/media_router/mojo/media_status_struct_traits.h
+++ b/chrome/common/media_router/mojom/media_status_mojom_traits.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 CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_STATUS_STRUCT_TRAITS_H_
-#define CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_STATUS_STRUCT_TRAITS_H_
+#ifndef CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_STATUS_MOJOM_TRAITS_H_
+#define CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_STATUS_MOJOM_TRAITS_H_
 
 #include <string>
 
 #include "chrome/common/media_router/media_status.h"
-#include "chrome/common/media_router/mojo/media_status.mojom.h"
+#include "chrome/common/media_router/mojom/media_status.mojom.h"
 
 namespace mojo {
 
@@ -97,4 +97,4 @@
 
 }  // namespace mojo
 
-#endif  // CHROME_COMMON_MEDIA_ROUTER_MOJO_MEDIA_STATUS_STRUCT_TRAITS_H_
+#endif  // CHROME_COMMON_MEDIA_ROUTER_MOJOM_MEDIA_STATUS_MOJOM_TRAITS_H_
diff --git a/chrome/common/media_router/mojom/typemaps.gni b/chrome/common/media_router/mojom/typemaps.gni
new file mode 100644
index 0000000..a151a2a
--- /dev/null
+++ b/chrome/common/media_router/mojom/typemaps.gni
@@ -0,0 +1,8 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+typemaps = [
+  "//chrome/common/media_router/mojom/media_router.typemap",
+  "//chrome/common/media_router/mojom/media_status.typemap",
+]
diff --git a/chrome/common/media_router/route_request_result.h b/chrome/common/media_router/route_request_result.h
index 0f579dbf..8b6a251 100644
--- a/chrome/common/media_router/route_request_result.h
+++ b/chrome/common/media_router/route_request_result.h
@@ -35,7 +35,7 @@
   // - RouteRequestResultCode in media_router.mojom
   // - MediaRouteProviderResult enum in tools/metrics/histograms.xml
   // - mr.RouteRequestResultCode in route_request_error.js
-  // - media_router_struct_traits.h
+  // - media_router_mojom_traits.h
   enum ResultCode {
     UNKNOWN_ERROR = 0,
     OK = 1,
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index 6885691..0387dde 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -30,8 +30,8 @@
     "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
   ]
   deps = [
-    "//chrome/common/media_router/mojo:media_controller_js",
-    "//chrome/common/media_router/mojo:media_router_js",
+    "//chrome/common/media_router/mojom:media_controller_js",
+    "//chrome/common/media_router/mojom:media_router_js",
     "//services/network/public/mojom:mojom_js",
     "//url/mojom:url_mojom_gurl_js",
     "//url/mojom:url_mojom_origin_js",
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
index a4cc63c..85938bda 100644
--- a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
+++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -205,13 +205,13 @@
 
   // Media router.
   source_map->RegisterSource(
-      "chrome/common/media_router/mojo/media_controller.mojom",
+      "chrome/common/media_router/mojom/media_controller.mojom",
       IDR_MEDIA_CONTROLLER_MOJOM_JS);
   source_map->RegisterSource(
-      "chrome/common/media_router/mojo/media_router.mojom",
+      "chrome/common/media_router/mojom/media_router.mojom",
       IDR_MEDIA_ROUTER_MOJOM_JS);
   source_map->RegisterSource(
-      "chrome/common/media_router/mojo/media_status.mojom",
+      "chrome/common/media_router/mojom/media_status.mojom",
       IDR_MEDIA_STATUS_MOJOM_JS);
   source_map->RegisterSource("media_router_bindings",
                              IDR_MEDIA_ROUTER_BINDINGS_JS);
diff --git a/chrome/renderer/loadtimes_extension_bindings.cc b/chrome/renderer/loadtimes_extension_bindings.cc
index d32f972..090b05b 100644
--- a/chrome/renderer/loadtimes_extension_bindings.cc
+++ b/chrome/renderer/loadtimes_extension_bindings.cc
@@ -153,12 +153,12 @@
     // browser-initiated navigations, this is some time after navigation start,
     // which means that developers who used this value as a way to track the
     // start of a navigation were misusing this timestamp and getting the wrong
-    // value - they should be using navigationStart intead. Additionally,
-    // once plznavigate ships, provisional loads will not be processed by the
-    // render process for browser-initiated navigations, so reporting the time a
-    // provisional load was processed in the render process will no longer make
-    // sense. Thus, we now report the time for navigationStart, which is a value
-    // more consistent with what developers currently use start_load_time for.
+    // value - they should be using navigationStart instead. Provisional loads
+    // will not be processed by the render process for browser-initiated
+    // navigations, so reporting the time a provisional load was processed in
+    // the render process will no longer make sense. Thus, we now report the
+    // time for navigationStart, which is a value more consistent with what
+    // developers currently use start_load_time for.
     double start_load_time = web_performance.NavigationStart();
     // TODO(bmcquade): Remove this. 'commit' time is a concept internal to
     // chrome that shouldn't be exposed to the web platform.
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js
index ede41b0..a66061c 100644
--- a/chrome/renderer/resources/extensions/media_router_bindings.js
+++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -9,9 +9,9 @@
 }
 mojo.config.autoLoadMojomDeps = false;
 
-loadScript('chrome/common/media_router/mojo/media_controller.mojom');
-loadScript('chrome/common/media_router/mojo/media_router.mojom');
-loadScript('chrome/common/media_router/mojo/media_status.mojom');
+loadScript('chrome/common/media_router/mojom/media_controller.mojom');
+loadScript('chrome/common/media_router/mojom/media_router.mojom');
+loadScript('chrome/common/media_router/mojom/media_status.mojom');
 loadScript('components/mirroring/mojom/cast_message_channel.mojom');
 loadScript('components/mirroring/mojom/mirroring_service_host.mojom');
 loadScript('components/mirroring/mojom/session_observer.mojom');
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index 91746f85..3e4b584 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -74,10 +74,10 @@
           <include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\chromeos/services/ime/public/mojom/input_engine.mojom.js" use_base_dir="false" type="BINDATA" />
         </if>
         <!-- Media Router Mojo service and bindings. -->
-        <include name="IDR_MEDIA_CONTROLLER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojo\media_controller.mojom.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_MEDIA_ROUTER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojo\media_router.mojom.js" use_base_dir="false" type="BINDATA" />
+        <include name="IDR_MEDIA_CONTROLLER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojom\media_controller.mojom.js" use_base_dir="false" type="BINDATA" />
+        <include name="IDR_MEDIA_ROUTER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojom\media_router.mojom.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_MEDIA_ROUTER_BINDINGS_JS" file="extensions\media_router_bindings.js" type="BINDATA" />
-        <include name="IDR_MEDIA_STATUS_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojo\media_status.mojom.js" use_base_dir="false" type="BINDATA" />
+        <include name="IDR_MEDIA_STATUS_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojom\media_status.mojom.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_MIRRORING_SERVICE_HOST_MOJOM_JS" file="${mojom_root}\components\mirroring\mojom\mirroring_service_host.mojom.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_MIRRORING_CAST_MESSAGE_CHANNEL_MOJOM_JS" file="${mojom_root}\components\mirroring\mojom\cast_message_channel.mojom.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_MIRRORING_SESSION_OBSERVER_MOJOM_JS" file="${mojom_root}\components\mirroring\mojom\session_observer.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 07a314e..de026aa 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3923,7 +3923,7 @@
       "../browser/ui/toolbar/mock_media_router_action_controller.h",
       "../common/media_router/discovery/media_sink_internal_unittest.cc",
       "../common/media_router/discovery/media_sink_service_base_unittest.cc",
-      "../common/media_router/mojo/media_router_struct_traits_unittest.cc",
+      "../common/media_router/mojom/media_router_mojom_traits_unittest.cc",
       "../common/media_router/providers/cast/cast_media_source_unittest.cc",
       "../renderer/media/webrtc_logging_agent_impl_unittest.cc",
     ]
diff --git a/chrome/test/data/extensions/api_test/login_screen_apis/extension.crx b/chrome/test/data/extensions/api_test/login_screen_apis/extension.crx
index 4ecf4eb..221b31ed 100644
--- a/chrome/test/data/extensions/api_test/login_screen_apis/extension.crx
+++ b/chrome/test/data/extensions/api_test/login_screen_apis/extension.crx
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/login_screen_apis/extension/background.js b/chrome/test/data/extensions/api_test/login_screen_apis/extension/background.js
index c2ed4f1..cd8f1ff 100644
--- a/chrome/test/data/extensions/api_test/login_screen_apis/extension/background.js
+++ b/chrome/test/data/extensions/api_test/login_screen_apis/extension/background.js
@@ -42,6 +42,20 @@
       chrome.test.succeed();
     });
   },
+  'LoginScreenUiUserCanCloseWindow': () => {
+    chrome.loginScreenUi.show({url: 'some/path.html',
+        userCanClose: true}, () => {
+      chrome.test.assertNoLastError();
+      chrome.test.succeed();
+    });
+  },
+  'LoginScreenUiUserCannotCloseWindow': () => {
+    chrome.loginScreenUi.show({url: 'some/path.html',
+        userCanClose: false}, () => {
+      chrome.test.assertNoLastError();
+      chrome.test.succeed();
+    });
+  },
 
   /* Storage ******************************************************************/
   'StorageCannotAccessLocalStorage': () => {
diff --git a/chrome/test/data/extensions/api_test/login_screen_apis/extension/manifest.json b/chrome/test/data/extensions/api_test/login_screen_apis/extension/manifest.json
index 27856e5..47ac707 100644
--- a/chrome/test/data/extensions/api_test/login_screen_apis/extension/manifest.json
+++ b/chrome/test/data/extensions/api_test/login_screen_apis/extension/manifest.json
@@ -1,6 +1,6 @@
 {
   "name": "Login screen APIs test extension",
-  "version": "1.17",
+  "version": "1.18",
   "manifest_version": 2,
   "description": "Login screen APIs test extension",
   "background": {
diff --git a/chrome/test/data/extensions/api_test/login_screen_apis/update_manifest.xml b/chrome/test/data/extensions/api_test/login_screen_apis/update_manifest.xml
index 37aea5d8..e005911 100644
--- a/chrome/test/data/extensions/api_test/login_screen_apis/update_manifest.xml
+++ b/chrome/test/data/extensions/api_test/login_screen_apis/update_manifest.xml
@@ -7,6 +7,6 @@
   <app appid='oclffehlkdgibkainkilopaalpdobkan'>
     <updatecheck
         codebase='http://mock.http/extensions/api_test/login_screen_apis/extension.crx'
-        version='1.17' />
+        version='1.18' />
    </app>
 </gupdate>
diff --git a/chrome/test/data/prerender/cacheable_image.png b/chrome/test/data/prerender/cacheable_image.png
new file mode 100644
index 0000000..48af4d55
--- /dev/null
+++ b/chrome/test/data/prerender/cacheable_image.png
Binary files differ
diff --git a/chrome/test/data/prerender/cacheable_image.png.mock-http-headers b/chrome/test/data/prerender/cacheable_image.png.mock-http-headers
new file mode 100644
index 0000000..8ad897b2
--- /dev/null
+++ b/chrome/test/data/prerender/cacheable_image.png.mock-http-headers
@@ -0,0 +1,4 @@
+HTTP/1.1 200 OK
+Content-Type: image/png
+Cache-Control: max-age=100000
+Access-Control-Allow-Origin: *
\ No newline at end of file
diff --git a/chrome/test/data/prerender/one_image.html b/chrome/test/data/prerender/one_image.html
new file mode 100644
index 0000000..6a92891
--- /dev/null
+++ b/chrome/test/data/prerender/one_image.html
@@ -0,0 +1 @@
+<img src="IMAGE_SRC">
\ No newline at end of file
diff --git a/chrome/test/data/prerender/two_iframes.html b/chrome/test/data/prerender/two_iframes.html
new file mode 100644
index 0000000..b4d6f0dc
--- /dev/null
+++ b/chrome/test/data/prerender/two_iframes.html
@@ -0,0 +1,2 @@
+<iframe name="iframe" src="IFRAME_1_SRC"></iframe>
+<iframe name="iframe" src="IFRAME_2_SRC"></iframe>
\ No newline at end of file
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc
index e437fe7..859d001 100644
--- a/components/download/internal/common/download_item_impl.cc
+++ b/components/download/internal/common/download_item_impl.cc
@@ -2034,14 +2034,6 @@
     job_->Cancel(false);
 
   if (IsCancellation(reason)) {
-    if (IsDangerous()) {
-      RecordDangerousDownloadDiscard(
-          reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
-              ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION
-              : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN,
-          GetDangerType(), GetTargetFilePath());
-    }
-
     RecordDownloadCountWithSource(CANCELLED_COUNT, download_source_);
     if (job_ && job_->IsParallelizable()) {
       RecordParallelizableDownloadCount(CANCELLED_COUNT,
diff --git a/components/download/internal/common/download_stats.cc b/components/download/internal/common/download_stats.cc
index 0f5f61a0..1191391 100644
--- a/components/download/internal/common/download_stats.cc
+++ b/components/download/internal/common/download_stats.cc
@@ -690,31 +690,6 @@
   }
 }
 
-void RecordDangerousDownloadDiscard(DownloadDiscardReason reason,
-                                    DownloadDangerType danger_type,
-                                    const base::FilePath& file_path) {
-  switch (reason) {
-    case DOWNLOAD_DISCARD_DUE_TO_USER_ACTION:
-      UMA_HISTOGRAM_ENUMERATION("Download.UserDiscard", danger_type,
-                                DOWNLOAD_DANGER_TYPE_MAX);
-      if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) {
-        base::UmaHistogramSparse("Download.DangerousFile.UserDiscard",
-                                 GetDangerousFileType(file_path));
-      }
-      break;
-    case DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN:
-      UMA_HISTOGRAM_ENUMERATION("Download.Discard", danger_type,
-                                DOWNLOAD_DANGER_TYPE_MAX);
-      if (danger_type == DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE) {
-        base::UmaHistogramSparse("Download.DangerousFile.Discard",
-                                 GetDangerousFileType(file_path));
-      }
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
 namespace {
 
 int GetMimeTypeMatch(const std::string& mime_type_string,
diff --git a/components/download/public/common/download_stats.h b/components/download/public/common/download_stats.h
index 74d2e9cd..e4735a5 100644
--- a/components/download/public/common/download_stats.h
+++ b/components/download/public/common/download_stats.h
@@ -279,12 +279,6 @@
     DownloadDangerType danger_type,
     const base::FilePath& file_path);
 
-// Record a dangerous download discard event.
-COMPONENTS_DOWNLOAD_EXPORT void RecordDangerousDownloadDiscard(
-    DownloadDiscardReason reason,
-    DownloadDangerType danger_type,
-    const base::FilePath& file_path);
-
 // Returns the type of download.
 COMPONENTS_DOWNLOAD_EXPORT DownloadContent
 DownloadContentFromMimeType(const std::string& mime_type_string,
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn
index 1dd58d3..e10c21c 100644
--- a/components/exo/BUILD.gn
+++ b/components/exo/BUILD.gn
@@ -128,6 +128,7 @@
   }
 
   if (is_chromecast) {
+    deps += [ "//ui/accessibility:accessibility" ]
     sources += [
       "fullscreen_shell_surface.cc",
       "fullscreen_shell_surface.h",
@@ -249,6 +250,7 @@
   }
 
   if (is_chromecast) {
+    deps += [ "//ui/accessibility:accessibility" ]
     sources += [ "fullscreen_shell_surface_unittest.cc" ]
   }
 }
diff --git a/components/exo/fullscreen_shell_surface.cc b/components/exo/fullscreen_shell_surface.cc
index 236da687..310e0db 100644
--- a/components/exo/fullscreen_shell_surface.cc
+++ b/components/exo/fullscreen_shell_surface.cc
@@ -243,4 +243,18 @@
   return true;
 }
 
+void FullscreenShellSurface::GetAccessibleNodeData(ui::AXNodeData* node_data) {
+  node_data->role = ax::mojom::Role::kClient;
+
+  if (child_ax_tree_id_ == ui::AXTreeIDUnknown())
+    return;
+
+  node_data->AddStringAttribute(ax::mojom::StringAttribute::kChildTreeId,
+                                child_ax_tree_id_.ToString());
+}
+
+void FullscreenShellSurface::SetChildAxTreeId(ui::AXTreeID child_ax_tree_id) {
+  child_ax_tree_id_ = child_ax_tree_id;
+}
+
 }  // namespace exo
diff --git a/components/exo/fullscreen_shell_surface.h b/components/exo/fullscreen_shell_surface.h
index e9175142..8c471f54 100644
--- a/components/exo/fullscreen_shell_surface.h
+++ b/components/exo/fullscreen_shell_surface.h
@@ -7,6 +7,8 @@
 
 #include "components/exo/surface_observer.h"
 #include "components/exo/surface_tree_host.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/accessibility/ax_tree_id.h"
 #include "ui/aura/window_observer.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -74,6 +76,11 @@
   // Overridden from aura::WindowObserver:
   void OnWindowDestroying(aura::Window* window) override;
 
+  // Overridden from ui::View
+  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
+
+  void SetChildAxTreeId(ui::AXTreeID child_ax_tree_id);
+
  private:
   void CreateFullscreenShellSurfaceWidget(ui::WindowShowState show_state);
   void CommitWidget();
@@ -85,6 +92,7 @@
   base::Optional<std::string> startup_id_;
   base::RepeatingClosure close_callback_;
   base::OnceClosure surface_destroyed_callback_;
+  ui::AXTreeID child_ax_tree_id_ = ui::AXTreeIDUnknown();
 
   DISALLOW_COPY_AND_ASSIGN(FullscreenShellSurface);
 };
diff --git a/components/exo/fullscreen_shell_surface_unittest.cc b/components/exo/fullscreen_shell_surface_unittest.cc
index b340598..29648551 100644
--- a/components/exo/fullscreen_shell_surface_unittest.cc
+++ b/components/exo/fullscreen_shell_surface_unittest.cc
@@ -12,6 +12,8 @@
 #include "components/exo/wm_helper.h"
 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/accessibility/ax_tree_id.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
 #include "ui/compositor/compositor.h"
@@ -181,5 +183,21 @@
   EXPECT_EQ(fullscreen_bounds, expected_bounds);
 }
 
+TEST_F(FullscreenShellSurfaceTest, SetAXChildTree) {
+  std::unique_ptr<Surface> surface(new Surface);
+  std::unique_ptr<FullscreenShellSurface> fullscreen_surface(
+      new FullscreenShellSurface(surface.get()));
+  ui::AXNodeData node_data;
+  fullscreen_surface->GetAccessibleNodeData(&node_data);
+  EXPECT_FALSE(
+      node_data.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
+
+  ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
+  fullscreen_surface->SetChildAxTreeId(tree_id);
+  fullscreen_surface->GetAccessibleNodeData(&node_data);
+  EXPECT_TRUE(
+      node_data.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
+}
+
 }  // namespace
 }  // namespace exo
diff --git a/components/optimization_guide/hints_processing_util.cc b/components/optimization_guide/hints_processing_util.cc
index 20427e0..a46666a 100644
--- a/components/optimization_guide/hints_processing_util.cc
+++ b/components/optimization_guide/hints_processing_util.cc
@@ -84,9 +84,8 @@
   return base::StringPrintf("%x", base::PersistentHash(host));
 }
 
-bool ProcessHints(
-    google::protobuf::RepeatedPtrField<optimization_guide::proto::Hint>* hints,
-    optimization_guide::HintUpdateData* hint_update_data) {
+bool ProcessHints(google::protobuf::RepeatedPtrField<proto::Hint>* hints,
+                  optimization_guide::HintUpdateData* hint_update_data) {
   // If there's no update data, then there's nothing to do.
   if (!hint_update_data)
     return false;
@@ -101,7 +100,7 @@
   for (auto& hint : *hints) {
     // We only support host suffixes at the moment. Skip anything else.
     // One |hint| applies to one host URL suffix.
-    if (hint.key_representation() != optimization_guide::proto::HOST_SUFFIX) {
+    if (hint.key_representation() != proto::HOST_SUFFIX) {
       continue;
     }
 
@@ -134,4 +133,22 @@
   return did_process_hints;
 }
 
+net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
+    proto::EffectiveConnectionType proto_ect) {
+  switch (proto_ect) {
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE;
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G;
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G;
+    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G:
+      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G;
+  }
+}
+
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/hints_processing_util.h b/components/optimization_guide/hints_processing_util.h
index 459dcbb..f8aadc70 100644
--- a/components/optimization_guide/hints_processing_util.h
+++ b/components/optimization_guide/hints_processing_util.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "components/optimization_guide/proto/hints.pb.h"
+#include "net/nqe/effective_connection_type.h"
 
 class GURL;
 
@@ -47,6 +48,10 @@
 bool ProcessHints(google::protobuf::RepeatedPtrField<proto::Hint>* hints,
                   HintUpdateData* hint_update_data);
 
+// Converts |proto_ect| into a net::EffectiveConnectionType.
+net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
+    proto::EffectiveConnectionType proto_ect);
+
 }  // namespace optimization_guide
 
 #endif  // COMPONENTS_OPTIMIZATION_GUIDE_HINTS_PROCESSING_UTIL_H_
diff --git a/components/optimization_guide/hints_processing_util_unittest.cc b/components/optimization_guide/hints_processing_util_unittest.cc
index 48540517..a1a258a 100644
--- a/components/optimization_guide/hints_processing_util_unittest.cc
+++ b/components/optimization_guide/hints_processing_util_unittest.cc
@@ -12,13 +12,7 @@
 
 namespace optimization_guide {
 
-class HintsProcessingUtilTest : public testing::Test {
- public:
-  HintsProcessingUtilTest() {}
-  ~HintsProcessingUtilTest() override {}
-};
-
-TEST_F(HintsProcessingUtilTest, FindPageHintForSubstringPagePattern) {
+TEST(HintsProcessingUtilTest, FindPageHintForSubstringPagePattern) {
   proto::Hint hint1;
 
   // Page hint for "/one/"
@@ -64,7 +58,7 @@
                             GURL("https://www.foo.org/bar/three.jpg"), &hint1));
 }
 
-TEST_F(HintsProcessingUtilTest, ProcessHintsNoUpdateData) {
+TEST(HintsProcessingUtilTest, ProcessHintsNoUpdateData) {
   proto::Hint hint;
   hint.set_key("whatever.com");
   hint.set_key_representation(proto::HOST_SUFFIX);
@@ -77,7 +71,7 @@
   EXPECT_FALSE(ProcessHints(&hints, nullptr));
 }
 
-TEST_F(HintsProcessingUtilTest, ProcessHintsWithNoPageHintsAndUpdateData) {
+TEST(HintsProcessingUtilTest, ProcessHintsWithNoPageHintsAndUpdateData) {
   proto::Hint hint;
   hint.set_key("whatever.com");
   hint.set_key_representation(proto::HOST_SUFFIX);
@@ -92,7 +86,7 @@
   EXPECT_EQ(1ul, update_data->TakeUpdateEntries()->size());
 }
 
-TEST_F(HintsProcessingUtilTest, ProcessHintsWithPageHintsAndUpdateData) {
+TEST(HintsProcessingUtilTest, ProcessHintsWithPageHintsAndUpdateData) {
   google::protobuf::RepeatedPtrField<proto::Hint> hints;
 
   proto::Hint hint;
@@ -121,4 +115,28 @@
   EXPECT_EQ(2ul, update_data->TakeUpdateEntries()->size());
 }
 
+TEST(HintsProcessingUtilTest, ConvertProtoEffectiveConnectionType) {
+  EXPECT_EQ(
+      ConvertProtoEffectiveConnectionType(
+          proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
+      net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
+  EXPECT_EQ(
+      ConvertProtoEffectiveConnectionType(
+          proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE),
+      net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE);
+  EXPECT_EQ(
+      ConvertProtoEffectiveConnectionType(
+          proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G),
+      net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+  EXPECT_EQ(ConvertProtoEffectiveConnectionType(
+                proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G),
+            net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G);
+  EXPECT_EQ(ConvertProtoEffectiveConnectionType(
+                proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G),
+            net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G);
+  EXPECT_EQ(ConvertProtoEffectiveConnectionType(
+                proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G),
+            net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G);
+}
+
 }  // namespace optimization_guide
diff --git a/components/previews/content/previews_hints.cc b/components/previews/content/previews_hints.cc
index 6b72e760..adfe31e 100644
--- a/components/previews/content/previews_hints.cc
+++ b/components/previews/content/previews_hints.cc
@@ -122,30 +122,6 @@
   }
 }
 
-net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
-    optimization_guide::proto::EffectiveConnectionType proto_ect) {
-  switch (proto_ect) {
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_UNKNOWN:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_OFFLINE:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE;
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_SLOW_2G:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_2G:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G;
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_3G:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G;
-    case optimization_guide::proto::EffectiveConnectionType::
-        EFFECTIVE_CONNECTION_TYPE_4G:
-      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G;
-  }
-}
-
 }  // namespace
 
 PreviewsHints::PreviewsHints(
@@ -353,13 +329,15 @@
     if (optimization.has_previews_metadata()) {
       *out_inflation_percent =
           optimization.previews_metadata().inflation_percent();
-      *out_ect_threshold = ConvertProtoEffectiveConnectionType(
-          optimization.previews_metadata().max_ect_trigger());
+      *out_ect_threshold =
+          optimization_guide::ConvertProtoEffectiveConnectionType(
+              optimization.previews_metadata().max_ect_trigger());
     } else {
       *out_inflation_percent = optimization.inflation_percent();
       if (matched_page_hint->has_max_ect_trigger()) {
-        *out_ect_threshold = ConvertProtoEffectiveConnectionType(
-            matched_page_hint->max_ect_trigger());
+        *out_ect_threshold =
+            optimization_guide::ConvertProtoEffectiveConnectionType(
+                matched_page_hint->max_ect_trigger());
       }
     }
 
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
index 081bb89e..120997b 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent.cc
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -125,49 +125,6 @@
   }
 }
 
-void SubresourceFilterAgent::RecordHistogramsOnLoadFinished() {
-  DCHECK(filter_for_last_committed_load_);
-  const auto& statistics =
-      filter_for_last_committed_load_->filter().statistics();
-
-  UMA_HISTOGRAM_COUNTS_1000(
-      "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Total",
-      statistics.num_loads_total);
-  UMA_HISTOGRAM_COUNTS_1000(
-      "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Evaluated",
-      statistics.num_loads_evaluated);
-  UMA_HISTOGRAM_COUNTS_1000(
-      "SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules",
-      statistics.num_loads_matching_rules);
-  UMA_HISTOGRAM_COUNTS_1000(
-      "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Disallowed",
-      statistics.num_loads_disallowed);
-
-  // If ThreadTicks is not supported or performance measuring is switched off,
-  // then no time measurements have been collected.
-  if (ScopedThreadTimers::IsSupported() &&
-      filter_for_last_committed_load_->filter()
-          .activation_state()
-          .measure_performance) {
-    UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
-        "SubresourceFilter.DocumentLoad.SubresourceEvaluation."
-        "TotalWallDuration",
-        statistics.evaluation_total_wall_duration,
-        base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
-        50);
-    UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
-        "SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration",
-        statistics.evaluation_total_cpu_duration,
-        base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
-        50);
-  } else {
-    DCHECK(statistics.evaluation_total_wall_duration.is_zero());
-    DCHECK(statistics.evaluation_total_cpu_duration.is_zero());
-  }
-
-  SendDocumentLoadStatistics(statistics);
-}
-
 void SubresourceFilterAgent::ResetInfoForNextCommit() {
   activation_state_for_next_commit_ = mojom::ActivationState();
 }
@@ -265,7 +222,9 @@
 void SubresourceFilterAgent::DidFinishLoad() {
   if (!filter_for_last_committed_load_)
     return;
-  RecordHistogramsOnLoadFinished();
+  const auto& statistics =
+      filter_for_last_committed_load_->filter().statistics();
+  SendDocumentLoadStatistics(statistics);
 }
 
 void SubresourceFilterAgent::WillCreateWorkerFetchContext(
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.h b/components/subresource_filter/content/renderer/subresource_filter_agent.h
index 70c0406..5e4f270 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent.h
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent.h
@@ -86,7 +86,6 @@
 
   void RecordHistogramsOnLoadCommitted(
       const mojom::ActivationState& activation_state);
-  void RecordHistogramsOnLoadFinished();
   void ResetInfoForNextCommit();
 
   const mojom::SubresourceFilterHostAssociatedPtr& GetSubresourceFilterHost();
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
index c038b95f..2e93e3b9 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
@@ -99,18 +99,6 @@
     "SubresourceFilter.DocumentLoad.RulesetIsAvailable";
 constexpr const char kDocumentLoadActivationLevel[] =
     "SubresourceFilter.DocumentLoad.ActivationState";
-constexpr const char kSubresourcesEvaluated[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Evaluated";
-constexpr const char kSubresourcesTotal[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Total";
-constexpr const char kSubresourcesMatchedRules[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules";
-constexpr const char kSubresourcesDisallowed[] =
-    "SubresourceFilter.DocumentLoad.NumSubresourceLoads.Disallowed";
-constexpr const char kEvaluationTotalWallDuration[] =
-    "SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalWallDuration";
-constexpr const char kEvaluationTotalCPUDuration[] =
-    "SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration";
 
 }  // namespace
 
@@ -246,13 +234,6 @@
       static_cast<int>(mojom::ActivationLevel::kDisabled), 1);
   histogram_tester.ExpectTotalCount(kDocumentLoadRulesetIsAvailable, 0);
 
-  histogram_tester.ExpectTotalCount(kSubresourcesTotal, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesEvaluated, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesMatchedRules, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesDisallowed, 0);
-
-  histogram_tester.ExpectTotalCount(kEvaluationTotalWallDuration, 0);
-  histogram_tester.ExpectTotalCount(kEvaluationTotalCPUDuration, 0);
 }
 
 TEST_F(SubresourceFilterAgentTest, MmapFailure_FailsToInjectSubresourceFilter) {
@@ -291,14 +272,6 @@
       kDocumentLoadActivationLevel,
       static_cast<int>(mojom::ActivationLevel::kEnabled), 1);
   histogram_tester.ExpectUniqueSample(kDocumentLoadRulesetIsAvailable, 0, 1);
-
-  histogram_tester.ExpectTotalCount(kSubresourcesTotal, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesEvaluated, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesMatchedRules, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesDisallowed, 0);
-
-  histogram_tester.ExpectTotalCount(kEvaluationTotalWallDuration, 0);
-  histogram_tester.ExpectTotalCount(kEvaluationTotalCPUDuration, 0);
 }
 
 // Never inject a filter for main frame about:blank loads, even though we do for
@@ -315,14 +288,6 @@
 
   histogram_tester.ExpectTotalCount(kDocumentLoadActivationLevel, 0);
   histogram_tester.ExpectTotalCount(kDocumentLoadRulesetIsAvailable, 0);
-
-  histogram_tester.ExpectTotalCount(kSubresourcesTotal, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesEvaluated, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesMatchedRules, 0);
-  histogram_tester.ExpectTotalCount(kSubresourcesDisallowed, 0);
-
-  histogram_tester.ExpectTotalCount(kEvaluationTotalWallDuration, 0);
-  histogram_tester.ExpectTotalCount(kEvaluationTotalCPUDuration, 0);
 }
 
 TEST_F(SubresourceFilterAgentTest, Enabled_FilteringIsInEffectForOneLoad) {
@@ -357,10 +322,6 @@
   // the figures below, as they came after the original page load event. There
   // should be no samples recorded into subresource count histograms during the
   // final load where there is no activation.
-  histogram_tester.ExpectUniqueSample(kSubresourcesTotal, 2, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesEvaluated, 2, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesMatchedRules, 1, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesDisallowed, 1, 1);
   EXPECT_THAT(
       histogram_tester.GetAllSamples(kDocumentLoadActivationLevel),
       ::testing::ElementsAre(
@@ -410,22 +371,6 @@
         kDocumentLoadActivationLevel,
         static_cast<int>(mojom::ActivationLevel::kEnabled), 2);
     histogram_tester.ExpectUniqueSample(kDocumentLoadRulesetIsAvailable, 1, 2);
-
-    EXPECT_THAT(histogram_tester.GetAllSamples(kSubresourcesTotal),
-                ::testing::ElementsAre(base::Bucket(2, 1), base::Bucket(3, 1)));
-    EXPECT_THAT(histogram_tester.GetAllSamples(kSubresourcesEvaluated),
-                ::testing::ElementsAre(base::Bucket(2, 1), base::Bucket(3, 1)));
-    EXPECT_THAT(histogram_tester.GetAllSamples(kSubresourcesMatchedRules),
-                ::testing::ElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
-    EXPECT_THAT(histogram_tester.GetAllSamples(kSubresourcesDisallowed),
-                ::testing::ElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
-
-    base::HistogramBase::Count expected_total_count =
-        measure_performance && base::ThreadTicks::IsSupported() ? 2 : 0;
-    histogram_tester.ExpectTotalCount(kEvaluationTotalWallDuration,
-                                      expected_total_count);
-    histogram_tester.ExpectTotalCount(kEvaluationTotalCPUDuration,
-                                      expected_total_count);
   }
 }
 
@@ -507,15 +452,6 @@
       static_cast<int>(mojom::ActivationLevel::kDryRun), 1);
   histogram_tester.ExpectUniqueSample(kDocumentLoadRulesetIsAvailable, 1, 1);
 
-  histogram_tester.ExpectUniqueSample(kSubresourcesTotal, 3, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesEvaluated, 3, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesMatchedRules, 2, 1);
-  histogram_tester.ExpectUniqueSample(kSubresourcesDisallowed, 0, 1);
-
-  // Performance measurement is switched off.
-  histogram_tester.ExpectTotalCount(kEvaluationTotalWallDuration, 0);
-  histogram_tester.ExpectTotalCount(kEvaluationTotalCPUDuration, 0);
-
   EXPECT_FALSE(agent()->IsAdSubframe());
 }
 
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc
index 29b68e56..9226002 100644
--- a/components/sync/driver/profile_sync_service.cc
+++ b/components/sync/driver/profile_sync_service.cc
@@ -1672,9 +1672,10 @@
 
 base::Optional<UserDemographics> ProfileSyncService::GetUserDemographics(
     base::Time now) {
-  // Do not provide demographics when sync is disabled because user demographics
-  // should only be provided when the other sync data is also provided.
-  if (!IsSyncFeatureEnabled())
+  // Do not provide demographics when sync is disabled or paused because user
+  // demographics should only be provided when the other sync data can be
+  // uploaded to the sync server.
+  if (!IsSyncFeatureEnabled() || auth_manager_->IsSyncPaused())
     return base::nullopt;
 
   return sync_prefs_.GetUserDemographics(now);
diff --git a/components/sync/driver/profile_sync_service_unittest.cc b/components/sync/driver/profile_sync_service_unittest.cc
index 6536737..ac88c565 100644
--- a/components/sync/driver/profile_sync_service_unittest.cc
+++ b/components/sync/driver/profile_sync_service_unittest.cc
@@ -1367,5 +1367,99 @@
   EXPECT_TRUE(HasBirthYearOffset(prefs()));
 }
 
+// Test whether sync service does not provide user demographics and does not
+// clear demographic prefs when sync is paused and enabled, which represents the
+// case where the kStopSyncInPausedState feature is disabled.
+TEST_F(ProfileSyncServiceTest,
+       GetUserDemographics_SyncPausedAndFeatureDisabled) {
+  base::test::ScopedFeatureList feature;
+  // Disable the feature that stops the sync engine (disables sync) when sync is
+  // paused.
+  feature.InitAndDisableFeature(switches::kStopSyncInPausedState);
+
+  // Initialize service with sync enabled at start.
+  SignIn();
+  CreateService(ProfileSyncService::AUTO_START);
+  InitializeForNthSync();
+  ASSERT_EQ(SyncService::TransportState::ACTIVE,
+            service()->GetTransportState());
+
+  // Set demographic prefs that are normally fetched from server when syncing.
+  SetDemographics(kOldEnoughForDemographicsUserBirthYear,
+                  metrics::UserDemographicsProto_Gender_GENDER_FEMALE);
+
+  // Set birth year noise offset that is usually set when calling
+  // SyncPrefs::GetUserDemographics.
+  prefs()->SetInteger(prefs::kSyncDemographicsBirthYearOffset, 2);
+
+  // Verify that demographic prefs exist (i.e., the test is set up).
+  ASSERT_TRUE(HasBirthYearDemographic(prefs()));
+  ASSERT_TRUE(HasGenderDemographic(prefs()));
+  ASSERT_TRUE(HasBirthYearOffset(prefs()));
+
+  // Simulate sign out using an invalid auth error.
+  identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
+  ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
+            service()->GetAuthError().state());
+  ASSERT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons());
+
+  // Verify that sync service does not provide demographics when sync is paused.
+  base::Optional<UserDemographics> user_demographics =
+      service()->GetUserDemographics(GetNowTime());
+  EXPECT_FALSE(user_demographics.has_value());
+
+  // Verify that demographic prefs are not cleared.
+  EXPECT_TRUE(HasBirthYearDemographic(prefs()));
+  EXPECT_TRUE(HasGenderDemographic(prefs()));
+  EXPECT_TRUE(HasBirthYearOffset(prefs()));
+}
+
+// Test whether sync service does not provide user demographics and does not
+// clear demographic prefs when sync is paused and disabled, which represents
+// the case where the kStopSyncInPausedState feature is enabled.
+TEST_F(ProfileSyncServiceTest,
+       GetUserDemographics_SyncPausedAndFeatureEnabled) {
+  base::test::ScopedFeatureList feature;
+  // Enable the feature that stops the sync engine (disables sync) when sync is
+  // paused.
+  feature.InitAndEnableFeature(switches::kStopSyncInPausedState);
+
+  // Initialize service with sync enabled at start.
+  SignIn();
+  CreateService(ProfileSyncService::AUTO_START);
+  InitializeForNthSync();
+  ASSERT_EQ(SyncService::TransportState::ACTIVE,
+            service()->GetTransportState());
+
+  // Set demographic prefs that are normally fetched from server when syncing.
+  SetDemographics(kOldEnoughForDemographicsUserBirthYear,
+                  metrics::UserDemographicsProto_Gender_GENDER_FEMALE);
+
+  // Set birth year noise offset that is usually set when calling
+  // SyncPrefs::GetUserDemographics.
+  prefs()->SetInteger(prefs::kSyncDemographicsBirthYearOffset, 2);
+
+  // Verify that demographic prefs exist (i.e., the test is set up).
+  ASSERT_TRUE(HasBirthYearDemographic(prefs()));
+  ASSERT_TRUE(HasGenderDemographic(prefs()));
+  ASSERT_TRUE(HasBirthYearOffset(prefs()));
+
+  // Simulate sign out using an invalid auth error.
+  identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
+  ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
+            service()->GetAuthError().state());
+  ASSERT_EQ(SyncService::DISABLE_REASON_PAUSED, service()->GetDisableReasons());
+
+  // Verify that sync service does not provide demographics when sync is paused.
+  base::Optional<UserDemographics> user_demographics =
+      service()->GetUserDemographics(GetNowTime());
+  EXPECT_FALSE(user_demographics.has_value());
+
+  // Verify that demographic prefs are not cleared.
+  EXPECT_TRUE(HasBirthYearDemographic(prefs()));
+  EXPECT_TRUE(HasGenderDemographic(prefs()));
+  EXPECT_TRUE(HasBirthYearOffset(prefs()));
+}
+
 }  // namespace
 }  // namespace syncer
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
index 481ce5f2..ac1777af 100644
--- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc
+++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -930,24 +930,37 @@
           <html>
           <body>
             <div contenteditable="true">Text inside field</div>
+            anonymous block
           </body>
           </html>)HTML"));
 
   AtkObject* document = GetRendererAccessible();
-  EXPECT_EQ(1, atk_object_get_n_accessible_children(document));
+  EXPECT_EQ(2, atk_object_get_n_accessible_children(document));
 
   AtkText* div_element = ATK_TEXT(atk_object_ref_accessible_child(document, 0));
   EXPECT_EQ(1, atk_object_get_n_accessible_children(ATK_OBJECT(div_element)));
   AtkText* text =
       ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(div_element), 0));
+  AtkText* anonymous_block =
+      ATK_TEXT(atk_object_ref_accessible_child(document, 1));
 
   auto callback = G_CALLBACK(+[](AtkText*, gint, bool* flag) { *flag = true; });
+
   bool saw_caret_move_in_text = false;
-  bool saw_caret_move_in_div = false;
   g_signal_connect(text, "text-caret-moved", callback, &saw_caret_move_in_text);
+
+  bool saw_caret_move_in_div = false;
   g_signal_connect(div_element, "text-caret-moved", callback,
                    &saw_caret_move_in_div);
 
+  bool saw_caret_move_in_anonymous_block = false;
+  g_signal_connect(anonymous_block, "text-caret-moved", callback,
+                   &saw_caret_move_in_anonymous_block);
+
+  bool saw_caret_move_in_document = false;
+  g_signal_connect(document, "text-caret-moved", callback,
+                   &saw_caret_move_in_document);
+
   AccessibilityNotificationWaiter selection_waiter(
       shell()->web_contents(), ui::kAXModeComplete,
       ax::mojom::Event::kTextSelectionChanged);
@@ -965,8 +978,19 @@
   // We should see the event happen in div and not the static text element.
   EXPECT_TRUE(saw_caret_move_in_div);
   EXPECT_FALSE(saw_caret_move_in_text);
+  EXPECT_FALSE(saw_caret_move_in_anonymous_block);
+  EXPECT_FALSE(saw_caret_move_in_document);
+
+  saw_caret_move_in_div = false;
+
+  atk_text_set_caret_offset(anonymous_block, 3);
+  EXPECT_FALSE(saw_caret_move_in_div);
+  EXPECT_FALSE(saw_caret_move_in_text);
+  EXPECT_FALSE(saw_caret_move_in_anonymous_block);
+  EXPECT_TRUE(saw_caret_move_in_document);
 
   g_object_unref(div_element);
+  g_object_unref(anonymous_block);
   g_object_unref(text);
 }
 
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 19d091a..dfbe8f0 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -315,6 +315,28 @@
   }
 }
 
+int GetNumAttemptsAfterEvent(BackgroundSyncType sync_type,
+                             int current_num_attempts,
+                             int max_attempts,
+                             blink::mojom::BackgroundSyncState sync_state,
+                             bool succeeded) {
+  int num_attempts = ++current_num_attempts;
+
+  if (sync_type == BackgroundSyncType::PERIODIC) {
+    if (succeeded)
+      return 0;
+    if (num_attempts == max_attempts)
+      return 0;
+  }
+
+  if (sync_state ==
+      blink::mojom::BackgroundSyncState::REREGISTERED_WHILE_FIRING) {
+    return 0;
+  }
+
+  return num_attempts;
+}
+
 // This prevents the browser process from shutting down when the last browser
 // window is closed and there are one-shot Background Sync events ready to fire.
 std::unique_ptr<BackgroundSyncController::BackgroundSyncEventKeepAlive>
@@ -1918,16 +1940,12 @@
             registration->sync_state());
 
   // It's important to update |num_attempts| before we update |delay_until|.
-  registration->set_num_attempts(registration->num_attempts() + 1);
-  if ((registration->sync_type() == BackgroundSyncType::PERIODIC &&
-       registration->num_attempts() == registration->max_attempts()) ||
-      (registration->sync_state() ==
-       blink::mojom::BackgroundSyncState::REREGISTERED_WHILE_FIRING)) {
-    registration->set_num_attempts(0);
-  }
+  bool succeeded = status_code == blink::ServiceWorkerStatusCode::kOk;
+  registration->set_num_attempts(GetNumAttemptsAfterEvent(
+      registration->sync_type(), registration->num_attempts(),
+      registration->max_attempts(), registration->sync_state(), succeeded));
 
   // If |delay_until| needs to be updated, get updated delay.
-  bool succeeded = status_code == blink::ServiceWorkerStatusCode::kOk;
   if (registration->sync_type() == BackgroundSyncType::PERIODIC ||
       (!succeeded &&
        registration->num_attempts() < registration->max_attempts())) {
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc
index d97e27c5..c7e95d1 100644
--- a/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -1408,9 +1408,8 @@
   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
   auto cache_handle =
       LegacyCacheStorage::From(cache_storage)->GetLoadedCache(kCacheName);
-  base::FilePath cache_path =
-      LegacyCacheStorageCache::From(cache_handle)->path();
-  base::FilePath index_path = cache_path.AppendASCII("index");
+  base::FilePath index_path =
+      LegacyCacheStorageCache::From(cache_handle)->path().AppendASCII("index");
   cache_handle = CacheStorageCacheHandle();
 
   DestroyStorageManager();
@@ -1419,16 +1418,6 @@
   ASSERT_FALSE(index_path.empty());
   ASSERT_EQ(5, base::WriteFile(index_path, "hello", 5));
 
-  // The cache_storage index is written from a background thread and may be
-  // written just after our overwrite of the simple disk_cache index here.
-  // We need the cache directory to have a newer time stamp, though, in order
-  // for the Size() method to actually try calculating the size from the
-  // corrupted simple disk_cache.  Therefore we force the cache directory
-  // to have a much newer time to ensure the cache_storage index is not used
-  // in the following Size() call.
-  base::Time t = base::Time::Now() + base::TimeDelta::FromHours(1);
-  EXPECT_TRUE(base::TouchFile(cache_path, t, t));
-
   CreateStorageManager();
 
   EXPECT_TRUE(Open(origin1_, kCacheName));
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage.cc b/content/browser/cache_storage/legacy/legacy_cache_storage.cc
index b1a4d62c..a064cef4 100644
--- a/content/browser/cache_storage/legacy/legacy_cache_storage.cc
+++ b/content/browser/cache_storage/legacy/legacy_cache_storage.cc
@@ -571,27 +571,18 @@
       quota_manager_proxy_(quota_manager_proxy),
       owner_(owner),
       cache_storage_manager_(cache_storage_manager) {
-  if (memory_only) {
+  if (memory_only)
     cache_loader_.reset(new MemoryLoader(
         cache_task_runner_.get(), std::move(scheduler_task_runner),
         quota_manager_proxy.get(), blob_context, this, origin, owner));
-    return;
-  }
-
-  cache_loader_.reset(new SimpleCacheLoader(
-      origin_path_, cache_task_runner_.get(), std::move(scheduler_task_runner),
-      quota_manager_proxy.get(), blob_context, this, origin, owner));
-
-#if defined(OS_ANDROID)
-  app_status_listener_ = base::android::ApplicationStatusListener::New(
-      base::BindRepeating(&LegacyCacheStorage::OnApplicationStateChange,
-                          weak_factory_.GetWeakPtr()));
-#endif
+  else
+    cache_loader_.reset(new SimpleCacheLoader(
+        origin_path_, cache_task_runner_.get(),
+        std::move(scheduler_task_runner), quota_manager_proxy.get(),
+        blob_context, this, origin, owner));
 }
 
-LegacyCacheStorage::~LegacyCacheStorage() {
-  FlushIndexIfDirty();
-}
+LegacyCacheStorage::~LegacyCacheStorage() {}
 
 CacheStorageHandle LegacyCacheStorage::CreateHandle() {
   return CacheStorageHandle(weak_factory_.GetWeakPtr());
@@ -819,19 +810,14 @@
 }
 
 void LegacyCacheStorage::ScheduleWriteIndex() {
-  // These values are chosen to be equal or greater than the simple disk_cache
-  // index write delays.  We want the cache_storage index to be written last.
-  static const int64_t kWriteIndexDelayMilliseconds = 20050;
-  static const int64_t kWriteIndexBackgroundDelayMilliseconds = 150;
-  int64_t delay_ms = app_on_background_ ? kWriteIndexBackgroundDelayMilliseconds
-                                        : kWriteIndexDelayMilliseconds;
+  static const int64_t kWriteIndexDelaySecs = 5;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   index_write_task_.Reset(base::BindOnce(&LegacyCacheStorage::WriteIndex,
                                          weak_factory_.GetWeakPtr(),
                                          base::DoNothing::Once<bool>()));
   base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, index_write_task_.callback(),
-      base::TimeDelta::FromMilliseconds(delay_ms));
+      base::TimeDelta::FromSeconds(kWriteIndexDelaySecs));
 }
 
 void LegacyCacheStorage::WriteIndex(base::OnceCallback<void(bool)> callback) {
@@ -1028,7 +1014,6 @@
       cache_ptr->cache_padding_key()->key()));
 
   CacheStorageCacheHandle handle = cache_ptr->CreateHandle();
-  index_write_task_.Cancel();
   cache_loader_->WriteIndex(
       *cache_index_,
       base::BindOnce(&LegacyCacheStorage::CreateCacheDidWriteIndex,
@@ -1087,7 +1072,6 @@
   DCHECK(scheduler_->IsRunningExclusiveOperation());
   LegacyCacheStorageCache::From(cache_handle)->SetObserver(nullptr);
   cache_index_->DoomCache(cache_name);
-  index_write_task_.Cancel();
   cache_loader_->WriteIndex(
       *cache_index_,
       base::BindOnce(&LegacyCacheStorage::DeleteCacheDidWriteIndex,
@@ -1413,24 +1397,4 @@
   }
 }
 
-void LegacyCacheStorage::FlushIndexIfDirty() {
-  if (!index_write_pending())
-    return;
-  index_write_task_.Cancel();
-  cache_loader_->WriteIndex(*cache_index_, base::DoNothing::Once<bool>());
-}
-
-#if defined(OS_ANDROID)
-void LegacyCacheStorage::OnApplicationStateChange(
-    base::android::ApplicationState state) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
-    app_on_background_ = false;
-  } else if (state == base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES) {
-    app_on_background_ = true;
-    FlushIndexIfDirty();
-  }
-}
-#endif
-
 }  // namespace content
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage.h b/content/browser/cache_storage/legacy/legacy_cache_storage.h
index 2e68fe9b..14ae5b6 100644
--- a/content/browser/cache_storage/legacy/legacy_cache_storage.h
+++ b/content/browser/cache_storage/legacy/legacy_cache_storage.h
@@ -15,16 +15,11 @@
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "build/build_config.h"
 #include "content/browser/cache_storage/cache_storage.h"
 #include "content/browser/cache_storage/cache_storage_cache_observer.h"
 #include "content/browser/cache_storage/cache_storage_scheduler_types.h"
 #include "content/browser/cache_storage/legacy/legacy_cache_storage_cache.h"
 
-#if defined(OS_ANDROID)
-#include "base/android/application_status_listener.h"
-#endif
-
 namespace base {
 class SequencedTaskRunner;
 }
@@ -265,12 +260,6 @@
   bool InitiateScheduledIndexWriteForTest(
       base::OnceCallback<void(bool)> callback);
 
-  void FlushIndexIfDirty();
-
-#if defined(OS_ANDROID)
-  void OnApplicationStateChange(base::android::ApplicationState state);
-#endif
-
   // Whether or not we've loaded the list of cache names into memory.
   bool initialized_;
   bool initializing_;
@@ -316,14 +305,6 @@
   base::CancelableOnceClosure index_write_task_;
   size_t handle_ref_count_ = 0;
 
-#if defined(OS_ANDROID)
-  std::unique_ptr<base::android::ApplicationStatusListener>
-      app_status_listener_;
-#endif
-
-  // True if running on android and the app is in the background.
-  bool app_on_background_ = false;
-
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<LegacyCacheStorage> weak_factory_{this};
 
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index a995983..8db58b5 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -1582,7 +1582,8 @@
     headers_dict->setString(net::HttpRequestHeaders::kReferer, referrer.spec());
 
   std::unique_ptr<Network::Response> redirect_response;
-  const CommitNavigationParams& commit_params = nav_request.commit_params();
+  const mojom::CommitNavigationParams& commit_params =
+      nav_request.commit_params();
   if (!commit_params.redirect_response.empty()) {
     redirect_response = BuildResponse(commit_params.redirects.back(),
                                       commit_params.redirect_response.back());
diff --git a/content/browser/fileapi/file_system_url_loader_factory.cc b/content/browser/fileapi/file_system_url_loader_factory.cc
index db8f7bca..38b7ec8d 100644
--- a/content/browser/fileapi/file_system_url_loader_factory.cc
+++ b/content/browser/fileapi/file_system_url_loader_factory.cc
@@ -192,9 +192,8 @@
 
     url_ = params_.file_system_context->CrackURL(request.url);
     if (!url_.is_valid()) {
-      const FileSystemRequestInfo request_info = {request.url, nullptr,
-                                                  params_.storage_domain,
-                                                  params_.frame_tree_node_id};
+      const FileSystemRequestInfo request_info = {
+          request.url, params_.storage_domain, params_.frame_tree_node_id};
       params_.file_system_context->AttemptAutoMountForURLRequest(
           request_info,
           base::BindOnce(&FileSystemEntryURLLoader::DidAttemptAutoMount,
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 2b7c0c1a..a960d28 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2271,7 +2271,7 @@
   params.started_from_context_menu = false;
   /* params.navigation_ui_data: skip */
   /* params.input_start: skip */
-  params.was_activated = WasActivatedOption::kUnknown;
+  params.was_activated = mojom::WasActivatedOption::kUnknown;
   /* params.reload_type: skip */
 
   std::unique_ptr<NavigationRequest> request =
@@ -3086,22 +3086,36 @@
           false /* is_history_navigation_in_new_child_frame */,
           params.input_start);
 
-  CommitNavigationParams commit_params(
-      frame_entry->committed_origin(), override_user_agent,
-      params.redirect_chain, common_params->url, common_params->method,
-      params.can_load_local_resources, frame_entry->page_state(),
-      entry->GetUniqueID(), entry->GetSubframeUniqueNames(node),
-      true /* intended_as_new_entry */, -1 /* pending_history_list_offset */,
-      params.should_clear_history_list ? -1 : GetLastCommittedEntryIndex(),
-      params.should_clear_history_list ? 0 : GetEntryCount(),
-      is_view_source_mode, params.should_clear_history_list);
+  mojom::CommitNavigationParamsPtr commit_params =
+      mojom::CommitNavigationParams::New(
+          frame_entry->committed_origin(), override_user_agent,
+          params.redirect_chain, std::vector<network::ResourceResponseHead>(),
+          std::vector<net::RedirectInfo>(),
+          std::string() /* post_content_type */, common_params->url,
+          common_params->method, params.can_load_local_resources,
+          frame_entry->page_state(), entry->GetUniqueID(),
+          entry->GetSubframeUniqueNames(node), true /* intended_as_new_entry */,
+          -1 /* pending_history_list_offset */,
+          params.should_clear_history_list ? -1 : GetLastCommittedEntryIndex(),
+          params.should_clear_history_list ? 0 : GetEntryCount(),
+          false /* was_discarded */, is_view_source_mode,
+          params.should_clear_history_list, mojom::NavigationTiming::New(),
+          base::nullopt /* appcache_host_id */,
+          mojom::WasActivatedOption::kUnknown,
+          base::UnguessableToken::Create() /* navigation_token */,
+          std::vector<PrefetchedSignedExchangeInfo>(),
+#if defined(OS_ANDROID)
+          std::string(), /* data_url_as_string */
+#endif
+          false /* is_browser_initiated */
+      );
 #if defined(OS_ANDROID)
   if (ValidateDataURLAsString(params.data_url_as_string)) {
-    commit_params.data_url_as_string = params.data_url_as_string->data();
+    commit_params->data_url_as_string = params.data_url_as_string->data();
   }
 #endif
 
-  commit_params.was_activated = params.was_activated;
+  commit_params->was_activated = params.was_activated;
 
   // A form submission may happen here if the navigation is a renderer-initiated
   // form submission that took the OpenURL path.
@@ -3112,7 +3126,7 @@
   base::ReplaceChars(params.extra_headers, "\n", "\r\n", &extra_headers_crlf);
 
   auto navigation_request = NavigationRequest::CreateBrowserInitiated(
-      node, std::move(common_params), commit_params,
+      node, std::move(common_params), std::move(commit_params),
       !params.is_renderer_initiated, extra_headers_crlf, *frame_entry, entry,
       request_body,
       params.navigation_ui_data ? params.navigation_ui_data->Clone() : nullptr);
@@ -3212,15 +3226,17 @@
   // TODO(clamy): |intended_as_new_entry| below should always be false once
   // Reload no longer leads to this being called for a pending NavigationEntry
   // of index -1.
-  CommitNavigationParams commit_params = entry->ConstructCommitNavigationParams(
-      *frame_entry, common_params->url, origin_to_commit, common_params->method,
-      entry->GetSubframeUniqueNames(frame_tree_node),
-      GetPendingEntryIndex() == -1 /* intended_as_new_entry */,
-      GetIndexOfEntry(entry), GetLastCommittedEntryIndex(), GetEntryCount());
-  commit_params.post_content_type = post_content_type;
+  mojom::CommitNavigationParamsPtr commit_params =
+      entry->ConstructCommitNavigationParams(
+          *frame_entry, common_params->url, origin_to_commit,
+          common_params->method, entry->GetSubframeUniqueNames(frame_tree_node),
+          GetPendingEntryIndex() == -1 /* intended_as_new_entry */,
+          GetIndexOfEntry(entry), GetLastCommittedEntryIndex(),
+          GetEntryCount());
+  commit_params->post_content_type = post_content_type;
 
   return NavigationRequest::CreateBrowserInitiated(
-      frame_tree_node, std::move(common_params), commit_params,
+      frame_tree_node, std::move(common_params), std::move(commit_params),
       !entry->is_renderer_initiated(), entry->extra_headers(), *frame_entry,
       entry, request_body, nullptr /* navigation_ui_data */);
 }
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h
index 4af7438..03bee52 100644
--- a/content/browser/frame_host/navigation_controller_impl.h
+++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -28,7 +28,6 @@
 struct FrameHostMsg_DidCommitProvisionalLoad_Params;
 
 namespace content {
-enum class WasActivatedOption;
 class FrameTreeNode;
 class RenderFrameHostImpl;
 class SiteInstance;
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index beabe4c..02fbb2544 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -691,12 +691,13 @@
       false /* is_history_navigation_in_new_child_frame */, input_start);
 }
 
-CommitNavigationParams NavigationEntryImpl::ConstructCommitNavigationParams(
+mojom::CommitNavigationParamsPtr
+NavigationEntryImpl::ConstructCommitNavigationParams(
     const FrameNavigationEntry& frame_entry,
     const GURL& original_url,
     const base::Optional<url::Origin>& origin_to_commit,
     const std::string& original_method,
-    const std::map<std::string, bool>& subframe_unique_names,
+    const base::flat_map<std::string, bool>& subframe_unique_names,
     bool intended_as_new_entry,
     int pending_history_list_offset,
     int current_history_list_offset,
@@ -720,15 +721,26 @@
     current_length_to_send = 0;
   }
 
-  CommitNavigationParams commit_params(
-      origin_to_commit, GetIsOverridingUserAgent(), redirects, original_url,
-      original_method, GetCanLoadLocalResources(), frame_entry.page_state(),
-      GetUniqueID(), subframe_unique_names, intended_as_new_entry,
-      pending_offset_to_send, current_offset_to_send, current_length_to_send,
-      IsViewSourceMode(), should_clear_history_list());
+  mojom::CommitNavigationParamsPtr commit_params =
+      mojom::CommitNavigationParams::New(
+          origin_to_commit, GetIsOverridingUserAgent(), redirects,
+          std::vector<network::ResourceResponseHead>(),
+          std::vector<net::RedirectInfo>(), std::string(), original_url,
+          original_method, GetCanLoadLocalResources(), frame_entry.page_state(),
+          GetUniqueID(), subframe_unique_names, intended_as_new_entry,
+          pending_offset_to_send, current_offset_to_send,
+          current_length_to_send, false, IsViewSourceMode(),
+          should_clear_history_list(), mojom::NavigationTiming::New(),
+          base::nullopt, mojom::WasActivatedOption::kUnknown,
+          base::UnguessableToken::Create(),
+          std::vector<PrefetchedSignedExchangeInfo>(),
+#if defined(OS_ANDROID)
+          std::string(),
+#endif
+          false);
 #if defined(OS_ANDROID)
   if (NavigationControllerImpl::ValidateDataURLAsString(GetDataURLAsString())) {
-    commit_params.data_url_as_string = GetDataURLAsString()->data();
+    commit_params->data_url_as_string = GetDataURLAsString()->data();
   }
 #endif
   return commit_params;
@@ -854,9 +866,9 @@
   return tree_node ? tree_node->frame_entry.get() : nullptr;
 }
 
-std::map<std::string, bool> NavigationEntryImpl::GetSubframeUniqueNames(
+base::flat_map<std::string, bool> NavigationEntryImpl::GetSubframeUniqueNames(
     FrameTreeNode* frame_tree_node) const {
-  std::map<std::string, bool> names;
+  base::flat_map<std::string, bool> names;
   NavigationEntryImpl::TreeNode* tree_node = GetTreeNode(frame_tree_node);
   if (tree_node) {
     // Return the names of all immediate children.
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h
index dca35a81..2bb6422 100644
--- a/content/browser/frame_host/navigation_entry_impl.h
+++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -7,11 +7,11 @@
 
 #include <stdint.h>
 
-#include <map>
 #include <memory>
 #include <string>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
@@ -21,6 +21,7 @@
 #include "content/browser/frame_host/frame_navigation_entry.h"
 #include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/site_instance_impl.h"
+#include "content/common/navigation_params.mojom.h"
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/global_request_id.h"
 #include "content/public/browser/navigation_entry.h"
@@ -33,7 +34,6 @@
 #include "url/origin.h"
 
 namespace content {
-struct CommitNavigationParams;
 
 class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
  public:
@@ -183,12 +183,12 @@
       PreviewsState previews_state,
       base::TimeTicks navigation_start,
       base::TimeTicks input_start);
-  CommitNavigationParams ConstructCommitNavigationParams(
+  mojom::CommitNavigationParamsPtr ConstructCommitNavigationParams(
       const FrameNavigationEntry& frame_entry,
       const GURL& original_url,
       const base::Optional<url::Origin>& origin_to_commit,
       const std::string& original_method,
-      const std::map<std::string, bool>& subframe_unique_names,
+      const base::flat_map<std::string, bool>& subframe_unique_names,
       bool intended_as_new_entry,
       int pending_offset_to_send,
       int current_offset_to_send,
@@ -250,7 +250,7 @@
   // same-process PageStates for the whole subtree, so that the renderer process
   // only needs to ask the browser process to handle the cross-process cases.
   // See https://crbug.com/639842.
-  std::map<std::string, bool> GetSubframeUniqueNames(
+  base::flat_map<std::string, bool> GetSubframeUniqueNames(
       FrameTreeNode* frame_tree_node) const;
 
   // Removes any subframe FrameNavigationEntries that match the unique name of
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index a6a63ad..4b780d2 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -32,10 +32,8 @@
 namespace content {
 
 NavigationHandleImpl::NavigationHandleImpl(
-    NavigationRequest* navigation_request,
-    net::HttpRequestHeaders request_headers)
-    : navigation_request_(navigation_request),
-      request_headers_(std::move(request_headers)) {
+    NavigationRequest* navigation_request)
+    : navigation_request_(navigation_request) {
   const GURL& url = navigation_request_->common_params().url;
   TRACE_EVENT_ASYNC_BEGIN2("navigation", "NavigationHandle", this,
                            "frame_tree_node",
@@ -170,23 +168,16 @@
 }
 
 const net::HttpRequestHeaders& NavigationHandleImpl::GetRequestHeaders() {
-  return request_headers_;
+  return navigation_request_->request_headers();
 }
 
 void NavigationHandleImpl::RemoveRequestHeader(const std::string& header_name) {
-  DCHECK(state() == NavigationRequest::PROCESSING_WILL_REDIRECT_REQUEST ||
-         state() == NavigationRequest::WILL_REDIRECT_REQUEST);
-  removed_request_headers_.push_back(header_name);
+  navigation_request_->RemoveRequestHeader(header_name);
 }
 
 void NavigationHandleImpl::SetRequestHeader(const std::string& header_name,
                                             const std::string& header_value) {
-  DCHECK(state() == NavigationRequest::INITIAL ||
-         state() == NavigationRequest::PROCESSING_WILL_START_REQUEST ||
-         state() == NavigationRequest::PROCESSING_WILL_REDIRECT_REQUEST ||
-         state() == NavigationRequest::WILL_START_REQUEST ||
-         state() == NavigationRequest::WILL_REDIRECT_REQUEST);
-  modified_request_headers_.SetHeader(header_name, header_value);
+  navigation_request_->SetRequestHeader(header_name, header_value);
 }
 
 const net::HttpResponseHeaders* NavigationHandleImpl::GetResponseHeaders() {
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 3dedf2fa..d2f6c86 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -185,14 +185,6 @@
     return navigation_request_->common_params().source_location;
   }
 
-  std::vector<std::string> TakeRemovedRequestHeaders() {
-    return std::move(removed_request_headers_);
-  }
-
-  net::HttpRequestHeaders TakeModifiedRequestHeaders() {
-    return std::move(modified_request_headers_);
-  }
-
   NavigationThrottle* GetDeferringThrottleForTesting() const {
     return navigation_request_->GetDeferringThrottleForTesting();
   }
@@ -208,8 +200,7 @@
   // start with |url|. Otherwise |redirect_chain| is used as the starting point.
   // |navigation_start| comes from the CommonNavigationParams associated with
   // this navigation.
-  NavigationHandleImpl(NavigationRequest* navigation_request,
-                       net::HttpRequestHeaders request_headers);
+  NavigationHandleImpl(NavigationRequest* navigation_request);
 
   NavigationRequest::NavigationHandleState state() const {
     return navigation_request_->handle_state();
@@ -218,16 +209,6 @@
   // The NavigationRequest that owns this NavigationHandle.
   NavigationRequest* navigation_request_;
 
-  // The headers used for the request.
-  net::HttpRequestHeaders request_headers_;
-
-  // Used to update the request's headers. When modified during the navigation
-  // start, the headers will be applied to the initial network request. When
-  // modified during a redirect, the headers will be applied to the redirected
-  // request.
-  std::vector<std::string> removed_request_headers_;
-  net::HttpRequestHeaders modified_request_headers_;
-
   // Allows to override response_headers_ in tests.
   // TODO(clamy): Clean this up once the architecture of unit tests is better.
   scoped_refptr<net::HttpResponseHeaders> response_headers_for_testing_;
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc
index 9a19a64..0ef32ec 100644
--- a/content/browser/frame_host/navigation_handle_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -231,8 +231,8 @@
         url::Origin::Create(GURL("https://initiator.example.com"));
     request_ = NavigationRequest::CreateBrowserInitiated(
         main_test_rfh()->frame_tree_node(), std::move(common_params),
-        CommitNavigationParams(), false /* browser-initiated */, std::string(),
-        *frame_entry, nullptr, nullptr, nullptr);
+        CreateCommitNavigationParams(), false /* browser-initiated */,
+        std::string(), *frame_entry, nullptr, nullptr, nullptr);
     request_->CreateNavigationHandle(true);
   }
 
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index dad3db45..427f3f2 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -474,7 +474,7 @@
 std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
     FrameTreeNode* frame_tree_node,
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool browser_initiated,
     const std::string& extra_headers,
     const FrameNavigationEntry& frame_entry,
@@ -503,9 +503,9 @@
 
   std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
       frame_tree_node, std::move(common_params), std::move(navigation_params),
-      commit_params, browser_initiated, false /* from_begin_navigation */,
-      false /* is_for_commit */, &frame_entry, entry,
-      std::move(navigation_ui_data), nullptr, nullptr));
+      std::move(commit_params), browser_initiated,
+      false /* from_begin_navigation */, false /* is_for_commit */,
+      &frame_entry, entry, std::move(navigation_ui_data), nullptr, nullptr));
   navigation_request->blob_url_loader_factory_ =
       frame_entry.blob_url_loader_factory();
 
@@ -553,23 +553,39 @@
 
   // TODO(clamy): See if the navigation start time should be measured in the
   // renderer and sent to the browser instead of being measured here.
-  CommitNavigationParams commit_params(
-      base::nullopt, override_user_agent,
-      std::vector<GURL>(),  // redirects
-      common_params->url, common_params->method,
-      false,                          // can_load_local_resources
-      PageState(),                    // page_state
-      0,                              // nav_entry_id
-      std::map<std::string, bool>(),  // subframe_unique_names
-      false,                          // intended_as_new_entry
-      -1,  // |pending_history_list_offset| is set to -1 because
-           // history-navigations do not use this path. See comments above.
-      current_history_list_offset, current_history_list_length,
-      false,  // is_view_source
-      false /*should_clear_history_list*/);
+  mojom::CommitNavigationParamsPtr commit_params =
+      mojom::CommitNavigationParams::New(
+          base::nullopt, override_user_agent,
+          std::vector<GURL>(),                           // redirects
+          std::vector<network::ResourceResponseHead>(),  // redirect_response
+          std::vector<net::RedirectInfo>(),              // redirect_infos
+          std::string(),                                 // post_content_type
+          common_params->url, common_params->method,
+          false,                                // can_load_local_resources
+          PageState(),                          // page_state
+          0,                                    // nav_entry_id
+          base::flat_map<std::string, bool>(),  // subframe_unique_names
+          false,                                // intended_as_new_entry
+          -1,  // |pending_history_list_offset| is set to -1 because
+               // history-navigations do not use this path. See comments above.
+          current_history_list_offset, current_history_list_length,
+          false,  // was_discarded
+          false,  // is_view_source
+          false /*should_clear_history_list*/,
+          mojom::NavigationTiming::New(),  // navigation_timing
+          base::nullopt,                   // appcache_host_id
+          mojom::WasActivatedOption::kUnknown,
+          base::UnguessableToken::Create(),  // navigation_token
+          std::vector<
+              PrefetchedSignedExchangeInfo>(),  // prefetched_signed_exchanges
+#if defined(OS_ANDROID)
+          std::string(),  // data_url_as_string
+#endif
+          false  // is_browser_initiated
+      );
   std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
       frame_tree_node, std::move(common_params), std::move(begin_params),
-      commit_params,
+      std::move(commit_params),
       false,  // browser_initiated
       true,   // from_begin_navigation
       false,  // is_for_commit
@@ -614,22 +630,34 @@
           std::string() /* href_translate */,
           false /* is_history_navigation_in_new_child_frame */,
           base::TimeTicks::Now());
-  CommitNavigationParams commit_params(
-      params.origin, params.is_overriding_user_agent, params.redirects,
-      params.original_request_url, params.method,
-      false /* can_load_local_resources */, params.page_state,
-      params.nav_entry_id,
-      std::map<std::string, bool>() /* subframe_unique_names */,
-      params.intended_as_new_entry, -1 /* pending_history_list_offset */,
-      -1 /* current_history_list_offset */,
-      -1 /* current_history_list_length */, false /* is_view_source */,
-      params.history_list_was_cleared);
+  mojom::CommitNavigationParamsPtr commit_params =
+      mojom::CommitNavigationParams::New(
+          params.origin, params.is_overriding_user_agent, params.redirects,
+          std::vector<network::ResourceResponseHead>(),
+          std::vector<net::RedirectInfo>(), std::string(),
+          params.original_request_url, params.method,
+          false /* can_load_local_resources */, params.page_state,
+          params.nav_entry_id,
+          base::flat_map<std::string, bool>() /* subframe_unique_names */,
+          params.intended_as_new_entry, -1 /* pending_history_list_offset */,
+          -1 /* current_history_list_offset */,
+          -1 /* current_history_list_length */, false /* was_discard */,
+          false /* is_view_source */, params.history_list_was_cleared,
+          mojom::NavigationTiming::New(), base::nullopt /* appcache_host_id; */,
+          mojom::WasActivatedOption::kUnknown,
+          base::UnguessableToken::Create() /* navigation_token */,
+          std::vector<PrefetchedSignedExchangeInfo>(),
+#if defined(OS_ANDROID)
+          std::string(), /* data_url_as_string */
+#endif
+          false /* is_browser_initiated */
+      );
   mojom::BeginNavigationParamsPtr begin_params =
       mojom::BeginNavigationParams::New();
   std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
       frame_tree_node, std::move(common_params), std::move(begin_params),
-      commit_params, !is_renderer_initiated, false /* from_begin_navigation */,
-      true /* is_for_commit */,
+      std::move(commit_params), !is_renderer_initiated,
+      false /* from_begin_navigation */, true /* is_for_commit */,
       entry ? entry->GetFrameEntry(frame_tree_node) : nullptr, entry,
       nullptr /* navigation_ui_data */,
       mojom::NavigationClientAssociatedPtrInfo(),
@@ -648,7 +676,7 @@
     FrameTreeNode* frame_tree_node,
     mojom::CommonNavigationParamsPtr common_params,
     mojom::BeginNavigationParamsPtr begin_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool browser_initiated,
     bool from_begin_navigation,
     bool is_for_commit,
@@ -660,7 +688,7 @@
     : frame_tree_node_(frame_tree_node),
       common_params_(std::move(common_params)),
       begin_params_(std::move(begin_params)),
-      commit_params_(commit_params),
+      commit_params_(std::move(commit_params)),
       browser_initiated_(browser_initiated),
       navigation_ui_data_(std::move(navigation_ui_data)),
       state_(NOT_STARTED),
@@ -749,7 +777,7 @@
   }
 
   std::string user_agent_override;
-  if (commit_params.is_overriding_user_agent ||
+  if (commit_params_->is_overriding_user_agent ||
       (entry && entry->GetIsOverridingUserAgent())) {
     user_agent_override =
         frame_tree_node_->navigator()->GetDelegate()->GetUserAgentOverride();
@@ -785,17 +813,17 @@
         frame_tree_node);
 
     if (begin_params_->is_form_submission) {
-      if (browser_initiated && !commit_params.post_content_type.empty()) {
+      if (browser_initiated && !commit_params_->post_content_type.empty()) {
         // This is a form resubmit, so make sure to set the Content-Type header.
         headers.SetHeaderIfMissing(net::HttpRequestHeaders::kContentType,
-                                   commit_params.post_content_type);
+                                   commit_params_->post_content_type);
       } else if (!browser_initiated) {
         // Save the Content-Type in case the form is resubmitted. This will get
         // sent back to the renderer in the CommitNavigation IPC. The renderer
         // will then send it back with the post body so that we can access it
         // along with the body in FrameNavigationEntry::page_state_.
         headers.GetHeader(net::HttpRequestHeaders::kContentType,
-                          &commit_params_.post_content_type);
+                          &commit_params_->post_content_type);
       }
     }
   }
@@ -809,7 +837,7 @@
 
   navigation_entry_offset_ = EstimateHistoryOffset();
 
-  commit_params_.is_browser_initiated = browser_initiated_;
+  commit_params_->is_browser_initiated = browser_initiated_;
 }
 
 NavigationRequest::~NavigationRequest() {
@@ -847,7 +875,7 @@
 
   if (!GetContentClient()->browser()->ShouldOverrideUrlLoading(
           frame_tree_node_->frame_tree_node_id(), browser_initiated_,
-          commit_params_.original_url, commit_params_.original_method,
+          commit_params_->original_url, commit_params_->original_method,
           common_params_->has_user_gesture, false,
           frame_tree_node_->IsMainFrame(), common_params_->transition,
           &should_override_url_loading)) {
@@ -986,19 +1014,19 @@
     // |begin_params_->client_side_redirect_url| will be set when the navigation
     // was triggered by a client-side redirect.
     redirect_chain_.push_back(begin_params_->client_side_redirect_url);
-  } else if (!commit_params_.redirects.empty()) {
+  } else if (!commit_params_->redirects.empty()) {
     // Redirects that were specified at NavigationRequest creation time should
     // be added to the list of redirects. In particular, if the
     // NavigationRequest was created at commit time, redirects that happened
-    // during the navigation have been added to |commit_params_.redirects| and
+    // during the navigation have been added to |commit_params_->redirects| and
     // should be passed to the NavigationHandle.
-    for (const auto& url : commit_params_.redirects)
+    for (const auto& url : commit_params_->redirects)
       redirect_chain_.push_back(url);
   }
 
   // Finally, add the current URL to the vector of redirects.
   // Note: for NavigationRequests created at commit time, the current URL has
-  // been added to |commit_params_.redirects|, so don't add it a second time.
+  // been added to |commit_params_->redirects|, so don't add it a second time.
   if (!is_for_commit)
     redirect_chain_.push_back(common_params_->url);
 
@@ -1021,8 +1049,11 @@
   handle_state_ = NavigationRequest::INITIAL;
   navigation_handle_id_ = CreateUniqueHandleID();
 
+  request_headers_ = std::move(headers);
+  modified_request_headers_.Clear();
+  removed_request_headers_.clear();
   std::unique_ptr<NavigationHandleImpl> navigation_handle =
-      base::WrapUnique(new NavigationHandleImpl(this, std::move(headers)));
+      base::WrapUnique(new NavigationHandleImpl(this));
 
   if (!frame_tree_node->navigation_request() && !is_for_commit) {
     // A callback could have cancelled this request synchronously in which case
@@ -1198,22 +1229,22 @@
     common_params_->post_data.reset();
 
   // Mark time for the Navigation Timing API.
-  if (commit_params_.navigation_timing.redirect_start.is_null()) {
-    commit_params_.navigation_timing.redirect_start =
-        commit_params_.navigation_timing.fetch_start;
+  if (commit_params_->navigation_timing->redirect_start.is_null()) {
+    commit_params_->navigation_timing->redirect_start =
+        commit_params_->navigation_timing->fetch_start;
   }
-  commit_params_.navigation_timing.redirect_end = base::TimeTicks::Now();
-  commit_params_.navigation_timing.fetch_start = base::TimeTicks::Now();
+  commit_params_->navigation_timing->redirect_end = base::TimeTicks::Now();
+  commit_params_->navigation_timing->fetch_start = base::TimeTicks::Now();
 
-  commit_params_.redirect_response.push_back(response_head->head);
-  commit_params_.redirect_infos.push_back(redirect_info);
+  commit_params_->redirect_response.push_back(response_head->head);
+  commit_params_->redirect_infos.push_back(redirect_info);
 
   // On redirects, the initial origin_to_commit is no longer correct, so it
   // must be cleared to avoid sending incorrect value to the renderer process.
-  if (commit_params_.origin_to_commit)
-    commit_params_.origin_to_commit.reset();
+  if (commit_params_->origin_to_commit)
+    commit_params_->origin_to_commit.reset();
 
-  commit_params_.redirects.push_back(common_params_->url);
+  commit_params_->redirects.push_back(common_params_->url);
   common_params_->url = redirect_info.new_url;
   common_params_->method = redirect_info.new_method;
   common_params_->referrer->url = GURL(redirect_info.new_referrer);
@@ -1334,7 +1365,7 @@
     net_error_ = net::ERR_ABORTED;
 
   // Update the AppCache params of the commit params.
-  commit_params_.appcache_host_id =
+  commit_params_->appcache_host_id =
       appcache_handle_
           ? base::make_optional(appcache_handle_->appcache_host_id())
           : base::nullopt;
@@ -1345,8 +1376,8 @@
   // worker ready time if it is greater than the current value to make sure
   // fetch start timing always comes after worker start timing (if a service
   // worker intercepted the navigation).
-  commit_params_.navigation_timing.fetch_start =
-      std::max(commit_params_.navigation_timing.fetch_start,
+  commit_params_->navigation_timing->fetch_start =
+      std::max(commit_params_->navigation_timing->fetch_start,
                response_head->head.service_worker_ready_time);
 
   // A navigation is user activated if it contains a user gesture or the frame
@@ -1366,8 +1397,8 @@
   //    context menu. This should apply to pages that open in a new tab and we
   //    have to follow the referrer. It means that the activation might not be
   //    transmitted if it should have.
-  if (commit_params_.was_activated == WasActivatedOption::kUnknown) {
-    commit_params_.was_activated = WasActivatedOption::kNo;
+  if (commit_params_->was_activated == mojom::WasActivatedOption::kUnknown) {
+    commit_params_->was_activated = mojom::WasActivatedOption::kNo;
 
     if (!browser_initiated_ &&
         (frame_tree_node_->has_received_user_gesture() ||
@@ -1375,7 +1406,7 @@
         ShouldPropagateUserActivation(
             frame_tree_node_->current_origin(),
             url::Origin::Create(common_params_->url))) {
-      commit_params_.was_activated = WasActivatedOption::kYes;
+      commit_params_->was_activated = mojom::WasActivatedOption::kYes;
       // TODO(805871): the next check is relying on sanitized_referrer_ but
       // should ideally use a more reliable source for the originating URL when
       // the navigation is renderer initiated.
@@ -1384,7 +1415,7 @@
                ShouldPropagateUserActivation(
                    url::Origin::Create(sanitized_referrer_->url),
                    url::Origin::Create(common_params_->url))) {
-      commit_params_.was_activated = WasActivatedOption::kYes;
+      commit_params_->was_activated = mojom::WasActivatedOption::kYes;
     }
   }
 
@@ -1761,7 +1792,7 @@
   }
 
   // Mark the fetch_start (Navigation Timing API).
-  commit_params_.navigation_timing.fetch_start = base::TimeTicks::Now();
+  commit_params_->navigation_timing->fetch_start = base::TimeTicks::Now();
 
   GURL site_for_cookies =
       frame_tree_node_->current_frame_host()
@@ -1798,7 +1829,7 @@
   // Merge headers with embedder's headers.
   net::HttpRequestHeaders headers;
   headers.AddHeadersFromString(begin_params_->headers);
-  headers.MergeFrom(navigation_handle_->TakeModifiedRequestHeaders());
+  headers.MergeFrom(TakeModifiedRequestHeaders());
   begin_params_->headers = headers.ToString();
 
   // TODO(clamy): Avoid cloning the navigation params and create the
@@ -1865,10 +1896,8 @@
 
   devtools_instrumentation::OnNavigationRequestWillBeSent(*this);
 
-  net::HttpRequestHeaders modified_headers =
-      navigation_handle_->TakeModifiedRequestHeaders();
-  std::vector<std::string> removed_headers =
-      navigation_handle_->TakeRemovedRequestHeaders();
+  net::HttpRequestHeaders modified_headers = TakeModifiedRequestHeaders();
+  std::vector<std::string> removed_headers = TakeRemovedRequestHeaders();
 
   BrowserContext* browser_context =
       frame_tree_node_->navigator()->GetController()->GetBrowserContext();
@@ -2031,7 +2060,7 @@
   // TODO(nasko): Create an opque origin here and pass it for the renderer
   // to commit into it. Potentially also make it an opaque origin derived from
   // the error page URL, so it can be checked at DidCommit processing.
-  commit_params_.origin_to_commit.reset();
+  commit_params_->origin_to_commit.reset();
   if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_ &&
       request_navigation_client_.is_bound()) {
     if (associated_site_instance_id_ ==
@@ -2047,7 +2076,7 @@
   }
 
   ReadyToCommitNavigation(true);
-  render_frame_host_->FailedNavigation(this, *common_params_, commit_params_,
+  render_frame_host_->FailedNavigation(this, *common_params_, *commit_params_,
                                        has_stale_copy_in_cache_, net_error_,
                                        error_page_content);
 }
@@ -2090,11 +2119,11 @@
   }
   if (subresource_loader_params_ &&
       !subresource_loader_params_->prefetched_signed_exchanges.empty()) {
-    commit_params_.prefetched_signed_exchanges =
+    commit_params_->prefetched_signed_exchanges =
         std::move(subresource_loader_params_->prefetched_signed_exchanges);
   }
   render_frame_host_->CommitNavigation(
-      this, *common_params_, commit_params_, response_head_.get(),
+      this, *common_params_, *commit_params_, response_head_.get(),
       std::move(response_body_), std::move(url_loader_client_endpoints_),
       is_view_source_, std::move(subresource_loader_params_),
       std::move(subresource_overrides_),
@@ -2287,7 +2316,7 @@
         parent->ShouldModifyRequestUrlForCsp(true /* is subresource */)) {
       upgrade_if_insecure_ = true;
       parent->ModifyRequestUrlForCsp(&common_params_->url);
-      commit_params_.original_url = common_params_->url;
+      commit_params_->original_url = common_params_->url;
     }
   }
 
@@ -2394,9 +2423,9 @@
 void NavigationRequest::UpdateCommitNavigationParamsHistory() {
   NavigationController* navigation_controller =
       frame_tree_node_->navigator()->GetController();
-  commit_params_.current_history_list_offset =
+  commit_params_->current_history_list_offset =
       navigation_controller->GetCurrentEntryIndex();
-  commit_params_.current_history_list_length =
+  commit_params_->current_history_list_length =
       navigation_controller->GetEntryCount();
 }
 
@@ -3002,4 +3031,20 @@
     g_commit_timeout = timeout;
 }
 
+void NavigationRequest::RemoveRequestHeader(const std::string& header_name) {
+  DCHECK(handle_state_ == PROCESSING_WILL_REDIRECT_REQUEST ||
+         handle_state_ == WILL_REDIRECT_REQUEST);
+  removed_request_headers_.push_back(header_name);
+}
+
+void NavigationRequest::SetRequestHeader(const std::string& header_name,
+                                         const std::string& header_value) {
+  DCHECK(handle_state_ == INITIAL ||
+         handle_state_ == PROCESSING_WILL_START_REQUEST ||
+         handle_state_ == PROCESSING_WILL_REDIRECT_REQUEST ||
+         handle_state_ == WILL_START_REQUEST ||
+         handle_state_ == WILL_REDIRECT_REQUEST);
+  modified_request_headers_.SetHeader(header_name, header_value);
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 97858ba..f293305a 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -133,7 +133,7 @@
   static std::unique_ptr<NavigationRequest> CreateBrowserInitiated(
       FrameTreeNode* frame_tree_node,
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool browser_initiated,
       const std::string& extra_headers,
       const FrameNavigationEntry& frame_entry,
@@ -187,7 +187,9 @@
     return begin_params_.get();
   }
 
-  const CommitNavigationParams& commit_params() const { return commit_params_; }
+  const mojom::CommitNavigationParams& commit_params() const {
+    return *commit_params_;
+  }
 
   // Updates the navigation start time.
   void set_navigation_start_time(const base::TimeTicks& time) {
@@ -231,7 +233,7 @@
     associated_site_instance_type_ = type;
   }
 
-  void set_was_discarded() { commit_params_.was_discarded = true; }
+  void set_was_discarded() { commit_params_->was_discarded = true; }
 
   NavigationHandleImpl* navigation_handle() const {
     return navigation_handle_.get();
@@ -472,6 +474,19 @@
   // default value if |timeout| is zero.
   static void SetCommitTimeoutForTesting(const base::TimeDelta& timeout);
 
+  const net::HttpRequestHeaders& request_headers() { return request_headers_; }
+
+  // Remove a request's header. If the header is not present, it has no effect.
+  // Must be called during a redirect.
+  void RemoveRequestHeader(const std::string& header_name);
+
+  // Set a request's header. If the header is already present, its value is
+  // overwritten. When modified during a navigation start, the headers will be
+  // applied to the initial network request. When modified during a redirect,
+  // the headers will be applied to the redirected request.
+  void SetRequestHeader(const std::string& header_name,
+                        const std::string& header_value);
+
  private:
   // TODO(clamy): Transform NavigationHandleImplTest into NavigationRequestTest
   // once NavigationHandleImpl has become a wrapper around NavigationRequest.
@@ -480,7 +495,7 @@
   NavigationRequest(FrameTreeNode* frame_tree_node,
                     mojom::CommonNavigationParamsPtr common_params,
                     mojom::BeginNavigationParamsPtr begin_params,
-                    const CommitNavigationParams& commit_params,
+                    mojom::CommitNavigationParamsPtr commit_params,
                     bool browser_initiated,
                     bool from_begin_navigation,
                     bool is_for_commit,
@@ -764,6 +779,14 @@
   void StopCommitTimeout();
   void RestartCommitTimeout();
 
+  std::vector<std::string> TakeRemovedRequestHeaders() {
+    return std::move(removed_request_headers_);
+  }
+
+  net::HttpRequestHeaders TakeModifiedRequestHeaders() {
+    return std::move(modified_request_headers_);
+  }
+
   FrameTreeNode* frame_tree_node_;
 
   // Invariant: At least one of |loader_| or |render_frame_host_| is null.
@@ -780,7 +803,7 @@
   // be set in CreatedNavigationRequest.
   mojom::CommonNavigationParamsPtr common_params_;
   mojom::BeginNavigationParamsPtr begin_params_;
-  CommitNavigationParams commit_params_;
+  mojom::CommitNavigationParamsPtr commit_params_;
   const bool browser_initiated_;
 
   // Stores the NavigationUIData for this navigation until the NavigationHandle
@@ -992,6 +1015,16 @@
   std::unique_ptr<base::CallbackList<void(bool)>::Subscription>
       render_process_blocked_state_changed_subscription_;
 
+  // The headers used for the request.
+  net::HttpRequestHeaders request_headers_;
+
+  // Used to update the request's headers. When modified during the navigation
+  // start, the headers will be applied to the initial network request. When
+  // modified during a redirect, the headers will be applied to the redirected
+  // request.
+  std::vector<std::string> removed_request_headers_;
+  net::HttpRequestHeaders modified_request_headers_;
+
   base::WeakPtrFactory<NavigationRequest> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(NavigationRequest);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 9bc4d5a..dfc9ca4 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4388,8 +4388,11 @@
       false /* started_from_context_menu */, false /* has_user_gesture */,
       InitiatorCSPInfo(), std::vector<int>(), std::string(),
       false /* is_history_navigation_in_new_child_frame */, base::TimeTicks());
+  mojom::CommitNavigationParams commit_params;
+  commit_params.navigation_token = base::UnguessableToken::Create();
+  commit_params.navigation_timing = mojom::NavigationTiming::New();
   CommitNavigation(
-      nullptr /* navigation_request */, common_params, CommitNavigationParams(),
+      nullptr /* navigation_request */, common_params, commit_params,
       nullptr /* response_head */, mojo::ScopedDataPipeConsumerHandle(),
       network::mojom::URLLoaderClientEndpointsPtr(), false, base::nullopt,
       base::nullopt /* subresource_overrides */, nullptr /* provider_info */,
@@ -4738,7 +4741,7 @@
 void RenderFrameHostImpl::CommitNavigation(
     NavigationRequest* navigation_request,
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     network::ResourceResponse* response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -5049,7 +5052,7 @@
   if (is_same_document) {
     DCHECK(same_document_navigation_request_);
     GetNavigationControl()->CommitSameDocumentNavigation(
-        common_params.Clone(), commit_params,
+        common_params.Clone(), commit_params.Clone(),
         base::BindOnce(&RenderFrameHostImpl::OnSameDocumentCommitProcessed,
                        base::Unretained(this),
                        same_document_navigation_request_->navigation_handle()
@@ -5178,7 +5181,7 @@
 
     SendCommitNavigation(
         navigation_client, navigation_request, common_params.Clone(),
-        commit_params, head, std::move(response_body),
+        commit_params.Clone(), head, std::move(response_body),
         std::move(url_loader_client_endpoints),
         std::move(subresource_loader_factories),
         std::move(subresource_overrides), std::move(controller),
@@ -5208,7 +5211,7 @@
 void RenderFrameHostImpl::FailedNavigation(
     NavigationRequest* navigation_request,
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content) {
@@ -5251,8 +5254,8 @@
 
   SendCommitFailedNavigation(
       navigation_client, navigation_request, common_params.Clone(),
-      commit_params, has_stale_copy_in_cache, error_code, error_page_content,
-      std::move(subresource_loader_factories));
+      commit_params.Clone(), has_stale_copy_in_cache, error_code,
+      error_page_content, std::move(subresource_loader_factories));
 
   // An error page is expected to commit, hence why is_loading_ is set to true.
   is_loading_ = true;
@@ -5706,7 +5709,7 @@
 
 void RenderFrameHostImpl::UpdatePermissionsForNavigation(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params) {
+    const mojom::CommitNavigationParams& commit_params) {
   // Browser plugin guests are not allowed to navigate outside web-safe schemes,
   // so do not grant them the ability to commit additional URLs.
   if (!GetProcess()->IsForGuestsOnly()) {
@@ -6972,7 +6975,7 @@
     mojom::NavigationClient* navigation_client,
     NavigationRequest* navigation_request,
     mojom::CommonNavigationParamsPtr common_params,
-    const content::CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -6987,7 +6990,7 @@
     const base::UnguessableToken& devtools_navigation_token) {
   if (navigation_client) {
     navigation_client->CommitNavigation(
-        std::move(common_params), commit_params, response_head,
+        std::move(common_params), std::move(commit_params), response_head,
         std::move(response_body), std::move(url_loader_client_endpoints),
         std::move(subresource_loader_factories),
         std::move(subresource_overrides), std::move(controller),
@@ -6996,7 +6999,7 @@
         BuildNavigationClientCommitNavigationCallback(navigation_request));
   } else {
     GetNavigationControl()->CommitNavigation(
-        std::move(common_params), commit_params, response_head,
+        std::move(common_params), std::move(commit_params), response_head,
         std::move(response_body), std::move(url_loader_client_endpoints),
         std::move(subresource_loader_factories),
         std::move(subresource_overrides), std::move(controller),
@@ -7010,7 +7013,7 @@
     mojom::NavigationClient* navigation_client,
     NavigationRequest* navigation_request,
     mojom::CommonNavigationParamsPtr common_params,
-    const content::CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int32_t error_code,
     const base::Optional<std::string>& error_page_content,
@@ -7018,14 +7021,16 @@
         subresource_loader_factories) {
   if (navigation_client) {
     navigation_client->CommitFailedNavigation(
-        std::move(common_params), commit_params, has_stale_copy_in_cache,
-        error_code, error_page_content, std::move(subresource_loader_factories),
+        std::move(common_params), std::move(commit_params),
+        has_stale_copy_in_cache, error_code, error_page_content,
+        std::move(subresource_loader_factories),
         BuildNavigationClientCommitFailedNavigationCallback(
             navigation_request));
   } else {
     GetNavigationControl()->CommitFailedNavigation(
-        std::move(common_params), commit_params, has_stale_copy_in_cache,
-        error_code, error_page_content, std::move(subresource_loader_factories),
+        std::move(common_params), std::move(commit_params),
+        has_stale_copy_in_cache, error_code, error_page_content,
+        std::move(subresource_loader_factories),
         BuildCommitFailedNavigationCallback(navigation_request));
   }
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 7f2b6ce8..0158a0a6 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -169,7 +169,6 @@
 struct ContextMenuParams;
 struct FrameOwnerProperties;
 struct PendingNavigation;
-struct CommitNavigationParams;
 struct ResourceTimingInfo;
 struct SubresourceLoaderParams;
 
@@ -692,7 +691,7 @@
   void CommitNavigation(
       NavigationRequest* navigation_request,
       const mojom::CommonNavigationParams& common_params,
-      const CommitNavigationParams& commit_params,
+      const mojom::CommitNavigationParams& commit_params,
       network::ResourceResponse* response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -708,7 +707,7 @@
   // an error page.
   void FailedNavigation(NavigationRequest* navigation_request,
                         const mojom::CommonNavigationParams& common_params,
-                        const CommitNavigationParams& commit_params,
+                        const mojom::CommitNavigationParams& commit_params,
                         bool has_stale_copy_in_cache,
                         int error_code,
                         const base::Optional<std::string>& error_page_content);
@@ -1034,7 +1033,7 @@
       mojom::NavigationClient* navigation_client,
       NavigationRequest* navigation_request,
       mojom::CommonNavigationParamsPtr common_params,
-      const content::CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -1052,7 +1051,7 @@
       mojom::NavigationClient* navigation_client,
       NavigationRequest* navigation_request,
       mojom::CommonNavigationParamsPtr common_params,
-      const content::CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int32_t error_code,
       const base::Optional<std::string>& error_page_content,
@@ -1355,7 +1354,7 @@
 
   void UpdatePermissionsForNavigation(
       const mojom::CommonNavigationParams& common_params,
-      const CommitNavigationParams& commit_params);
+      const mojom::CommitNavigationParams& commit_params);
 
   // Creates a Network Service-backed factory from appropriate |NetworkContext|
   // and sets a connection error handler to trigger
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 50ec9b6a..fddc7a9 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -425,7 +425,7 @@
             blink::mojom::Referrer::New(referrer.url, referrer.policy),
             navigate_type, PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(),
             base::TimeTicks::Now());
-    CommitNavigationParams commit_params =
+    mojom::CommitNavigationParamsPtr commit_params =
         entry->ConstructCommitNavigationParams(
             *frame_entry, common_params->url, frame_entry->committed_origin(),
             common_params->method,
@@ -435,11 +435,11 @@
             controller->GetIndexOfEntry(entry),
             controller->GetLastCommittedEntryIndex(),
             controller->GetEntryCount());
-    commit_params.post_content_type = post_content_type;
+    commit_params->post_content_type = post_content_type;
 
     std::unique_ptr<NavigationRequest> navigation_request =
         NavigationRequest::CreateBrowserInitiated(
-            frame_tree_node, std::move(common_params), commit_params,
+            frame_tree_node, std::move(common_params), std::move(commit_params),
             !entry->is_renderer_initiated(), entry->extra_headers(),
             *frame_entry, entry, request_body,
             nullptr /* navigation_ui_data */);
@@ -2931,17 +2931,19 @@
           blink::mojom::Referrer::New(referrer.url, referrer.policy),
           mojom::NavigationType::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED,
           base::TimeTicks::Now(), base::TimeTicks::Now());
-  CommitNavigationParams commit_params = entry.ConstructCommitNavigationParams(
-      *frame_entry, common_params->url, frame_entry->committed_origin(),
-      common_params->method, entry.GetSubframeUniqueNames(frame_tree_node),
-      controller().GetPendingEntryIndex() == -1 /* intended_as_new_entry */,
-      static_cast<NavigationControllerImpl&>(controller())
-          .GetIndexOfEntry(&entry),
-      controller().GetLastCommittedEntryIndex(), controller().GetEntryCount());
+  mojom::CommitNavigationParamsPtr commit_params =
+      entry.ConstructCommitNavigationParams(
+          *frame_entry, common_params->url, frame_entry->committed_origin(),
+          common_params->method, entry.GetSubframeUniqueNames(frame_tree_node),
+          controller().GetPendingEntryIndex() == -1 /* intended_as_new_entry */,
+          static_cast<NavigationControllerImpl&>(controller())
+              .GetIndexOfEntry(&entry),
+          controller().GetLastCommittedEntryIndex(),
+          controller().GetEntryCount());
 
   std::unique_ptr<NavigationRequest> navigation_request =
       NavigationRequest::CreateBrowserInitiated(
-          frame_tree_node, std::move(common_params), commit_params,
+          frame_tree_node, std::move(common_params), std::move(commit_params),
           !entry.is_renderer_initiated(), entry.extra_headers(), *frame_entry,
           &entry, nullptr /* request_body */, nullptr /* navigation_ui_data */);
   manager->DidCreateNavigationRequest(navigation_request.get());
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc
index 79d7e20..c2a13ae 100644
--- a/content/browser/indexed_db/database_impl.cc
+++ b/content/browser/indexed_db/database_impl.cc
@@ -320,7 +320,8 @@
   connection_->database()->OpenCursor(
       transaction, object_store_id, index_id,
       std::make_unique<IndexedDBKeyRange>(key_range), direction, key_only,
-      task_type, std::move(aborting_callback), dispatcher_host_->AsWeakPtr());
+      task_type, std::move(aborting_callback), origin_,
+      dispatcher_host_->AsWeakPtr(), idb_runner_);
 }
 
 void DatabaseImpl::Count(
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 1605acb..360b23d 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -1813,7 +1813,9 @@
     bool key_only,
     blink::mojom::IDBTaskType task_type,
     blink::mojom::IDBDatabase::OpenCursorCallback callback,
-    base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host) {
+    const url::Origin& origin,
+    base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+    scoped_refptr<base::SequencedTaskRunner> idb_runner) {
   DCHECK(transaction);
   IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction->id());
 
@@ -1830,29 +1832,20 @@
       key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE;
   params->task_type = task_type;
   params->callback = std::move(callback);
-  transaction->ScheduleTask(
-      BindWeakOperation(&IndexedDBDatabase::OpenCursorOperation, AsWeakPtr(),
-                        std::move(params), std::move(dispatcher_host)));
+  transaction->ScheduleTask(BindWeakOperation(
+      &IndexedDBDatabase::OpenCursorOperation, AsWeakPtr(), std::move(params),
+      origin, std::move(dispatcher_host), std::move(idb_runner)));
 }
 
 Status IndexedDBDatabase::OpenCursorOperation(
     std::unique_ptr<OpenCursorOperationParams> params,
+    const url::Origin& origin,
     base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+    scoped_refptr<base::SequencedTaskRunner> idb_runner,
     IndexedDBTransaction* transaction) {
   IDB_TRACE1("IndexedDBDatabase::OpenCursorOperation", "txn.id",
              transaction->id());
 
-  Status s = Status::OK();
-  if (!dispatcher_host) {
-    IndexedDBDatabaseError error =
-        CreateError(blink::kWebIDBDatabaseExceptionUnknownError,
-                    "Dispatcher not connected.", transaction);
-    std::move(params->callback)
-        .Run(blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult(
-            blink::mojom::IDBError::New(error.code(), error.message())));
-    return s;
-  }
-
   // The frontend has begun indexing, so this pauses the transaction
   // until the indexing is complete. This can't happen any earlier
   // because we don't want to switch to early mode in case multiple
@@ -1860,6 +1853,7 @@
   if (params->task_type == blink::mojom::IDBTaskType::Preemptive)
     transaction->AddPreemptiveEvent();
 
+  Status s = Status::OK();
   std::unique_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
   if (params->index_id == IndexedDBIndexMetadata::kInvalidId) {
     if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) {
@@ -1903,6 +1897,16 @@
   IndexedDBCursor* cursor_ptr = cursor.get();
   transaction->RegisterOpenCursor(cursor_ptr);
 
+  if (!dispatcher_host) {
+    IndexedDBDatabaseError error =
+        CreateError(blink::kWebIDBDatabaseExceptionUnknownError,
+                    "Dispatcher not connected.", transaction);
+    std::move(params->callback)
+        .Run(blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult(
+            blink::mojom::IDBError::New(error.code(), error.message())));
+    return s;
+  }
+
   blink::mojom::IDBValuePtr mojo_value;
   std::vector<IndexedDBBlobInfo> blob_info;
   if (cursor_ptr->Value()) {
@@ -1910,6 +1914,8 @@
     blob_info.swap(cursor_ptr->Value()->blob_info);
   }
 
+  auto cursor_impl = std::make_unique<CursorImpl>(
+      std::move(cursor), origin, dispatcher_host.get(), idb_runner);
   if (mojo_value &&
       !IndexedDBCallbacks::CreateAllBlobs(
           dispatcher_host->blob_storage_context(),
@@ -1918,11 +1924,13 @@
     return s;
   }
 
+  blink::mojom::IDBCursorAssociatedPtrInfo ptr_info;
+  auto request = mojo::MakeRequest(&ptr_info);
+  dispatcher_host->AddCursorBinding(std::move(cursor_impl), std::move(request));
   std::move(params->callback)
       .Run(blink::mojom::IDBDatabaseOpenCursorResult::NewValue(
           blink::mojom::IDBDatabaseOpenCursorValue::New(
-              dispatcher_host->CreateCursorBinding(std::move(cursor)),
-              cursor_ptr->key(), cursor_ptr->primary_key(),
+              std::move(ptr_info), cursor_ptr->key(), cursor_ptr->primary_key(),
               std::move(mojo_value))));
   return s;
 }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index a343030..d822c2a 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -195,7 +195,9 @@
                   bool key_only,
                   blink::mojom::IDBTaskType task_type,
                   blink::mojom::IDBDatabase::OpenCursorCallback callback,
-                  base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host);
+                  const url::Origin& origin,
+                  base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+                  scoped_refptr<base::SequencedTaskRunner> idb_runner);
   void Count(IndexedDBTransaction* transaction,
              int64_t object_store_id,
              int64_t index_id,
@@ -271,7 +273,9 @@
   struct OpenCursorOperationParams;
   leveldb::Status OpenCursorOperation(
       std::unique_ptr<OpenCursorOperationParams> params,
+      const url::Origin& origin,
       base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+      scoped_refptr<base::SequencedTaskRunner> idb_runner,
       IndexedDBTransaction* transaction);
   leveldb::Status CountOperation(
       int64_t object_store_id,
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
index e35949e..56d7579 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -17,7 +17,6 @@
 #include "content/browser/indexed_db/indexed_db_callbacks.h"
 #include "content/browser/indexed_db/indexed_db_connection.h"
 #include "content/browser/indexed_db/indexed_db_context_impl.h"
-#include "content/browser/indexed_db/indexed_db_cursor.h"
 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
 #include "content/browser/indexed_db/indexed_db_pending_connection.h"
@@ -94,21 +93,16 @@
   database_bindings_.AddBinding(std::move(database), std::move(request));
 }
 
-blink::mojom::IDBCursorAssociatedPtrInfo
-IndexedDBDispatcherHost::CreateCursorBinding(
-    std::unique_ptr<IndexedDBCursor> cursor) {
+void IndexedDBDispatcherHost::AddCursorBinding(
+    std::unique_ptr<CursorImpl> cursor,
+    blink::mojom::IDBCursorAssociatedRequest request) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const auto& context = bindings_.dispatch_context();
-  auto cursor_impl = std::make_unique<CursorImpl>(
-      std::move(cursor), context.origin, this, IDBTaskRunner());
-  auto* cursor_impl_ptr = cursor_impl.get();
-  blink::mojom::IDBCursorAssociatedPtrInfo ptr_info;
-  mojo::BindingId binding_id = cursor_bindings_.AddBinding(
-      std::move(cursor_impl), mojo::MakeRequest(&ptr_info));
-  cursor_impl_ptr->OnRemoveBinding(
+  auto* cursor_ptr = cursor.get();
+  mojo::BindingId binding_id =
+      cursor_bindings_.AddBinding(std::move(cursor), std::move(request));
+  cursor_ptr->OnRemoveBinding(
       base::BindOnce(&IndexedDBDispatcherHost::RemoveCursorBinding,
                      weak_factory_.GetWeakPtr(), binding_id));
-  return ptr_info;
 }
 
 void IndexedDBDispatcherHost::RemoveCursorBinding(mojo::BindingId binding_id) {
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h
index f650974..02891034 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.h
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -33,8 +33,8 @@
 }
 
 namespace content {
+class CursorImpl;
 class IndexedDBContextImpl;
-class IndexedDBCursor;
 class IndexedDBTransaction;
 
 // Constructed on UI thread.  All remaining calls (including destruction) should
@@ -55,8 +55,8 @@
   void AddDatabaseBinding(std::unique_ptr<blink::mojom::IDBDatabase> database,
                           blink::mojom::IDBDatabaseAssociatedRequest request);
 
-  blink::mojom::IDBCursorAssociatedPtrInfo CreateCursorBinding(
-      std::unique_ptr<IndexedDBCursor> cursor);
+  void AddCursorBinding(std::unique_ptr<CursorImpl> cursor,
+                        blink::mojom::IDBCursorAssociatedRequest request);
   void RemoveCursorBinding(mojo::BindingId binding_id);
 
   void AddTransactionBinding(
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index b609cb62..fad580a 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -1039,8 +1039,8 @@
     // TODO(davidben): This copy could be avoided if ResourceResponse weren't
     // reference counted and the loader stack passed unique ownership of the
     // response. https://crbug.com/416050
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
+    RunOrPostTaskIfNecessary(
+        FROM_HERE, BrowserThread::UI,
         base::BindOnce(&NavigationURLLoaderImpl::OnReceiveResponse, owner_,
                        response->DeepCopy(),
                        std::move(url_loader_client_endpoints),
diff --git a/content/browser/notifications/notification_database.cc b/content/browser/notifications/notification_database.cc
index d432fda..3d0746f 100644
--- a/content/browser/notifications/notification_database.cc
+++ b/content/browser/notifications/notification_database.cc
@@ -350,9 +350,8 @@
   NotificationDatabaseData data;
   Status status = ReadNotificationData(notification_id, origin, &data);
   if (status == STATUS_OK && record_notification_to_ukm_callback_) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(record_notification_to_ukm_callback_, data));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(record_notification_to_ukm_callback_, data));
   }
 
   leveldb::WriteBatch batch;
@@ -507,10 +506,9 @@
     }
 
     if (record_notification_to_ukm_callback_) {
-      base::PostTaskWithTraits(
-          FROM_HERE, {BrowserThread::UI},
-          base::BindOnce(record_notification_to_ukm_callback_,
-                         notification_database_data));
+      base::PostTask(FROM_HERE, {BrowserThread::UI},
+                     base::BindOnce(record_notification_to_ukm_callback_,
+                                    notification_database_data));
     }
 
     std::string notification_id = notification_database_data.notification_id;
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc
index 4caf49c..29f157f 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -87,7 +87,7 @@
     NotificationDispatchCompleteCallback dispatch_complete_callback,
     blink::ServiceWorkerStatusCode service_worker_status) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(std::move(dispatch_complete_callback),
                      ConvertServiceWorkerStatus(service_worker_status)));
@@ -149,9 +149,8 @@
       break;
   }
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(dispatch_complete_callback), status));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(dispatch_complete_callback), status));
 }
 
 // Finds the ServiceWorkerRegistration associated with the |origin| and
@@ -176,7 +175,7 @@
     return;
   }
 
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&ServiceWorkerContextWrapper::FindReadyRegistrationForId,
                      service_worker_context,
@@ -248,7 +247,7 @@
     NotificationDispatchCompleteCallback dispatch_complete_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&notifications::LogNotificationClickedEventToDevTools,
                      browser_context, notification_database_data, action_index,
@@ -290,7 +289,7 @@
     NotificationDispatchCompleteCallback dispatch_complete_callback,
     blink::ServiceWorkerStatusCode status_code) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(
           &PlatformNotificationContext::DeleteNotificationData,
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc
index 564d4fdb..2722cebb 100644
--- a/content/browser/notifications/platform_notification_context_impl.cc
+++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -242,10 +242,9 @@
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   std::set<GURL> origins;
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       std::move(origins)));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  std::move(origins)));
     return;
   }
 
@@ -264,7 +263,7 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI},
       base::BindOnce(std::move(callback), success, std::move(origins)));
 }
@@ -310,10 +309,9 @@
     bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       /* deleted_count= */ 0));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  /* deleted_count= */ 0));
     return;
   }
 
@@ -344,9 +342,9 @@
       service_proxy_->CloseNotification(notification_id);
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), success,
-                                          deleted_notification_ids.size()));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), success,
+                                deleted_notification_ids.size()));
 }
 
 void PlatformNotificationContextImpl::ReadNotificationDataAndRecordInteraction(
@@ -368,10 +366,9 @@
     bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       NotificationDatabaseData()));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  NotificationDatabaseData()));
     return;
   }
 
@@ -384,10 +381,9 @@
                             NotificationDatabase::STATUS_COUNT);
 
   if (status == NotificationDatabase::STATUS_OK) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ true,
-                       database_data));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ true,
+                                  database_data));
     return;
   }
 
@@ -395,10 +391,9 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(callback), /* success= */ false,
-                     NotificationDatabaseData()));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), /* success= */ false,
+                                NotificationDatabaseData()));
 }
 
 void PlatformNotificationContextImpl::TriggerNotifications() {
@@ -470,9 +465,8 @@
     bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false));
     return;
   }
 
@@ -503,9 +497,8 @@
   }
 
   if (status == NotificationDatabase::STATUS_OK) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ true));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ true));
     return;
   }
 
@@ -513,9 +506,8 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(callback), /* success= */ false));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), /* success= */ false));
 }
 
 void PlatformNotificationContextImpl::ReDisplayNotifications(
@@ -537,9 +529,8 @@
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   size_t display_count = 0;
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), display_count));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), display_count));
     return;
   }
 
@@ -581,9 +572,9 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
-      base::BindOnce(std::move(callback), display_count));
+  base::PostTask(FROM_HERE,
+                 {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
+                 base::BindOnce(std::move(callback), display_count));
 }
 
 void PlatformNotificationContextImpl::ReadNotificationResources(
@@ -603,10 +594,9 @@
     bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       blink::NotificationResources()));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  blink::NotificationResources()));
     return;
   }
 
@@ -618,10 +608,9 @@
                             status, NotificationDatabase::STATUS_COUNT);
 
   if (status == NotificationDatabase::STATUS_OK) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ true,
-                       notification_resources));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ true,
+                                  notification_resources));
     return;
   }
 
@@ -629,10 +618,9 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(callback), /* success= */ false,
-                     blink::NotificationResources()));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), /* success= */ false,
+                                blink::NotificationResources()));
 }
 
 void PlatformNotificationContextImpl::
@@ -687,10 +675,9 @@
         bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       std::vector<NotificationDatabaseData>()));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  std::vector<NotificationDatabaseData>()));
     return;
   }
 
@@ -722,10 +709,9 @@
       }
     }
 
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ true,
-                       notification_datas));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ true,
+                                  notification_datas));
 
     // Remove notifications that are not actually on display anymore.
     for (const auto& it : obsolete_notifications)
@@ -737,10 +723,9 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(callback), /* success= */ false,
-                     std::vector<NotificationDatabaseData>()));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), /* success= */ false,
+                                std::vector<NotificationDatabaseData>()));
 }
 
 void PlatformNotificationContextImpl::WriteNotificationData(
@@ -788,10 +773,9 @@
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(database_data.notification_id.empty());
   if (!initialized || !service_proxy_) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       /* notification_id= */ ""));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  /* notification_id= */ ""));
     return;
   }
 
@@ -824,10 +808,9 @@
     if (delete_status == NotificationDatabase::STATUS_ERROR_CORRUPTED) {
       DestroyDatabase();
 
-      base::PostTaskWithTraits(
-          FROM_HERE, {BrowserThread::UI},
-          base::BindOnce(std::move(callback), /* success= */ false,
-                         /* notification_id= */ ""));
+      base::PostTask(FROM_HERE, {BrowserThread::UI},
+                     base::BindOnce(std::move(callback), /* success= */ false,
+                                    /* notification_id= */ ""));
       return;
     }
   }
@@ -840,10 +823,9 @@
   if (CanTrigger(write_database_data) &&
       !DoCheckNotificationTriggerQuota(origin)) {
     // TODO(knollr): Reply with a custom error so developers can handle this.
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       /* notification_id= */ ""));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  /* notification_id= */ ""));
     return;
   }
 
@@ -866,10 +848,9 @@
       service_proxy_->ScheduleNotification(std::move(write_database_data));
 
       // Respond with success as this notification got scheduled successfully.
-      base::PostTaskWithTraits(
-          FROM_HERE, {BrowserThread::UI},
-          base::BindOnce(std::move(callback), /* success= */ true,
-                         notification_id));
+      base::PostTask(FROM_HERE, {BrowserThread::UI},
+                     base::BindOnce(std::move(callback), /* success= */ true,
+                                    notification_id));
       return;
     }
 
@@ -885,10 +866,9 @@
   if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
     DestroyDatabase();
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(std::move(callback), /* success= */ false,
-                     /* notification_id= */ ""));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), /* success= */ false,
+                                /* notification_id= */ ""));
 }
 
 void PlatformNotificationContextImpl::DeleteNotificationData(
@@ -918,8 +898,8 @@
     bool initialized) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   if (!initialized) {
-    base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                             base::BindOnce(std::move(callback), false));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(std::move(callback), false));
     return;
   }
 
@@ -948,8 +928,8 @@
     success = true;
   }
 
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::BindOnce(std::move(callback), success));
+  base::PostTask(FROM_HERE, {BrowserThread::UI},
+                 base::BindOnce(std::move(callback), success));
 }
 
 void PlatformNotificationContextImpl::OnRegistrationDeleted(
@@ -1009,8 +989,9 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (!task_runner_) {
-    task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-        {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+    task_runner_ =
+        base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                         base::TaskPriority::USER_VISIBLE});
   }
 
   task_runner_->PostTask(
diff --git a/content/browser/notifications/platform_notification_service_proxy.cc b/content/browser/notifications/platform_notification_service_proxy.cc
index c5c1871..66464701 100644
--- a/content/browser/notifications/platform_notification_service_proxy.cc
+++ b/content/browser/notifications/platform_notification_service_proxy.cc
@@ -63,16 +63,16 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (status == blink::ServiceWorkerStatusCode::kOk &&
       registration->scope().GetOrigin() == data.origin) {
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
         base::BindOnce(&PlatformNotificationServiceProxy::DoDisplayNotification,
                        AsWeakPtr(), data, registration->scope(),
                        std::move(callback)));
   } else {
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
-        base::BindOnce(std::move(callback), /* success= */ false,
-                       /* notification_id= */ ""));
+    base::PostTask(FROM_HERE,
+                   {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
+                   base::BindOnce(std::move(callback), /* success= */ false,
+                                  /* notification_id= */ ""));
   }
 }
 
@@ -80,14 +80,14 @@
     const NotificationDatabaseData& data,
     DisplayResultCallback callback) {
   if (!service_worker_context_) {
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
         base::BindOnce(&PlatformNotificationServiceProxy::DoDisplayNotification,
                        AsWeakPtr(), data, GURL(), std::move(callback)));
     return;
   }
 
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO, base::TaskPriority::USER_VISIBLE},
       base::BindOnce(
           &ServiceWorkerContextWrapper::FindReadyRegistrationForId,
@@ -102,7 +102,7 @@
     const std::string& notification_id) {
   if (!notification_service_)
     return;
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
       base::BindOnce(&PlatformNotificationServiceProxy::DoCloseNotification,
                      AsWeakPtr(), notification_id));
@@ -117,7 +117,7 @@
 void PlatformNotificationServiceProxy::ScheduleTrigger(base::Time timestamp) {
   if (!notification_service_)
     return;
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
       base::BindOnce(&PlatformNotificationServiceProxy::DoScheduleTrigger,
                      AsWeakPtr(), timestamp));
@@ -133,7 +133,7 @@
   DCHECK(data.notification_data.show_trigger_timestamp.has_value());
   if (!notification_service_)
     return;
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
       base::BindOnce(&PlatformNotificationServiceProxy::DoScheduleNotification,
                      AsWeakPtr(), data));
@@ -172,10 +172,10 @@
 
 void PlatformNotificationServiceProxy::LogClose(
     const NotificationDatabaseData& data) {
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI, base::TaskPriority::BEST_EFFORT},
-      base::BindOnce(&PlatformNotificationServiceProxy::DoLogClose, AsWeakPtr(),
-                     data));
+  base::PostTask(FROM_HERE,
+                 {BrowserThread::UI, base::TaskPriority::BEST_EFFORT},
+                 base::BindOnce(&PlatformNotificationServiceProxy::DoLogClose,
+                                AsWeakPtr(), data));
 }
 
 void PlatformNotificationServiceProxy::DoLogClose(
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index f22e5fa..9b4eccf 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -81,21 +81,13 @@
   host_frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_);
 }
 
-void DelegatedFrameHost::AddObserverForTesting(Observer* observer) {
-  observers_.AddObserver(observer);
-}
-
-void DelegatedFrameHost::RemoveObserverForTesting(Observer* observer) {
-  observers_.RemoveObserver(observer);
-}
-
 void DelegatedFrameHost::WasShown(
     const viz::LocalSurfaceId& new_local_surface_id,
     const gfx::Size& new_dip_size,
     const base::Optional<RecordTabSwitchTimeRequest>&
         record_tab_switch_time_request) {
   // Cancel any pending frame eviction and unpause it if paused.
-  SetFrameEvictionStateAndNotifyObservers(FrameEvictionState::kNotStarted);
+  frame_eviction_state_ = FrameEvictionState::kNotStarted;
 
   frame_evictor_->SetVisible(true);
   if (record_tab_switch_time_request && compositor_) {
@@ -189,16 +181,6 @@
       viz::SurfaceId(frame_sink_id_, local_surface_id_), std::move(request));
 }
 
-void DelegatedFrameHost::SetFrameEvictionStateAndNotifyObservers(
-    FrameEvictionState frame_eviction_state) {
-  if (frame_eviction_state_ == frame_eviction_state)
-    return;
-
-  frame_eviction_state_ = frame_eviction_state;
-  for (auto& obs : observers_)
-    obs.OnFrameEvictionStateChanged(frame_eviction_state_);
-}
-
 bool DelegatedFrameHost::CanCopyFromCompositingSurface() const {
   return local_surface_id_.is_valid();
 }
@@ -391,8 +373,7 @@
   // CrOS overview mode.
   if (client_->ShouldShowStaleContentOnEviction() &&
       !stale_content_layer_->has_external_content()) {
-    SetFrameEvictionStateAndNotifyObservers(
-        FrameEvictionState::kPendingEvictionRequests);
+    frame_eviction_state_ = FrameEvictionState::kPendingEvictionRequests;
     auto callback =
         base::BindOnce(&DelegatedFrameHost::DidCopyStaleContent, GetWeakPtr());
 
@@ -418,7 +399,7 @@
   DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
 
   DCHECK_NE(frame_eviction_state_, FrameEvictionState::kNotStarted);
-  SetFrameEvictionStateAndNotifyObservers(FrameEvictionState::kNotStarted);
+  frame_eviction_state_ = FrameEvictionState::kNotStarted;
   ContinueDelegatedFrameEviction();
 
   auto transfer_resource = viz::TransferableResource::MakeGL(
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h
index 7fe79a1..c01fba1 100644
--- a/content/browser/renderer_host/delegated_frame_host.h
+++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -69,19 +69,6 @@
       public viz::mojom::CompositorFrameSinkClient,
       public viz::HostFrameSinkClient {
  public:
-  enum class FrameEvictionState {
-    kNotStarted = 0,          // Frame eviction is ready.
-    kPendingEvictionRequests  // Frame eviction is paused with pending requests.
-  };
-
-  class Observer {
-   public:
-    virtual void OnFrameEvictionStateChanged(FrameEvictionState new_state) = 0;
-
-   protected:
-    virtual ~Observer() = default;
-  };
-
   // |should_register_frame_sink_id| flag indicates whether DelegatedFrameHost
   // is responsible for registering the associated FrameSinkId with the
   // compositor or not. This is set only on non-aura platforms, since aura is
@@ -91,9 +78,6 @@
                      bool should_register_frame_sink_id);
   ~DelegatedFrameHost() override;
 
-  void AddObserverForTesting(Observer* observer);
-  void RemoveObserverForTesting(Observer* observer);
-
   // ui::CompositorObserver implementation.
   void OnCompositingShuttingDown(ui::Compositor* compositor) override;
 
@@ -189,14 +173,6 @@
     return weak_factory_.GetWeakPtr();
   }
 
-  const ui::Layer* stale_content_layer() const {
-    return stale_content_layer_.get();
-  }
-
-  FrameEvictionState frame_eviction_state() const {
-    return frame_eviction_state_;
-  }
-
  private:
   friend class DelegatedFrameHostClient;
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraBrowserTest,
@@ -224,9 +200,6 @@
       viz::CopyOutputRequest::ResultFormat format,
       viz::CopyOutputRequest::CopyOutputRequestCallback callback);
 
-  void SetFrameEvictionStateAndNotifyObservers(
-      FrameEvictionState frame_eviction_state);
-
   const viz::FrameSinkId frame_sink_id_;
   DelegatedFrameHostClient* const client_;
   const bool enable_viz_;
@@ -258,6 +231,11 @@
 
   viz::LocalSurfaceId first_local_surface_id_after_navigation_;
 
+  enum class FrameEvictionState {
+    kNotStarted = 0,          // Frame eviction is ready.
+    kPendingEvictionRequests  // Frame eviction is paused with pending requests.
+  };
+
   FrameEvictionState frame_eviction_state_ = FrameEvictionState::kNotStarted;
 
   // Layer responsible for displaying the stale content for the DFHC when the
@@ -267,8 +245,6 @@
 
   TabSwitchTimeRecorder tab_switch_time_recorder_;
 
-  base::ObserverList<Observer>::Unchecked observers_;
-
   base::WeakPtrFactory<DelegatedFrameHost> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(DelegatedFrameHost);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index f12a39c..2bc54fe 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -459,8 +459,6 @@
 
   class WindowAncestorObserver;
   friend class WindowAncestorObserver;
-  friend void VerifyStaleContentOnFrameEviction(
-      RenderWidgetHostView* render_widget_host_view);
 
   // Allocate a new FrameSinkId if this object is the platform view of a
   // RenderWidgetHostViewGuest. This FrameSinkId will not be actually used in
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index 47cfc0a..3430552 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -100,7 +100,7 @@
   // mojom::NavigationClientPtr implementation:
   void CommitNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& request_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -120,7 +120,7 @@
   }
   void CommitFailedNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
@@ -221,7 +221,7 @@
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
   navigation_client_->CommitNavigation(
-      std::move(common_params), CommitNavigationParams(),
+      std::move(common_params), CreateCommitNavigationParams(),
       network::ResourceResponseHead(), mojo::ScopedDataPipeConsumerHandle(),
       nullptr, nullptr, base::nullopt, nullptr, std::move(info),
       mojo::NullRemote(), base::UnguessableToken::Create(),
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index c9cb924..769b35b 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -78,10 +78,6 @@
               gfx.mojom.Rect clip_rect);
 };
 
-// See src/content/common/navigation_params.h
-[Native]
-struct CommitNavigationParams;
-
 // Implemented by the frame provider and currently must be associated with the
 // legacy IPC channel.
 // KEEP THE COMMIT FUNCTIONS IN SYNC in content/common/navigation_client.mojom.
diff --git a/content/common/frame.typemap b/content/common/frame.typemap
deleted file mode 100644
index 36e3849..0000000
--- a/content/common/frame.typemap
+++ /dev/null
@@ -1,12 +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.
-
-mojom = "//content/common/frame.mojom"
-public_headers = [ "//content/common/navigation_params.h" ]
-traits_headers = [ "//content/common/frame_messages.h" ]
-deps = [
-  "//content:export",
-]
-type_mappings =
-    [ "content.mojom.CommitNavigationParams=content::CommitNavigationParams" ]
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 72cf248..a4971e4 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -47,7 +47,6 @@
 #include "content/public/common/screen_info.h"
 #include "content/public/common/stop_find_action.h"
 #include "content/public/common/three_d_api_types.h"
-#include "content/public/common/was_activated_option.h"
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_platform_file.h"
 #include "mojo/public/cpp/system/message_pipe.h"
@@ -145,8 +144,6 @@
                           blink::UserActivationUpdateType::kMaxValue)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::WebMediaPlayerAction::Type,
                           blink::WebMediaPlayerAction::Type::kMaxValue)
-IPC_ENUM_TRAITS_MAX_VALUE(content::WasActivatedOption,
-                          content::WasActivatedOption::kMaxValue)
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScrollDirection,
                               blink::kFirstScrollDirection,
                               blink::kLastScrollDirection)
@@ -477,43 +474,6 @@
   IPC_STRUCT_TRAITS_MEMBER(loader_factory_handle)
 IPC_STRUCT_TRAITS_END()
 
-IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming)
-  IPC_STRUCT_TRAITS_MEMBER(redirect_start)
-  IPC_STRUCT_TRAITS_MEMBER(redirect_end)
-  IPC_STRUCT_TRAITS_MEMBER(fetch_start)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::CommitNavigationParams)
-  IPC_STRUCT_TRAITS_MEMBER(origin_to_commit)
-  IPC_STRUCT_TRAITS_MEMBER(is_overriding_user_agent)
-  IPC_STRUCT_TRAITS_MEMBER(redirects)
-  IPC_STRUCT_TRAITS_MEMBER(redirect_response)
-  IPC_STRUCT_TRAITS_MEMBER(redirect_infos)
-  IPC_STRUCT_TRAITS_MEMBER(post_content_type)
-  IPC_STRUCT_TRAITS_MEMBER(original_url)
-  IPC_STRUCT_TRAITS_MEMBER(original_method)
-  IPC_STRUCT_TRAITS_MEMBER(can_load_local_resources)
-  IPC_STRUCT_TRAITS_MEMBER(page_state)
-  IPC_STRUCT_TRAITS_MEMBER(nav_entry_id)
-  IPC_STRUCT_TRAITS_MEMBER(subframe_unique_names)
-  IPC_STRUCT_TRAITS_MEMBER(intended_as_new_entry)
-  IPC_STRUCT_TRAITS_MEMBER(pending_history_list_offset)
-  IPC_STRUCT_TRAITS_MEMBER(current_history_list_offset)
-  IPC_STRUCT_TRAITS_MEMBER(current_history_list_length)
-  IPC_STRUCT_TRAITS_MEMBER(was_discarded)
-  IPC_STRUCT_TRAITS_MEMBER(is_view_source)
-  IPC_STRUCT_TRAITS_MEMBER(should_clear_history_list)
-  IPC_STRUCT_TRAITS_MEMBER(navigation_timing)
-  IPC_STRUCT_TRAITS_MEMBER(appcache_host_id)
-  IPC_STRUCT_TRAITS_MEMBER(was_activated)
-  IPC_STRUCT_TRAITS_MEMBER(navigation_token)
-  IPC_STRUCT_TRAITS_MEMBER(prefetched_signed_exchanges)
-#if defined(OS_ANDROID)
-  IPC_STRUCT_TRAITS_MEMBER(data_url_as_string)
-#endif
-  IPC_STRUCT_TRAITS_MEMBER(is_browser_initiated)
-IPC_STRUCT_TRAITS_END()
-
 IPC_STRUCT_TRAITS_BEGIN(blink::ParsedFeaturePolicyDeclaration)
   IPC_STRUCT_TRAITS_MEMBER(feature)
   IPC_STRUCT_TRAITS_MEMBER(values)
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom
index 9c386653..4f891bf 100644
--- a/content/common/navigation_client.mojom
+++ b/content/common/navigation_client.mojom
@@ -16,10 +16,6 @@
 import "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom";
 import "third_party/blink/public/mojom/commit_result/commit_result.mojom";
 
-// See src/content/common/navigation_params.h
-[Native]
-struct CommitNavigationParams;
-
 interface NavigationClient {
   // Tells the renderer that a navigation is ready to commit.
   //
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc
index 0c532666..dd256ac 100644
--- a/content/common/navigation_params.cc
+++ b/content/common/navigation_params.cc
@@ -35,45 +35,12 @@
 
 InitiatorCSPInfo::~InitiatorCSPInfo() = default;
 
-CommitNavigationParams::CommitNavigationParams()
-    : navigation_token(base::UnguessableToken::Create()) {}
+mojom::CommitNavigationParamsPtr CreateCommitNavigationParams() {
+  auto commit_params = mojom::CommitNavigationParams::New();
+  commit_params->navigation_token = base::UnguessableToken::Create();
+  commit_params->navigation_timing = mojom::NavigationTiming::New();
 
-CommitNavigationParams::CommitNavigationParams(
-    const base::Optional<url::Origin>& origin_to_commit,
-    bool is_overriding_user_agent,
-    const std::vector<GURL>& redirects,
-    const GURL& original_url,
-    const std::string& original_method,
-    bool can_load_local_resources,
-    const PageState& page_state,
-    int nav_entry_id,
-    std::map<std::string, bool> subframe_unique_names,
-    bool intended_as_new_entry,
-    int pending_history_list_offset,
-    int current_history_list_offset,
-    int current_history_list_length,
-    bool is_view_source,
-    bool should_clear_history_list)
-    : origin_to_commit(origin_to_commit),
-      is_overriding_user_agent(is_overriding_user_agent),
-      redirects(redirects),
-      original_url(original_url),
-      original_method(original_method),
-      can_load_local_resources(can_load_local_resources),
-      page_state(page_state),
-      nav_entry_id(nav_entry_id),
-      subframe_unique_names(subframe_unique_names),
-      intended_as_new_entry(intended_as_new_entry),
-      pending_history_list_offset(pending_history_list_offset),
-      current_history_list_offset(current_history_list_offset),
-      current_history_list_length(current_history_list_length),
-      is_view_source(is_view_source),
-      should_clear_history_list(should_clear_history_list),
-      navigation_token(base::UnguessableToken::Create()) {}
-
-CommitNavigationParams::CommitNavigationParams(
-    const CommitNavigationParams& other) = default;
-
-CommitNavigationParams::~CommitNavigationParams() = default;
+  return commit_params;
+}
 
 }  // namespace content
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h
index 88c983c..4da72d1 100644
--- a/content/common/navigation_params.h
+++ b/content/common/navigation_params.h
@@ -25,7 +25,7 @@
 #include "content/public/common/page_state.h"
 #include "content/public/common/previews_state.h"
 #include "content/public/common/referrer.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "net/url_request/redirect_info.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/resource_response.h"
@@ -81,157 +81,7 @@
   base::Optional<CSPSource> initiator_self_source;
 };
 
-// Provided by the browser -----------------------------------------------------
-
-// Timings collected in the browser during navigation for the
-// Navigation Timing API. Sent to Blink in CommitNavigationParams when
-// the navigation is ready to be committed.
-struct CONTENT_EXPORT NavigationTiming {
-  base::TimeTicks redirect_start;
-  base::TimeTicks redirect_end;
-  base::TimeTicks fetch_start;
-};
-
-// Used by commit IPC messages. Holds the parameters needed by the renderer to
-// commit a navigation besides those in CommonNavigationParams.
-struct CONTENT_EXPORT CommitNavigationParams {
-  CommitNavigationParams();
-  CommitNavigationParams(const base::Optional<url::Origin>& origin_to_commit,
-                         bool is_overriding_user_agent,
-                         const std::vector<GURL>& redirects,
-                         const GURL& original_url,
-                         const std::string& original_method,
-                         bool can_load_local_resources,
-                         const PageState& page_state,
-                         int nav_entry_id,
-                         std::map<std::string, bool> subframe_unique_names,
-                         bool intended_as_new_entry,
-                         int pending_history_list_offset,
-                         int current_history_list_offset,
-                         int current_history_list_length,
-                         bool is_view_source,
-                         bool should_clear_history_list);
-  CommitNavigationParams(const CommitNavigationParams& other);
-  ~CommitNavigationParams();
-
-  // The origin to be used for committing the navigation, if specified.
-  // This will be an origin that's compatible with the |url| in the
-  // CommonNavigationParams; if |url| is data: or about:blank, or the frame has
-  // sandbox attributes, this determines the origin of the resulting document.
-  // It is specified for session history navigations, for which the origin is
-  // known and saved in the FrameNavigationEntry.
-  base::Optional<url::Origin> origin_to_commit;
-
-  // Whether or not the user agent override string should be used.
-  bool is_overriding_user_agent = false;
-
-  // Any redirect URLs that occurred before |url|. Useful for cross-process
-  // navigations; defaults to empty.
-  std::vector<GURL> redirects;
-
-  // The ResourceResponseInfos received during redirects.
-  std::vector<network::ResourceResponseHead> redirect_response;
-
-  // The RedirectInfos received during redirects.
-  std::vector<net::RedirectInfo> redirect_infos;
-
-  // The content type from the request headers for POST requests.
-  std::string post_content_type;
-
-  // The original URL & method for this navigation.
-  GURL original_url;
-  std::string original_method;
-
-  // Whether or not this url should be allowed to access local file://
-  // resources.
-  bool can_load_local_resources = false;
-
-  // Opaque history state (received by ViewHostMsg_UpdateState).
-  PageState page_state;
-
-  // For browser-initiated navigations, this is the unique id of the
-  // NavigationEntry being navigated to. (For renderer-initiated navigations it
-  // is 0.) If the load succeeds, then this nav_entry_id will be reflected in
-  // the resulting FrameHostMsg_DidCommitProvisionalLoad_Params.
-  int nav_entry_id = 0;
-
-  // If this is a history navigation, this contains a map of frame unique names
-  // to |is_about_blank| for immediate children of the frame being navigated for
-  // which there are history items.  The renderer process only needs to check
-  // with the browser process for newly created subframes that have these unique
-  // names (and only when not staying on about:blank).
-  // TODO(creis): Expand this to a data structure including corresponding
-  // same-process PageStates for the whole subtree in https://crbug.com/639842.
-  std::map<std::string, bool> subframe_unique_names;
-
-  // For browser-initiated navigations, this is true if this is a new entry
-  // being navigated to. This is false otherwise. TODO(avi): Remove this when
-  // the pending entry situation is made sane and the browser keeps them around
-  // long enough to match them via nav_entry_id, above.
-  bool intended_as_new_entry = false;
-
-  // For history navigations, this is the offset in the history list of the
-  // pending load. For non-history navigations, this will be ignored.
-  int pending_history_list_offset = -1;
-
-  // Where its current page contents reside in session history and the total
-  // size of the session history list.
-  int current_history_list_offset = -1;
-  int current_history_list_length = 0;
-
-  // Indicates that the tab was previously discarded.
-  // wasDiscarded is exposed on Document after discard, see:
-  // https://github.com/WICG/web-lifecycle
-  bool was_discarded = false;
-
-  // Indicates whether the navigation is to a view-source:// scheme or not.
-  // It is a separate boolean as the view-source scheme is stripped from the
-  // URL before it is sent to the renderer process and the RenderFrame needs
-  // to be put in special view source mode.
-  bool is_view_source = false;
-
-  // Whether session history should be cleared. In that case, the RenderView
-  // needs to notify the browser that the clearing was succesful when the
-  // navigation commits.
-  bool should_clear_history_list = false;
-
-  // Timing of navigation events.
-  NavigationTiming navigation_timing;
-
-  // The AppCache host id to be used to identify this navigation.
-  base::Optional<base::UnguessableToken> appcache_host_id;
-
-  // Set to |kYes| if a navigation is following the rules of user activation
-  // propagation. This is different from |has_user_gesture|
-  // (in CommonNavigationParams) as the activation may have happened before
-  // the navigation was triggered, for example.
-  // In other words, the distinction isn't regarding user activation and user
-  // gesture but whether there was an activation prior to the navigation or to
-  // start it. `was_activated` will answer the former question while
-  // `user_gesture` will answer the latter.
-  WasActivatedOption was_activated = WasActivatedOption::kUnknown;
-
-  // A token that should be passed to the browser process in
-  // DidCommitProvisionalLoadParams.
-  // TODO(clamy): Remove this once NavigationClient has shipped and
-  // same-document browser-initiated navigations are properly handled as well.
-  base::UnguessableToken navigation_token;
-
-  // Prefetched signed exchanges. Used when SignedExchangeSubresourcePrefetch
-  // feature is enabled.
-  std::vector<PrefetchedSignedExchangeInfo> prefetched_signed_exchanges;
-
-#if defined(OS_ANDROID)
-  // The real content of the data: URL. Only used in Android WebView for
-  // implementing LoadDataWithBaseUrl API method to circumvent the restriction
-  // on the GURL max length in the IPC layer. Short data: URLs can still be
-  // passed in the |CommonNavigationParams::url| field.
-  std::string data_url_as_string;
-#endif
-
-  // Whether this navigation was browser initiated.
-  bool is_browser_initiated = false;
-};
+CONTENT_EXPORT mojom::CommitNavigationParamsPtr CreateCommitNavigationParams();
 
 }  // namespace content
 
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom
index 71a9a447..6bf27ad 100644
--- a/content/common/navigation_params.mojom
+++ b/content/common/navigation_params.mojom
@@ -4,7 +4,9 @@
 
 module content.mojom;
 
+import "content/public/common/was_activated_option.mojom";
 import "mojo/public/mojom/base/time.mojom";
+import "mojo/public/mojom/base/unguessable_token.mojom";
 import "mojo/public/mojom/base/values.mojom";
 import "services/network/public/mojom/url_loader.mojom";
 import "third_party/blink/public/mojom/fetch/fetch_api_request.mojom";
@@ -23,9 +25,15 @@
 struct NavigationDownloadPolicy;
 
 [Native]
+struct PageState;
+
+[Native]
 enum PageTransition;
 
 [Native]
+struct PrefetchedSignedExchangeInfo;
+
+[Native]
 struct SourceLocation;
 
 enum NavigationType {
@@ -206,3 +214,135 @@
   // setting it.
   mojo_base.mojom.TimeTicks input_start;
 };
+
+// Provided by the browser -----------------------------------------------------
+
+// Timings collected in the browser during navigation for the
+// Navigation Timing API. Sent to Blink in CommitNavigationParams when
+// the navigation is ready to be committed.
+struct NavigationTiming {
+  mojo_base.mojom.TimeTicks redirect_start;
+  mojo_base.mojom.TimeTicks redirect_end;
+  mojo_base.mojom.TimeTicks fetch_start;
+};
+
+// Used by commit IPC messages. Holds the parameters needed by the renderer to
+// commit a navigation besides those in CommonNavigationParams.
+struct CommitNavigationParams {
+  // The origin to be used for committing the navigation, if specified.
+  // This will be an origin that's compatible with the |url| in the
+  // CommonNavigationParams; if |url| is data: or about:blank, or the frame has
+  // sandbox attributes, this determines the origin of the resulting document.
+  // It is specified for session history navigations, for which the origin is
+  // known and saved in the FrameNavigationEntry.
+  url.mojom.Origin? origin_to_commit;
+
+  // Whether or not the user agent override string should be used.
+  bool is_overriding_user_agent = false;
+
+  // Any redirect URLs that occurred before |url|. Useful for cross-process
+  // navigations; defaults to empty.
+  array<url.mojom.Url> redirects;
+
+  // The ResourceResponseInfos received during redirects.
+  array<network.mojom.URLResponseHead> redirect_response;
+
+  // The RedirectInfos received during redirects.
+  array<network.mojom.URLRequestRedirectInfo> redirect_infos;
+
+  // The content type from the request headers for POST requests.
+  string post_content_type;
+
+  // The original URL & method for this navigation.
+  url.mojom.Url original_url;
+  string original_method;
+
+  // Whether or not this url should be allowed to access local file://
+  // resources.
+  bool can_load_local_resources = false;
+
+  // Opaque history state (received by FrameHostMsg_UpdateState).
+  PageState page_state;
+
+  // For browser-initiated navigations, this is the unique id of the
+  // NavigationEntry being navigated to. (For renderer-initiated navigations it
+  // is 0.) If the load succeeds, then this nav_entry_id will be reflected in
+  // the resulting FrameHostMsg_DidCommitProvisionalLoad_Params.
+  int32 nav_entry_id = 0;
+
+  // If this is a history navigation, this contains a map of frame unique names
+  // to |is_about_blank| for immediate children of the frame being navigated for
+  // which there are history items.  The renderer process only needs to check
+  // with the browser process for newly created subframes that have these unique
+  // names (and only when not staying on about:blank).
+  // TODO(creis): Expand this to a data structure including corresponding
+  // same-process PageStates for the whole subtree in https://crbug.com/639842.
+  map<string, bool> subframe_unique_names;
+
+  // For browser-initiated navigations, this is true if this is a new entry
+  // being navigated to. This is false otherwise. TODO(avi): Remove this when
+  // the pending entry situation is made sane and the browser keeps them around
+  // long enough to match them via nav_entry_id, above.
+  bool intended_as_new_entry = false;
+
+  // For history navigations, this is the offset in the history list of the
+  // pending load. For non-history navigations, this will be ignored.
+  int32 pending_history_list_offset = -1;
+
+  // Where its current page contents reside in session history and the total
+  // size of the session history list.
+  int32 current_history_list_offset = -1;
+  int32 current_history_list_length = 0;
+
+  // Indicates that the tab was previously discarded.
+  // wasDiscarded is exposed on Document after discard, see:
+  // https://github.com/WICG/web-lifecycle
+  bool was_discarded = false;
+
+  // Indicates whether the navigation is to a view-source:// scheme or not.
+  // It is a separate boolean as the view-source scheme is stripped from the
+  // URL before it is sent to the renderer process and the RenderFrame needs
+  // to be put in special view source mode.
+  bool is_view_source = false;
+
+  // Whether session history should be cleared. In that case, the RenderView
+  // needs to notify the browser that the clearing was successful when the
+  // navigation commits.
+  bool should_clear_history_list = false;
+
+  // Timing of navigation events.
+  NavigationTiming navigation_timing;
+
+  // The AppCache host id to be used to identify this navigation.
+  mojo_base.mojom.UnguessableToken? appcache_host_id;
+
+  // Set to |kYes| if a navigation is following the rules of user activation
+  // propagation. This is different from |has_user_gesture|
+  // (in CommonNavigationParams) as the activation may have happened before
+  // the navigation was triggered, for example.
+  // In other words, the distinction isn't regarding user activation and user
+  // gesture but whether there was an activation prior to the navigation or to
+  // start it. `was_activated` will answer the former question while
+  // `user_gesture` will answer the latter.
+  WasActivatedOption was_activated = kUnknown;
+
+  // A token that should be passed to the browser process in
+  // DidCommitProvisionalLoadParams.
+  // TODO(clamy): Remove this once NavigationClient has shipped and
+  // same-document browser-initiated navigations are properly handled as well.
+  mojo_base.mojom.UnguessableToken navigation_token;
+
+  // Prefetched signed exchanges. Used when SignedExchangeSubresourcePrefetch
+  // feature is enabled.
+  array<PrefetchedSignedExchangeInfo> prefetched_signed_exchanges;
+
+  // The real content of the data: URL. Only used in Android WebView for
+  // implementing LoadDataWithBaseUrl API method to circumvent the restriction
+  // on the GURL max length in the IPC layer. Short data: URLs can still be
+  // passed in the |CommonNavigationParams::url| field.
+  [EnableIf=is_android]
+  string data_url_as_string;
+
+  // Whether this navigation was browser initiated.
+  bool is_browser_initiated = false;
+};
diff --git a/content/common/navigation_params.typemap b/content/common/navigation_params.typemap
index a394fbd..c3ab177 100644
--- a/content/common/navigation_params.typemap
+++ b/content/common/navigation_params.typemap
@@ -5,6 +5,8 @@
 mojom = "//content/common/navigation_params.mojom"
 public_headers = [
   "//content/common/navigation_params.h",
+  "//content/common/prefetched_signed_exchange_info.h",
+  "//content/public/common/page_state.h",
   "//content/public/common/navigation_policy.h",
   "//third_party/blink/public/platform/web_mixed_content_context_type.h",
   "//ui/base/page_transition_types.h",
@@ -20,6 +22,8 @@
   "content.mojom.InitiatorCSPInfo=::content::InitiatorCSPInfo",
   "content.mojom.MixedContentContextType=::blink::WebMixedContentContextType",
   "content.mojom.NavigationDownloadPolicy=::content::NavigationDownloadPolicy",
+  "content.mojom.PageState=::content::PageState",
   "content.mojom.PageTransition=::ui::PageTransition",
+  "content.mojom.PrefetchedSignedExchangeInfo=::content::PrefetchedSignedExchangeInfo",
   "content.mojom.SourceLocation=::content::SourceLocation",
 ]
diff --git a/content/common/typemaps.gni b/content/common/typemaps.gni
index 920be07..e01e065 100644
--- a/content/common/typemaps.gni
+++ b/content/common/typemaps.gni
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 typemaps = [
-  "//content/common/frame.typemap",
   "//content/common/frame_messages.typemap",
   "//content/common/input/synchronous_compositor.typemap",
   "//content/common/native_types.typemap",
diff --git a/content/public/browser/navigation_controller.cc b/content/public/browser/navigation_controller.cc
index 7b11ca8f..e152cc82 100644
--- a/content/public/browser/navigation_controller.cc
+++ b/content/public/browser/navigation_controller.cc
@@ -7,7 +7,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "build/build_config.h"
 #include "content/public/browser/render_frame_host.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 
 namespace content {
 
@@ -26,7 +26,7 @@
       started_from_context_menu(false),
       navigation_ui_data(nullptr),
       from_download_cross_origin_redirect(false),
-      was_activated(WasActivatedOption::kUnknown),
+      was_activated(mojom::WasActivatedOption::kUnknown),
       reload_type(ReloadType::NONE) {}
 
 NavigationController::LoadURLParams::~LoadURLParams() {
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h
index 254b4a1..a3048715 100644
--- a/content/public/browser/navigation_controller.h
+++ b/content/public/browser/navigation_controller.h
@@ -24,6 +24,7 @@
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/common/referrer.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "ui/base/page_transition_types.h"
@@ -38,7 +39,6 @@
 
 namespace content {
 
-enum class WasActivatedOption;
 class BrowserContext;
 class NavigationEntry;
 class WebContents;
@@ -223,7 +223,7 @@
 
     // Set to |kYes| if the navigation should propagate user activation. This
     // is used by embedders where the activation has occurred outside the page.
-    WasActivatedOption was_activated;
+    mojom::WasActivatedOption was_activated;
 
     // If this navigation was initiated from a link that specified the
     // hrefTranslate attribute, this contains the attribute's value (a BCP47
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index d3492e0c..62bea64 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -209,7 +209,6 @@
     "use_zoom_for_dsf_policy.cc",
     "use_zoom_for_dsf_policy.h",
     "user_agent.h",
-    "was_activated_option.h",
     "web_preferences.cc",
     "web_preferences.h",
     "webplugininfo.cc",
@@ -366,6 +365,7 @@
     "resource_load_info.mojom",
     "resource_usage_reporter.mojom",
     "transferrable_url_loader.mojom",
+    "was_activated_option.mojom",
     "webplugininfo.mojom",
     "window_container_type.mojom",
   ]
diff --git a/content/public/common/was_activated_option.h b/content/public/common/was_activated_option.mojom
similarity index 67%
rename from content/public/common/was_activated_option.h
rename to content/public/common/was_activated_option.mojom
index 23b37bf..16b10bf 100644
--- a/content/public/common/was_activated_option.h
+++ b/content/public/common/was_activated_option.mojom
@@ -2,14 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
-#define CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
-
-namespace content {
+module content.mojom;
 
 // Whether the navigation should propagate user activation. This can be
 // specified by embedders in NavigationController::LoadURLParams.
-enum class WasActivatedOption {
+enum WasActivatedOption {
   // The content layer should make a decision about whether to propagate user
   // activation.
   kUnknown,
@@ -19,9 +16,4 @@
 
   // The navigation should not propagate user activation.
   kNo,
-  kMaxValue = kNo,
 };
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index f2ad5fd..e3c556b 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -6,7 +6,6 @@
 
 #include "media/base/renderer_factory.h"
 #include "third_party/blink/public/platform/web_audio_device.h"
-#include "third_party/blink/public/platform/web_media_stream_center.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/web_speech_synthesizer.h"
 #include "third_party/blink/public/web/modules/mediastream/web_media_stream_renderer_factory.h"
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index e0a1895..fe24460 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -137,7 +137,6 @@
 #endif
 
 #if defined(USE_AURA)
-#include "content/browser/renderer_host/delegated_frame_host.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
 #include "ui/aura/test/window_event_dispatcher_test_api.h"
@@ -3093,78 +3092,6 @@
   return raw_mock;
 }
 
-namespace {
-
-// This class interacts with the internals of the DelegatedFrameHost without
-// exposing them in the header.
-class EvictionStateWaiter : public DelegatedFrameHost::Observer {
- public:
-  EvictionStateWaiter(DelegatedFrameHost* delegated_frame_host)
-      : delegated_frame_host_(delegated_frame_host) {
-    delegated_frame_host_->AddObserverForTesting(this);
-  }
-
-  ~EvictionStateWaiter() override {
-    delegated_frame_host_->RemoveObserverForTesting(this);
-  }
-
-  void WaitForEvictionState(DelegatedFrameHost::FrameEvictionState state) {
-    if (delegated_frame_host_->frame_eviction_state() == state)
-      return;
-
-    waited_eviction_state_ = state;
-    base::RunLoop run_loop;
-    quit_closure_ = run_loop.QuitClosure();
-    run_loop.Run();
-  }
-
-  // DelegatedFrameHost::Observer:
-  void OnFrameEvictionStateChanged(
-      DelegatedFrameHost::FrameEvictionState new_state) override {
-    if (!quit_closure_.is_null() && (new_state == waited_eviction_state_))
-      std::move(quit_closure_).Run();
-  }
-
- private:
-  DelegatedFrameHost* delegated_frame_host_;
-  DelegatedFrameHost::FrameEvictionState waited_eviction_state_;
-  base::OnceClosure quit_closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(EvictionStateWaiter);
-};
-
-}  // namespace
-
-void VerifyStaleContentOnFrameEviction(
-    RenderWidgetHostView* render_widget_host_view) {
-  auto* render_widget_host_view_aura =
-      static_cast<RenderWidgetHostViewAura*>(render_widget_host_view);
-  DelegatedFrameHost* delegated_frame_host =
-      render_widget_host_view_aura->GetDelegatedFrameHost();
-
-  // Initially there should be no stale content set.
-  EXPECT_FALSE(
-      delegated_frame_host->stale_content_layer()->has_external_content());
-  EXPECT_EQ(delegated_frame_host->frame_eviction_state(),
-            DelegatedFrameHost::FrameEvictionState::kNotStarted);
-
-  // Hide the view and evict the frame, and expect that stale content will be
-  // set.
-  EvictionStateWaiter waiter{delegated_frame_host};
-  render_widget_host_view_aura->WasOccluded();
-  static_cast<viz::FrameEvictorClient*>(delegated_frame_host)
-      ->EvictDelegatedFrame();
-  EXPECT_EQ(delegated_frame_host->frame_eviction_state(),
-            DelegatedFrameHost::FrameEvictionState::kPendingEvictionRequests);
-  // Wait until the stale frame content is copied and set onto the layer, i.e.
-  // the eviction state changes from kPendingEvictionRequests back to
-  // kNotStarted.
-  waiter.WaitForEvictionState(
-      DelegatedFrameHost::FrameEvictionState::kNotStarted);
-  EXPECT_TRUE(
-      delegated_frame_host->stale_content_layer()->has_external_content());
-}
-
 #endif  // defined(USE_AURA)
 
 ContextMenuFilter::ContextMenuFilter()
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index eb64149..82a0d6a 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -1590,12 +1590,6 @@
   // Waits until the mock receives a consumed GestureScrollUpdate.
   virtual void WaitForConsumedScroll() = 0;
 };
-
-// Tests that a |render_widget_host_view| stores a stale content when its frame
-// gets evicted. |render_widget_host_view| has to be a RenderWidgetHostViewAura.
-void VerifyStaleContentOnFrameEviction(
-    RenderWidgetHostView* render_widget_host_view);
-
 #endif  // defined(USE_AURA)
 
 // This class filters for FrameHostMsg_ContextMenu messages coming in
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 7c3f1623..b2b8182 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -664,7 +664,7 @@
   TestRenderFrame* frame =
       static_cast<TestRenderFrame*>(impl->GetMainRenderFrame());
   FrameLoadWaiter waiter(frame);
-  frame->Navigate(std::move(common_params), CommitNavigationParams());
+  frame->Navigate(std::move(common_params), CreateCommitNavigationParams());
   waiter.Wait();
   view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
       blink::WebWidget::LifecycleUpdateReason::kTest);
@@ -807,17 +807,17 @@
       false /* started_from_context_menu */, false /* has_user_gesture */,
       InitiatorCSPInfo(), std::vector<int>(), std::string(),
       false /* is_history_navigation_in_new_child_frame */, base::TimeTicks());
-  CommitNavigationParams commit_params;
-  commit_params.page_state = state;
-  commit_params.nav_entry_id = pending_offset + 1;
-  commit_params.pending_history_list_offset = pending_offset;
-  commit_params.current_history_list_offset = impl->history_list_offset_;
-  commit_params.current_history_list_length = history_list_length;
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->page_state = state;
+  commit_params->nav_entry_id = pending_offset + 1;
+  commit_params->pending_history_list_offset = pending_offset;
+  commit_params->current_history_list_offset = impl->history_list_offset_;
+  commit_params->current_history_list_length = history_list_length;
 
   TestRenderFrame* frame =
       static_cast<TestRenderFrame*>(impl->GetMainRenderFrame());
   FrameLoadWaiter waiter(frame);
-  frame->Navigate(std::move(common_params), commit_params);
+  frame->Navigate(std::move(common_params), std::move(commit_params));
   // The load may actually happen asynchronously, so we pump messages to process
   // the pending continuation.
   waiter.Wait();
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 6da3ab0..9157c57 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -198,8 +198,6 @@
     "media/renderer_webmediaplayer_delegate.h",
     "media/stream/apply_constraints_processor.cc",
     "media/stream/apply_constraints_processor.h",
-    "media/stream/media_stream_center.cc",
-    "media/stream/media_stream_center.h",
     "media/stream/user_media_client_impl.cc",
     "media/stream/user_media_client_impl.h",
     "media/stream/user_media_processor.cc",
diff --git a/content/renderer/loader/navigation_body_loader.cc b/content/renderer/loader/navigation_body_loader.cc
index 95e15eb..50fc776 100644
--- a/content/renderer/loader/navigation_body_loader.cc
+++ b/content/renderer/loader/navigation_body_loader.cc
@@ -21,7 +21,7 @@
 // static
 void NavigationBodyLoader::FillNavigationParamsResponseAndBodyLoader(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     int request_id,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
diff --git a/content/renderer/loader/navigation_body_loader.h b/content/renderer/loader/navigation_body_loader.h
index 889f0b2..90844dd8 100644
--- a/content/renderer/loader/navigation_body_loader.h
+++ b/content/renderer/loader/navigation_body_loader.h
@@ -50,7 +50,7 @@
   // redirects and response, and also creates a body loader if needed.
   static void FillNavigationParamsResponseAndBodyLoader(
       const mojom::CommonNavigationParams& common_params,
-      const CommitNavigationParams& commit_params,
+      const mojom::CommitNavigationParams& commit_params,
       int request_id,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
diff --git a/content/renderer/loader/navigation_body_loader_unittest.cc b/content/renderer/loader/navigation_body_loader_unittest.cc
index 6f364a33..3dd7878 100644
--- a/content/renderer/loader/navigation_body_loader_unittest.cc
+++ b/content/renderer/loader/navigation_body_loader_unittest.cc
@@ -48,8 +48,9 @@
     auto common_params = mojom::CommonNavigationParams::New();
     common_params->referrer = blink::mojom::Referrer::New();
     common_params->navigation_start = base::TimeTicks::Now();
+    auto commit_params = CreateCommitNavigationParams();
     NavigationBodyLoader::FillNavigationParamsResponseAndBodyLoader(
-        *common_params, CommitNavigationParams(), 1 /* request_id */,
+        *common_params, *commit_params, 1 /* request_id */,
         network::ResourceResponseHead(),
         mojo::ScopedDataPipeConsumerHandle() /* response_body */,
         std::move(endpoints),
@@ -316,11 +317,12 @@
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
   common_params->url = GURL("https://example.test");
+  auto commit_params = CreateCommitNavigationParams();
 
   blink::WebNavigationParams navigation_params;
   auto endpoints = network::mojom::URLLoaderClientEndpoints::New();
   NavigationBodyLoader::FillNavigationParamsResponseAndBodyLoader(
-      *common_params, CommitNavigationParams(), 1 /* request_id */, response,
+      *common_params, *commit_params, 1 /* request_id */, response,
       mojo::ScopedDataPipeConsumerHandle() /* response_body */,
       std::move(endpoints),
       blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
diff --git a/content/renderer/media/stream/media_stream_center.cc b/content/renderer/media/stream/media_stream_center.cc
deleted file mode 100644
index 6d17470..0000000
--- a/content/renderer/media/stream/media_stream_center.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/stream/media_stream_center.h"
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "media/base/sample_format.h"
-#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
-#include "third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
-#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
-#include "third_party/blink/public/web/modules/mediastream/processed_local_audio_source.h"
-#include "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h"
-
-namespace content {
-
-namespace {
-
-void CreateNativeAudioMediaStreamTrack(
-    const blink::WebMediaStreamTrack& track,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  blink::WebMediaStreamSource source = track.Source();
-  blink::MediaStreamAudioSource* media_stream_source =
-      blink::MediaStreamAudioSource::From(source);
-
-  // At this point, a MediaStreamAudioSource instance must exist. The one
-  // exception is when a WebAudio destination node is acting as a source of
-  // audio.
-  //
-  // TODO(miu): This needs to be moved to an appropriate location. A WebAudio
-  // source should have been created before this method was called so that this
-  // special case code isn't needed here.
-  if (!media_stream_source && source.RequiresAudioConsumer()) {
-    DVLOG(1) << "Creating WebAudio media stream source.";
-    media_stream_source =
-        new blink::WebAudioMediaStreamSource(&source, task_runner);
-    source.SetPlatformSource(
-        base::WrapUnique(media_stream_source));  // Takes ownership.
-
-    blink::WebMediaStreamSource::Capabilities capabilities;
-    capabilities.device_id = source.Id();
-    capabilities.echo_cancellation = std::vector<bool>({false});
-    capabilities.auto_gain_control = std::vector<bool>({false});
-    capabilities.noise_suppression = std::vector<bool>({false});
-    capabilities.sample_size = {
-        media::SampleFormatToBitsPerChannel(media::kSampleFormatS16),  // min
-        media::SampleFormatToBitsPerChannel(media::kSampleFormatS16)   // max
-    };
-    auto parameters = media_stream_source->GetAudioParameters();
-    if (parameters.IsValid()) {
-      capabilities.channel_count = {1, parameters.channels()};
-      capabilities.sample_rate = {parameters.sample_rate(),
-                                  parameters.sample_rate()};
-      capabilities.latency = {parameters.GetBufferDuration().InSecondsF(),
-                              parameters.GetBufferDuration().InSecondsF()};
-    }
-    source.SetCapabilities(capabilities);
-  }
-
-  if (media_stream_source)
-    media_stream_source->ConnectToTrack(track);
-  else
-    LOG(DFATAL) << "WebMediaStreamSource missing its MediaStreamAudioSource.";
-}
-
-void CreateNativeVideoMediaStreamTrack(blink::WebMediaStreamTrack track) {
-  DCHECK(track.GetPlatformTrack() == nullptr);
-  blink::WebMediaStreamSource source = track.Source();
-  DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
-  blink::MediaStreamVideoSource* native_source =
-      blink::MediaStreamVideoSource::GetVideoSource(source);
-  DCHECK(native_source);
-  track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
-      native_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
-      track.IsEnabled()));
-}
-
-void CloneNativeVideoMediaStreamTrack(
-    const blink::WebMediaStreamTrack& original,
-    blink::WebMediaStreamTrack clone) {
-  DCHECK(!clone.GetPlatformTrack());
-  blink::WebMediaStreamSource source = clone.Source();
-  DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
-  blink::MediaStreamVideoSource* native_source =
-      blink::MediaStreamVideoSource::GetVideoSource(source);
-  DCHECK(native_source);
-  blink::MediaStreamVideoTrack* original_track =
-      blink::MediaStreamVideoTrack::GetVideoTrack(original);
-  DCHECK(original_track);
-  clone.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
-      native_source, original_track->adapter_settings(),
-      original_track->noise_reduction(), original_track->is_screencast(),
-      original_track->min_frame_rate(),
-      blink::MediaStreamVideoSource::ConstraintsCallback(), clone.IsEnabled()));
-}
-
-}  // namespace
-
-MediaStreamCenter::MediaStreamCenter(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : task_runner_(task_runner) {}
-
-MediaStreamCenter::~MediaStreamCenter() = default;
-
-void MediaStreamCenter::DidCreateMediaStreamTrack(
-    const blink::WebMediaStreamTrack& track) {
-  DVLOG(1) << "MediaStreamCenter::didCreateMediaStreamTrack";
-  DCHECK(!track.IsNull() && !track.GetPlatformTrack());
-  DCHECK(!track.Source().IsNull());
-
-  switch (track.Source().GetType()) {
-    case blink::WebMediaStreamSource::kTypeAudio:
-      CreateNativeAudioMediaStreamTrack(track, task_runner_);
-      break;
-    case blink::WebMediaStreamSource::kTypeVideo:
-      CreateNativeVideoMediaStreamTrack(track);
-      break;
-  }
-}
-
-void MediaStreamCenter::DidCloneMediaStreamTrack(
-    const blink::WebMediaStreamTrack& original,
-    const blink::WebMediaStreamTrack& clone) {
-  DCHECK(!clone.IsNull());
-  DCHECK(!clone.GetPlatformTrack());
-  DCHECK(!clone.Source().IsNull());
-
-  switch (clone.Source().GetType()) {
-    case blink::WebMediaStreamSource::kTypeAudio:
-      CreateNativeAudioMediaStreamTrack(clone, task_runner_);
-      break;
-    case blink::WebMediaStreamSource::kTypeVideo:
-      CloneNativeVideoMediaStreamTrack(original, clone);
-      break;
-  }
-}
-
-void MediaStreamCenter::DidEnableMediaStreamTrack(
-    const blink::WebMediaStreamTrack& track) {
-  blink::WebPlatformMediaStreamTrack* native_track =
-      blink::WebPlatformMediaStreamTrack::GetTrack(track);
-  if (native_track)
-    native_track->SetEnabled(true);
-}
-
-void MediaStreamCenter::DidDisableMediaStreamTrack(
-    const blink::WebMediaStreamTrack& track) {
-  blink::WebPlatformMediaStreamTrack* native_track =
-      blink::WebPlatformMediaStreamTrack::GetTrack(track);
-  if (native_track)
-    native_track->SetEnabled(false);
-}
-
-blink::WebAudioSourceProvider*
-MediaStreamCenter::CreateWebAudioSourceFromMediaStreamTrack(
-    const blink::WebMediaStreamTrack& track,
-    int context_sample_rate) {
-  DVLOG(1) << "MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack";
-  blink::WebPlatformMediaStreamTrack* media_stream_track =
-      track.GetPlatformTrack();
-  if (!media_stream_track) {
-    DLOG(ERROR) << "Native track missing for webaudio source.";
-    return nullptr;
-  }
-
-  blink::WebMediaStreamSource source = track.Source();
-  DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeAudio);
-
-  return new blink::WebAudioMediaStreamAudioSink(track, context_sample_rate);
-}
-
-void MediaStreamCenter::DidStopMediaStreamSource(
-    const blink::WebMediaStreamSource& web_source) {
-  if (web_source.IsNull())
-    return;
-  blink::WebPlatformMediaStreamSource* const source =
-      web_source.GetPlatformSource();
-  DCHECK(source);
-  source->StopSource();
-}
-
-}  // namespace content
diff --git a/content/renderer/media/stream/media_stream_center.h b/content/renderer/media/stream/media_stream_center.h
deleted file mode 100644
index 535bbb3..0000000
--- a/content/renderer/media/stream/media_stream_center.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CENTER_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CENTER_H_
-
-#include "third_party/blink/public/platform/web_media_stream_center.h"
-
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "content/common/content_export.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace blink {
-class WebAudioSourceProvider;
-}
-
-namespace content {
-
-class CONTENT_EXPORT MediaStreamCenter : public blink::WebMediaStreamCenter {
- public:
-  MediaStreamCenter(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-  ~MediaStreamCenter() override;
-
- private:
-  void DidCreateMediaStreamTrack(
-      const blink::WebMediaStreamTrack& track) override;
-
-  void DidCloneMediaStreamTrack(
-      const blink::WebMediaStreamTrack& original,
-      const blink::WebMediaStreamTrack& clone) override;
-
-  void DidEnableMediaStreamTrack(
-      const blink::WebMediaStreamTrack& track) override;
-
-  void DidDisableMediaStreamTrack(
-      const blink::WebMediaStreamTrack& track) override;
-
-  blink::WebAudioSourceProvider* CreateWebAudioSourceFromMediaStreamTrack(
-      const blink::WebMediaStreamTrack& track,
-      int context_sample_rate) override;
-
-  void DidStopMediaStreamSource(
-      const blink::WebMediaStreamSource& web_source) override;
-
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStreamCenter);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CENTER_H_
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index 1765789..0bb8c7f2 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -17,7 +17,7 @@
 
 void NavigationClient::CommitNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -36,7 +36,7 @@
   // unexpectedly abort the ongoing navigation. Remove when the races are fixed.
   ResetDisconnectionHandler();
   render_frame_->CommitPerNavigationMojoInterfaceNavigation(
-      std::move(common_params), commit_params, response_head,
+      std::move(common_params), std::move(commit_params), response_head,
       std::move(response_body), std::move(url_loader_client_endpoints),
       std::move(subresource_loaders), std::move(subresource_overrides),
       std::move(controller_service_worker_info), std::move(provider_info),
@@ -46,7 +46,7 @@
 
 void NavigationClient::CommitFailedNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content,
@@ -54,9 +54,9 @@
     CommitFailedNavigationCallback callback) {
   ResetDisconnectionHandler();
   render_frame_->CommitFailedPerNavigationMojoInterfaceNavigation(
-      std::move(common_params), commit_params, has_stale_copy_in_cache,
-      error_code, error_page_content, std::move(subresource_loaders),
-      std::move(callback));
+      std::move(common_params), std::move(commit_params),
+      has_stale_copy_in_cache, error_code, error_page_content,
+      std::move(subresource_loaders), std::move(callback));
 }
 
 void NavigationClient::Bind(mojom::NavigationClientAssociatedRequest request) {
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h
index 36f07828..56199316 100644
--- a/content/renderer/navigation_client.h
+++ b/content/renderer/navigation_client.h
@@ -20,7 +20,7 @@
   // mojom::NavigationClient implementation:
   void CommitNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -36,7 +36,7 @@
       CommitNavigationCallback callback) override;
   void CommitFailedNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
diff --git a/content/renderer/navigation_state.cc b/content/renderer/navigation_state.cc
index 2239f05..66413a2 100644
--- a/content/renderer/navigation_state.cc
+++ b/content/renderer/navigation_state.cc
@@ -22,7 +22,7 @@
 // static
 std::unique_ptr<NavigationState> NavigationState::CreateBrowserInitiated(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     base::TimeTicks time_commit_requested,
     mojom::FrameNavigationControl::CommitNavigationCallback callback,
     mojom::NavigationClient::CommitNavigationCallback
@@ -30,8 +30,9 @@
     std::unique_ptr<NavigationClient> navigation_client,
     bool was_initiated_in_this_frame) {
   return base::WrapUnique(new NavigationState(
-      std::move(common_params), commit_params, time_commit_requested, false,
-      std::move(callback), std::move(per_navigation_mojo_interface_callback),
+      std::move(common_params), std::move(commit_params), time_commit_requested,
+      false, std::move(callback),
+      std::move(per_navigation_mojo_interface_callback),
       std::move(navigation_client), was_initiated_in_this_frame));
 }
 
@@ -41,8 +42,9 @@
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
   return base::WrapUnique(new NavigationState(
-      std::move(common_params), CommitNavigationParams(), base::TimeTicks(),
-      true, content::mojom::FrameNavigationControl::CommitNavigationCallback(),
+      std::move(common_params), CreateCommitNavigationParams(),
+      base::TimeTicks(), true,
+      content::mojom::FrameNavigationControl::CommitNavigationCallback(),
       content::mojom::NavigationClient::CommitNavigationCallback(), nullptr,
       true));
 }
@@ -80,7 +82,7 @@
 
 NavigationState::NavigationState(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     base::TimeTicks time_commit_requested,
     bool is_content_initiated,
     mojom::FrameNavigationControl::CommitNavigationCallback callback,
@@ -93,7 +95,7 @@
       was_initiated_in_this_frame_(was_initiated_in_this_frame),
       is_content_initiated_(is_content_initiated),
       common_params_(std::move(common_params)),
-      commit_params_(commit_params),
+      commit_params_(std::move(commit_params)),
       time_commit_requested_(time_commit_requested),
       navigation_client_(std::move(navigation_client)),
       commit_callback_(std::move(callback)),
diff --git a/content/renderer/navigation_state.h b/content/renderer/navigation_state.h
index 7938258..5d3b40d 100644
--- a/content/renderer/navigation_state.h
+++ b/content/renderer/navigation_state.h
@@ -32,7 +32,7 @@
 
   static std::unique_ptr<NavigationState> CreateBrowserInitiated(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       base::TimeTicks time_commit_requested,
       mojom::FrameNavigationControl::CommitNavigationCallback callback,
       mojom::NavigationClient::CommitNavigationCallback
@@ -54,7 +54,9 @@
   const mojom::CommonNavigationParams& common_params() const {
     return *common_params_;
   }
-  const CommitNavigationParams& commit_params() const { return commit_params_; }
+  const mojom::CommitNavigationParams& commit_params() const {
+    return *commit_params_;
+  }
   bool request_committed() const { return request_committed_; }
   bool uses_per_navigation_mojo_interface() const {
     return navigation_client_.get();
@@ -95,7 +97,7 @@
  private:
   NavigationState(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       base::TimeTicks time_commit_requested,
       bool is_content_initiated,
       content::mojom::FrameNavigationControl::CommitNavigationCallback callback,
@@ -131,7 +133,7 @@
   // swaps because FrameLoader::loadWithNavigationAction treats loads before a
   // FrameLoader has committedFirstRealDocumentLoad as a replacement. (Added for
   // http://crbug.com/178380).
-  const CommitNavigationParams commit_params_;
+  mojom::CommitNavigationParamsPtr commit_params_;
 
   // Time when RenderFrameImpl::CommitNavigation() is called.
   base::TimeTicks time_commit_requested_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index acebcca..4c3e0dea 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -440,7 +440,7 @@
 
 void FillNavigationParamsRequest(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     blink::WebNavigationParams* navigation_params) {
   // Use the original navigation url to start with. We'll replay the redirects
   // afterwards and will eventually arrive to the final url.
@@ -887,7 +887,7 @@
 // navigation parameters available in the RenderFrameImpl.
 std::unique_ptr<DocumentState> BuildDocumentStateFromParams(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     base::TimeTicks time_commit_requested,
     mojom::FrameNavigationControl::CommitNavigationCallback commit_callback,
     mojom::NavigationClient::CommitNavigationCallback
@@ -953,7 +953,7 @@
 
   InternalDocumentStateData::FromDocumentState(document_state.get())
       ->set_navigation_state(NavigationState::CreateBrowserInitiated(
-          common_params.Clone(), commit_params, time_commit_requested,
+          common_params.Clone(), commit_params.Clone(), time_commit_requested,
           std::move(commit_callback),
           std::move(per_navigation_mojo_interface_commit_callback),
           std::move(navigation_client), was_initiated_in_this_frame));
@@ -999,7 +999,7 @@
 // format, blink::WebNavigationTimings.
 blink::WebNavigationTimings BuildNavigationTimings(
     base::TimeTicks navigation_start,
-    const NavigationTiming& browser_navigation_timings,
+    const mojom::NavigationTiming& browser_navigation_timings,
     base::TimeTicks input_start) {
   blink::WebNavigationTimings renderer_navigation_timings;
 
@@ -1031,14 +1031,14 @@
 // format, blink::WebNavigationParams.
 void FillMiscNavigationParams(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     blink::WebNavigationParams* navigation_params) {
   navigation_params->navigation_timings = BuildNavigationTimings(
-      common_params.navigation_start, commit_params.navigation_timing,
+      common_params.navigation_start, *commit_params.navigation_timing,
       common_params.input_start);
 
   navigation_params->is_user_activated =
-      commit_params.was_activated == WasActivatedOption::kYes;
+      commit_params.was_activated == mojom::WasActivatedOption::kYes;
 
   navigation_params->is_browser_initiated = commit_params.is_browser_initiated;
 
@@ -3381,7 +3381,7 @@
 
 void RenderFrameImpl::CommitNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -3400,7 +3400,7 @@
   // IsPerNavigationMojoInterfaceEnabled() == true, for non-committed
   // interstitials where no NavigationRequest was created. Therefore, no DCHECK.
   CommitNavigationInternal(
-      std::move(common_params), commit_params, response_head,
+      std::move(common_params), std::move(commit_params), response_head,
       std::move(response_body), std::move(url_loader_client_endpoints),
       std::move(subresource_loader_factories), std::move(subresource_overrides),
       std::move(controller_service_worker_info), std::move(provider_info),
@@ -3411,7 +3411,7 @@
 
 void RenderFrameImpl::CommitPerNavigationMojoInterfaceNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -3429,7 +3429,7 @@
   DCHECK(navigation_client_impl_);
   DCHECK(IsPerNavigationMojoInterfaceEnabled());
   CommitNavigationInternal(
-      std::move(common_params), commit_params, response_head,
+      std::move(common_params), std::move(commit_params), response_head,
       std::move(response_body), std::move(url_loader_client_endpoints),
       std::move(subresource_loader_factories), std::move(subresource_overrides),
       std::move(controller_service_worker_info), std::move(provider_info),
@@ -3440,7 +3440,7 @@
 
 void RenderFrameImpl::CommitNavigationInternal(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -3458,7 +3458,7 @@
         per_navigation_mojo_interface_callback) {
   DCHECK(!IsRendererDebugURL(common_params->url));
   DCHECK(!NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
-  if (ShouldIgnoreCommitNavigation(commit_params)) {
+  if (ShouldIgnoreCommitNavigation(*commit_params)) {
     browser_side_navigation_pending_url_ = GURL();
     AbortCommitNavigation(std::move(callback),
                           blink::mojom::CommitResult::Aborted);
@@ -3473,8 +3473,8 @@
   } else {
     was_initiated_in_this_frame =
         browser_side_navigation_pending_ &&
-        browser_side_navigation_pending_url_ == commit_params.original_url &&
-        commit_params.nav_entry_id == 0;
+        browser_side_navigation_pending_url_ == commit_params->original_url &&
+        commit_params->nav_entry_id == 0;
   }
 
   // Sanity check that the browser always sends us new loader factories on
@@ -3492,7 +3492,7 @@
                                                                 : nullptr;
   int request_id = ResourceDispatcher::MakeRequestID();
   std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
-      *common_params, commit_params, base::TimeTicks::Now(),
+      *common_params, *commit_params, base::TimeTicks::Now(),
       std::move(callback), std::move(per_navigation_mojo_interface_callback),
       document_state_response_head, std::move(navigation_client_impl_),
       request_id, was_initiated_in_this_frame);
@@ -3503,12 +3503,12 @@
   auto navigation_params =
       std::make_unique<WebNavigationParams>(devtools_navigation_token);
   navigation_params->is_client_redirect = is_client_redirect;
-  FillMiscNavigationParams(*common_params, commit_params,
+  FillMiscNavigationParams(*common_params, *commit_params,
                            navigation_params.get());
 
   auto commit_with_params = base::BindOnce(
       &RenderFrameImpl::CommitNavigationWithParams, weak_factory_.GetWeakPtr(),
-      common_params.Clone(), commit_params,
+      common_params.Clone(), commit_params.Clone(),
       std::move(subresource_loader_factories), std::move(subresource_overrides),
       std::move(controller_service_worker_info), std::move(provider_info),
       std::move(prefetch_loader_factory), std::move(document_state));
@@ -3517,12 +3517,12 @@
   // Note: the base URL might be invalid, so also check the data URL string.
   bool should_load_data_url = !common_params->base_url_for_data_url.is_empty();
 #if defined(OS_ANDROID)
-  should_load_data_url |= !commit_params.data_url_as_string.empty();
+  should_load_data_url |= !commit_params->data_url_as_string.empty();
 #endif
   if (is_main_frame_ && should_load_data_url) {
     std::string mime_type, charset, data;
     GURL base_url;
-    DecodeDataURL(*common_params, commit_params, &mime_type, &charset, &data,
+    DecodeDataURL(*common_params, *commit_params, &mime_type, &charset, &data,
                   &base_url);
     navigation_params->url = base_url;
     WebNavigationParams::FillStaticResponse(navigation_params.get(),
@@ -3535,7 +3535,7 @@
     return;
   }
 
-  FillNavigationParamsRequest(*common_params, commit_params,
+  FillNavigationParamsRequest(*common_params, *commit_params,
                               navigation_params.get());
   if (!url_loader_client_endpoints &&
       common_params->url.SchemeIs(url::kDataScheme)) {
@@ -3553,7 +3553,7 @@
                                             WebString::FromUTF8(charset), data);
   } else {
     NavigationBodyLoader::FillNavigationParamsResponseAndBodyLoader(
-        *common_params, commit_params, request_id, response_head,
+        *common_params, *commit_params, request_id, response_head,
         std::move(response_body), std::move(url_loader_client_endpoints),
         GetTaskRunner(blink::TaskType::kInternalLoading), GetRoutingID(),
         !frame_->Parent(), navigation_params.get());
@@ -3581,7 +3581,7 @@
 }
 
 bool RenderFrameImpl::ShouldIgnoreCommitNavigation(
-    const CommitNavigationParams& commit_params) {
+    const mojom::CommitNavigationParams& commit_params) {
   // We can ignore renderer-initiated navigations (nav_entry_id == 0) which
   // have been canceled in the renderer, but browser was not aware yet at the
   // moment of issuing a CommitNavigation call.
@@ -3596,7 +3596,7 @@
 
 void RenderFrameImpl::CommitNavigationWithParams(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
         subresource_loader_factories,
     base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
@@ -3607,7 +3607,7 @@
         prefetch_loader_factory,
     std::unique_ptr<DocumentState> document_state,
     std::unique_ptr<WebNavigationParams> navigation_params) {
-  if (ShouldIgnoreCommitNavigation(commit_params)) {
+  if (ShouldIgnoreCommitNavigation(*commit_params)) {
     browser_side_navigation_pending_url_ = GURL();
     return;
   }
@@ -3653,15 +3653,15 @@
 
   // If the navigation is for "view source", the WebLocalFrame needs to be put
   // in a special mode.
-  if (commit_params.is_view_source)
+  if (commit_params->is_view_source)
     frame_->EnableViewSourceMode(true);
 
-  PrepareFrameForCommit(common_params->url, commit_params);
+  PrepareFrameForCommit(common_params->url, *commit_params);
 
   blink::WebFrameLoadType load_type =
       NavigationTypeToLoadType(common_params->navigation_type,
                                common_params->should_replace_current_entry,
-                               commit_params.page_state.IsValid());
+                               commit_params->page_state.IsValid());
 
   WebHistoryItem item_for_history_navigation;
   blink::mojom::CommitResult commit_status = blink::mojom::CommitResult::Ok;
@@ -3670,11 +3670,11 @@
     // We must know the nav entry ID of the page we are navigating back to,
     // which should be the case because history navigations are routed via the
     // browser.
-    DCHECK_NE(0, commit_params.nav_entry_id);
+    DCHECK_NE(0, commit_params->nav_entry_id);
 
     // Check that the history navigation can commit.
     commit_status = PrepareForHistoryNavigationCommit(
-        *common_params, commit_params, &item_for_history_navigation,
+        *common_params, *commit_params, &item_for_history_navigation,
         &load_type);
   }
 
@@ -3700,7 +3700,7 @@
 
 void RenderFrameImpl::CommitFailedNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content,
@@ -3710,15 +3710,15 @@
   DCHECK(!navigation_client_impl_);
   DCHECK(!IsPerNavigationMojoInterfaceEnabled());
   CommitFailedNavigationInternal(
-      std::move(common_params), commit_params, has_stale_copy_in_cache,
-      error_code, error_page_content, std::move(subresource_loader_factories),
-      std::move(callback),
+      std::move(common_params), std::move(commit_params),
+      has_stale_copy_in_cache, error_code, error_page_content,
+      std::move(subresource_loader_factories), std::move(callback),
       mojom::NavigationClient::CommitFailedNavigationCallback());
 }
 
 void RenderFrameImpl::CommitFailedPerNavigationMojoInterfaceNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content,
@@ -3729,15 +3729,16 @@
   DCHECK(navigation_client_impl_);
   DCHECK(IsPerNavigationMojoInterfaceEnabled());
   CommitFailedNavigationInternal(
-      std::move(common_params), commit_params, has_stale_copy_in_cache,
-      error_code, error_page_content, std::move(subresource_loader_factories),
+      std::move(common_params), std::move(commit_params),
+      has_stale_copy_in_cache, error_code, error_page_content,
+      std::move(subresource_loader_factories),
       mojom::FrameNavigationControl::CommitFailedNavigationCallback(),
       std::move(per_navigation_mojo_interface_callback));
 }
 
 void RenderFrameImpl::CommitFailedNavigationInternal(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content,
@@ -3750,7 +3751,7 @@
                "RenderFrameImpl::CommitFailedNavigation", "id", routing_id_);
   DCHECK(!NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
   RenderFrameImpl::PrepareRenderViewForNavigation(common_params->url,
-                                                  commit_params);
+                                                  *commit_params);
   sync_navigation_callback_.Cancel();
   mhtml_body_loader_client_.reset();
 
@@ -3769,7 +3770,7 @@
       WebURLError::IsWebSecurityViolation::kFalse, common_params->url);
 
   auto navigation_params = std::make_unique<WebNavigationParams>();
-  FillNavigationParamsRequest(*common_params, commit_params,
+  FillNavigationParamsRequest(*common_params, *commit_params,
                               navigation_params.get());
   navigation_params->url = GURL(kUnreachableWebDataURL);
   navigation_params->error_code = error_code;
@@ -3798,7 +3799,7 @@
   if (!weak_this)
     return;
 
-  if (commit_params.nav_entry_id == 0) {
+  if (commit_params->nav_entry_id == 0) {
     // For renderer initiated navigations, we send out a
     // DidFailProvisionalLoad() notification.
     NotifyObserversOfFailedProvisionalLoad(error);
@@ -3846,8 +3847,8 @@
                  common_params->url == GetLoadingUrl() ||
                  common_params->should_replace_current_entry;
   std::unique_ptr<HistoryEntry> history_entry;
-  if (commit_params.page_state.IsValid())
-    history_entry = PageStateToHistoryEntry(commit_params.page_state);
+  if (commit_params->page_state.IsValid())
+    history_entry = PageStateToHistoryEntry(commit_params->page_state);
 
   std::string error_html;
   if (error_page_content.has_value()) {
@@ -3874,7 +3875,7 @@
   }
   navigation_params->service_worker_network_provider =
       ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance();
-  FillMiscNavigationParams(*common_params, commit_params,
+  FillMiscNavigationParams(*common_params, *commit_params,
                            navigation_params.get());
   WebNavigationParams::FillStaticResponse(navigation_params.get(), "text/html",
                                           "UTF-8", error_html);
@@ -3884,7 +3885,7 @@
   // was not initiated through BeginNavigation, therefore
   // |was_initiated_in_this_frame| is false.
   std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
-      *common_params, commit_params, base::TimeTicks(), std::move(callback),
+      *common_params, *commit_params, base::TimeTicks(), std::move(callback),
       std::move(per_navigation_mojo_interface_callback), nullptr,
       std::move(navigation_client_impl_), ResourceDispatcher::MakeRequestID(),
       false /* was_initiated_in_this_frame */);
@@ -3904,33 +3905,33 @@
 
 void RenderFrameImpl::CommitSameDocumentNavigation(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     CommitSameDocumentNavigationCallback callback) {
   DCHECK(!IsRendererDebugURL(common_params->url));
   DCHECK(!NavigationTypeUtils::IsReload(common_params->navigation_type));
-  DCHECK(!commit_params.is_view_source);
+  DCHECK(!commit_params->is_view_source);
   DCHECK(NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
 
-  PrepareFrameForCommit(common_params->url, commit_params);
+  PrepareFrameForCommit(common_params->url, *commit_params);
 
   blink::WebFrameLoadType load_type =
       NavigationTypeToLoadType(common_params->navigation_type,
                                common_params->should_replace_current_entry,
-                               commit_params.page_state.IsValid());
+                               commit_params->page_state.IsValid());
 
   blink::mojom::CommitResult commit_status = blink::mojom::CommitResult::Ok;
   WebHistoryItem item_for_history_navigation;
 
   if (common_params->navigation_type ==
       mojom::NavigationType::HISTORY_SAME_DOCUMENT) {
-    DCHECK(commit_params.page_state.IsValid());
+    DCHECK(commit_params->page_state.IsValid());
     // We must know the nav entry ID of the page we are navigating back to,
     // which should be the case because history navigations are routed via the
     // browser.
-    DCHECK_NE(0, commit_params.nav_entry_id);
+    DCHECK_NE(0, commit_params->nav_entry_id);
     DCHECK(!common_params->is_history_navigation_in_new_child_frame);
     commit_status = PrepareForHistoryNavigationCommit(
-        *common_params, commit_params, &item_for_history_navigation,
+        *common_params, *commit_params, &item_for_history_navigation,
         &load_type);
   }
 
@@ -3948,8 +3949,9 @@
         InternalDocumentStateData::FromDocumentState(original_document_state));
     // This is a browser-initiated same-document navigation (as opposed to a
     // fragment link click), therefore |was_initiated_in_this_frame| is false.
+    auto url = common_params->url;
     internal_data->set_navigation_state(NavigationState::CreateBrowserInitiated(
-        common_params.Clone(), commit_params,
+        std::move(common_params), std::move(commit_params),
         base::TimeTicks(),  // Not used for same-document navigation.
         mojom::FrameNavigationControl::CommitNavigationCallback(),
         mojom::NavigationClient::CommitNavigationCallback(), nullptr,
@@ -3957,8 +3959,8 @@
 
     // Load the request.
     commit_status = frame_->CommitSameDocumentNavigation(
-        common_params->url, load_type, item_for_history_navigation,
-        is_client_redirect, std::move(document_state));
+        url, load_type, item_for_history_navigation, is_client_redirect,
+        std::move(document_state));
 
     // The load of the URL can result in this frame being removed. Use a
     // WeakPtr as an easy way to detect whether this has occured. If so, this
@@ -6111,7 +6113,7 @@
     blink::WebHistoryCommitType commit_type) {
   NavigationState* navigation_state =
       NavigationState::FromDocumentLoader(frame_->GetDocumentLoader());
-  const CommitNavigationParams& commit_params =
+  const mojom::CommitNavigationParams& commit_params =
       navigation_state->commit_params();
 
   // Update the current history item for this frame.
@@ -6240,7 +6242,7 @@
 
 void RenderFrameImpl::PrepareFrameForCommit(
     const GURL& url,
-    const CommitNavigationParams& commit_params) {
+    const mojom::CommitNavigationParams& commit_params) {
   browser_side_navigation_pending_ = false;
   browser_side_navigation_pending_url_ = GURL();
   sync_navigation_callback_.Cancel();
@@ -6254,7 +6256,7 @@
 
 blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     WebHistoryItem* item_for_history_navigation,
     blink::WebFrameLoadType* load_type) {
   mojom::NavigationType navigation_type = common_params.navigation_type;
@@ -7124,7 +7126,7 @@
 
 void RenderFrameImpl::PrepareRenderViewForNavigation(
     const GURL& url,
-    const CommitNavigationParams& commit_params) {
+    const mojom::CommitNavigationParams& commit_params) {
   DCHECK(render_view_->webview());
 
   render_view_->history_list_offset_ =
@@ -7263,7 +7265,7 @@
 
 void RenderFrameImpl::DecodeDataURL(
     const mojom::CommonNavigationParams& common_params,
-    const CommitNavigationParams& commit_params,
+    const mojom::CommitNavigationParams& commit_params,
     std::string* mime_type,
     std::string* charset,
     std::string* data,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index f78f012..dcf012ae 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -37,6 +37,7 @@
 #include "content/common/frame_delete_intention.h"
 #include "content/common/host_zoom.mojom.h"
 #include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
+#include "content/common/navigation_params.mojom.h"
 #include "content/common/renderer.mojom.h"
 #include "content/common/unique_name_helper.h"
 #include "content/common/widget.mojom.h"
@@ -172,7 +173,6 @@
 struct CustomContextMenuContext;
 struct FrameOwnerProperties;
 struct FrameReplicationState;
-struct CommitNavigationParams;
 struct ScreenInfo;
 
 class CONTENT_EXPORT RenderFrameImpl
@@ -560,8 +560,8 @@
 
   // mojom::FrameNavigationControl implementation:
   void CommitNavigation(
-      const mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommonNavigationParamsPtr common_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -583,7 +583,7 @@
   // the one from NavigationClient mojo interface.
   void CommitPerNavigationMojoInterfaceNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -602,7 +602,7 @@
 
   void CommitFailedNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
@@ -615,7 +615,7 @@
   // the one from NavigationClient mojo interface.
   void CommitFailedPerNavigationMojoInterfaceNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
@@ -626,7 +626,7 @@
 
   void CommitSameDocumentNavigation(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       CommitSameDocumentNavigationCallback callback) override;
   void HandleRendererDebugURL(const GURL& url) override;
   void UpdateSubresourceLoaderFactories(
@@ -1251,7 +1251,7 @@
   // Does preparation for the navigation to |url|.
   void PrepareRenderViewForNavigation(
       const GURL& url,
-      const CommitNavigationParams& commit_params);
+      const mojom::CommitNavigationParams& commit_params);
 
   // Sends a FrameHostMsg_BeginNavigation to the browser
   void BeginNavigationInternal(std::unique_ptr<blink::WebNavigationInfo> info,
@@ -1269,7 +1269,7 @@
   // Commit navigation with |navigation_params| prepared.
   void CommitNavigationWithParams(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
           subresource_loader_factories,
       base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
@@ -1286,11 +1286,11 @@
   // in the renderer, but browser was not aware yet at the moment of issuing
   // a CommitNavigation call.
   bool ShouldIgnoreCommitNavigation(
-      const CommitNavigationParams& commit_params);
+      const mojom::CommitNavigationParams& commit_params);
 
   // Decodes a data url for navigation commit.
   void DecodeDataURL(const mojom::CommonNavigationParams& common_params,
-                     const CommitNavigationParams& commit_params,
+                     const mojom::CommitNavigationParams& commit_params,
                      std::string* mime_type,
                      std::string* charset,
                      std::string* data,
@@ -1397,8 +1397,9 @@
   blink::WebLocalFrameClient::AppCacheType GetAppCacheType() override;
 
   // Updates the state of this frame when asked to commit a navigation.
-  void PrepareFrameForCommit(const GURL& url,
-                             const CommitNavigationParams& commit_params);
+  void PrepareFrameForCommit(
+      const GURL& url,
+      const mojom::CommitNavigationParams& commit_params);
 
   // Updates the state when asked to commit a history navigation.  Sets
   // |item_for_history_navigation| and |load_type| to the appropriate values for
@@ -1426,7 +1427,7 @@
   // so that it can be performed in cross-document fashion.
   blink::mojom::CommitResult PrepareForHistoryNavigationCommit(
       const mojom::CommonNavigationParams& common_params,
-      const CommitNavigationParams& commit_params,
+      const mojom::CommitNavigationParams& commit_params,
       blink::WebHistoryItem* item_for_history_navigation,
       blink::WebFrameLoadType* load_type);
 
@@ -1445,7 +1446,7 @@
   // Commit*PerNavigationMojoInterfaceNavigation functions.
   void CommitNavigationInternal(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -1465,7 +1466,7 @@
 
   void CommitFailedNavigationInternal(
       mojom::CommonNavigationParamsPtr common_params,
-      const CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
@@ -1562,7 +1563,7 @@
   // is never used after the initial navigation.
   // TODO(creis): Expand this to include any corresponding same-process
   // PageStates for the whole subtree in https://crbug.com/639842.
-  std::map<std::string, bool> history_subframe_unique_names_;
+  base::flat_map<std::string, bool> history_subframe_unique_names_;
 
   // Stores the current history item for this frame, so that updates to it can
   // be reported to the browser process via SendUpdateState.
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc
index b6d9eaa0..a0f2cb1 100644
--- a/content/renderer/render_frame_impl_browsertest.cc
+++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -455,7 +455,7 @@
   common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
   GetMainRenderFrame()->SetHostZoomLevel(common_params->url, kMinZoomLevel);
   GetMainRenderFrame()->Navigate(common_params.Clone(),
-                                 CommitNavigationParams());
+                                 CreateCommitNavigationParams());
   base::RunLoop().RunUntilIdle();
   EXPECT_DOUBLE_EQ(kMinZoomLevel, view_->GetWebView()->ZoomLevel());
 
@@ -465,7 +465,7 @@
   common_params->url = GURL("data:text/html,max_zoomlimit_test");
   GetMainRenderFrame()->SetHostZoomLevel(common_params->url, kMaxZoomLevel);
   GetMainRenderFrame()->Navigate(common_params.Clone(),
-                                 CommitNavigationParams());
+                                 CreateCommitNavigationParams());
   base::RunLoop().RunUntilIdle();
   EXPECT_DOUBLE_EQ(kMaxZoomLevel, view_->GetWebView()->ZoomLevel());
 }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 707e580..06fa941 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -91,7 +91,6 @@
 #include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
 #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
 #include "content/renderer/media/render_media_client.h"
-#include "content/renderer/media/stream/media_stream_center.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/peer_connection_tracker.h"
 #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
@@ -1994,13 +1993,6 @@
   return &associated_interfaces_;
 }
 
-std::unique_ptr<blink::WebMediaStreamCenter>
-RenderThreadImpl::CreateMediaStreamCenter() {
-  DCHECK(main_thread_runner()->BelongsToCurrentThread());
-  // TODO(hajimehoshi): Pass a per-frame task runner if possible.
-  return std::make_unique<MediaStreamCenter>(main_thread_runner());
-}
-
 PeerConnectionDependencyFactory*
 RenderThreadImpl::GetPeerConnectionDependencyFactory() {
   return peer_connection_factory_.get();
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index d3b39bc9..543b682 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -69,7 +69,6 @@
 
 namespace blink {
 class WebVideoCaptureImplManager;
-class WebMediaStreamCenter;
 }
 
 namespace base {
@@ -298,10 +297,6 @@
   bool EnableStreamTextureCopy();
 #endif
 
-  // Creates the embedder implementation of WebMediaStreamCenter.
-  // The resulting object is owned by WebKit and deleted by WebKit at tear-down.
-  std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter();
-
   BrowserPluginManager* browser_plugin_manager() const {
     return browser_plugin_manager_.get();
   }
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index e93043af..bf66006 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -277,16 +277,16 @@
   void GoToOffsetWithParams(int offset,
                             const PageState& state,
                             mojom::CommonNavigationParamsPtr common_params,
-                            CommitNavigationParams commit_params) {
+                            mojom::CommitNavigationParamsPtr commit_params) {
     EXPECT_TRUE(common_params->transition & ui::PAGE_TRANSITION_FORWARD_BACK);
     int pending_offset = offset + view()->history_list_offset_;
 
-    commit_params.page_state = state;
-    commit_params.nav_entry_id = pending_offset + 1;
-    commit_params.pending_history_list_offset = pending_offset;
-    commit_params.current_history_list_offset = view()->history_list_offset_;
-    commit_params.current_history_list_length = view()->history_list_length_;
-    frame()->Navigate(std::move(common_params), commit_params);
+    commit_params->page_state = state;
+    commit_params->nav_entry_id = pending_offset + 1;
+    commit_params->pending_history_list_offset = pending_offset;
+    commit_params->current_history_list_offset = view()->history_list_offset_;
+    commit_params->current_history_list_length = view()->history_list_length_;
+    frame()->Navigate(std::move(common_params), std::move(commit_params));
 
     // The load actually happens asynchronously, so we pump messages to process
     // the pending continuation.
@@ -636,7 +636,6 @@
   auto common_params = mojom::CommonNavigationParams::New();
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
-  CommitNavigationParams commit_params;
   common_params->url = GURL("data:text/html,<div>Page</div>");
   common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
   common_params->transition = ui::PAGE_TRANSITION_TYPED;
@@ -650,7 +649,7 @@
   post_data->AppendBytes(raw_data, length);
   common_params->post_data = post_data;
 
-  frame()->Navigate(std::move(common_params), commit_params);
+  frame()->Navigate(std::move(common_params), CreateCommitNavigationParams());
   base::RunLoop().RunUntilIdle();
 
   auto last_commit_params = frame()->TakeLastCommitParams();
@@ -689,12 +688,12 @@
   common_params->transition = ui::PAGE_TRANSITION_TYPED;
   common_params->base_url_for_data_url = GURL("about:blank");
   common_params->history_url_for_data_url = GURL("about:blank");
-  CommitNavigationParams commit_params;
-  commit_params.data_url_as_string =
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->data_url_as_string =
       "data:text/html,<html><head><title>Data page</title></head></html>";
 
   render_thread_->sink().ClearMessages();
-  frame()->Navigate(std::move(common_params), commit_params);
+  frame()->Navigate(std::move(common_params), std::move(commit_params));
   const IPC::Message* frame_title_msg = nullptr;
   do {
     base::RunLoop().RunUntilIdle();
@@ -1087,9 +1086,9 @@
   common_params->url = GURL("data:text/html,<div>Page</div>");
   common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
   common_params->transition = ui::PAGE_TRANSITION_TYPED;
-  CommitNavigationParams commit_params;
 
-  provisional_frame->Navigate(std::move(common_params), commit_params);
+  provisional_frame->Navigate(std::move(common_params),
+                              CreateCommitNavigationParams());
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
@@ -1502,7 +1501,7 @@
   common_params->navigation_start = base::TimeTicks::Now();
   common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
   common_params->url = GURL("data:text/html,test data");
-  frame()->Navigate(std::move(common_params), CommitNavigationParams());
+  frame()->Navigate(std::move(common_params), CreateCommitNavigationParams());
 
   // A cancellation occurred.
   view()->GetMainRenderFrame()->DidFailProvisionalLoad(error, "GET");
@@ -1879,23 +1878,23 @@
   LoadHTML("hello <iframe srcdoc='fail' name='frame'></iframe>");
 
   // Navigate the frame only.
-  mojom::CommonNavigationParams common_params;
-  common_params.referrer = blink::mojom::Referrer::New();
-  common_params.navigation_start = base::TimeTicks::Now();
-  common_params.url = GURL("data:text/html,world");
-  common_params.navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
-  common_params.transition = ui::PAGE_TRANSITION_TYPED;
-  common_params.navigation_start = base::TimeTicks::FromInternalValue(1);
-  CommitNavigationParams commit_params;
-  commit_params.current_history_list_length = 1;
-  commit_params.current_history_list_offset = 0;
-  commit_params.pending_history_list_offset = 1;
+  auto common_params = mojom::CommonNavigationParams::New();
+  common_params->referrer = blink::mojom::Referrer::New();
+  common_params->navigation_start = base::TimeTicks::Now();
+  common_params->url = GURL("data:text/html,world");
+  common_params->navigation_type = mojom::NavigationType::DIFFERENT_DOCUMENT;
+  common_params->transition = ui::PAGE_TRANSITION_TYPED;
+  common_params->navigation_start = base::TimeTicks::FromInternalValue(1);
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->current_history_list_length = 1;
+  commit_params->current_history_list_offset = 0;
+  commit_params->pending_history_list_offset = 1;
 
   TestRenderFrame* subframe =
       static_cast<TestRenderFrame*>(RenderFrameImpl::FromWebFrame(
           frame()->GetWebFrame()->FindFrameByName("frame")));
   FrameLoadWaiter waiter(subframe);
-  subframe->Navigate(common_params.Clone(), commit_params);
+  subframe->Navigate(std::move(common_params), std::move(commit_params));
   waiter.Wait();
 
   // Copy the document content to std::string and compare with the
@@ -2002,7 +2001,7 @@
   common_params->url = GURL("http://example.com/suppress");
   TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
   main_frame->NavigateWithError(
-      std::move(common_params), CommitNavigationParams(),
+      std::move(common_params), CreateCommitNavigationParams(),
       net::ERR_FILE_NOT_FOUND, "A suffusion of yellow.");
 
   const int kMaxOutputCharacters = 22;
@@ -2026,7 +2025,7 @@
   common_params->url = GURL("http://example.com/dont-suppress");
   TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
   main_frame->NavigateWithError(
-      std::move(common_params), CommitNavigationParams(),
+      std::move(common_params), CreateCommitNavigationParams(),
       net::ERR_FILE_NOT_FOUND, "A suffusion of yellow.");
 
   // The error page itself is loaded asynchronously.
@@ -2063,7 +2062,7 @@
 
   TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
   main_frame->Navigate(head, std::move(common_params),
-                       CommitNavigationParams());
+                       CreateCommitNavigationParams());
   main_frame->DidFinishDocumentLoad();
   main_frame->RunScriptsAtDocumentReady(true);
 
@@ -2169,7 +2168,7 @@
   auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
 
   FrameLoadWaiter waiter(frame());
-  frame()->Navigate(common_params.Clone(), CommitNavigationParams());
+  frame()->Navigate(common_params.Clone(), CreateCommitNavigationParams());
   waiter.Wait();
   NavigationState* navigation_state = NavigationState::FromDocumentLoader(
       frame()->GetWebFrame()->GetDocumentLoader());
@@ -2187,7 +2186,7 @@
   auto late_common_params = MakeCommonNavigationParams(TimeDelta::FromDays(42));
   late_common_params->method = "POST";
 
-  frame()->Navigate(late_common_params.Clone(), CommitNavigationParams());
+  frame()->Navigate(late_common_params.Clone(), CreateCommitNavigationParams());
   base::RunLoop().RunUntilIdle();
   base::Time after_navigation =
       base::Time::Now() + base::TimeDelta::FromDays(1);
@@ -2207,7 +2206,7 @@
 
   auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
   FrameLoadWaiter waiter(frame());
-  frame()->Navigate(common_params.Clone(), CommitNavigationParams());
+  frame()->Navigate(common_params.Clone(), CreateCommitNavigationParams());
   waiter.Wait();
   NavigationState* navigation_state = NavigationState::FromDocumentLoader(
       frame()->GetWebFrame()->GetDocumentLoader());
@@ -2233,7 +2232,7 @@
   // The browser navigation_start should not be used because beforeunload will
   // be fired during Navigate.
   FrameLoadWaiter waiter(frame());
-  frame()->Navigate(common_params.Clone(), CommitNavigationParams());
+  frame()->Navigate(common_params.Clone(), CreateCommitNavigationParams());
   waiter.Wait();
 
   // The browser navigation_start is always used.
@@ -2262,7 +2261,7 @@
   common_params_back->navigation_type =
       mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT;
   GoToOffsetWithParams(-1, back_state, common_params_back.Clone(),
-                       CommitNavigationParams());
+                       CreateCommitNavigationParams());
   NavigationState* navigation_state = NavigationState::FromDocumentLoader(
       frame()->GetWebFrame()->GetDocumentLoader());
 
@@ -2280,7 +2279,7 @@
   common_params_forward->navigation_type =
       mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT;
   GoToOffsetWithParams(1, forward_state, common_params_forward.Clone(),
-                       CommitNavigationParams());
+                       CreateCommitNavigationParams());
   navigation_state = NavigationState::FromDocumentLoader(
       frame()->GetWebFrame()->GetDocumentLoader());
   EXPECT_EQ(common_params_forward->navigation_start,
@@ -2293,15 +2292,15 @@
   common_params->navigation_type =
       mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT;
 
-  CommitNavigationParams commit_params;
-  commit_params.page_state =
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->page_state =
       PageState::CreateForTesting(common_params->url, false, nullptr, nullptr);
-  commit_params.nav_entry_id = 42;
-  commit_params.pending_history_list_offset = 1;
-  commit_params.current_history_list_offset = 0;
-  commit_params.current_history_list_length = 1;
+  commit_params->nav_entry_id = 42;
+  commit_params->pending_history_list_offset = 1;
+  commit_params->current_history_list_offset = 0;
+  commit_params->current_history_list_length = 1;
   FrameLoadWaiter waiter(frame());
-  frame()->Navigate(common_params.Clone(), commit_params);
+  frame()->Navigate(common_params.Clone(), std::move(commit_params));
   waiter.Wait();
 
   NavigationState* navigation_state = NavigationState::FromDocumentLoader(
@@ -2360,13 +2359,13 @@
                    view()->HistoryForwardListCount() + 1);
 
   // Receive a CommitNavigation message with history parameters.
-  CommitNavigationParams commit_params;
-  commit_params.current_history_list_offset = 1;
-  commit_params.current_history_list_length = 2;
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->current_history_list_offset = 1;
+  commit_params->current_history_list_length = 2;
   auto common_params = mojom::CommonNavigationParams::New();
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
-  frame()->Navigate(std::move(common_params), commit_params);
+  frame()->Navigate(std::move(common_params), std::move(commit_params));
 
   // The current history list in RenderView is updated.
   EXPECT_EQ(1, view()->HistoryBackListCount());
@@ -2382,15 +2381,15 @@
                    view()->HistoryForwardListCount() + 1);
 
   // Receive a CommitNavigation message with history parameters.
-  CommitNavigationParams commit_params;
-  commit_params.current_history_list_offset = 1;
-  commit_params.current_history_list_length = 25;
-  commit_params.pending_history_list_offset = 12;
-  commit_params.nav_entry_id = 777;
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->current_history_list_offset = 1;
+  commit_params->current_history_list_length = 25;
+  commit_params->pending_history_list_offset = 12;
+  commit_params->nav_entry_id = 777;
   auto common_params = mojom::CommonNavigationParams::New();
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
-  frame()->Navigate(std::move(common_params), commit_params);
+  frame()->Navigate(std::move(common_params), std::move(commit_params));
 
   // The current history list in RenderView is updated.
   EXPECT_EQ(12, view()->HistoryBackListCount());
@@ -2406,14 +2405,14 @@
                    view()->HistoryForwardListCount() + 1);
 
   // Receive a CommitNavigation message with history parameters.
-  CommitNavigationParams commit_params;
-  commit_params.current_history_list_offset = 12;
-  commit_params.current_history_list_length = 25;
-  commit_params.should_clear_history_list = true;
+  auto commit_params = CreateCommitNavigationParams();
+  commit_params->current_history_list_offset = 12;
+  commit_params->current_history_list_length = 25;
+  commit_params->should_clear_history_list = true;
   auto common_params = mojom::CommonNavigationParams::New();
   common_params->referrer = blink::mojom::Referrer::New();
   common_params->navigation_start = base::TimeTicks::Now();
-  frame()->Navigate(std::move(common_params), commit_params);
+  frame()->Navigate(std::move(common_params), std::move(commit_params));
 
   // The current history list in RenderView is updated.
   EXPECT_EQ(0, view()->HistoryBackListCount());
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 2c96d67..1590e2b 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -3394,8 +3394,7 @@
 void RenderWidget::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
                                            bool use_anchor,
                                            float new_page_scale,
-                                           double duration_sec) {
-  base::TimeDelta duration = base::TimeDelta::FromSecondsD(duration_sec);
+                                           base::TimeDelta duration) {
   layer_tree_view_->layer_tree_host()->StartPageScaleAnimation(
       target_offset, use_anchor, new_page_scale, duration);
 }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 4df405f..ca3618a 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -455,7 +455,7 @@
   void StartPageScaleAnimation(const gfx::Vector2d& destination,
                                bool use_anchor,
                                float new_page_scale,
-                               double duration_sec) override;
+                               base::TimeDelta duration) override;
   void ForceRecalculateRasterScales() override;
   void RequestDecode(const cc::PaintImage& image,
                      base::OnceCallback<void(bool)> callback) override;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 8b6182e..5663e0a0 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -89,7 +89,6 @@
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_audio_latency_hint.h"
 #include "third_party/blink/public/platform/web_blob_registry.h"
-#include "third_party/blink/public/platform/web_media_stream_center.h"
 #include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
@@ -120,7 +119,6 @@
 using blink::WebAudioDevice;
 using blink::WebAudioLatencyHint;
 using blink::WebBlobRegistry;
-using blink::WebMediaStreamCenter;
 using blink::WebMediaStreamTrack;
 using blink::WebRTCPeerConnectionHandler;
 using blink::WebRTCPeerConnectionHandlerClient;
@@ -133,8 +131,6 @@
 
 namespace {
 
-bool g_sandbox_enabled = true;
-
 media::AudioParameters GetAudioHardwareParams() {
   blink::WebLocalFrame* const web_frame =
       blink::WebLocalFrame::FrameForCurrentContext();
@@ -200,7 +196,7 @@
   }
 
 #if defined(OS_LINUX) || defined(OS_MACOSX)
-  if (g_sandbox_enabled && sandboxEnabled()) {
+  if (sandboxEnabled()) {
 #if defined(OS_MACOSX)
     sandbox_support_.reset(new WebSandboxSupportMac(connector_.get()));
 #else
@@ -566,24 +562,6 @@
 
 //------------------------------------------------------------------------------
 
-std::unique_ptr<WebMediaStreamCenter>
-RendererBlinkPlatformImpl::CreateMediaStreamCenter() {
-  RenderThreadImpl* render_thread = RenderThreadImpl::current();
-  DCHECK(render_thread);
-  if (!render_thread)
-    return nullptr;
-  return render_thread->CreateMediaStreamCenter();
-}
-
-// static
-bool RendererBlinkPlatformImpl::SetSandboxEnabledForTesting(bool enable) {
-  bool was_enabled = g_sandbox_enabled;
-  g_sandbox_enabled = enable;
-  return was_enabled;
-}
-
-//------------------------------------------------------------------------------
-
 scoped_refptr<base::SingleThreadTaskRunner>
 RendererBlinkPlatformImpl::GetWebRtcWorkerThread() {
   RenderThreadImpl* render_thread = RenderThreadImpl::current();
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index f8c415ed..395b83f 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -134,8 +134,6 @@
       scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
   std::unique_ptr<blink::WebRTCCertificateGenerator>
   CreateRTCCertificateGenerator() override;
-  std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter()
-      override;
   scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcWorkerThread() override;
   rtc::Thread* GetWebRtcWorkerThreadRtcThread() override;
   scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcSignalingTaskRunner()
@@ -196,15 +194,6 @@
 
   void RecordMetricsForBackgroundedRendererPurge() override;
 
-  // Disables the WebSandboxSupport implementation for testing.
-  // Tests that do not set up a full sandbox environment should call
-  // SetSandboxEnabledForTesting(false) _before_ creating any instances
-  // of this class, to ensure that we don't attempt to use sandbox-related
-  // file descriptors or other resources.
-  //
-  // Returns the previous |enable| value.
-  static bool SetSandboxEnabledForTesting(bool enable);
-
   std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory()
       override;
   std::unique_ptr<blink::CodeCacheLoader> CreateCodeCacheLoader() override;
diff --git a/content/shell/renderer/web_test/web_test_content_renderer_client.cc b/content/shell/renderer/web_test/web_test_content_renderer_client.cc
index f32247a7..8637959 100644
--- a/content/shell/renderer/web_test/web_test_content_renderer_client.cc
+++ b/content/shell/renderer/web_test/web_test_content_renderer_client.cc
@@ -34,7 +34,6 @@
 #include "media/base/mime_util.h"
 #include "media/media_buildflags.h"
 #include "third_party/blink/public/platform/web_audio_latency_hint.h"
-#include "third_party/blink/public/platform/web_media_stream_center.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/web_runtime_features.h"
 #include "third_party/blink/public/web/blink.h"
@@ -47,7 +46,6 @@
 using blink::WebAudioDevice;
 using blink::WebFrame;
 using blink::WebLocalFrame;
-using blink::WebMediaStreamCenter;
 using blink::WebPlugin;
 using blink::WebPluginParams;
 using blink::WebRTCPeerConnectionHandler;
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index a511327..6998ef35 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -262,9 +262,9 @@
 
 void TestRenderFrame::Navigate(const network::ResourceResponseHead& head,
                                mojom::CommonNavigationParamsPtr common_params,
-                               const CommitNavigationParams& commit_params) {
+                               mojom::CommitNavigationParamsPtr commit_params) {
   if (!IsPerNavigationMojoInterfaceEnabled()) {
-    CommitNavigation(std::move(common_params), commit_params, head,
+    CommitNavigation(std::move(common_params), std::move(commit_params), head,
                      mojo::ScopedDataPipeConsumerHandle(),
                      network::mojom::URLLoaderClientEndpointsPtr(),
                      std::make_unique<blink::URLLoaderFactoryBundleInfo>(),
@@ -277,7 +277,7 @@
     BindNavigationClient(
         mojo::MakeRequestAssociatedWithDedicatedPipe(&mock_navigation_client_));
     CommitPerNavigationMojoInterfaceNavigation(
-        std::move(common_params), commit_params, head,
+        std::move(common_params), std::move(commit_params), head,
         mojo::ScopedDataPipeConsumerHandle(),
         network::mojom::URLLoaderClientEndpointsPtr(),
         std::make_unique<blink::URLLoaderFactoryBundleInfo>(), base::nullopt,
@@ -291,25 +291,25 @@
 }
 
 void TestRenderFrame::Navigate(mojom::CommonNavigationParamsPtr common_params,
-                               const CommitNavigationParams& commit_params) {
+                               mojom::CommitNavigationParamsPtr commit_params) {
   Navigate(network::ResourceResponseHead(), std::move(common_params),
-           commit_params);
+           std::move(commit_params));
 }
 
 void TestRenderFrame::NavigateWithError(
     mojom::CommonNavigationParamsPtr common_params,
-    const CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     int error_code,
     const base::Optional<std::string>& error_page_content) {
   if (!IsPerNavigationMojoInterfaceEnabled()) {
-    CommitFailedNavigation(std::move(common_params), commit_params,
+    CommitFailedNavigation(std::move(common_params), std::move(commit_params),
                            false /* has_stale_copy_in_cache */, error_code,
                            error_page_content, nullptr, base::DoNothing());
   } else {
     BindNavigationClient(
         mojo::MakeRequestAssociatedWithDedicatedPipe(&mock_navigation_client_));
     mock_navigation_client_->CommitFailedNavigation(
-        std::move(common_params), commit_params,
+        std::move(common_params), std::move(commit_params),
         false /* has_stale_copy_in_cache */, error_code, error_page_content,
         nullptr,
         base::BindOnce(&MockFrameHost::DidCommitProvisionalLoad,
diff --git a/content/test/test_render_frame.h b/content/test/test_render_frame.h
index 4e68429..48e4d19 100644
--- a/content/test/test_render_frame.h
+++ b/content/test/test_render_frame.h
@@ -11,6 +11,7 @@
 #include "base/optional.h"
 #include "content/common/frame.mojom.h"
 #include "content/common/input/input_handler.mojom.h"
+#include "content/common/navigation_params.mojom.h"
 #include "content/renderer/render_frame_impl.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
 
@@ -21,7 +22,6 @@
 namespace content {
 
 class MockFrameHost;
-struct CommitNavigationParams;
 
 // A test class to use in RenderViewTests.
 class TestRenderFrame : public RenderFrameImpl {
@@ -41,11 +41,11 @@
 
   void Navigate(const network::ResourceResponseHead& head,
                 mojom::CommonNavigationParamsPtr common_params,
-                const CommitNavigationParams& commit_params);
+                mojom::CommitNavigationParamsPtr commit_params);
   void Navigate(mojom::CommonNavigationParamsPtr common_params,
-                const CommitNavigationParams& commit_params);
+                mojom::CommitNavigationParamsPtr commit_params);
   void NavigateWithError(mojom::CommonNavigationParamsPtr common_params,
-                         const CommitNavigationParams& request_params,
+                         mojom::CommitNavigationParamsPtr request_params,
                          int error_code,
                          const base::Optional<std::string>& error_page_content);
   void SwapOut(int proxy_routing_id,
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 4c803d2..fc8ea1e 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -539,7 +539,7 @@
     mojom::NavigationClient* navigation_client,
     NavigationRequest* navigation_request,
     mojom::CommonNavigationParamsPtr common_params,
-    const content::CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     const network::ResourceResponseHead& response_head,
     mojo::ScopedDataPipeConsumerHandle response_body,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -567,7 +567,7 @@
     mojom::NavigationClient* navigation_client,
     NavigationRequest* navigation_request,
     mojom::CommonNavigationParamsPtr common_params,
-    const content::CommitNavigationParams& commit_params,
+    mojom::CommitNavigationParamsPtr commit_params,
     bool has_stale_copy_in_cache,
     int32_t error_code,
     const base::Optional<std::string>& error_page_content,
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h
index 281a9e7..bdd24d6 100644
--- a/content/test/test_render_frame_host.h
+++ b/content/test/test_render_frame_host.h
@@ -211,7 +211,7 @@
       mojom::NavigationClient* navigation_client,
       NavigationRequest* navigation_request,
       mojom::CommonNavigationParamsPtr common_params,
-      const content::CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       const network::ResourceResponseHead& response_head,
       mojo::ScopedDataPipeConsumerHandle response_body,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
@@ -229,7 +229,7 @@
       mojom::NavigationClient* navigation_client,
       NavigationRequest* navigation_request,
       mojom::CommonNavigationParamsPtr common_params,
-      const content::CommitNavigationParams& commit_params,
+      mojom::CommitNavigationParamsPtr commit_params,
       bool has_stale_copy_in_cache,
       int32_t error_code,
       const base::Optional<std::string>& error_page_content,
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
index 97d6648f..a46d60b 100644
--- a/crypto/nss_util.cc
+++ b/crypto/nss_util.cc
@@ -319,9 +319,10 @@
     std::unique_ptr<TPMModuleAndSlot> tpm_args(
         new TPMModuleAndSlot(chaps_module_));
     TPMModuleAndSlot* tpm_args_ptr = tpm_args.get();
-    base::PostTaskWithTraitsAndReply(
+    base::PostTaskAndReply(
         FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
         base::BindOnce(&NSSInitSingleton::InitializeTPMTokenInThreadPool,
                        system_slot_id, tpm_args_ptr),
         base::BindOnce(&NSSInitSingleton::OnInitializedTPMTokenAndSystemSlot,
@@ -482,9 +483,10 @@
     std::unique_ptr<TPMModuleAndSlot> tpm_args(
         new TPMModuleAndSlot(chaps_module_));
     TPMModuleAndSlot* tpm_args_ptr = tpm_args.get();
-    base::PostTaskWithTraitsAndReply(
+    base::PostTaskAndReply(
         FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
         base::BindOnce(&NSSInitSingleton::InitializeTPMTokenInThreadPool,
                        slot_id, tpm_args_ptr),
         base::BindOnce(&NSSInitSingleton::OnInitializedTPMForChromeOSUser,
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index 5bf7eeda..250ed1a8 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -230,6 +230,15 @@
 }
 #endif
 
+#if defined(OS_CHROMEOS)
+void BluetoothAdapter::NotifyDeviceBatteryChanged(BluetoothDevice* device) {
+  DCHECK_EQ(device->GetAdapter(), this);
+  for (auto& observer : observers_) {
+    observer.DeviceBatteryChanged(this, device, device->battery_percentage());
+  }
+}
+#endif
+
 void BluetoothAdapter::NotifyGattServiceAdded(
     BluetoothRemoteGattService* service) {
   DCHECK_EQ(service->GetDevice()->GetAdapter(), this);
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index d342282..7961317 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -170,6 +170,14 @@
                                              bool is_now_connected) {}
 #endif
 
+#if defined(OS_CHROMEOS)
+    // Called when the battery level of the device has been updated.
+    virtual void DeviceBatteryChanged(
+        BluetoothAdapter* adapter,
+        BluetoothDevice* device,
+        base::Optional<uint8_t> new_battery_percentage) {}
+#endif
+
     // Called when the device |device| is removed from the adapter |adapter|,
     // either as a result of a discovered device being lost between discovering
     // phases or pairing information deleted. |device| should not be
@@ -582,6 +590,11 @@
   void NotifyDevicePairedChanged(BluetoothDevice* device,
                                  bool new_paired_status);
 #endif
+
+#if defined(OS_CHROMEOS)
+  void NotifyDeviceBatteryChanged(BluetoothDevice* device);
+#endif
+
   void NotifyGattServiceAdded(BluetoothRemoteGattService* service);
   void NotifyGattServiceRemoved(BluetoothRemoteGattService* service);
   void NotifyGattServiceChanged(BluetoothRemoteGattService* service);
diff --git a/device/bluetooth/bluetooth_device.cc b/device/bluetooth/bluetooth_device.cc
index dc28014..399a627 100644
--- a/device/bluetooth/bluetooth_device.cc
+++ b/device/bluetooth/bluetooth_device.cc
@@ -465,6 +465,20 @@
   return services;
 }
 
+#if defined(OS_CHROMEOS)
+void BluetoothDevice::SetBatteryPercentage(
+    base::Optional<uint8_t> battery_percentage) {
+  if (battery_percentage)
+    DCHECK_LE(battery_percentage.value(), 100);
+
+  if (battery_percentage_ == battery_percentage)
+    return;
+
+  battery_percentage_ = battery_percentage;
+  GetAdapter()->NotifyDeviceBatteryChanged(this);
+}
+#endif
+
 void BluetoothDevice::DidConnectGatt() {
   for (const auto& callback : create_gatt_connection_success_callbacks_) {
     callback.Run(
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index 8a45ce71..dbe3b2f 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -579,7 +579,6 @@
   // Aborts all the previous prepare writes in a reliable write session.
   virtual void AbortWrite(const base::Closure& callback,
                           const AbortWriteErrorCallback& error_callback) = 0;
-#endif
 
   // Set the remaining battery of the device to show in the UI. This value must
   // be between 0 and 100, inclusive.
@@ -587,13 +586,7 @@
   // ash::GattBatteryPoller and used only by Chrome OS. In the future, when
   // there is a unified Mojo service, this logic will be moved to
   // BluetoothDeviceInfo.
-  void set_battery_percentage(base::Optional<uint8_t> battery_percentage) {
-    if (battery_percentage) {
-      DCHECK(battery_percentage.value() >= 0 &&
-             battery_percentage.value() <= 100);
-    }
-    battery_percentage_ = battery_percentage;
-  }
+  void SetBatteryPercentage(base::Optional<uint8_t> battery_percentage);
 
   // Returns the remaining battery for the device.
   // TODO(https://crbug.com/973237): Battery percentage is populated by
@@ -603,6 +596,7 @@
   const base::Optional<uint8_t>& battery_percentage() const {
     return battery_percentage_;
   }
+#endif
 
  protected:
   // BluetoothGattConnection is a friend to call Add/RemoveGattConnection.
@@ -737,13 +731,13 @@
   // a device type for display when |name_| is empty.
   base::string16 GetAddressWithLocalizedDeviceTypeName() const;
 
+#if defined(OS_CHROMEOS)
   // Remaining battery level of the device.
-  // TODO(https://crbug.com/973237): This field is populated by
-  // ash::GattBatteryPoller and used only by Chrome OS. This field is different
-  // from others because it is not filled by the platform. In the future, when
-  // there is a unified Mojo service, this field will be moved to
-  // BluetoothDeviceInfo.
+  // TODO(https://crbug.com/973237): This field is different from others because
+  // it is not filled by the platform. In the future, when there is a unified
+  // Mojo service, this field will be moved to BluetoothDeviceInfo.
   base::Optional<uint8_t> battery_percentage_;
+#endif
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothDevice);
 };
diff --git a/extensions/browser/api/bluetooth/bluetooth_api_utils.cc b/extensions/browser/api/bluetooth/bluetooth_api_utils.cc
index 8f352df82..3d73eb427 100644
--- a/extensions/browser/api/bluetooth/bluetooth_api_utils.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_api_utils.cc
@@ -159,10 +159,12 @@
   else
     out->inquiry_tx_power.reset();
 
+#if defined(OS_CHROMEOS)
   if (device.battery_percentage())
     out->battery_percentage.reset(new int(device.battery_percentage().value()));
   else
     out->battery_percentage.reset();
+#endif
 
 #if defined(OS_LINUX)
   ConvertTransportToApi(device.GetType(), &(out->transport));
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc
index 642d9ccb..cdb59c5 100644
--- a/extensions/browser/app_window/app_window.cc
+++ b/extensions/browser/app_window/app_window.cc
@@ -454,10 +454,6 @@
   app_delegate_->ExitPictureInPicture();
 }
 
-bool AppWindow::ShouldShowStaleContentOnEviction(content::WebContents* source) {
-  return true;
-}
-
 bool AppWindow::OnMessageReceived(const IPC::Message& message,
                                   content::RenderFrameHost* render_frame_host) {
   bool handled = true;
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h
index 2d78220..c12d125 100644
--- a/extensions/browser/app_window/app_window.h
+++ b/extensions/browser/app_window/app_window.h
@@ -451,7 +451,6 @@
       const viz::SurfaceId& surface_id,
       const gfx::Size& natural_size) override;
   void ExitPictureInPicture() override;
-  bool ShouldShowStaleContentOnEviction(content::WebContents* source) override;
 
   // content::WebContentsObserver implementation.
   bool OnMessageReceived(const IPC::Message& message,
diff --git a/extensions/browser/app_window/app_window_browsertest.cc b/extensions/browser/app_window/app_window_browsertest.cc
index b05be56..b409cd8 100644
--- a/extensions/browser/app_window/app_window_browsertest.cc
+++ b/extensions/browser/app_window/app_window_browsertest.cc
@@ -66,18 +66,6 @@
   CloseAppWindow(app_window);
 }
 
-#if defined(OS_CHROMEOS)
-
-IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, ShouldShowStaleContentOnEviction) {
-  AppWindow* app_window = CreateTestAppWindow("{}");
-  // Helper function as this test requires inspecting a number of content::
-  // internal objects.
-  content::VerifyStaleContentOnFrameEviction(
-      app_window->web_contents()->GetRenderWidgetHostView());
-}
-
-#endif  // defined(OS_CHROMEOS)
-
 }  // namespace
 
 }  // namespace extensions
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc
index 0793e4d..04a1590b 100644
--- a/fuchsia/engine/browser/frame_impl.cc
+++ b/fuchsia/engine/browser/frame_impl.cc
@@ -18,7 +18,7 @@
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/renderer_preferences_util.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "fuchsia/base/mem_buffer_util.h"
 #include "fuchsia/base/message_port.h"
 #include "fuchsia/engine/browser/context_impl.h"
diff --git a/fuchsia/engine/browser/navigation_controller_impl.cc b/fuchsia/engine/browser/navigation_controller_impl.cc
index cf0eb7e..5752459 100644
--- a/fuchsia/engine/browser/navigation_controller_impl.cc
+++ b/fuchsia/engine/browser/navigation_controller_impl.cc
@@ -9,7 +9,7 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
 #include "ui/base/page_transition_types.h"
 
 namespace {
@@ -145,9 +145,9 @@
   params_converted.transition_type = ui::PageTransitionFromInt(
       ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
   if (params.has_was_user_activated() && params.was_user_activated()) {
-    params_converted.was_activated = content::WasActivatedOption::kYes;
+    params_converted.was_activated = content::mojom::WasActivatedOption::kYes;
   } else {
-    params_converted.was_activated = content::WasActivatedOption::kNo;
+    params_converted.was_activated = content::mojom::WasActivatedOption::kNo;
   }
 
   web_contents_->GetController().LoadURLWithParams(params_converted);
diff --git a/fuchsia/http/http_service_unittest.cc b/fuchsia/http/http_service_unittest.cc
index c1b52fc..5f584f1b 100644
--- a/fuchsia/http/http_service_unittest.cc
+++ b/fuchsia/http/http_service_unittest.cc
@@ -203,7 +203,8 @@
 
 void CheckResponseHeaders(const oldhttp::URLResponse& response,
                           ResponseHeaders* expected_headers) {
-  for (auto& header : response.headers.get()) {
+  ASSERT_TRUE(response.headers.has_value());
+  for (auto& header : response.headers.value()) {
     const std::string header_name = header.name.data();
     const std::string header_value = header.value.data();
     auto iter = std::find_if(expected_headers->begin(), expected_headers->end(),
diff --git a/fuchsia/http/url_loader_impl.cc b/fuchsia/http/url_loader_impl.cc
index f745b9c2..681ad48 100644
--- a/fuchsia/http/url_loader_impl.cc
+++ b/fuchsia/http/url_loader_impl.cc
@@ -420,12 +420,13 @@
     size_t iter = 0;
     std::string header_name;
     std::string header_value;
+    response.headers.emplace();
     while (response_headers->EnumerateHeaderLines(&iter, &header_name,
                                                   &header_value)) {
       oldhttp::HttpHeader header;
       header.name = header_name;
       header.value = header_value;
-      response.headers.push_back(header);
+      response.headers->push_back(header);
     }
   }
 
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index f819a2b..1260fd2 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -405,6 +405,10 @@
     else if (use_gl == gl::kGLImplementationDisabledName)
       return ComputeGpuFeatureInfoWithNoGpu();
   }
+  if (gpu_preferences.use_vulkan ==
+      gpu::VulkanImplementationName::kSwiftshader) {
+    use_swift_shader = true;
+  }
 
   GpuFeatureInfo gpu_feature_info;
   std::set<int> blacklisted_features;
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
index e423696..f7b2740 100644
--- a/headless/app/headless_shell.cc
+++ b/headless/app/headless_shell.cc
@@ -228,8 +228,8 @@
 void HeadlessShell::OnStart(HeadlessBrowser* browser) {
   browser_ = browser;
   devtools_client_ = HeadlessDevToolsClient::Create();
-  file_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+  file_task_runner_ = base::CreateSequencedTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 
   HeadlessBrowserContext::Builder context_builder =
       browser_->CreateBrowserContextBuilder();
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc
index 8759337..272e69f 100644
--- a/headless/lib/browser/headless_browser_impl.cc
+++ b/headless/lib/browser/headless_browser_impl.cc
@@ -55,8 +55,7 @@
 
 scoped_refptr<base::SingleThreadTaskRunner>
 HeadlessBrowserImpl::BrowserMainThread() const {
-  return base::CreateSingleThreadTaskRunnerWithTraits(
-      {content::BrowserThread::UI});
+  return base::CreateSingleThreadTaskRunner({content::BrowserThread::UI});
 }
 
 void HeadlessBrowserImpl::Shutdown() {
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc
index aefe06e..405bec70 100644
--- a/headless/lib/browser/headless_devtools_client_impl.cc
+++ b/headless/lib/browser/headless_devtools_client_impl.cc
@@ -86,8 +86,8 @@
 }
 
 void HeadlessDevToolsClientImpl::InitBrowserMainThread() {
-  browser_main_thread_ = base::CreateSingleThreadTaskRunnerWithTraits(
-      {content::BrowserThread::UI});
+  browser_main_thread_ =
+      base::CreateSingleThreadTaskRunner({content::BrowserThread::UI});
 }
 
 void HeadlessDevToolsClientImpl::ChannelClosed() {
diff --git a/headless/lib/browser/protocol/browser_handler.cc b/headless/lib/browser/protocol/browser_handler.cc
index cdf433e..0e131f4 100644
--- a/headless/lib/browser/protocol/browser_handler.cc
+++ b/headless/lib/browser/protocol/browser_handler.cc
@@ -70,9 +70,8 @@
 }
 
 Response BrowserHandler::Close() {
-  base::PostTaskWithTraits(
-      FROM_HERE, {content::BrowserThread::UI},
-      base::BindOnce(&HeadlessBrowserImpl::Shutdown, browser()));
+  base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+                 base::BindOnce(&HeadlessBrowserImpl::Shutdown, browser()));
   return Response::OK();
 }
 
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index 213deaf806..be02da2 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -90,9 +90,9 @@
   }
 
   Response* FindResponse(const std::string& method, const std::string& url) {
-    base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                             base::BindOnce(&TestNetworkInterceptor::LogRequest,
-                                            interceptor_, method, url));
+    base::PostTask(FROM_HERE, {BrowserThread::UI},
+                   base::BindOnce(&TestNetworkInterceptor::LogRequest,
+                                  interceptor_, method, url));
     auto it = response_map_.find(StripFragment(url));
     return it == response_map_.end() ? nullptr : it->second.get();
   }
@@ -177,7 +177,7 @@
 
 void TestNetworkInterceptor::InsertResponse(std::string url,
                                             Response response) {
-  base::PostTaskWithTraits(
+  base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&Impl::InsertResponse, base::Unretained(impl_.get()),
                      std::move(url), std::move(response)));
diff --git a/infra/OWNERS b/infra/OWNERS
index 931d3d7f..4d61de2 100644
--- a/infra/OWNERS
+++ b/infra/OWNERS
@@ -1,6 +1,7 @@
 # This is reserved for people that are comfortable with Chromium builders
 # and understand the implications of changing their configurations.
 
+agable@chromium.org
 bpastene@chromium.org
 dpranke@chromium.org
 hans@chromium.org
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg
index 3db98496..489eaf8e 100644
--- a/infra/config/cr-buildbucket.cfg
+++ b/infra/config/cr-buildbucket.cfg
@@ -330,13 +330,13 @@
 
 builder_mixins {
   name: "android-angle-try"
-  dimensions: "os:Ubuntu-16.04"
+  mixins: "linux-xenial"
   mixins: "angle-try"
 }
 
 builder_mixins {
   name: "android-gpu-ci"
-  dimensions: "os:Ubuntu-16.04"
+  mixins: "linux-xenial"
   mixins: "builderless"
   recipe {
     properties: "mastername:chromium.gpu"
@@ -345,7 +345,7 @@
 
 builder_mixins {
   name: "android-gpu-fyi-ci"
-  dimensions: "os:Ubuntu-16.04"
+  mixins: "linux-xenial"
   mixins: "builderless"
   mixins: "gpu-fyi-ci"
   mixins: "gpu-slow-bot"
@@ -353,7 +353,7 @@
 
 builder_mixins {
   name: "android-optional-gpu-try"
-  dimensions: "os:Ubuntu-16.04"
+  mixins: "linux-xenial"
   mixins: "android-try"
   mixins: "gpu-optional-try"
   mixins: "gpu-slow-bot"
@@ -1130,7 +1130,7 @@
       name: "android-asan"
       mixins: "builderless"
       mixins: "memory-ci"
-      dimensions: "os:Ubuntu-16.04"
+      mixins: "linux-xenial"
     }
 
     builders {
@@ -1242,14 +1242,14 @@
       name: "android-kitkat-arm-rel"
       mixins: "android-ci"
       mixins: "builderless"
-      dimensions: "os:Ubuntu-16.04"
+      mixins: "linux-xenial"
     }
 
     builders {
       name: "android-marshmallow-arm64-rel"
       mixins: "android-ci"
       mixins: "builderless"
-      dimensions: "os:Ubuntu-16.04"
+      mixins: "linux-xenial"
     }
 
     builders {
@@ -3674,18 +3674,25 @@
       name: "android-cronet-arm-dbg"
     }
     builders {
+      name: "android-kitkat-arm-coverage-dbg"
       mixins: "android-try"
       mixins: "goma-j150"
       mixins: "builderless"
+      mixins: "linux-xenial"
+    }
+    builders {
       name: "android-kitkat-arm-rel"
-      dimensions: "os:Ubuntu-16.04"
+      mixins: "android-try"
+      mixins: "goma-j150"
+      mixins: "builderless"
+      mixins: "linux-xenial"
     }
     builders {
       name: "android-marshmallow-arm64-rel"
       mixins: "android-try"
       mixins: "builderless"
       mixins: "goma-j300"
-      dimensions: "os:Ubuntu-16.04"
+      mixins: "linux-xenial"
       dimensions: "cores:16"
       dimensions: "ssd:1"
     }
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg
index 6e9eed0..6f6a6b53 100644
--- a/infra/config/luci-milo.cfg
+++ b/infra/config/luci-milo.cfg
@@ -4700,6 +4700,9 @@
     name: "buildbucket/luci.chromium.try/android-cronet-arm-dbg"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/android-kitkat-arm-coverage-dbg"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/android-kitkat-arm-rel"
   }
   builders {
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 0dae68e6..cdbcef2 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -143,6 +143,7 @@
     ":mode",
     ":tests_hook",
     "//base",
+    "//build:branding_buildflags",
     "//components/bookmarks/browser",
     "//components/browser_sync",
     "//components/browsing_data/core",
diff --git a/ios/chrome/app/startup_tasks.mm b/ios/chrome/app/startup_tasks.mm
index 47a63ce2..ade03257 100644
--- a/ios/chrome/app/startup_tasks.mm
+++ b/ios/chrome/app/startup_tasks.mm
@@ -7,6 +7,7 @@
 #import <MediaPlayer/MediaPlayer.h>
 
 #include "base/bind.h"
+#include "build/branding_buildflags.h"
 #include "components/bookmarks/browser/startup_task_runner_service.h"
 #import "ios/chrome/app/deferred_initialization_runner.h"
 #include "ios/chrome/app/intents/SearchInChromeIntent.h"
@@ -61,7 +62,7 @@
 }
 
 - (void)initializeOmaha {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (tests_hook::DisableUpdateService())
     return;
   // Start omaha service. We only do this on official builds.
@@ -70,7 +71,7 @@
       base::BindRepeating(^(const UpgradeRecommendedDetails& details) {
         [[UpgradeCenter sharedInstance] upgradeNotificationDidOccur:details];
       }));
-#endif  // defined(GOOGLE_CHROME_BUILD)
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 }
 
 - (void)registerForApplicationWillResignActiveNotification {
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd
index 178e970..fcccc0b 100644
--- a/ios/chrome/app/strings/ios_chromium_strings.grd
+++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -213,6 +213,9 @@
       <message name="IDS_IOS_MOVE_TO_DOCK_TIP" desc="Text displayed on the New Tab Page for the move Chromium to the dock promo. [iOS only]">
         Tip: <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Move Chromium to your dock<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
       </message>
+      <message name="IDS_IOS_REVIEW_UPDATED_CHROME_TOS" desc="Text displayed on the New Tab Page to notify users of changed Terms of Serice">
+        <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Review the updated Chromium Terms of Service.<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
+      </message>
       <message name="IDS_IOS_OPEN_TABS_NO_SESSION_INSTRUCTIONS" desc="Information about sync displayed when the user has signed in on mobile but not on desktop">
         Access the tabs you have open on your computer, right here. Just open Chromium on your computer, go to the menu, and select “Sign in to Chromium…”
       </message>
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1
new file mode 100644
index 0000000..965eae7
--- /dev/null
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1
@@ -0,0 +1 @@
+80eca64ffc994eeada04245dc0c6f2bac74728e7
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd
index 8a5137a..c4b1664 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings.grd
+++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -213,6 +213,9 @@
       <message name="IDS_IOS_MOVE_TO_DOCK_TIP" desc="Text displayed on the New Tab Page for the move Chrome to the dock promo. [iOS only]">
         Tip: <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Move Chrome to your dock<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
       </message>
+      <message name="IDS_IOS_REVIEW_UPDATED_CHROME_TOS" desc="Text displayed on the New Tab Page to notify users of changed Terms of Serice">
+        <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Review the updated Chrome Terms of Service.<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
+      </message>
       <message name="IDS_IOS_OPEN_TABS_NO_SESSION_INSTRUCTIONS" desc="Information about sync displayed when the user has signed in on mobile but not on desktop">
         Access the tabs you have open on your computer, right here. Just open Chrome on your computer, go to the menu, and select “Sign in to Chrome…”
       </message>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1
new file mode 100644
index 0000000..f0a55f7
--- /dev/null
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_REVIEW_UPDATED_CHROME_TOS.png.sha1
@@ -0,0 +1 @@
+a1dc451b6dc7bd77937abf6f333fb88914245f53
\ No newline at end of file
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index ca016f6..c72886e 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -17,6 +17,7 @@
 
   deps = [
     "//base",
+    "//build:branding_buildflags",
     "//components/gcm_driver",
   ]
 }
diff --git a/ios/chrome/browser/chrome_paths.mm b/ios/chrome/browser/chrome_paths.mm
index d206d23..7aa1288 100644
--- a/ios/chrome/browser/chrome_paths.mm
+++ b/ios/chrome/browser/chrome_paths.mm
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
+#include "build/branding_buildflags.h"
 #include "components/gcm_driver/gcm_driver_constants.h"
 #include "ios/chrome/browser/chrome_paths_internal.h"
 
@@ -20,7 +21,7 @@
 namespace ios {
 namespace {
 
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 const base::FilePath::CharType kProductDirName[] =
     FILE_PATH_LITERAL("Google/Chrome");
 #else
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm
index 510c2636..4d4564a 100644
--- a/ios/chrome/browser/context_menu/context_menu_egtest.mm
+++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -162,7 +162,7 @@
 
 @implementation ContextMenuTestCase
 
-// TODO(crbug.com/976259) Disable broken context menu tests on Xcode 11 beta 5.
+// TODO(crbug.com/989550) Disable broken context menu tests on Xcode 11 beta 5.
 + (NSArray*)testInvocations {
   if (@available(iOS 13, *))
     return @[];
diff --git a/ios/chrome/browser/download/BUILD.gn b/ios/chrome/browser/download/BUILD.gn
index 437749b..362b636 100644
--- a/ios/chrome/browser/download/BUILD.gn
+++ b/ios/chrome/browser/download/BUILD.gn
@@ -19,8 +19,6 @@
     "download_manager_tab_helper_delegate.h",
     "google_drive_app_util.h",
     "google_drive_app_util.mm",
-    "pass_kit_mime_type.cc",
-    "pass_kit_mime_type.h",
     "pass_kit_tab_helper.h",
     "pass_kit_tab_helper.mm",
     "pass_kit_tab_helper_delegate.h",
@@ -28,6 +26,10 @@
     "usdz_mime_type.h",
   ]
 
+  public_deps = [
+    ":pass_kit_mime_type",
+  ]
+
   deps = [
     ":features",
     "//base",
@@ -62,6 +64,19 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+source_set("pass_kit_mime_type") {
+  sources = [
+    "pass_kit_mime_type.cc",
+    "pass_kit_mime_type.h",
+  ]
+
+  deps = [
+    "//base",
+  ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 source_set("unit_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
diff --git a/ios/chrome/browser/gcm/BUILD.gn b/ios/chrome/browser/gcm/BUILD.gn
index a442eded..9da2469 100644
--- a/ios/chrome/browser/gcm/BUILD.gn
+++ b/ios/chrome/browser/gcm/BUILD.gn
@@ -9,6 +9,7 @@
   ]
   deps = [
     "//base",
+    "//build:branding_buildflags",
     "//components/gcm_driver",
     "//components/keyed_service/ios",
     "//ios/chrome/browser",
diff --git a/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.cc b/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.cc
index 5f0c50334..d9f040e 100644
--- a/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.cc
+++ b/ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.cc
@@ -10,6 +10,7 @@
 #include "base/no_destructor.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task/post_task.h"
+#include "build/branding_buildflags.h"
 #include "components/gcm_driver/gcm_client_factory.h"
 #include "components/gcm_driver/gcm_profile_service.h"
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
@@ -66,7 +67,7 @@
 
 // static
 std::string IOSChromeGCMProfileServiceFactory::GetProductCategoryForSubtypes() {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   return "com.chrome.ios";
 #else
   return "org.chromium.ios";
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn
index 53e50b4..293fc7b 100644
--- a/ios/chrome/browser/metrics/BUILD.gn
+++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -133,6 +133,7 @@
     ":metrics",
     "//base",
     "//base/test:test_support",
+    "//build:branding_buildflags",
     "//components/metrics",
     "//components/metrics:test_support",
     "//components/network_time:network_time",
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
index 792d173..95344ffe 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h"
+#include "build/branding_buildflags.h"
 
 #include "base/macros.h"
 #include "components/metrics/metrics_pref_names.h"
@@ -26,7 +27,7 @@
 };
 
 TEST_F(IOSChromeMetricsServiceAccessorTest, MetricsReportingEnabled) {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   const char* pref = metrics::prefs::kMetricsReportingEnabled;
   GetLocalState()->SetDefaultPrefValue(pref, base::Value(false));
 
@@ -40,7 +41,7 @@
   EXPECT_FALSE(
       IOSChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 #else
-  // Metrics Reporting is never enabled when GOOGLE_CHROME_BUILD is undefined.
+  // Metrics Reporting is never enabled when GOOGLE_CHROME_BRANDING is not set.
   EXPECT_FALSE(
       IOSChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 #endif
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
index d4bc3147..75aa534 100644
--- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
+++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -44,12 +44,14 @@
 				<integer>0</integer>
 				<integer>1</integer>
 				<integer>2</integer>
+				<integer>3</integer>
 			</array>
 			<key>Titles</key>
 			<array>
 				<string>Default</string>
 				<string>Tip Command Test</string>
 				<string>Tip Move to Dock Promo</string>
+				<string>Tip Review Updated ToS</string>
 			</array>
 		</dict>
 		<dict>
diff --git a/ios/chrome/browser/system_flags.h b/ios/chrome/browser/system_flags.h
index df6fa65..2886990 100644
--- a/ios/chrome/browser/system_flags.h
+++ b/ios/chrome/browser/system_flags.h
@@ -25,6 +25,7 @@
   WHATS_NEW_DEFAULT = 0,         // Not forced to enable a promo.
   WHATS_NEW_TEST_COMMAND_TIP,    // Test Tip that runs a command.
   WHATS_NEW_MOVE_TO_DOCK_TIP,    // Force enable Move To Dock Tip promo.
+  WHATS_NEW_REVIEW_UPDATED_TOS,  // Force enable Review Updated ToS promo.
   WHATS_NEW_PROMO_STATUS_COUNT,  // Count of Whats New Promo Statuses.
 };
 
diff --git a/ios/chrome/browser/ui/authentication/cells/BUILD.gn b/ios/chrome/browser/ui/authentication/cells/BUILD.gn
index b3a7f0d..1d3de93 100644
--- a/ios/chrome/browser/ui/authentication/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/cells/BUILD.gn
@@ -24,6 +24,7 @@
   ]
   deps = [
     "//base",
+    "//build:branding_buildflags",
     "//components/unified_consent",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
index 10114d2..9bdbebb 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
+#include "build/branding_buildflags.h"
 #include "components/signin/public/base/signin_metrics.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_delegate.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
@@ -217,11 +218,11 @@
 - (void)activateColdMode {
   DCHECK_EQ(_mode, SigninPromoViewModeColdState);
   UIImage* logo = nil;
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   logo = [UIImage imageNamed:@"signin_promo_logo_chrome_color"];
 #else
   logo = [UIImage imageNamed:@"signin_promo_logo_chromium_color"];
-#endif  // defined(GOOGLE_CHROME_BUILD)
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
   DCHECK(logo);
   _imageView.image = logo;
   [_primaryButton
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
index 6417a97..c290751 100644
--- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
+++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -579,6 +579,13 @@
 
 // Tests that an alert is presented after a new tab animation is finished.
 - (void)testShowJavaScriptAfterNewTabAnimation {
+  // TODO(crbug.com/989550) Disable broken context menu tests on Xc11b5.
+  if (@available(iOS 13, *)) {
+    if ([ChromeEarlGrey isIPadIdiom]) {
+      EARL_GREY_TEST_DISABLED(@"Test disabled on iPad.");
+    }
+  }
+
   // Load the test page with a link to kOnLoadAlertURL and long tap on the link.
   [self loadPageWithLink];
 
diff --git a/ios/chrome/browser/ui/download/BUILD.gn b/ios/chrome/browser/ui/download/BUILD.gn
index 7e72506..8d0351f 100644
--- a/ios/chrome/browser/ui/download/BUILD.gn
+++ b/ios/chrome/browser/ui/download/BUILD.gn
@@ -104,6 +104,7 @@
 }
 
 source_set("eg_tests") {
+  defines = [ "CHROME_EARL_GREY_1" ]
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
@@ -128,6 +129,7 @@
     "//ios/chrome/test/app:test_support",
     "//ios/chrome/test/earl_grey:test_support",
     "//ios/testing:embedded_test_server_support",
+    "//ios/testing/earl_grey:earl_grey_support",
     "//ios/third_party/earl_grey:earl_grey+link",
     "//ios/web:earl_grey_test_support",
     "//ios/web/public",
@@ -145,10 +147,17 @@
   ]
   testonly = true
 
-  sources = []
+  sources = [
+    "pass_kit_egtest.mm",
+  ]
 
   deps = [
+    "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/browser/download:pass_kit_mime_type",
+    "//ios/chrome/browser/download:test_support",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+    "//ios/third_party/earl_grey2:test_lib",
     "//ios/web/public/test:element_selector",
     "//net:test_support",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/download/pass_kit_egtest.mm b/ios/chrome/browser/ui/download/pass_kit_egtest.mm
index f575718a..f28f333 100644
--- a/ios/chrome/browser/ui/download/pass_kit_egtest.mm
+++ b/ios/chrome/browser/ui/download/pass_kit_egtest.mm
@@ -2,33 +2,36 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <EarlGrey/EarlGrey.h>
 #import <PassKit/PassKit.h>
 
 #include <memory>
 
 #include "base/bind.h"
 #import "base/test/ios/wait_util.h"
-#import "ios/chrome/app/main_controller.h"
 #include "ios/chrome/browser/download/download_test_util.h"
 #include "ios/chrome/browser/download/pass_kit_mime_type.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
-#include "ios/chrome/browser/ui/util/ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
+#if defined(CHROME_EARL_GREY_1)
+// EG1 test relies on view controller presentation as the signal that PassKit
+// Dialog is shown.
+#import "ios/chrome/app/main_controller.h"  // nogncheck
+#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"  // nogncheck
+#import "ios/chrome/test/app/chrome_test_util.h"  // nogncheck
+#endif
+
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 using base::test::ios::WaitUntilConditionOrTimeout;
 using base::test::ios::kWaitForDownloadTimeout;
-using chrome_test_util::GetMainController;
 
 namespace {
 
@@ -104,10 +107,12 @@
   [ChromeEarlGrey tapWebStateElementWithID:@"good"];
 
   // PKAddPassesViewController UI is rendered out of host process so EarlGrey
-  // matcher can not find PassKit Dialog UI. Instead this test relies on view
-  // controller presentation as the signal that PassKit Dialog is shown.
+  // matcher can not find PassKit Dialog UI.
+#if defined(CHROME_EARL_GREY_1)
+  // EG1 test relies on view controller presentation as the signal that PassKit
+  // Dialog is shown.
   id<BrowserInterface> interface =
-      GetMainController().interfaceProvider.mainInterface;
+      chrome_test_util::GetMainController().interfaceProvider.mainInterface;
   UIViewController* viewController = interface.viewController;
   bool dialogShown = WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{
     UIViewController* presentedController =
@@ -115,6 +120,16 @@
     return [presentedController class] == [PKAddPassesViewController class];
   });
   GREYAssert(dialogShown, @"PassKit dialog was not shown");
+#elif defined(CHROME_EARL_GREY_2)
+  // EG2 test can use XCUIApplication API to check for PassKit dialog UI
+  // presentation.
+  XCUIApplication* app = [[XCUIApplication alloc] init];
+  XCUIElement* title = app.otherElements[@"Toy Town Membership"];
+  GREYAssert([title waitForExistenceWithTimeout:kWaitForDownloadTimeout],
+             @"PassKit dialog UI was not presented");
+#else
+#error Must define either CHROME_EARL_GREY_1 or CHROME_EARL_GREY_2.
+#endif
 }
 
 @end
diff --git a/ios/chrome/browser/ui/material_components/BUILD.gn b/ios/chrome/browser/ui/material_components/BUILD.gn
index 39579086..391c14e 100644
--- a/ios/chrome/browser/ui/material_components/BUILD.gn
+++ b/ios/chrome/browser/ui/material_components/BUILD.gn
@@ -15,6 +15,7 @@
   ]
   deps = [
     "//base",
+    "//build:branding_buildflags",
     "//ios/chrome/browser/ui/colors",
     "//ios/chrome/common/colors",
     "//ios/third_party/material_components_ios",
diff --git a/ios/chrome/browser/ui/material_components/activity_indicator.mm b/ios/chrome/browser/ui/material_components/activity_indicator.mm
index e5361fd..88e9988 100644
--- a/ios/chrome/browser/ui/material_components/activity_indicator.mm
+++ b/ios/chrome/browser/ui/material_components/activity_indicator.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/material_components/activity_indicator.h"
 
+#include "build/branding_buildflags.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 
@@ -12,7 +13,7 @@
 #endif
 
 NSArray* ActivityIndicatorBrandedCycleColors() {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   return @[
     [[MDCPalette cr_bluePalette] tint500], [[MDCPalette cr_redPalette] tint500],
     [[MDCPalette cr_yellowPalette] tint500],
diff --git a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
index c5d4539..d112f45 100644
--- a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
+++ b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
@@ -34,7 +34,7 @@
 
 struct PromoStringToIdsMapEntry {
   const char* promo_text_str;
-  // Use |nonlocalized_message| instead of |message_id| if non-NULL.
+  // Use |nonlocalized_message| instead of |message_id| if non-nullptr.
   const char* nonlocalized_message;
   int message_id;
 };
@@ -42,7 +42,8 @@
 // A mapping from a string to a l10n message id.
 const PromoStringToIdsMapEntry kPromoStringToIdsMap[] = {
     {"testWhatsNewCommand", kTestWhatsNewMessage, 0},
-    {"moveToDockTip", NULL, IDS_IOS_MOVE_TO_DOCK_TIP},
+    {"moveToDockTip", nullptr, IDS_IOS_MOVE_TO_DOCK_TIP},
+    {"reviewChromeToS", nullptr, IDS_IOS_REVIEW_UPDATED_CHROME_TOS},
 };
 
 // Returns a localized version of |promo_text| if it has an entry in the
@@ -90,6 +91,10 @@
                       "https://support.google.com/chrome/?p=iphone_dock&ios=1",
                       "MoveToDockTipPromo", "logoWithRoundedRectangle");
       break;
+    case experimental_flags::WHATS_NEW_REVIEW_UPDATED_TOS:
+      InjectFakePromo("3", "reviewChromeToS", "url", "", "chrome://terms",
+                      "ReviewUpdatedChromeToS", "logoWithRoundedRectangle");
+      break;
     default:
       NOTREACHED();
       break;
@@ -275,7 +280,7 @@
                             "  \"promo_id\":$7"
                             "}";
   std::string promo_json_filled_in =
-      base::ReplaceStringPlaceholders(promo_json, replacements, NULL);
+      base::ReplaceStringPlaceholders(promo_json, replacements, nullptr);
 
   base::Optional<base::Value> value =
       base::JSONReader::Read(promo_json_filled_in);
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
index 11863329..a45d707 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
@@ -105,6 +105,11 @@
 }
 
 - (void)testCopyPaste {
+  // TODO(crbug.com/989550) Disable broken system callout tests on Xc11b5.
+  if (@available(iOS 13, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test disabled on iOS13.");
+  }
+
   [self openPage1];
 
   // Long pressing should allow copying.
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
index 62ac29f2..60079ee 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -641,6 +641,8 @@
 void OmniboxViewIOS::WillPaste() {
   if (model())
     model()->OnPaste();
+
+  [field_ exitPreEditState];
 }
 
 // static
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 1c386ca..61ef5a6 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -340,6 +340,7 @@
     ":settings",
     "//base",
     "//base/test:test_support",
+    "//build:branding_buildflags",
     "//components/autofill/core/common",
     "//components/browser_sync",
     "//components/browsing_data/core",
diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm
index 3e92056e..a5c2774 100644
--- a/ios/chrome/browser/ui/settings/settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
@@ -12,6 +12,7 @@
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/task/post_task.h"
+#include "build/branding_buildflags.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/prefs/pref_member.h"
@@ -393,7 +394,7 @@
 // Split here:  Official build vs. Development build.
 // Official builds allow recording and uploading of data, honoring the
 // metrics prefs.  Development builds should never record or upload data.
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Official build.
   // The values of the prefs and the wwan vs wifi state should be honored by
   // the services, turning on and off according to the rules laid out above.
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
index 8655386..838da37 100644
--- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -80,7 +80,12 @@
 // Computes the page from the offset and width of |scrollView|.
 TabGridPage GetPageFromScrollView(UIScrollView* scrollView) {
   CGFloat pageWidth = scrollView.frame.size.width;
-  NSUInteger page = lround(scrollView.contentOffset.x / pageWidth);
+  CGFloat offset = scrollView.contentOffset.x;
+  NSUInteger page = lround(offset / pageWidth);
+  // Fence |page| to valid values; page values of 3 (rounded up from 2.5) are
+  // possible, as are large int values if |pageWidth| is somehow very small.
+  page = page < TabGridPageIncognitoTabs ? TabGridPageIncognitoTabs : page;
+  page = page > TabGridPageRemoteTabs ? TabGridPageRemoteTabs : page;
   if (UseRTLLayout()) {
     // In RTL, page indexes are inverted, so subtract |page| from the highest-
     // index TabGridPage value.
diff --git a/ios/chrome/browser/web/tab_order_egtest.mm b/ios/chrome/browser/web/tab_order_egtest.mm
index 57c643c08..28f296a 100644
--- a/ios/chrome/browser/web/tab_order_egtest.mm
+++ b/ios/chrome/browser/web/tab_order_egtest.mm
@@ -53,6 +53,13 @@
 
 // Tests that new tabs are always inserted after their parent tab.
 - (void)testChildTabOrdering {
+  // TODO(crbug.com/989550) Disable broken context menu tests on Xc11b5.
+  if (@available(iOS 13, *)) {
+    if ([ChromeEarlGrey isIPadIdiom]) {
+      EARL_GREY_TEST_DISABLED(@"Test disabled on iPad.");
+    }
+  }
+
   GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
   const GURL URL1 = self.testServer->GetURL(kLinksTestURL1);
 
diff --git a/ios/chrome/common/BUILD.gn b/ios/chrome/common/BUILD.gn
index 193525e..765e2f7 100644
--- a/ios/chrome/common/BUILD.gn
+++ b/ios/chrome/common/BUILD.gn
@@ -18,6 +18,7 @@
 
   deps = [
     "//base",
+    "//build:branding_buildflags",
     "//components/version_info",
     "//components/version_info:version_string",
     "//ios/chrome/common/app_group:main_app",
diff --git a/ios/chrome/common/channel_info.mm b/ios/chrome/common/channel_info.mm
index 54404e0..3e767c9e 100644
--- a/ios/chrome/common/channel_info.mm
+++ b/ios/chrome/common/channel_info.mm
@@ -9,6 +9,7 @@
 
 #import "base/mac/bundle_locations.h"
 #import "base/strings/sys_string_conversions.h"
+#include "build/branding_buildflags.h"
 #include "components/version_info/version_info.h"
 #include "components/version_info/version_string.h"
 
@@ -18,7 +19,7 @@
 
 namespace {
 
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Channel of the running application, initialized by the first call to
 // GetChannel() and cached for the whole application lifetime.
 version_info::Channel g_channel = version_info::Channel::UNKNOWN;
@@ -31,7 +32,7 @@
 }
 
 std::string GetChannelString() {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Only ever return one of "" (for STABLE channel), "unknown", "beta", "dev"
   // or "canary" in branded build.
   switch (GetChannel()) {
@@ -57,7 +58,7 @@
 }
 
 version_info::Channel GetChannel() {
-#if defined(GOOGLE_CHROME_BUILD)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   static dispatch_once_t channel_dispatch_token;
   dispatch_once(&channel_dispatch_token, ^{
     NSBundle* bundle = base::mac::OuterBundle();
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm
index 4cb85944..920759f0 100644
--- a/ios/web/navigation/crw_session_controller.mm
+++ b/ios/web/navigation/crw_session_controller.mm
@@ -408,8 +408,10 @@
     NSInteger newItemIndex = self.pendingItemIndex;
     if (newItemIndex == -1) {
       [self clearForwardItems];
-      // Add the new item at the end.
-      _items.push_back(std::move(_pendingItem));
+      if (_pendingItem) {
+        // Add the new item at the end.
+        _items.push_back(std::move(_pendingItem));
+      }
       newItemIndex = self.items.size() - 1;
     }
     _previousItemIndex = _lastCommittedItemIndex;
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm
index 9b60ebb5..527071f00 100644
--- a/ios/web/shell/test/context_menu_egtest.mm
+++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -38,7 +38,7 @@
 
 @implementation ContextMenuTestCase
 
-// TODO(crbug.com/976259) Disable broken context menu tests on Xcode 11 beta 5.
+// TODO(crbug.com/989550) Disable broken context menu tests on Xcode 11 beta 5.
 + (NSArray*)testInvocations {
   if (@available(iOS 13, *))
     return @[];
diff --git a/jingle/glue/network_service_config_test_util.cc b/jingle/glue/network_service_config_test_util.cc
index 745b4225..a34b2f1 100644
--- a/jingle/glue/network_service_config_test_util.cc
+++ b/jingle/glue/network_service_config_test_util.cc
@@ -44,7 +44,7 @@
 
 NetworkServiceConfigTestUtil::NetworkServiceConfigTestUtil(
     NetworkContextGetter network_context_getter)
-    : net_runner_(base::CreateSingleThreadTaskRunnerWithTraits({})),
+    : net_runner_(base::CreateSingleThreadTaskRunner({base::ThreadPool()})),
       mojo_runner_(base::SequencedTaskRunnerHandle::Get()),
       network_context_getter_(network_context_getter),
       weak_ptr_factory_(this) {}
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
index 13fad5d7..74ae897 100644
--- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni
+++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -5,7 +5,7 @@
 _typemap_imports = [
   "//chrome/chrome_cleaner/mojom/typemaps/typemaps.gni",
   "//chrome/common/importer/typemaps.gni",
-  "//chrome/common/media_router/mojo/typemaps.gni",
+  "//chrome/common/media_router/mojom/typemaps.gni",
   "//chrome/typemaps.gni",
   "//chromecast/typemaps.gni",
   "//chromeos/typemaps.gni",
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc
index ac46244..b7bba50 100644
--- a/net/disk_cache/backend_unittest.cc
+++ b/net/disk_cache/backend_unittest.cc
@@ -4992,12 +4992,26 @@
 }
 
 TEST_F(DiskCacheBackendTest, SimpleOwnershipTransferBackendDestroyRace) {
+  struct CleanupContext {
+    explicit CleanupContext(bool* ran_ptr) : ran_ptr(ran_ptr) {}
+    ~CleanupContext() {
+      *ran_ptr = true;
+      // A realistic CleanupContext would call Close on non-null,
+      // which would be a double-Close when what this is testing was broken.
+      // Here, just check for expected case.
+      EXPECT_EQ(owned_entry, nullptr);
+    }
+
+    bool* ran_ptr;
+    disk_cache::Entry* owned_entry = nullptr;
+  };
+
   const char kKey[] = "skeleton";
 
   // See https://crbug.com/946349
   // This tests that if the SimpleBackendImpl is destroyed after SimpleEntryImpl
   // decides to return an entry to the caller, but before the callback is run
-  // that no entry is leaked.
+  // that no entry is leaked, and that the out pointer is not written to.
   SetSimpleCacheMode();
   InitCache();
 
@@ -5006,11 +5020,30 @@
   // Make sure create actually succeeds, not just optimistically.
   RunUntilIdle();
 
-  disk_cache::Entry* alias = nullptr;
-  // This is relying on the alias code resulting in synchronous posting of async
-  // result, so that backend destruction can be neatly slotted in between.
+  bool cleanup_context_ran = false;
+  auto cleanup_context = std::make_unique<CleanupContext>(&cleanup_context_ran);
+  disk_cache::Entry** dest = &cleanup_context->owned_entry;
+
+  // The OpenEntry code below will find a pre-existing entry in a READY state,
+  // so it will immediately post a task to return a result. Destroying the
+  // backend before running the event loop again will run that callback in the
+  // dead-backend state, while OpenEntry completion was still with it alive.
+
   EXPECT_EQ(net::ERR_IO_PENDING,
-            cache_->OpenEntry(kKey, net::HIGHEST, &alias, base::DoNothing()));
+            cache_->OpenEntry(
+                kKey, net::HIGHEST, dest,
+                base::BindOnce(
+                    [](std::unique_ptr<CleanupContext>, int net_status) {
+                      // The callback is here for ownership of CleanupContext,
+                      // and it shouldn't get invoked in this test.
+                      ADD_FAILURE() << "This should not actually run";
+                    },
+                    std::move(cleanup_context))));
   cache_.reset();
+
+  // Give CleanupContext a chance to do its thing.
+  RunUntilIdle();
+  EXPECT_TRUE(cleanup_context_ran);
+
   entry->Close();
 }
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index 20fc2869..c147a4b 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -95,21 +95,6 @@
   std::move(completion_callback).Run(result);
 }
 
-void InvokeCallbackIfBackendIsAliveOrCloseEntry(
-    const base::WeakPtr<SimpleBackendImpl>& backend,
-    SimpleEntryImpl* entry,
-    net::CompletionOnceCallback completion_callback) {
-  DCHECK(!completion_callback.is_null());
-  if (!backend.get()) {
-    // Backend got destroyed while |entry| was in process of being transferred
-    // to client ownership. Give up on that.
-    entry->Close();
-    return;
-  }
-
-  std::move(completion_callback).Run(net::OK);
-}
-
 // If |sync_possible| is false, and callback is available, posts rv to it and
 // return net::ERR_IO_PENDING; otherwise just passes through rv.
 int PostToCallbackIfNeeded(bool sync_possible,
@@ -701,39 +686,52 @@
 }
 
 void SimpleEntryImpl::ReturnEntryToCaller(Entry** out_entry) {
+  DCHECK(backend_);
   DCHECK(out_entry);
   ++open_count_;
   AddRef();  // Balanced in Close()
-  if (!backend_.get()) {
-    // This method can be called when an asynchronous operation completed.
-    // If the backend no longer exists, the callback won't be invoked, and so we
-    // must close ourselves to avoid leaking. As well, there's no guarantee the
-    // client-provided pointer (|out_entry|) hasn't been freed, and no point
-    // dereferencing it, either.
-    Close();
-    return;
-  }
   *out_entry = this;
 }
 
-void SimpleEntryImpl::ReturnEntryToCallerAndPostCallback(
+void SimpleEntryImpl::ReturnEntryToCallerAsync(
     Entry** out_entry,
+    bool* out_opened,
+    bool opened,
     CompletionOnceCallback callback) {
   DCHECK(!callback.is_null());
-  ReturnEntryToCaller(out_entry);
-  if (!backend_.get())
-    return;  // ReturnEntryToCaller takes care of case of already-dead backend_.
+  DCHECK(out_entry);
+
+  // |open_count_| must be incremented immediately, so that a Close on an alias
+  // doesn't try to wrap things up.
+  ++open_count_;
 
   // Note that the callback is posted rather than directly invoked to avoid
-  // reentrancy issues. Unretained(this) is safe since ReturnEntryToCaller
-  // increments the reference count; this effect is also why this chooses to
-  // potentially call ReturnEntryToCaller and then roll it back rather than
-  // delay ReturnEntryToCaller: it protects |this| till any potential ownership
-  // share transfer is sorted out.
+  // reentrancy issues.
   base::SequencedTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::BindOnce(&InvokeCallbackIfBackendIsAliveOrCloseEntry, backend_,
-                     base::Unretained(this), std::move(callback)));
+      base::BindOnce(&SimpleEntryImpl::FinishReturnEntryToCallerAsync, this,
+                     out_entry, out_opened, opened, std::move(callback)));
+}
+
+void SimpleEntryImpl::FinishReturnEntryToCallerAsync(
+    Entry** out_entry,
+    bool* out_opened,
+    bool opened,
+    CompletionOnceCallback callback) {
+  AddRef();  // Balanced in Close()
+  if (!backend_.get()) {
+    // With backend dead, Open/Create operations are responsible for cleaning up
+    // the entry --- the ownership is never transferred to the caller, and their
+    // callback isn't invoked.
+    Close();
+    return;
+  }
+
+  *out_entry = this;
+  if (out_opened)
+    *out_opened = opened;
+
+  std::move(callback).Run(net::OK);
 }
 
 void SimpleEntryImpl::MarkAsDoomed(DoomState new_state) {
@@ -806,7 +804,8 @@
   net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_BEGIN);
 
   if (state_ == STATE_READY) {
-    ReturnEntryToCallerAndPostCallback(out_entry, std::move(callback));
+    ReturnEntryToCallerAsync(out_entry, /* out_opened = */ nullptr,
+                             /* opened = */ true, std::move(callback));
     NetLogSimpleEntryCreation(net_log_,
                               net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END,
                               net::NetLogEventPhase::NONE, this, net::OK);
@@ -907,9 +906,8 @@
   DCHECK(entry_struct != nullptr || state_ == STATE_UNINITIALIZED);
 
   if (state_ == STATE_READY) {
-    entry_struct->opened = true;
-    ReturnEntryToCallerAndPostCallback(&entry_struct->entry,
-                                       std::move(callback));
+    ReturnEntryToCallerAsync(&entry_struct->entry, &entry_struct->opened,
+                             /* opened = */ true, std::move(callback));
     NetLogSimpleEntryCreation(
         net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END,
         net::NetLogEventPhase::NONE, this, net::OK);
@@ -1472,12 +1470,6 @@
   if (backend_ && doom_state_ == DOOM_NONE)
     backend_->index()->Insert(entry_hash_);
 
-  // Access to out_opened must be guarded by backend_ check since there is no
-  // requirement to keep this alive past backend destruction, as the callback
-  // will not be invoked.
-  if (backend_ && out_opened)
-    *out_opened = !in_results->created;
-
   state_ = STATE_READY;
   synchronous_entry_ = in_results->sync_entry;
 
@@ -1528,9 +1520,10 @@
   // out_entry is nullptr and there is no callback, or should be returned
   // to out_entry with callback invoked.
   DCHECK_EQ(out_entry == nullptr, completion_callback.is_null());
-  if (out_entry)
-    ReturnEntryToCallerAndPostCallback(out_entry,
-                                       std::move(completion_callback));
+  if (out_entry) {
+    ReturnEntryToCallerAsync(out_entry, out_opened, !in_results->created,
+                             std::move(completion_callback));
+  }
 }
 
 void SimpleEntryImpl::EntryOperationComplete(
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h
index cae5d5d..271746c 100644
--- a/net/disk_cache/simple/simple_entry_impl.h
+++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -214,10 +214,21 @@
   // count.
   void ReturnEntryToCaller(Entry** out_entry);
 
-  // Like above, but also invokes the result callback (with net::OK), making
-  // sure to handle the backend being deleted in the interim.
-  void ReturnEntryToCallerAndPostCallback(Entry** out_entry,
-                                          CompletionOnceCallback callback);
+  // Like above, but for asynchronous return after the event loop runs again,
+  // also invoking the callback per the usual net convention.
+  // The return is cancelled if the backend is deleted in the interim.
+  //
+  // |out_opened| may be null.
+  void ReturnEntryToCallerAsync(Entry** out_entry,
+                                bool* out_opened,
+                                bool opened,
+                                CompletionOnceCallback callback);
+
+  // Portion of the above that runs off the event loop.
+  void FinishReturnEntryToCallerAsync(Entry** out_entry,
+                                      bool* out_opened,
+                                      bool opened,
+                                      CompletionOnceCallback callback);
 
   // Remove |this| from the Backend and the index, either because
   // SimpleSynchronousEntry has detected an error or because we are about to
diff --git a/pdf/pdfium/accessibility_unittest.cc b/pdf/pdfium/accessibility_unittest.cc
index d8036667..a02b6c7 100644
--- a/pdf/pdfium/accessibility_unittest.cc
+++ b/pdf/pdfium/accessibility_unittest.cc
@@ -9,7 +9,7 @@
 #include "pdf/pdfium/pdfium_test_base.h"
 #include "pdf/test/test_client.h"
 #include "ppapi/c/private/ppb_pdf.h"
-#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_CHROMEOS)
 #include "base/system/sys_info.h"
diff --git a/pdf/pdfium/pdfium_engine_exports_unittest.cc b/pdf/pdfium/pdfium_engine_exports_unittest.cc
index ed3e31c3..f1c99b32 100644
--- a/pdf/pdfium/pdfium_engine_exports_unittest.cc
+++ b/pdf/pdfium/pdfium_engine_exports_unittest.cc
@@ -8,7 +8,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "gin/v8_initializer.h"
 #include "pdf/pdf.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
diff --git a/remoting/host/file_transfer/local_file_operations.cc b/remoting/host/file_transfer/local_file_operations.cc
index 844f496..c362f922 100644
--- a/remoting/host/file_transfer/local_file_operations.cc
+++ b/remoting/host/file_transfer/local_file_operations.cc
@@ -50,12 +50,12 @@
   // logged-in user, while the process as a whole runs as SYSTEM. Since user
   // impersonation is per-thread on Windows, we need a dedicated thread to
   // ensure that no other code is accidentally run with the wrong privileges.
-  return base::CreateSingleThreadTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+  return base::CreateSingleThreadTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
       base::SingleThreadTaskRunnerThreadMode::DEDICATED);
 #else
-  return base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+  return base::CreateSequencedTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 #endif
 }
 
diff --git a/remoting/host/it2me/it2me_native_messaging_host_chromeos.cc b/remoting/host/it2me/it2me_native_messaging_host_chromeos.cc
index 16c9ac0..be1b304d 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_chromeos.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_chromeos.cc
@@ -25,8 +25,9 @@
   std::unique_ptr<ChromotingHostContext> context =
       ChromotingHostContext::CreateForChromeOS(
           io_runnner, ui_runnner,
-          base::CreateSingleThreadTaskRunnerWithTraits(
-              {base::MayBlock(), base::TaskPriority::BEST_EFFORT}));
+          base::CreateSingleThreadTaskRunner(
+              {base::ThreadPool(), base::MayBlock(),
+               base::TaskPriority::BEST_EFFORT}));
   std::unique_ptr<PolicyWatcher> policy_watcher =
       PolicyWatcher::CreateWithPolicyService(policy_service);
   std::unique_ptr<extensions::NativeMessageHost> host(
diff --git a/remoting/protocol/webrtc_video_renderer_adapter.cc b/remoting/protocol/webrtc_video_renderer_adapter.cc
index 54e752ad..7f8e9e2 100644
--- a/remoting/protocol/webrtc_video_renderer_adapter.cc
+++ b/remoting/protocol/webrtc_video_renderer_adapter.cc
@@ -176,8 +176,9 @@
       video_renderer_->GetFrameConsumer()->AllocateFrame(
           webrtc::DesktopSize(frame->width(), frame->height()));
 
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+  base::PostTaskAndReplyWithResult(
+      FROM_HERE,
+      {base::ThreadPool(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::Bind(&ConvertYuvToRgb, base::Passed(&frame),
                  base::Passed(&rgb_frame),
                  video_renderer_->GetFrameConsumer()->GetPixelFormat()),
diff --git a/remoting/signaling/ftl_messaging_client_unittest.cc b/remoting/signaling/ftl_messaging_client_unittest.cc
index f708975..036271ff 100644
--- a/remoting/signaling/ftl_messaging_client_unittest.cc
+++ b/remoting/signaling/ftl_messaging_client_unittest.cc
@@ -171,7 +171,7 @@
 
 void FtlMessagingClientTest::SetUp() {
   server_task_runner_ =
-      base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
+      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()});
   server_ = std::make_unique<test::GrpcAsyncTestServer>(
       std::make_unique<Messaging::AsyncService>());
   FtlGrpcContext::SetChannelForTesting(server_->CreateInProcessChannel());
diff --git a/remoting/test/cli_util.cc b/remoting/test/cli_util.cc
index c33460d..c65440a3 100644
--- a/remoting/test/cli_util.cc
+++ b/remoting/test/cli_util.cc
@@ -92,9 +92,9 @@
 }
 
 void WaitForEnterKey(base::OnceClosure on_done) {
-  base::PostTaskWithTraitsAndReply(FROM_HERE, {base::MayBlock()},
-                                   base::BindOnce([]() { getchar(); }),
-                                   std::move(on_done));
+  base::PostTaskAndReply(FROM_HERE, {base::ThreadPool(), base::MayBlock()},
+                         base::BindOnce([]() { getchar(); }),
+                         std::move(on_done));
 }
 
 }  // namespace test
diff --git a/rlz/lib/financial_ping.cc b/rlz/lib/financial_ping.cc
index 80b9e07..84de7c1 100644
--- a/rlz/lib/financial_ping.cc
+++ b/rlz/lib/financial_ping.cc
@@ -260,9 +260,9 @@
   // How frequently the financial ping thread should check
   // the shutdown condition?
   const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(500);
-  base::PostDelayedTaskWithTraits(FROM_HERE, {base::TaskPriority::BEST_EFFORT},
-                                  base::BindOnce(&ShutdownCheck, event),
-                                  kInterval);
+  base::PostDelayedTask(FROM_HERE,
+                        {base::ThreadPool(), base::TaskPriority::BEST_EFFORT},
+                        base::BindOnce(&ShutdownCheck, event), kInterval);
 }
 #endif
 
@@ -390,15 +390,16 @@
 
   base::subtle::Release_Store(&g_cancelShutdownCheck, 0);
 
-  base::PostTaskWithTraits(FROM_HERE, {base::TaskPriority::BEST_EFFORT},
-                           base::BindOnce(&ShutdownCheck, event));
+  base::PostTask(FROM_HERE,
+                 {base::ThreadPool(), base::TaskPriority::BEST_EFFORT},
+                 base::BindOnce(&ShutdownCheck, event));
 
   // PingRlzServer must be run in a separate sequence so that the TimedWait()
   // call below does not block the URL fetch response from being handled by
   // the URL delegate.
   scoped_refptr<base::SequencedTaskRunner> background_runner(
-      base::CreateSequencedTaskRunnerWithTraits(
-          {base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
+      base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
            base::TaskPriority::BEST_EFFORT}));
   background_runner->PostTask(FROM_HERE,
                               base::BindOnce(&PingRlzServer, url, event));
diff --git a/services/audio/public/cpp/debug_recording_session.cc b/services/audio/public/cpp/debug_recording_session.cc
index 562b6cc..9307d6e07 100644
--- a/services/audio/public/cpp/debug_recording_session.cc
+++ b/services/audio/public/cpp/debug_recording_session.cc
@@ -50,9 +50,9 @@
     media::AudioDebugRecordingStreamType stream_type,
     uint32_t id,
     CreateWavFileCallback reply_callback) {
-  base::PostTaskWithTraitsAndReplyWithResult(
+  base::PostTaskAndReplyWithResult(
       FROM_HERE,
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
       base::BindOnce(
           [](const base::FilePath& file_name) {
diff --git a/services/device/device_service.cc b/services/device/device_service.cc
index 180e5514..8ba0500f 100644
--- a/services/device/device_service.cc
+++ b/services/device/device_service.cc
@@ -194,8 +194,8 @@
   // blocking IO.
   serial_port_manager_ = std::make_unique<SerialPortManagerImpl>(
       io_task_runner_, base::ThreadTaskRunnerHandle::Get());
-  serial_port_manager_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+  serial_port_manager_task_runner_ = base::CreateSequencedTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT});
   registry_.AddInterface<mojom::SerialPortManager>(
       base::BindRepeating(&SerialPortManagerImpl::Bind,
                           base::Unretained(serial_port_manager_.get())),
diff --git a/services/device/device_service_test_base.cc b/services/device/device_service_test_base.cc
index fc8dbf1..a77de49b4 100644
--- a/services/device/device_service_test_base.cc
+++ b/services/device/device_service_test_base.cc
@@ -54,10 +54,11 @@
 }  // namespace
 
 DeviceServiceTestBase::DeviceServiceTestBase()
-    : file_task_runner_(base::CreateSingleThreadTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::BEST_EFFORT})),
-      io_task_runner_(base::CreateSingleThreadTaskRunnerWithTraits(
-          {base::TaskPriority::USER_VISIBLE})),
+    : file_task_runner_(base::CreateSingleThreadTaskRunner(
+          {base::ThreadPool(), base::MayBlock(),
+           base::TaskPriority::BEST_EFFORT})),
+      io_task_runner_(base::CreateSingleThreadTaskRunner(
+          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE})),
       network_connection_tracker_(
           network::TestNetworkConnectionTracker::CreateInstance()),
       connector_(test_connector_factory_.CreateConnector()) {}
diff --git a/services/device/generic_sensor/platform_sensor_provider_linux.cc b/services/device/generic_sensor/platform_sensor_provider_linux.cc
index dfbc2ad..cd72ab2 100644
--- a/services/device/generic_sensor/platform_sensor_provider_linux.cc
+++ b/services/device/generic_sensor/platform_sensor_provider_linux.cc
@@ -25,7 +25,7 @@
 namespace {
 
 constexpr base::TaskTraits kBlockingTaskRunnerTraits = {
-    base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+    base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
     base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
 
 bool IsFusionSensorType(mojom::SensorType type) {
@@ -46,7 +46,7 @@
     : sensor_nodes_enumerated_(false),
       sensor_nodes_enumeration_started_(false),
       blocking_task_runner_(
-          base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskRunnerTraits)),
+          base::CreateSequencedTaskRunner(kBlockingTaskRunnerTraits)),
       sensor_device_manager_(nullptr,
                              base::OnTaskRunnerDeleter(blocking_task_runner_)) {
   sensor_device_manager_.reset(
diff --git a/services/device/generic_sensor/platform_sensor_provider_win.cc b/services/device/generic_sensor/platform_sensor_provider_win.cc
index 5d7af8d1d..75cbdb42 100644
--- a/services/device/generic_sensor/platform_sensor_provider_win.cc
+++ b/services/device/generic_sensor/platform_sensor_provider_win.cc
@@ -22,8 +22,8 @@
 namespace device {
 
 PlatformSensorProviderWin::PlatformSensorProviderWin()
-    : com_sta_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
-          base::TaskPriority::USER_VISIBLE)) {}
+    : com_sta_task_runner_(base::CreateCOMSTATaskRunner(
+          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE})) {}
 
 PlatformSensorProviderWin::~PlatformSensorProviderWin() = default;
 
diff --git a/services/device/generic_sensor/platform_sensor_provider_winrt.cc b/services/device/generic_sensor/platform_sensor_provider_winrt.cc
index b7919c9..7d38cb4 100644
--- a/services/device/generic_sensor/platform_sensor_provider_winrt.cc
+++ b/services/device/generic_sensor/platform_sensor_provider_winrt.cc
@@ -22,8 +22,8 @@
 }
 
 PlatformSensorProviderWinrt::PlatformSensorProviderWinrt()
-    : com_sta_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
-          base::TaskPriority::USER_VISIBLE)),
+    : com_sta_task_runner_(base::CreateCOMSTATaskRunner(
+          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE})),
       sensor_reader_factory_(std::make_unique<SensorReaderFactory>()) {}
 
 PlatformSensorProviderWinrt::~PlatformSensorProviderWinrt() = default;
@@ -102,4 +102,4 @@
   return sensor_reader_factory_->CreateSensorReader(type);
 }
 
-}  // namespace device
\ No newline at end of file
+}  // namespace device
diff --git a/services/device/generic_sensor/platform_sensor_reader_linux.cc b/services/device/generic_sensor/platform_sensor_reader_linux.cc
index f3242ee3..8fd9eaab1 100644
--- a/services/device/generic_sensor/platform_sensor_reader_linux.cc
+++ b/services/device/generic_sensor/platform_sensor_reader_linux.cc
@@ -91,8 +91,9 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_ =
-      base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+      base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::MayBlock(),
+           base::TaskPriority::USER_VISIBLE,
            base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
 
   std::unique_ptr<BlockingTaskRunnerHelper, base::OnTaskRunnerDeleter>
diff --git a/services/device/geolocation/wifi_data_provider_win_unittest.cc b/services/device/geolocation/wifi_data_provider_win_unittest.cc
index c05cc250..f3a3476 100644
--- a/services/device/geolocation/wifi_data_provider_win_unittest.cc
+++ b/services/device/geolocation/wifi_data_provider_win_unittest.cc
@@ -6,14 +6,16 @@
 // WifiDataProviderCommon and covered by it's unit tests.
 
 #include "services/device/geolocation/wifi_data_provider_win.h"
-#include "base/message_loop/message_loop.h"
+
+#include "base/test/scoped_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace device {
 
 TEST(GeolocationWifiDataProviderWinTest, CreateDestroy) {
   // WifiDataProvider requires a task runner to be present.
-  base::MessageLoopForUI message_loop_;
+  base::test::ScopedTaskEnvironment scoped_task_environment(
+      base::test::ScopedTaskEnvironment::MainThreadType::UI);
   scoped_refptr<WifiDataProviderWin> instance(new WifiDataProviderWin);
   instance = NULL;
   SUCCEED();
diff --git a/services/device/hid/hid_connection_mac.cc b/services/device/hid/hid_connection_mac.cc
index e3ff2ed1..a95ab92 100644
--- a/services/device/hid/hid_connection_mac.cc
+++ b/services/device/hid/hid_connection_mac.cc
@@ -32,8 +32,8 @@
     : HidConnection(device_info),
       device_(std::move(device)),
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          HidService::kBlockingTaskTraits)) {
+      blocking_task_runner_(
+          base::CreateSequencedTaskRunner(HidService::kBlockingTaskTraits)) {
   IOHIDDeviceScheduleWithRunLoop(device_.get(), CFRunLoopGetMain(),
                                  kCFRunLoopDefaultMode);
 
diff --git a/services/device/hid/hid_service.h b/services/device/hid/hid_service.h
index b1af0ac..f5f40e0 100644
--- a/services/device/hid/hid_service.h
+++ b/services/device/hid/hid_service.h
@@ -48,7 +48,7 @@
       base::Callback<void(scoped_refptr<HidConnection> connection)>;
 
   static constexpr base::TaskTraits kBlockingTaskTraits = {
-      base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+      base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
 
   // This function should be called on a thread with a MessageLoopForUI.
diff --git a/services/device/hid/hid_service_linux.cc b/services/device/hid/hid_service_linux.cc
index 926077f..92b57f0 100644
--- a/services/device/hid/hid_service_linux.cc
+++ b/services/device/hid/hid_service_linux.cc
@@ -56,7 +56,7 @@
         callback(callback),
         task_runner(base::SequencedTaskRunnerHandle::Get()),
         blocking_task_runner(
-            base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)) {}
+            base::CreateSequencedTaskRunner(kBlockingTaskTraits)) {}
   ~ConnectParams() {}
 
   scoped_refptr<HidDeviceInfo> device_info;
@@ -194,7 +194,7 @@
 
 HidServiceLinux::HidServiceLinux()
     : blocking_task_runner_(
-          base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)),
+          base::CreateSequencedTaskRunner(kBlockingTaskTraits)),
       helper_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)) {
   // We need to properly initialize |blocking_task_helper_| here because we need
   // |weak_factory_| to be created first.
diff --git a/services/device/hid/hid_service_mac.cc b/services/device/hid/hid_service_mac.cc
index cea770a..f83c76a3 100644
--- a/services/device/hid/hid_service_mac.cc
+++ b/services/device/hid/hid_service_mac.cc
@@ -136,7 +136,7 @@
     return;
   }
 
-  base::PostTaskWithTraitsAndReplyWithResult(
+  base::PostTaskAndReplyWithResult(
       FROM_HERE, kBlockingTaskTraits,
       base::BindOnce(&HidServiceMac::OpenOnBlockingThread, map_entry->second),
       base::BindOnce(&HidServiceMac::DeviceOpened, weak_factory_.GetWeakPtr(),
diff --git a/services/device/hid/hid_service_win.cc b/services/device/hid/hid_service_win.cc
index 576ed6ec..86b717a 100644
--- a/services/device/hid/hid_service_win.cc
+++ b/services/device/hid/hid_service_win.cc
@@ -34,7 +34,7 @@
 HidServiceWin::HidServiceWin()
     : task_runner_(base::SequencedTaskRunnerHandle::Get()),
       blocking_task_runner_(
-          base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)),
+          base::CreateSequencedTaskRunner(kBlockingTaskTraits)),
       device_observer_(this),
       weak_factory_(this) {
   DeviceMonitorWin* device_monitor =
diff --git a/services/device/serial/serial_io_handler.cc b/services/device/serial/serial_io_handler.cc
index a29ffbc..4e77def 100644
--- a/services/device/serial/serial_io_handler.cc
+++ b/services/device/serial/serial_io_handler.cc
@@ -65,11 +65,11 @@
                      base::BindRepeating(&SerialIoHandler::OnPathOpenError,
                                          this, task_runner)));
 #else
-  base::PostTaskWithTraits(
-      FROM_HERE,
-      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-      base::BindOnce(&SerialIoHandler::StartOpen, this,
-                     base::ThreadTaskRunnerHandle::Get()));
+  base::PostTask(FROM_HERE,
+                 {base::ThreadPool(), base::MayBlock(),
+                  base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+                 base::BindOnce(&SerialIoHandler::StartOpen, this,
+                                base::ThreadTaskRunnerHandle::Get()));
 #endif  // defined(OS_CHROMEOS)
 }
 
@@ -163,9 +163,10 @@
 
 void SerialIoHandler::Close(base::OnceClosure callback) {
   if (file_.IsValid()) {
-    base::PostTaskWithTraitsAndReply(
+    base::PostTaskAndReply(
         FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
         base::BindOnce(&SerialIoHandler::DoClose, std::move(file_)),
         std::move(callback));
   }
diff --git a/services/device/usb/usb_service.cc b/services/device/usb/usb_service.cc
index 4c40740..664ab0e7e 100644
--- a/services/device/usb/usb_service.cc
+++ b/services/device/usb/usb_service.cc
@@ -64,7 +64,7 @@
 // static
 scoped_refptr<base::SequencedTaskRunner>
 UsbService::CreateBlockingTaskRunner() {
-  return base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits);
+  return base::CreateSequencedTaskRunner(kBlockingTaskTraits);
 }
 
 UsbService::~UsbService() {
diff --git a/services/device/usb/usb_service.h b/services/device/usb/usb_service.h
index 9574231..9436f3b 100644
--- a/services/device/usb/usb_service.h
+++ b/services/device/usb/usb_service.h
@@ -53,7 +53,7 @@
   // These task traits are to be used for posting blocking tasks to the task
   // scheduler.
   static constexpr base::TaskTraits kBlockingTaskTraits = {
-      base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+      base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
 
   // Returns nullptr when initialization fails.
diff --git a/services/device/usb/usb_service_impl.cc b/services/device/usb/usb_service_impl.cc
index 975bc33..08b6516 100644
--- a/services/device/usb/usb_service_impl.cc
+++ b/services/device/usb/usb_service_impl.cc
@@ -226,7 +226,7 @@
 #endif
       weak_factory_(this) {
   weak_self_ = weak_factory_.GetWeakPtr();
-  base::PostTaskWithTraitsAndReplyWithResult(
+  base::PostTaskAndReplyWithResult(
       FROM_HERE, kBlockingTaskTraits,
       base::BindOnce(&InitializeUsbContextBlocking),
       base::BindOnce(&UsbServiceImpl::OnUsbContext,
@@ -326,7 +326,7 @@
     pending_path_enumerations_.pop();
   }
 
-  base::PostTaskWithTraitsAndReplyWithResult(
+  base::PostTaskAndReplyWithResult(
       FROM_HERE, kBlockingTaskTraits,
       base::BindOnce(&GetDeviceListBlocking, device_path, context_),
       base::BindOnce(&UsbServiceImpl::OnDeviceList,
diff --git a/services/file/file_service.cc b/services/file/file_service.cc
index cd7fa5b3..bf05403 100644
--- a/services/file/file_service.cc
+++ b/services/file/file_service.cc
@@ -81,10 +81,12 @@
 FileService::FileService(
     mojo::PendingReceiver<service_manager::mojom::Service> receiver)
     : service_binding_(this, std::move(receiver)),
-      file_service_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
-      leveldb_service_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) {
+      file_service_runner_(base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::MayBlock(),
+           base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
+      leveldb_service_runner_(base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::MayBlock(),
+           base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) {
   binders_.Add<leveldb::mojom::LevelDBService>(base::BindRepeating(
       &FileService::BindLevelDBServiceReceiver, base::Unretained(this)));
   binders_.Add<mojom::FileSystem>(base::BindRepeating(
diff --git a/services/image_annotation/public/cpp/image_processor.cc b/services/image_annotation/public/cpp/image_processor.cc
index c22bcbf..14fd36659 100644
--- a/services/image_annotation/public/cpp/image_processor.cc
+++ b/services/image_annotation/public/cpp/image_processor.cc
@@ -79,8 +79,9 @@
 
 ImageProcessor::ImageProcessor(base::RepeatingCallback<SkBitmap()> get_pixels)
     : get_pixels_(std::move(get_pixels)),
-      background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}
+      background_task_runner_(
+          base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                           base::TaskPriority::BEST_EFFORT})) {}
 
 ImageProcessor::~ImageProcessor() = default;
 
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc
index ead50df..d358662a 100644
--- a/services/network/cookie_manager_unittest.cc
+++ b/services/network/cookie_manager_unittest.cc
@@ -2136,7 +2136,7 @@
 
  private:
   const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
-      base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
+      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()});
   base::ScopedTempDir temp_dir_;
 };
 
diff --git a/services/network/crl_set_distributor.cc b/services/network/crl_set_distributor.cc
index 346ac954..17a6160 100644
--- a/services/network/crl_set_distributor.cc
+++ b/services/network/crl_set_distributor.cc
@@ -45,8 +45,8 @@
   std::string crl_set_string(reinterpret_cast<const char*>(crl_set.data()),
                              crl_set.size());
 
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::TaskPriority::BEST_EFFORT},
+  base::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::ThreadPool(), base::TaskPriority::BEST_EFFORT},
       base::BindOnce(&ParseCRLSet, std::move(crl_set_string)),
       base::BindOnce(&CRLSetDistributor::OnCRLSetParsed,
                      weak_factory_.GetWeakPtr()));
diff --git a/services/network/net_log_exporter.cc b/services/network/net_log_exporter.cc
index cc22a62..bcac474 100644
--- a/services/network/net_log_exporter.cc
+++ b/services/network/net_log_exporter.cc
@@ -60,9 +60,10 @@
   static_assert(kUnlimitedFileSize == net::FileNetLogObserver::kNoLimit,
                 "Inconsistent unbounded size constants");
   if (max_file_size != kUnlimitedFileSize) {
-    base::PostTaskWithTraitsAndReplyWithResult(
+    base::PostTaskAndReplyWithResult(
         FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
         base::BindOnce(&NetLogExporter::CreateScratchDir,
                        scratch_dir_create_handler_for_tests_),
 
@@ -111,9 +112,10 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (file.IsValid()) {
-    base::PostTaskWithTraits(
+    base::PostTask(
         FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
         base::BindOnce([](base::File f) { f.Close(); }, std::move(file)));
   }
 }
@@ -146,17 +148,17 @@
   } else if (!scratch_dir_path.empty()) {
     // An NetLogExporter got destroyed while it was trying to create a scratch
     // dir.
-    base::PostTaskWithTraits(
-        FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
-        base::BindOnce(
-            [](const base::FilePath& dir) {
-              // The delete is non-recursive (2nd argument false) since the
-              // only time this is invoked the directory is expected to be
-              // empty.
-              base::DeleteFile(dir, false);
-            },
-            scratch_dir_path));
+    base::PostTask(FROM_HERE,
+                   {base::ThreadPool(), base::MayBlock(),
+                    base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+                   base::BindOnce(
+                       [](const base::FilePath& dir) {
+                         // The delete is non-recursive (2nd argument
+                         // false) since the only time this is invoked
+                         // the directory is expected to be empty.
+                         base::DeleteFile(dir, false);
+                       },
+                       scratch_dir_path));
   }
 }
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index d550c0e..b1108bb 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1730,11 +1730,11 @@
     scoped_refptr<base::SequencedTaskRunner> client_task_runner =
         base::ThreadTaskRunnerHandle::Get();
     scoped_refptr<base::SequencedTaskRunner> background_task_runner =
-        base::CreateSequencedTaskRunnerWithTraits(
-            {base::MayBlock(), net::GetCookieStoreBackgroundSequencePriority(),
+        base::CreateSequencedTaskRunner(
+            {base::ThreadPool(), base::MayBlock(),
+             net::GetCookieStoreBackgroundSequencePriority(),
              base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
 
-
     net::CookieCryptoDelegate* crypto_delegate = nullptr;
     if (params_->enable_encrypted_cookies) {
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(IS_CHROMECAST)
@@ -1822,11 +1822,12 @@
 
   std::unique_ptr<PrefService> pref_service;
   if (params_->http_server_properties_path) {
-    scoped_refptr<JsonPrefStore> json_pref_store(new JsonPrefStore(
-        *params_->http_server_properties_path, nullptr,
-        base::CreateSequencedTaskRunnerWithTraits(
-            {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
-             base::TaskPriority::BEST_EFFORT})));
+    scoped_refptr<JsonPrefStore> json_pref_store(
+        new JsonPrefStore(*params_->http_server_properties_path, nullptr,
+                          base::CreateSequencedTaskRunner(
+                              {base::ThreadPool(), base::MayBlock(),
+                               base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
+                               base::TaskPriority::BEST_EFFORT})));
     PrefServiceFactory pref_service_factory;
     pref_service_factory.set_user_prefs(json_pref_store);
     pref_service_factory.set_async(true);
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index ef87812..225abad 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -582,8 +582,8 @@
   auto networks = std::make_unique<net::NetworkInterfaceList>();
   auto* raw_networks = networks.get();
   // net::GetNetworkList may block depending on platform.
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock()},
+  base::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::ThreadPool(), base::MayBlock()},
       base::BindOnce(&net::GetNetworkList, raw_networks, policy),
       base::BindOnce(&OnGetNetworkList, std::move(networks),
                      std::move(callback)));
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc
index bd627d8..6ea67a1 100644
--- a/services/network/p2p/socket_manager.cc
+++ b/services/network/p2p/socket_manager.cc
@@ -151,8 +151,9 @@
     net::URLRequestContext* url_request_context)
     : delete_callback_(std::move(delete_callback)),
       url_request_context_(url_request_context),
-      network_list_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE})),
+      network_list_task_runner_(
+          base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                           base::TaskPriority::USER_VISIBLE})),
       trusted_socket_manager_client_(std::move(trusted_socket_manager_client)),
       trusted_socket_manager_binding_(
           this,
diff --git a/services/network/proxy_resolver_factory_mojo.cc b/services/network/proxy_resolver_factory_mojo.cc
index 663117aa..b24ba503 100644
--- a/services/network/proxy_resolver_factory_mojo.cc
+++ b/services/network/proxy_resolver_factory_mojo.cc
@@ -149,8 +149,9 @@
     //
     // However the better place to focus on is de-duplication and caching on the
     // proxy service side (which currently caches but doesn't de-duplicate).
-    return base::CreateSequencedTaskRunnerWithTraits(
-        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
+    return base::CreateSequencedTaskRunner(
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
          base::TaskPriority::USER_VISIBLE});
   }
 
diff --git a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
index 67c41e39..e85c7de4 100644
--- a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
+++ b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
@@ -53,8 +53,8 @@
  protected:
   void SetUp() override {
     main_thread_ = base::SequencedTaskRunnerHandle::Get();
-    loader_thread_ = base::CreateSequencedTaskRunnerWithTraits(
-        {base::MayBlock(), base::WithBaseSyncPrimitives()});
+    loader_thread_ = base::CreateSequencedTaskRunner(
+        {base::ThreadPool(), base::MayBlock(), base::WithBaseSyncPrimitives()});
 
     test_url_loader_factory_ =
         std::make_unique<CloneCheckingURLLoaderFactory>(loader_thread_);
@@ -180,8 +180,8 @@
 TEST_F(CrossThreadSharedURLLoaderFactoryInfoTest, CloneThirdThread) {
   // Clone to a third thread.
   scoped_refptr<base::SequencedTaskRunner> third_thread =
-      base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::WithBaseSyncPrimitives()});
+      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                       base::WithBaseSyncPrimitives()});
 
   scoped_refptr<SharedURLLoaderFactory> main_thread_factory =
       SharedURLLoaderFactory::Create(std::move(factory_info_));
diff --git a/services/network/public/cpp/simple_url_loader.cc b/services/network/public/cpp/simple_url_loader.cc
index b575b0b..8441e9f 100644
--- a/services/network/public/cpp/simple_url_loader.cc
+++ b/services/network/public/cpp/simple_url_loader.cc
@@ -847,8 +847,8 @@
                base::TaskPriority priority,
                base::RepeatingCallback<void(int64_t)> progress_callback)
         : body_handler_task_runner_(base::SequencedTaskRunnerHandle::Get()),
-          file_writer_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-              {base::MayBlock(), priority,
+          file_writer_task_runner_(base::CreateSequencedTaskRunner(
+              {base::ThreadPool(), base::MayBlock(), priority,
                base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
           path_(path),
           create_temp_file_(create_temp_file),
diff --git a/services/network/session_cleanup_cookie_store_unittest.cc b/services/network/session_cleanup_cookie_store_unittest.cc
index eaa5fb0..2da99e3 100644
--- a/services/network/session_cleanup_cookie_store_unittest.cc
+++ b/services/network/session_cleanup_cookie_store_unittest.cc
@@ -54,7 +54,7 @@
   CanonicalCookieVector CreateAndLoad() {
     auto sqlite_store = base::MakeRefCounted<net::SQLitePersistentCookieStore>(
         temp_dir_.GetPath().Append(kTestCookiesFilename),
-        base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
+        base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()}),
         background_task_runner_, true, nullptr);
     store_ =
         base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store.get());
@@ -85,7 +85,7 @@
 
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
-      base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
+      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()});
   base::ScopedTempDir temp_dir_;
   scoped_refptr<SessionCleanupCookieStore> store_;
   net::BoundTestNetLog net_log_;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index d066761f..0c00ce9 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -547,12 +547,14 @@
     file_opener->FilesForUploadOpenedDone(net::OK);
   }
 
-  // |opened_files| need to be closed on a blocking task runner, so move
-  // the |opened_files| vector onto a sequence that can block so it gets
-  // destroyed there.
+  // |opened_files| need to be closed on a blocking task runner, so move the
+  // |opened_files| vector onto a sequence that can block so it gets destroyed
+  // there.
   static void PostCloseFiles(std::vector<base::File> opened_files) {
-    base::PostTaskWithTraits(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
+    base::PostTask(
+        FROM_HERE,
+        {base::ThreadPool(), base::MayBlock(),
+         base::TaskPriority::USER_BLOCKING},
         base::BindOnce(base::DoNothing::Once<std::vector<base::File>>(),
                        std::move(opened_files)));
   }
@@ -632,8 +634,8 @@
     return;
   }
   scoped_refptr<base::SequencedTaskRunner> task_runner =
-      base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+      base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                       base::TaskPriority::USER_VISIBLE});
   url_request_->set_upload(CreateUploadDataStream(
       request.request_body.get(), opened_files, task_runner.get()));
 
diff --git a/services/service_manager/README.md b/services/service_manager/README.md
index 50f0f2f..14ccc771 100644
--- a/services/service_manager/README.md
+++ b/services/service_manager/README.md
@@ -666,8 +666,8 @@
 
 ``` cpp
 std::unique_ptr<service_manager::Connector> new_connector = connector->Clone();
-base::PostTaskWithTraits(...[elsewhere]...,
-                         base::BindOnce(..., std::move(new_connector)));
+base::PostTask(...[elsewhere]...,
+               base::BindOnce(..., std::move(new_connector)));
 ```
 
 Or you can fabricate a brand new `Connector` right from where you're standing,
@@ -682,7 +682,7 @@
 // yet being associated with the establshed Connector. The calls will queue as
 // long as necessary.
 
-base::PostTaskWithTraits(
+base::PostTask(
     ...[over to the correct thread]...,
     base::BindOnce([](service_manager::ConnectorRequest request) {
       service_manager::Connector* connector = GetMyConnectorForThisThread();
diff --git a/services/service_manager/service_process_launcher.cc b/services/service_manager/service_process_launcher.cc
index e2c6e41..1e27bde 100644
--- a/services/service_manager/service_process_launcher.cc
+++ b/services/service_manager/service_process_launcher.cc
@@ -81,9 +81,9 @@
       service_path_(service_path.empty()
                         ? base::CommandLine::ForCurrentProcess()->GetProgram()
                         : service_path),
-      background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::TaskPriority::USER_VISIBLE, base::WithBaseSyncPrimitives(),
-           base::MayBlock()})) {}
+      background_task_runner_(base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
+           base::WithBaseSyncPrimitives(), base::MayBlock()})) {}
 
 ServiceProcessLauncher::~ServiceProcessLauncher() {
   // We don't really need to wait for the process to be joined, as long as it
diff --git a/services/tracing/coordinator.cc b/services/tracing/coordinator.cc
index 9c8c2965..2d406e95 100644
--- a/services/tracing/coordinator.cc
+++ b/services/tracing/coordinator.cc
@@ -284,9 +284,9 @@
       // TODO(fdoray): Once we have support for dynamic priorities
       // (https://crbug.com/889029), use BEST_EFFORT initially and increase the
       // priority only when blocking the tracing UI.
-      backend_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::TaskPriority::USER_VISIBLE, base::MayBlock(),
-           base::WithBaseSyncPrimitives()})),
+      backend_task_runner_(base::CreateSequencedTaskRunner(
+          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
+           base::MayBlock(), base::WithBaseSyncPrimitives()})),
       weak_ptr_factory_(this) {
   DCHECK(agent_registry_);
 }
diff --git a/services/tracing/perfetto/consumer_host.cc b/services/tracing/perfetto/consumer_host.cc
index a3c16c77..ce54023 100644
--- a/services/tracing/perfetto/consumer_host.cc
+++ b/services/tracing/perfetto/consumer_host.cc
@@ -53,8 +53,9 @@
   using Slices = std::vector<std::string>;
 
   static scoped_refptr<base::SequencedTaskRunner> CreateTaskRunner() {
-    return base::CreateSequencedTaskRunnerWithTraits(
-        {base::WithBaseSyncPrimitives(), base::TaskPriority::BEST_EFFORT});
+    return base::CreateSequencedTaskRunner({base::ThreadPool(),
+                                            base::WithBaseSyncPrimitives(),
+                                            base::TaskPriority::BEST_EFFORT});
   }
 
   StreamWriter(mojo::ScopedDataPipeProducerHandle stream,
diff --git a/services/tracing/perfetto/consumer_host_unittest.cc b/services/tracing/perfetto/consumer_host_unittest.cc
index 4aa5afa..a0c4fbf 100644
--- a/services/tracing/perfetto/consumer_host_unittest.cc
+++ b/services/tracing/perfetto/consumer_host_unittest.cc
@@ -42,8 +42,9 @@
 class ThreadedPerfettoService : public mojom::TracingSessionClient {
  public:
   ThreadedPerfettoService()
-      : task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-            {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
+      : task_runner_(base::CreateSequencedTaskRunner(
+            {base::ThreadPool(), base::MayBlock(),
+             base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
              base::WithBaseSyncPrimitives(),
              base::TaskPriority::BEST_EFFORT})) {
     perfetto_service_ = std::make_unique<PerfettoService>(task_runner_);
diff --git a/services/tracing/public/cpp/perfetto/task_runner.cc b/services/tracing/public/cpp/perfetto/task_runner.cc
index 68e40036..74271bd4 100644
--- a/services/tracing/public/cpp/perfetto/task_runner.cc
+++ b/services/tracing/public/cpp/perfetto/task_runner.cc
@@ -116,8 +116,9 @@
 PerfettoTaskRunner::GetOrCreateTaskRunner() {
   if (!task_runner_) {
     DCHECK(base::ThreadPoolInstance::Get());
-    task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-        {base::MayBlock(), base::TaskPriority::USER_BLOCKING});
+    task_runner_ =
+        base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock(),
+                                         base::TaskPriority::USER_BLOCKING});
   }
 
   return task_runner_;
diff --git a/services/tracing/public/cpp/perfetto/task_runner_unittest.cc b/services/tracing/public/cpp/perfetto/task_runner_unittest.cc
index e26c458..a9f25d1 100644
--- a/services/tracing/public/cpp/perfetto/task_runner_unittest.cc
+++ b/services/tracing/public/cpp/perfetto/task_runner_unittest.cc
@@ -96,8 +96,9 @@
   }
 
   scoped_refptr<base::SequencedTaskRunner> CreateNewTaskrunner() {
-    return base::CreateSingleThreadTaskRunnerWithTraits(
-        {base::MayBlock()}, base::SingleThreadTaskRunnerThreadMode::DEDICATED);
+    return base::CreateSingleThreadTaskRunner(
+        {base::ThreadPool(), base::MayBlock()},
+        base::SingleThreadTaskRunnerThreadMode::DEDICATED);
   }
   void SetTaskExpectations(base::OnceClosure on_complete,
                            size_t expected_tasks,
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
index a470a01a..2aa69df 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -1176,8 +1176,8 @@
   // deleting startup registry and setting the producer.
   auto wait_for_start_tracing = std::make_unique<base::WaitableEvent>();
   base::WaitableEvent* wait_ptr = wait_for_start_tracing.get();
-  base::PostTaskWithTraits(
-      FROM_HERE, base::TaskPriority::BEST_EFFORT,
+  base::PostTask(
+      FROM_HERE, {base::ThreadPool(), base::TaskPriority::BEST_EFFORT},
       base::BindOnce(
           [](std::unique_ptr<base::WaitableEvent> wait_for_start_tracing) {
             // This event can be hit anytime before startup registry is
diff --git a/services/tracing/public/cpp/stack_sampling/stack_unwinder_android_unittest.cc b/services/tracing/public/cpp/stack_sampling/stack_unwinder_android_unittest.cc
index 7c3a17f..1a03dfe71 100644
--- a/services/tracing/public/cpp/stack_sampling/stack_unwinder_android_unittest.cc
+++ b/services/tracing/public/cpp/stack_sampling/stack_unwinder_android_unittest.cc
@@ -60,8 +60,8 @@
 
 TEST_F(StackUnwinderTest, UnwindOtherThread) {
   base::WaitableEvent unwind_finished_event;
-  auto task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+  auto task_runner = base::CreateSingleThreadTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 
   auto callback = [](StackUnwinderAndroid* unwinder, base::PlatformThreadId tid,
                      base::WaitableEvent* unwind_finished_event,
@@ -105,8 +105,8 @@
 }
 
 TEST_F(StackUnwinderTest, UnwindOtherThreadOnJNICall) {
-  auto task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+  auto task_runner = base::CreateSingleThreadTaskRunner(
+      {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 
   auto callback = [](StackUnwinderAndroid* unwinder, base::PlatformThreadId tid,
                      uintptr_t test_pc) {
diff --git a/services/video_capture/video_capture_service_impl.cc b/services/video_capture/video_capture_service_impl.cc
index b6a7238..2d9531a9 100644
--- a/services/video_capture/video_capture_service_impl.cc
+++ b/services/video_capture/video_capture_service_impl.cc
@@ -36,8 +36,9 @@
 class VideoCaptureServiceImpl::GpuDependenciesContext {
  public:
   GpuDependenciesContext() : weak_factory_for_gpu_io_thread_(this) {
-    gpu_io_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-        {base::TaskPriority::BEST_EFFORT, base::MayBlock()});
+    gpu_io_task_runner_ = base::CreateSequencedTaskRunner(
+        {base::ThreadPool(), base::TaskPriority::BEST_EFFORT,
+         base::MayBlock()});
   }
 
   ~GpuDependenciesContext() {
diff --git a/skia/ext/test_fonts_fuchsia.cc b/skia/ext/test_fonts_fuchsia.cc
index fa3667dc..d47c3409 100644
--- a/skia/ext/test_fonts_fuchsia.cc
+++ b/skia/ext/test_fonts_fuchsia.cc
@@ -26,7 +26,7 @@
   // fonts, which must be bundled in the calling process' package.
   fuchsia::sys::LaunchInfo launch_info;
   launch_info.url = "fuchsia-pkg://fuchsia.com/fonts#meta/fonts.cmx";
-  launch_info.arguments.reset(
+  launch_info.arguments.emplace(
       {"--no-default-fonts",
        "--font-manifest=/test_fonts/fuchsia_test_fonts_manifest.json"});
   launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New();
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index fdd3766..d9d4253 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -83,8 +83,6 @@
     "fileapi/file_system_backend.h",
     "fileapi/file_system_context.cc",
     "fileapi/file_system_context.h",
-    "fileapi/file_system_dir_url_request_job.cc",
-    "fileapi/file_system_dir_url_request_job.h",
     "fileapi/file_system_features.cc",
     "fileapi/file_system_features.h",
     "fileapi/file_system_file_stream_reader.cc",
@@ -273,7 +271,6 @@
     "fileapi/file_stream_test_utils.cc",
     "fileapi/file_stream_test_utils.h",
     "fileapi/file_system_context_unittest.cc",
-    "fileapi/file_system_dir_url_request_job_unittest.cc",
     "fileapi/file_system_file_stream_reader_unittest.cc",
     "fileapi/file_system_operation_impl_unittest.cc",
     "fileapi/file_system_operation_impl_write_unittest.cc",
diff --git a/storage/browser/fileapi/file_system_context.h b/storage/browser/fileapi/file_system_context.h
index 7946694..b49512b 100644
--- a/storage/browser/fileapi/file_system_context.h
+++ b/storage/browser/fileapi/file_system_context.h
@@ -36,10 +36,6 @@
 class Env;
 }
 
-namespace net {
-class URLRequest;
-}
-
 namespace storage {
 
 class AsyncFileUtil;
@@ -66,8 +62,6 @@
 struct FileSystemRequestInfo {
   // The original request URL (always set).
   const GURL url;
-  // The network request (only set when not using the network service).
-  const net::URLRequest* request = nullptr;
   // The storage domain (always set).
   const std::string storage_domain;
   // Set by the network service for use by callbacks.
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job.cc b/storage/browser/fileapi/file_system_dir_url_request_job.cc
deleted file mode 100644
index 7daabb9d..0000000
--- a/storage/browser/fileapi/file_system_dir_url_request_job.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "storage/browser/fileapi/file_system_dir_url_request_job.h"
-
-#include <stddef.h>
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "components/services/filesystem/public/mojom/types.mojom.h"
-#include "net/base/directory_listing.h"
-#include "net/base/io_buffer.h"
-#include "net/url_request/url_request.h"
-#include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_operation_runner.h"
-#include "storage/common/fileapi/file_system_util.h"
-#include "url/gurl.h"
-
-using net::NetworkDelegate;
-using net::URLRequest;
-using net::URLRequestJob;
-using net::URLRequestStatus;
-
-namespace storage {
-
-FileSystemDirURLRequestJob::FileSystemDirURLRequestJob(
-    URLRequest* request,
-    NetworkDelegate* network_delegate,
-    const std::string& storage_domain,
-    FileSystemContext* file_system_context)
-    : URLRequestJob(request, network_delegate),
-      storage_domain_(storage_domain),
-      file_system_context_(file_system_context),
-      weak_factory_(this) {
-}
-
-FileSystemDirURLRequestJob::~FileSystemDirURLRequestJob() = default;
-
-int FileSystemDirURLRequestJob::ReadRawData(net::IOBuffer* dest,
-                                            int dest_size) {
-  int count = std::min(dest_size, base::checked_cast<int>(data_.size()));
-  if (count > 0) {
-    memcpy(dest->data(), data_.data(), count);
-    data_.erase(0, count);
-  }
-  return count;
-}
-
-void FileSystemDirURLRequestJob::Start() {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&FileSystemDirURLRequestJob::StartAsync,
-                                weak_factory_.GetWeakPtr()));
-}
-
-void FileSystemDirURLRequestJob::Kill() {
-  URLRequestJob::Kill();
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-bool FileSystemDirURLRequestJob::GetMimeType(std::string* mime_type) const {
-  *mime_type = "text/html";
-  return true;
-}
-
-bool FileSystemDirURLRequestJob::GetCharset(std::string* charset) {
-  *charset = "utf-8";
-  return true;
-}
-
-void FileSystemDirURLRequestJob::StartAsync() {
-  if (!request_)
-    return;
-  url_ = file_system_context_->CrackURL(request_->url());
-  if (!url_.is_valid()) {
-    const FileSystemRequestInfo request_info = {request_->url(), request_,
-                                                storage_domain_, 0};
-    file_system_context_->AttemptAutoMountForURLRequest(
-        request_info,
-        base::BindOnce(&FileSystemDirURLRequestJob::DidAttemptAutoMount,
-                       weak_factory_.GetWeakPtr()));
-    return;
-  }
-  if (!file_system_context_->CanServeURLRequest(url_)) {
-    // In incognito mode the API is not usable and there should be no data.
-    if (url_.is_valid() && VirtualPath::IsRootPath(url_.virtual_path())) {
-      // Return an empty directory if the filesystem root is queried.
-      DidReadDirectory(base::File::FILE_OK,
-                       std::vector<filesystem::mojom::DirectoryEntry>(), false);
-      return;
-    }
-    NotifyStartError(URLRequestStatus::FromError(net::ERR_FILE_NOT_FOUND));
-    return;
-  }
-  file_system_context_->operation_runner()->ReadDirectory(
-      url_, base::BindRepeating(&FileSystemDirURLRequestJob::DidReadDirectory,
-                                weak_factory_.GetWeakPtr()));
-}
-
-void FileSystemDirURLRequestJob::DidAttemptAutoMount(base::File::Error result) {
-  if (result >= 0 &&
-      file_system_context_->CrackURL(request_->url()).is_valid()) {
-    StartAsync();
-  } else {
-    NotifyStartError(URLRequestStatus::FromError(net::ERR_FILE_NOT_FOUND));
-  }
-}
-
-void FileSystemDirURLRequestJob::DidReadDirectory(
-    base::File::Error result,
-    std::vector<filesystem::mojom::DirectoryEntry> entries,
-    bool has_more) {
-  if (result != base::File::FILE_OK) {
-    int rv = net::ERR_FILE_NOT_FOUND;
-    if (result == base::File::FILE_ERROR_INVALID_URL)
-      rv = net::ERR_INVALID_URL;
-    NotifyStartError(URLRequestStatus::FromError(rv));
-    return;
-  }
-
-  if (!request_)
-    return;
-
-  if (data_.empty()) {
-    base::FilePath relative_path = url_.path();
-#if defined(OS_POSIX)
-    relative_path =
-        base::FilePath(FILE_PATH_LITERAL("/") + relative_path.value());
-#endif
-    const base::string16& title = relative_path.LossyDisplayName();
-    data_.append(net::GetDirectoryListingHeader(title));
-  }
-
-  entries_.insert(entries_.end(), entries.begin(), entries.end());
-
-  if (!has_more) {
-    if (entries_.size()) {
-      GetMetadata(0);
-    } else {
-      set_expected_content_size(data_.size());
-      NotifyHeadersComplete();
-    }
-  }
-}
-
-void FileSystemDirURLRequestJob::GetMetadata(size_t index) {
-  const filesystem::mojom::DirectoryEntry& entry = entries_[index];
-  const FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
-      url_.origin().GetURL(), url_.type(),
-      url_.path().Append(base::FilePath(entry.name)));
-  DCHECK(url.is_valid());
-  file_system_context_->operation_runner()->GetMetadata(
-      url,
-      FileSystemOperation::GET_METADATA_FIELD_SIZE |
-          FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
-      base::BindOnce(&FileSystemDirURLRequestJob::DidGetMetadata,
-                     weak_factory_.GetWeakPtr(), index));
-}
-
-void FileSystemDirURLRequestJob::DidGetMetadata(
-    size_t index,
-    base::File::Error result,
-    const base::File::Info& file_info) {
-  if (result != base::File::FILE_OK) {
-    int rv = net::ERR_FILE_NOT_FOUND;
-    if (result == base::File::FILE_ERROR_INVALID_URL)
-      rv = net::ERR_INVALID_URL;
-    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, rv));
-  }
-
-  if (!request_)
-    return;
-
-  const filesystem::mojom::DirectoryEntry& entry = entries_[index];
-  const base::string16& name = base::FilePath(entry.name).LossyDisplayName();
-  data_.append(net::GetDirectoryListingEntry(
-      name, std::string(),
-      entry.type == filesystem::mojom::FsFileType::DIRECTORY, file_info.size,
-      file_info.last_modified));
-
-  if (index < entries_.size() - 1) {
-    GetMetadata(index + 1);
-  } else {
-    set_expected_content_size(data_.size());
-    NotifyHeadersComplete();
-  }
-}
-
-}  // namespace storage
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job.h b/storage/browser/fileapi/file_system_dir_url_request_job.h
deleted file mode 100644
index ecca687..0000000
--- a/storage/browser/fileapi/file_system_dir_url_request_job.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_DIR_URL_REQUEST_JOB_H_
-#define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_DIR_URL_REQUEST_JOB_H_
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "base/component_export.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/services/filesystem/public/mojom/types.mojom.h"
-#include "net/url_request/url_request_job.h"
-#include "storage/browser/fileapi/file_system_url.h"
-
-namespace storage {
-
-class FileSystemContext;
-
-// A request job that handles reading filesystem: URLs for directories.
-class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemDirURLRequestJob
-    : public net::URLRequestJob {
- public:
-  FileSystemDirURLRequestJob(
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate,
-      const std::string& storage_domain,
-      FileSystemContext* file_system_context);
-
-  ~FileSystemDirURLRequestJob() override;
-
-  // URLRequestJob methods:
-  void Start() override;
-  void Kill() override;
-  int ReadRawData(net::IOBuffer* buf, int buf_size) override;
-  bool GetCharset(std::string* charset) override;
-
-  // FilterContext methods (via URLRequestJob):
-  bool GetMimeType(std::string* mime_type) const override;
-  // TODO(adamk): Implement GetResponseInfo and GetResponseCode to simulate
-  // an HTTP response.
-
- private:
-  class CallbackDispatcher;
-
-  void StartAsync();
-  void DidAttemptAutoMount(base::File::Error result);
-  void DidReadDirectory(base::File::Error result,
-                        std::vector<filesystem::mojom::DirectoryEntry> entries,
-                        bool has_more);
-
-  // Reads metadata for the |index|-th entry in the directory. Must be called
-  // after |entries_| is filled.
-  void GetMetadata(size_t index);
-  void DidGetMetadata(size_t index,
-                      base::File::Error result,
-                      const base::File::Info& file_info);
-
-  std::vector<filesystem::mojom::DirectoryEntry> entries_;
-  std::string data_;
-  FileSystemURL url_;
-  const std::string storage_domain_;
-  FileSystemContext* file_system_context_;
-  base::WeakPtrFactory<FileSystemDirURLRequestJob> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileSystemDirURLRequestJob);
-};
-
-}  // namespace storage
-
-#endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_DIR_URL_REQUEST_JOB_H_
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc b/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc
deleted file mode 100644
index d01a0f3..0000000
--- a/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdint.h>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/feature_list.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/format_macros.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "net/base/net_errors.h"
-#include "net/base/request_priority.h"
-#include "net/http/http_request_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_test_util.h"
-#include "storage/browser/fileapi/external_mount_points.h"
-#include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/fileapi/file_system_dir_url_request_job.h"
-#include "storage/browser/fileapi/file_system_features.h"
-#include "storage/browser/fileapi/file_system_file_util.h"
-#include "storage/browser/fileapi/file_system_operation_context.h"
-#include "storage/browser/fileapi/file_system_url.h"
-#include "storage/browser/test/mock_special_storage_policy.h"
-#include "storage/browser/test/test_file_system_backend.h"
-#include "storage/browser/test/test_file_system_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/source/i18n/unicode/datefmt.h"
-#include "third_party/icu/source/i18n/unicode/regex.h"
-
-using storage::FileSystemContext;
-using storage::FileSystemOperationContext;
-using storage::FileSystemURL;
-
-namespace content {
-namespace {
-
-enum class TestMode { kRegular, kIncognito, kRegularWithIncognitoEnabled };
-
-// We always use the TEMPORARY FileSystem in this test.
-const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/";
-
-const char kValidExternalMountPoint[] = "mnt_name";
-
-// An auto mounter that will try to mount anything for |storage_domain| =
-// "automount", but will only succeed for the mount point "mnt_name".
-bool TestAutoMountForURLRequest(
-    const storage::FileSystemRequestInfo& request_info,
-    const storage::FileSystemURL& filesystem_url,
-    base::OnceCallback<void(base::File::Error result)> callback) {
-  if (request_info.storage_domain != "automount")
-    return false;
-
-  std::vector<base::FilePath::StringType> components;
-  filesystem_url.path().GetComponents(&components);
-  std::string mount_point = base::FilePath(components[0]).AsUTF8Unsafe();
-
-  if (mount_point == kValidExternalMountPoint) {
-    storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
-        kValidExternalMountPoint,
-        storage::kFileSystemTypeTest,
-        storage::FileSystemMountOption(),
-        base::FilePath());
-    std::move(callback).Run(base::File::FILE_OK);
-  } else {
-    std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND);
-  }
-  return true;
-}
-
-class FileSystemDirURLRequestJobFactory : public net::URLRequestJobFactory {
- public:
-  FileSystemDirURLRequestJobFactory(const std::string& storage_domain,
-                                    FileSystemContext* context)
-      : storage_domain_(storage_domain), file_system_context_(context) {
-  }
-
-  net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
-      const std::string& scheme,
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate) const override {
-    return new storage::FileSystemDirURLRequestJob(
-        request, network_delegate, storage_domain_, file_system_context_);
-  }
-
-  net::URLRequestJob* MaybeInterceptRedirect(
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate,
-      const GURL& location) const override {
-    return nullptr;
-  }
-
-  net::URLRequestJob* MaybeInterceptResponse(
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate) const override {
-    return nullptr;
-  }
-
-  bool IsHandledProtocol(const std::string& scheme) const override {
-    return true;
-  }
-
-  bool IsSafeRedirectTarget(const GURL& location) const override {
-    return false;
-  }
-
- private:
-  std::string storage_domain_;
-  FileSystemContext* file_system_context_;
-};
-
-
-}  // namespace
-
-class FileSystemDirURLRequestJobTest
-    : public testing::Test,
-      public ::testing::WithParamInterface<TestMode> {
- protected:
-  FileSystemDirURLRequestJobTest()
-    : weak_factory_(this) {
-    if (GetParam() == TestMode::kIncognito ||
-        GetParam() == TestMode::kRegularWithIncognitoEnabled) {
-      feature_list_.InitAndEnableFeature(
-          storage::features::kEnableFilesystemInIncognito);
-    }
-  }
-
-  bool IsInMemoryFileSystemEnabled() {
-    return base::FeatureList::IsEnabled(
-        storage::features::kEnableFilesystemInIncognito);
-  }
-
-  bool IsIncognito() { return GetParam() == TestMode::kIncognito; }
-
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    special_storage_policy_ = new MockSpecialStoragePolicy;
-    file_system_context_ =
-        IsIncognito()
-            ? CreateIncognitoFileSystemContextForTesting(
-                  base::ThreadTaskRunnerHandle::Get(),
-                  base::ThreadTaskRunnerHandle::Get(), nullptr,
-                  temp_dir_.GetPath())
-            : CreateFileSystemContextForTesting(nullptr, temp_dir_.GetPath());
-
-    file_system_context_->OpenFileSystem(
-        GURL("http://remote/"), storage::kFileSystemTypeTemporary,
-        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
-        base::BindOnce(&FileSystemDirURLRequestJobTest::OnOpenFileSystem,
-                       weak_factory_.GetWeakPtr()));
-    base::RunLoop().RunUntilIdle();
-  }
-
-  void TearDown() override {
-    // NOTE: order matters, request must die before delegate
-    request_.reset(nullptr);
-    delegate_.reset(nullptr);
-  }
-
-  void SetUpAutoMountContext(base::FilePath* mnt_point) {
-    *mnt_point = temp_dir_.GetPath().AppendASCII("auto_mount_dir");
-    ASSERT_TRUE(base::CreateDirectory(*mnt_point));
-
-    std::vector<std::unique_ptr<storage::FileSystemBackend>>
-        additional_providers;
-    additional_providers.emplace_back(std::make_unique<TestFileSystemBackend>(
-        base::ThreadTaskRunnerHandle::Get().get(), *mnt_point));
-
-    std::vector<storage::URLRequestAutoMountHandler> handlers;
-    handlers.emplace_back(base::BindRepeating(&TestAutoMountForURLRequest));
-
-    file_system_context_ = CreateFileSystemContextWithAutoMountersForTesting(
-        base::ThreadTaskRunnerHandle::Get(),
-        base::ThreadTaskRunnerHandle::Get(), nullptr,
-        std::move(additional_providers), handlers, temp_dir_.GetPath());
-  }
-
-  void OnOpenFileSystem(const GURL& root_url,
-                        const std::string& name,
-                        base::File::Error result) {
-    ASSERT_EQ(base::File::FILE_OK, result);
-  }
-
-  void TestRequestHelper(const GURL& url, bool run_to_completion,
-                         FileSystemContext* file_system_context) {
-    delegate_.reset(new net::TestDelegate());
-    job_factory_.reset(new FileSystemDirURLRequestJobFactory(
-        url.GetOrigin().host(), file_system_context));
-    empty_context_.set_job_factory(job_factory_.get());
-
-    request_ = empty_context_.CreateRequest(url, net::DEFAULT_PRIORITY,
-                                            delegate_.get(),
-                                            TRAFFIC_ANNOTATION_FOR_TESTS);
-    request_->Start();
-    ASSERT_TRUE(request_->is_pending());  // verify that we're starting async
-    if (run_to_completion)
-      delegate_->RunUntilComplete();
-  }
-
-  void TestRequest(const GURL& url) {
-    TestRequestHelper(url, true, file_system_context_.get());
-  }
-
-  void TestRequestWithContext(const GURL& url,
-                              FileSystemContext* file_system_context) {
-    TestRequestHelper(url, true, file_system_context);
-  }
-
-  void TestRequestNoRun(const GURL& url) {
-    TestRequestHelper(url, false, file_system_context_.get());
-  }
-
-  FileSystemURL CreateURL(const base::FilePath& file_path) {
-    return file_system_context_->CreateCrackedFileSystemURL(
-        GURL("http://remote"), storage::kFileSystemTypeTemporary, file_path);
-  }
-
-  FileSystemOperationContext* NewOperationContext() {
-    FileSystemOperationContext* context(
-        new FileSystemOperationContext(file_system_context_.get()));
-    context->set_allowed_bytes_growth(1024);
-    return context;
-  }
-
-  void CreateDirectory(const base::StringPiece& dir_name) {
-    base::FilePath path = base::FilePath().AppendASCII(dir_name);
-    std::unique_ptr<FileSystemOperationContext> context(NewOperationContext());
-    ASSERT_EQ(base::File::FILE_OK, file_util()->CreateDirectory(
-        context.get(),
-        CreateURL(path),
-        false /* exclusive */,
-        false /* recursive */));
-  }
-
-  void EnsureFileExists(const base::StringPiece file_name) {
-    base::FilePath path = base::FilePath().AppendASCII(file_name);
-    std::unique_ptr<FileSystemOperationContext> context(NewOperationContext());
-    ASSERT_EQ(
-        base::File::FILE_OK,
-        file_util()->EnsureFileExists(context.get(), CreateURL(path), nullptr));
-  }
-
-  void TruncateFile(const base::StringPiece file_name, int64_t length) {
-    base::FilePath path = base::FilePath().AppendASCII(file_name);
-    std::unique_ptr<FileSystemOperationContext> context(NewOperationContext());
-    ASSERT_EQ(base::File::FILE_OK, file_util()->Truncate(
-        context.get(), CreateURL(path), length));
-  }
-
-  base::File::Error GetFileInfo(const base::FilePath& path,
-                                base::File::Info* file_info,
-                                base::FilePath* platform_file_path) {
-    std::unique_ptr<FileSystemOperationContext> context(NewOperationContext());
-    return file_util()->GetFileInfo(context.get(),
-                                    CreateURL(path),
-                                    file_info, platform_file_path);
-  }
-
-  // If |size| is negative, the reported size is ignored.
-  void VerifyListingEntry(const std::string& entry_line,
-                          const std::string& name,
-                          const std::string& url,
-                          bool is_directory,
-                          int64_t size) {
-#define NUMBER "([0-9-]*)"
-#define STR "([^\"]*)"
-    icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR
-        "\",(0|1)," NUMBER ",\"" STR "\"," NUMBER ",\"" STR "\"\\);</script>");
-#undef NUMBER
-#undef STR
-    icu::UnicodeString input(entry_line.c_str());
-
-    UErrorCode status = U_ZERO_ERROR;
-    icu::RegexMatcher match(pattern, input, 0, status);
-
-    EXPECT_TRUE(match.find());
-    EXPECT_EQ(7, match.groupCount());
-    EXPECT_EQ(icu::UnicodeString(name.c_str()), match.group(1, status));
-    EXPECT_EQ(icu::UnicodeString(url.c_str()), match.group(2, status));
-    EXPECT_EQ(icu::UnicodeString(is_directory ? "1" : "0"),
-              match.group(3, status));
-    if (size >= 0) {
-      icu::UnicodeString size_string(
-          base::FormatBytesUnlocalized(size).c_str());
-      EXPECT_EQ(size_string, match.group(5, status));
-    }
-
-    icu::UnicodeString date_ustr(match.group(7, status));
-    std::unique_ptr<icu::DateFormat> formatter(
-        icu::DateFormat::createDateTimeInstance(icu::DateFormat::kShort));
-    UErrorCode parse_status = U_ZERO_ERROR;
-    UDate udate = formatter->parse(date_ustr, parse_status);
-    EXPECT_TRUE(U_SUCCESS(parse_status));
-    base::Time date = base::Time::FromJsTime(udate);
-    EXPECT_FALSE(date.is_null());
-  }
-
-  GURL CreateFileSystemURL(const std::string& path) {
-    return GURL(kFileSystemURLPrefix + path);
-  }
-
-  storage::FileSystemFileUtil* file_util() {
-    return file_system_context_->sandbox_delegate()->sync_file_util();
-  }
-
-  // Put the message loop at the top, so that it's the last thing deleted.
-  // Delete all task runner objects before the MessageLoop, to help prevent
-  // leaks caused by tasks posted during shutdown.
-  base::MessageLoopForIO message_loop_;
-
-  base::test::ScopedFeatureList feature_list_;
-  base::ScopedTempDir temp_dir_;
-  net::URLRequestContext empty_context_;
-  std::unique_ptr<net::TestDelegate> delegate_;
-  std::unique_ptr<net::URLRequest> request_;
-  std::unique_ptr<FileSystemDirURLRequestJobFactory> job_factory_;
-  scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
-  scoped_refptr<FileSystemContext> file_system_context_;
-  base::WeakPtrFactory<FileSystemDirURLRequestJobTest> weak_factory_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    ,
-    FileSystemDirURLRequestJobTest,
-    testing::Values(TestMode::kRegular,
-                    TestMode::kIncognito,
-                    TestMode::kRegularWithIncognitoEnabled));
-
-namespace {
-
-TEST_P(FileSystemDirURLRequestJobTest, DirectoryListing) {
-  CreateDirectory("foo");
-  CreateDirectory("foo/bar");
-  CreateDirectory("foo/bar/baz");
-
-  EnsureFileExists("foo/bar/hoge");
-  TruncateFile("foo/bar/hoge", 10);
-
-  TestRequest(CreateFileSystemURL("foo/bar/"));
-
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(1, delegate_->response_started_count());
-  EXPECT_FALSE(delegate_->received_data_before_response());
-  EXPECT_GT(delegate_->bytes_received(), 0);
-
-  std::istringstream in(delegate_->data_received());
-  std::string line;
-  EXPECT_TRUE(std::getline(in, line));
-
-#if defined(OS_WIN)
-  EXPECT_EQ("<script>start(\"foo\\\\bar\");</script>", line);
-#elif defined(OS_POSIX)
-  EXPECT_EQ("<script>start(\"/foo/bar\");</script>", line);
-#endif
-
-  EXPECT_TRUE(std::getline(in, line));
-  VerifyListingEntry(line, "hoge", "hoge", false, 10);
-
-  EXPECT_TRUE(std::getline(in, line));
-  VerifyListingEntry(line, "baz", "baz", true, 0);
-  EXPECT_FALSE(!!std::getline(in, line));
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, InvalidURL) {
-  TestRequest(GURL("filesystem:/foo/bar/baz"));
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_TRUE(delegate_->request_failed());
-  EXPECT_EQ(net::ERR_INVALID_URL, delegate_->request_status());
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, NoSuchRoot) {
-  TestRequest(GURL("filesystem:http://remote/persistent/somedir/"));
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, NoSuchDirectory) {
-  TestRequest(CreateFileSystemURL("somedir/"));
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, Cancel) {
-  CreateDirectory("foo");
-  TestRequestNoRun(CreateFileSystemURL("foo/"));
-  // Run StartAsync() and only StartAsync().
-  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
-                                                  request_.release());
-  base::RunLoop().RunUntilIdle();
-  // If we get here, success! we didn't crash!
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, Incognito) {
-  CreateDirectory("foo");
-
-  scoped_refptr<FileSystemContext> file_system_context =
-      CreateIncognitoFileSystemContextForTesting(
-          base::ThreadTaskRunnerHandle::Get(),
-          base::ThreadTaskRunnerHandle::Get(), nullptr, temp_dir_.GetPath());
-  TestRequestWithContext(CreateFileSystemURL("/"),
-                         file_system_context.get());
-  ASSERT_FALSE(request_->is_pending());
-
-  if (IsInMemoryFileSystemEnabled()) {
-    // When in-memory file system is enabled, the request fails as the requested
-    // directory does not exist in in-memory obfuscated file system.
-    EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-  } else {
-    std::istringstream in(delegate_->data_received());
-    std::string line;
-    EXPECT_TRUE(std::getline(in, line));
-    EXPECT_FALSE(!!std::getline(in, line));
-  }
-
-  TestRequestWithContext(CreateFileSystemURL("foo"),
-                         file_system_context.get());
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, AutoMountDirectoryListing) {
-  base::FilePath mnt_point;
-  SetUpAutoMountContext(&mnt_point);
-  ASSERT_TRUE(base::CreateDirectory(mnt_point));
-  ASSERT_TRUE(base::CreateDirectory(mnt_point.AppendASCII("foo")));
-  ASSERT_EQ(10,
-            base::WriteFile(mnt_point.AppendASCII("bar"), "1234567890", 10));
-
-  TestRequest(GURL("filesystem:http://automount/external/mnt_name"));
-
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(1, delegate_->response_started_count());
-  EXPECT_FALSE(delegate_->received_data_before_response());
-  EXPECT_GT(delegate_->bytes_received(), 0);
-
-  std::istringstream in(delegate_->data_received());
-  std::string line;
-  EXPECT_TRUE(std::getline(in, line));  // |line| contains the temp dir path.
-
-  // Result order is not guaranteed, so sort the results.
-  std::vector<std::string> listing_entries;
-  while (!!std::getline(in, line))
-    listing_entries.push_back(line);
-
-  ASSERT_EQ(2U, listing_entries.size());
-  std::sort(listing_entries.begin(), listing_entries.end());
-  VerifyListingEntry(listing_entries[0], "bar", "bar", false, 10);
-  VerifyListingEntry(listing_entries[1], "foo", "foo", true, -1);
-
-  ASSERT_TRUE(
-      storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
-          kValidExternalMountPoint));
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, AutoMountInvalidRoot) {
-  base::FilePath mnt_point;
-  SetUpAutoMountContext(&mnt_point);
-  TestRequest(GURL("filesystem:http://automount/external/invalid"));
-
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-
-  ASSERT_FALSE(
-      storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
-          "invalid"));
-}
-
-TEST_P(FileSystemDirURLRequestJobTest, AutoMountNoHandler) {
-  base::FilePath mnt_point;
-  SetUpAutoMountContext(&mnt_point);
-  TestRequest(GURL("filesystem:http://noauto/external/mnt_name"));
-
-  ASSERT_FALSE(request_->is_pending());
-  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, delegate_->request_status());
-
-  ASSERT_FALSE(
-      storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
-          kValidExternalMountPoint));
-}
-
-}  // namespace
-}  // namespace content
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 8f0d15d9..6987375 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -103,6 +103,36 @@
           "shards": 2
         },
         "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--enable-gpu",
+          "--test-launcher-bot-mode",
+          "--test-launcher-jobs=1",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
+          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
+          "--use-vulkan=swiftshader",
+          "--enable-oop-rasterization",
+          "--enable-gpu-rasterization",
+          "--force-gpu-rasterization",
+          "--disable-software-compositing-fallback",
+          "--disable-vulkan-fallback-to-gl-for-testing",
+          "--disable-headless-mode"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "vulkan_swiftshader_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ]
+        },
+        "test": "content_browsertests"
       }
     ],
     "isolated_scripts": [
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 5519adc..3e1fdb2 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -8124,11 +8124,9 @@
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
           "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
-          "--use-gl=any",
           "--use-vulkan=native",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
-          "--enable-raster-to-sk-image",
           "--force-gpu-rasterization",
           "--disable-software-compositing-fallback",
           "--disable-vulkan-fallback-to-gl-for-testing",
@@ -8880,11 +8878,9 @@
           "--test-launcher-jobs=1",
           "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
           "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
-          "--use-gl=any",
           "--use-vulkan=native",
           "--enable-oop-rasterization",
           "--enable-gpu-rasterization",
-          "--enable-raster-to-sk-image",
           "--force-gpu-rasterization",
           "--disable-software-compositing-fallback",
           "--disable-vulkan-fallback-to-gl-for-testing",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 7fe4aa9..8b2843d 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -19,6 +19,7 @@
   'android_webview_unittests': {
     'remove_from': [
       # On chromium.android, these do not need to run prior to M.
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'KitKat Phone Tester (dbg)',
       'KitKat Tablet Tester',
@@ -293,6 +294,11 @@
     ],
     'modifications': {
       # chromium.android
+      'android-kitkat-arm-coverage-dbg': {
+        'swarming': {
+          'shards': 12,
+        }
+      },
       'android-kitkat-arm-rel': {
         'swarming': {
           'shards': 12,
@@ -1043,6 +1049,7 @@
       # chromium.android
       'android-asan',
       # Don't run on trybots; waterfall is enough.
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       # No capacity for tablet testers.
@@ -1056,6 +1063,7 @@
       # chromium.android
       'android-asan',
       # Don't run on trybots; waterfall is enough.
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       # No capacity for tablet testers.
@@ -1069,6 +1077,7 @@
       # chromium.android
       'android-asan',
       # Don't run on trybots; waterfall is enough.
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       # No capacity for tablet testers.
@@ -1082,6 +1091,7 @@
       # chromium.android
       'android-asan',
       # Don't run on trybots; waterfall is enough.
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       # No capacity for tablet testers.
@@ -1094,6 +1104,7 @@
     # Only run these on the phone testers for now due to capacity.
     'remove_from': [
       # chromium.android
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       'KitKat Tablet Tester',
@@ -1241,6 +1252,7 @@
     'remove_from': [
       'android-asan',
       'android-code-coverage',
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'android-marshmallow-arm64-rel',
       'Android CFI',
@@ -1415,6 +1427,20 @@
   'telemetry_perf_unittests': {
     'modifications': {
       # chromium.android
+      'android-kitkat-arm-coverage-dbg': {
+        'args': [
+          '--browser=android-chromium',
+          '--device=android',
+        ],
+        'swarming': {
+          'dimension_sets': [
+            {
+              'temp_band': '<30',
+            },
+          ],
+          'shards': 15,
+        },
+      },
       'android-kitkat-arm-rel': {
         'args': [
           '--browser=android-chromium',
@@ -2031,6 +2057,7 @@
     'remove_from': [
       # This test frequently fails on Android, https://crbug.com/824959
       # chromium.android
+      'android-kitkat-arm-coverage-dbg',
       'android-kitkat-arm-rel',
       'KitKat Phone Tester (dbg)',
       'KitKat Tablet Tester',
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 478688d..a6f507b 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3497,11 +3497,30 @@
           '--test-launcher-jobs=1',
           '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter',
           '--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization',
-          '--use-gl=any',
           '--use-vulkan=native',
           '--enable-oop-rasterization',
           '--enable-gpu-rasterization',
-          '--enable-raster-to-sk-image',
+          '--force-gpu-rasterization',
+          '--disable-software-compositing-fallback',
+          '--disable-vulkan-fallback-to-gl-for-testing',
+          '--disable-headless-mode',
+        ],
+        'linux_args': [ '--no-xvfb' ],
+        'test': 'content_browsertests',
+      },
+    },
+
+    'gpu_fyi_vulkan_swiftshader_gtests': {
+      'vulkan_swiftshader_content_browsertests': {
+        'args': [
+          '--enable-gpu',
+          '--test-launcher-bot-mode',
+          '--test-launcher-jobs=1',
+          '--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter',
+          '--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization',
+          '--use-vulkan=swiftshader',
+          '--enable-oop-rasterization',
+          '--enable-gpu-rasterization',
           '--force-gpu-rasterization',
           '--disable-software-compositing-fallback',
           '--disable-vulkan-fallback-to-gl-for-testing',
@@ -4513,7 +4532,7 @@
         'args': [
           '--enable-features=VizDisplayCompositor,UseSkiaRenderer',
           '--test-launcher-filter-file=../../testing/buildbot/filters/skia_renderer.content_browsertests.filter',
-	],
+        ],
         'swarming': {
           'shards': 1,
         },
@@ -4577,7 +4596,7 @@
         },
         'results_handler': 'layout tests',
       },
-   },
+    },
 
     'system_webview_shell_instrumentation_tests': {
       'system_webview_shell_layout_test_apk': {},
@@ -5509,6 +5528,7 @@
     ],
 
     'linux_viz_gtests': [
+      'gpu_fyi_vulkan_swiftshader_gtests',
       'skia_renderer_fyi_gtests',
     ],
 
diff --git a/testing/buildbot/tryserver.chromium.android.json b/testing/buildbot/tryserver.chromium.android.json
index cd9a1eed..5cb4004a 100644
--- a/testing/buildbot/tryserver.chromium.android.json
+++ b/testing/buildbot/tryserver.chromium.android.json
@@ -1,6 +1,2836 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "android-kitkat-arm-coverage-dbg": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "android_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "android_browsertests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "angle_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "base_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "base_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "base_util_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "base_util_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_common_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "blink_common_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_heap_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "blink_heap_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_platform_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "blink_platform_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webkit_unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "webkit_unit_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 2
+        },
+        "test": "blink_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "boringssl_crypto_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "boringssl_crypto_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "boringssl_ssl_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "boringssl_ssl_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "breakpad_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "breakpad_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "cacheinvalidation_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "cacheinvalidation_unittests"
+      },
+      {
+        "args": [
+          "--gtest_filter=-*UsingRealWebcam*",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "capture_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "cast_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "cast_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "cc_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "cc_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 12
+        },
+        "test": "chrome_public_test_apk"
+      },
+      {
+        "args": [
+          "--shared-prefs-file=//chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json",
+          "--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_test_vr_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 2
+        },
+        "test": "chrome_public_test_vr_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "components_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "components_browsertests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "components_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "components_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 9
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--disable-perfetto",
+          "--gtest_filter=TracingControllerTest.*:BackgroundTracingManagerBrowserTest.*",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "nonperfetto_content_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "nonperfetto_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_shell_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 3
+        },
+        "test": "content_shell_test_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 3
+        },
+        "test": "content_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "crypto_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "crypto_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "device_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "device_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "display_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "display_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "events_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "events_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gcm_unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gcm_unit_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gfx_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gfx_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gin_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gin_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gl_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gl_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "google_apis_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "google_apis_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gpu_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ipc_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "jingle_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "jingle_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "latency_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "latency_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "libjingle_xmpp_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "libjingle_xmpp_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "media_blink_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "media_blink_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "media_service_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "media_service_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "media_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "media_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "midi_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "midi_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "mojo_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "mojo_test_apk"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "mojo_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "mojo_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "net_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 3
+        },
+        "test": "net_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "sandbox_linux_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "sandbox_linux_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "services_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "services_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "shell_dialogs_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "shell_dialogs_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "skia_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "skia_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "sql_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "sql_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "storage_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "storage_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_android_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "ui_android_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_base_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "ui_base_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_touch_selection_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "ui_touch_selection_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "shards": 10
+        },
+        "test": "unit_tests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "url_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "url_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "viz_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "viz_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "vr_android_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "vr_android_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "vr_common_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "vr_common_unittests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "vr_pixeltests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "vr_pixeltests"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "isolate_coverage_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "wtf_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "KTU84P",
+              "device_os_type": "userdebug",
+              "device_type": "hammerhead",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "wtf_unittests"
+      }
+    ],
+    "junit_tests": [
+      {
+        "test": "android_webview_junit_tests"
+      },
+      {
+        "test": "base_junit_tests"
+      },
+      {
+        "test": "chrome_junit_tests"
+      },
+      {
+        "test": "components_background_task_scheduler_junit_tests"
+      },
+      {
+        "test": "components_gcm_driver_junit_tests"
+      },
+      {
+        "test": "components_invalidation_impl_junit_tests"
+      },
+      {
+        "test": "components_policy_junit_tests"
+      },
+      {
+        "test": "components_signin_junit_tests"
+      },
+      {
+        "test": "components_variations_junit_tests"
+      },
+      {
+        "test": "content_junit_tests"
+      },
+      {
+        "test": "device_junit_tests"
+      },
+      {
+        "test": "junit_unit_tests"
+      },
+      {
+        "test": "keyboard_accessory_junit_tests"
+      },
+      {
+        "test": "media_base_junit_tests"
+      },
+      {
+        "test": "media_router_junit_tests"
+      },
+      {
+        "test": "net_junit_tests"
+      },
+      {
+        "test": "service_junit_tests"
+      },
+      {
+        "test": "ui_junit_tests"
+      },
+      {
+        "test": "webapk_client_junit_tests"
+      },
+      {
+        "test": "webapk_shell_apk_h2o_junit_tests"
+      },
+      {
+        "test": "webapk_shell_apk_junit_tests"
+      }
+    ]
+  },
   "android_blink_rel": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index d8f2f24..7b57b43821 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -4322,6 +4322,18 @@
   {
     'name': 'tryserver.chromium.android',
     'machines': {
+      'android-kitkat-arm-coverage-dbg': {
+        'mixins': [
+          'code-coverage',
+          'kitkat',
+          'hammerhead',
+        ],
+        'test_suites': {
+          'gtest_tests': 'chromium_android_gtests',
+          'junit_tests': 'chromium_junit_tests',
+        },
+        'os_type': 'android',
+      },
       'android_blink_rel': {
         'mixins': [
           'kitkat',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b0ae402..5defff77 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -5369,6 +5369,21 @@
             ]
         }
     ],
+    "TabToGTSAnimation": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "TabToGTSAnimation"
+                    ]
+                }
+            ]
+        }
+    ],
     "ThirdPartyModulesBlocking": [
         {
             "platforms": [
diff --git a/third_party/blink/common/mediastream/media_stream_controls.cc b/third_party/blink/common/mediastream/media_stream_controls.cc
index b992bd65..8c806fe 100644
--- a/third_party/blink/common/mediastream/media_stream_controls.cc
+++ b/third_party/blink/common/mediastream/media_stream_controls.cc
@@ -6,6 +6,11 @@
 
 namespace blink {
 
+const char kMediaStreamSourceTab[] = "tab";
+const char kMediaStreamSourceScreen[] = "screen";
+const char kMediaStreamSourceDesktop[] = "desktop";
+const char kMediaStreamSourceSystem[] = "system";
+
 TrackControls::TrackControls() {}
 
 TrackControls::TrackControls(bool request, mojom::MediaStreamType type)
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 8492f42..b8265fa 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -276,7 +276,6 @@
     "platform/web_media_player_source.h",
     "platform/web_media_source.h",
     "platform/web_media_stream.h",
-    "platform/web_media_stream_center.h",
     "platform/web_media_stream_source.h",
     "platform/web_media_stream_track.h",
     "platform/web_memory_pressure_level.h",
@@ -391,7 +390,6 @@
     "web/modules/mediastream/web_media_stream_device_observer.h",
     "web/modules/mediastream/web_media_stream_renderer_factory.h",
     "web/modules/mediastream/web_media_stream_utils.h",
-    "web/modules/mediastream/webaudio_media_stream_audio_sink.h",
     "web/modules/mediastream/webmediaplayer_ms.h",
     "web/modules/peerconnection/media_stream_remote_video_source.h",
     "web/modules/service_worker/web_service_worker_context_client.h",
diff --git a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
index 8953e863..285f5dd 100644
--- a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
+++ b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEB_PLATFORM_MEDIA_STREAM_SOURCE_H_
 
 #include "base/callback.h"
+#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
 #include "third_party/blink/public/platform/web_common.h"
@@ -17,15 +18,6 @@
 class MediaStreamSource;
 class WebMediaStreamSource;
 
-// Names for media stream source capture types.
-// These are values set via the "chromeMediaSource" constraint.
-BLINK_PLATFORM_EXPORT extern const char kMediaStreamSourceTab[];
-BLINK_PLATFORM_EXPORT extern const char
-    kMediaStreamSourceScreen[]; /* video only */
-BLINK_PLATFORM_EXPORT extern const char kMediaStreamSourceDesktop[];
-BLINK_PLATFORM_EXPORT extern const char
-    kMediaStreamSourceSystem[]; /* audio only */
-
 class BLINK_PLATFORM_EXPORT WebPlatformMediaStreamSource {
  public:
   using SourceStoppedCallback =
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 6973645..5c249d0 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -122,7 +122,6 @@
 class WebGraphicsContext3DProvider;
 class WebLocalFrame;
 class WebMediaCapabilitiesClient;
-class WebMediaStreamCenter;
 class WebPrescientNetworking;
 class WebPublicSuffixList;
 class WebRtcAudioDeviceImpl;
@@ -584,10 +583,6 @@
   virtual std::unique_ptr<WebRTCCertificateGenerator>
   CreateRTCCertificateGenerator();
 
-  // May return null if WebRTC functionality is not available or out of
-  // resources.
-  virtual std::unique_ptr<WebMediaStreamCenter> CreateMediaStreamCenter();
-
   // Returns the SingleThreadTaskRunner suitable for running WebRTC networking.
   // An rtc::Thread will have already been created.
   // May return null if WebRTC functionality is not implemented.
diff --git a/third_party/blink/public/platform/web_media_stream_center.h b/third_party/blink/public/platform/web_media_stream_center.h
deleted file mode 100644
index 63b5954..0000000
--- a/third_party/blink/public/platform/web_media_stream_center.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_STREAM_CENTER_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_STREAM_CENTER_H_
-
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace blink {
-
-class WebAudioSourceProvider;
-class WebMediaStreamTrack;
-class WebMediaStreamSource;
-
-class WebMediaStreamCenter {
- public:
-  virtual ~WebMediaStreamCenter() = default;
-
-  // Track functionality.
-  virtual void DidCreateMediaStreamTrack(const WebMediaStreamTrack&) {}
-  virtual void DidCloneMediaStreamTrack(const WebMediaStreamTrack& original,
-                                        const WebMediaStreamTrack& clone) {}
-  virtual void DidEnableMediaStreamTrack(const WebMediaStreamTrack&) {}
-  virtual void DidDisableMediaStreamTrack(const WebMediaStreamTrack&) {}
-
-  // Source functionality.
-  virtual void DidStopMediaStreamSource(const WebMediaStreamSource&) {}
-
-  // Caller must take the ownership of the returned |WebAudioSourceProvider|
-  // object.
-  virtual WebAudioSourceProvider* CreateWebAudioSourceFromMediaStreamTrack(
-      const WebMediaStreamTrack&,
-      int context_sample_rate) {
-    return nullptr;
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_STREAM_CENTER_H_
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h
index 20bd110..2a95eb2b 100644
--- a/third_party/blink/public/web/web_view.h
+++ b/third_party/blink/public/web/web_view.h
@@ -182,8 +182,10 @@
   // send it.
   virtual void ClearFocusedElement() = 0;
 
-  // Smooth scroll the root layer to |targetX|, |targetY| in |durationMs|.
-  virtual void SmoothScroll(int target_x, int target_y, uint64_t duration_ms) {}
+  // Smooth scroll the root layer to |targetX|, |targetY| in |duration|.
+  virtual void SmoothScroll(int target_x,
+                            int target_y,
+                            base::TimeDelta duration) {}
 
   // Advance the focus of the WebView forward to the next element or to the
   // previous element in the tab sequence (if reverse is true).
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h
index 02f7e530..10befc559 100644
--- a/third_party/blink/public/web/web_widget_client.h
+++ b/third_party/blink/public/web/web_widget_client.h
@@ -286,7 +286,7 @@
   virtual void StartPageScaleAnimation(const gfx::Vector2d& destination,
                                        bool use_anchor,
                                        float new_page_scale,
-                                       double duration_sec) {}
+                                       base::TimeDelta duration) {}
 
   // For when the embedder itself change scales on the page (e.g. devtools)
   // and wants all of the content at the new scale to be crisp.
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
index bf313ab9..544e49d 100644
--- a/third_party/blink/renderer/core/animation/animation.cc
+++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -464,25 +464,10 @@
   if (!compositor_state_ || compositor_state_->pending_action == kNone)
     return;
 
-  switch (compositor_state_->pending_action) {
-    case kStart:
-      if (compositor_state_->start_time) {
-        DCHECK_EQ(start_time_.value(), compositor_state_->start_time.value());
-        compositor_state_->pending_action = kNone;
-      }
-      break;
-    case kPause:
-    case kPauseThenStart:
-      DCHECK(!start_time_);
-      compositor_state_->pending_action = kNone;
-      SetCurrentTimeInternal(
-          (timeline_time - compositor_state_->start_time.value()) *
-              playback_rate_,
-          kTimingUpdateForAnimationFrame);
-      current_time_pending_ = false;
-      break;
-    default:
-      NOTREACHED();
+  DCHECK_EQ(kStart, compositor_state_->pending_action);
+  if (compositor_state_->start_time) {
+    DCHECK_EQ(start_time_.value(), compositor_state_->start_time.value());
+    compositor_state_->pending_action = kNone;
   }
 }
 
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h
index adbf1e5..f2f3acb 100644
--- a/third_party/blink/renderer/core/animation/animation.h
+++ b/third_party/blink/renderer/core/animation/animation.h
@@ -76,7 +76,7 @@
   enum AnimationPlayState {
     kUnset,
     kIdle,
-    kPending,
+    kPending,  // TODO(crbug.com/958433) remove non-spec compliant state.
     kRunning,
     kPaused,
     kFinished
@@ -245,7 +245,7 @@
                           RegisteredEventListener&) override;
 
  private:
-  // TODO(crbug/960944): Deprecate. This version of the play state is not to
+  // TODO(crbug.com/960944): Deprecate. This version of the play state is not to
   // spec due to the inclusion of a 'pending' state. Whether or not an animation
   // is pending is separate from the actual play state.
   AnimationPlayState PlayStateInternal() const;
@@ -369,7 +369,9 @@
 
   Member<Event> pending_cancelled_event_;
 
-  enum CompositorAction { kNone, kPause, kStart, kPauseThenStart };
+  // TODO(crbug.com/960944): Consider reintroducing kPause and cleanup use of
+  // mutually exclusive pending_play_ and pending_pause_ flags.
+  enum CompositorAction { kNone, kStart };
 
   class CompositorState {
     USING_FAST_MALLOC(CompositorState);
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index f667910..f047854 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -1459,6 +1459,7 @@
       name: "clear",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       field_template: "keyword",
+      computed_style_custom_functions: ["getter"],
       keywords: ["none", "left", "right", "both", "inline-start", "inline-end"],
       typedom_types: ["Keyword"],
       default_value: "none",
@@ -1764,6 +1765,7 @@
       name: "float",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       field_template: "keyword",
+      computed_style_custom_functions: ["getter"],
       keywords: ["none", "left", "right", "inline-start", "inline-end"],
       typedom_types: ["Keyword"],
       default_value: "none",
@@ -2671,10 +2673,11 @@
       property_methods: ["CSSValueFromComputedStyleInternal"],
       field_group: "*",
       field_template: "keyword",
+      computed_style_custom_functions: ["getter"],
+      style_builder_custom_functions: ["value"],
       keywords: ["none", "both", "horizontal", "vertical", "block", "inline"],
       typedom_types: ["Keyword"],
       default_value: "none",
-      style_builder_custom_functions: ["value"],
     },
     {
       name: "right",
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 194854e..557a797 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4011,7 +4011,7 @@
 
     // Send the source ID of the document to the browser.
     if (frame_->Client()->GetRemoteNavigationAssociatedInterfaces()) {
-      mojom::blink::UkmSourceIdFrameHostAssociatedPtr ukm_binding;
+      mojo::AssociatedRemote<mojom::blink::UkmSourceIdFrameHost> ukm_binding;
       frame_->Client()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
           &ukm_binding);
       DCHECK(ukm_binding.is_bound());
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
index 3e9be2f..032b716 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -828,7 +828,7 @@
 static void RemoveHeadContents(ReplacementFragment& fragment) {
   Node* next = nullptr;
   for (Node* node = fragment.FirstChild(); node; node = next) {
-    if (IsHTMLBaseElement(*node) || IsHTMLLinkElement(*node) ||
+    if (IsA<HTMLBaseElement>(*node) || IsHTMLLinkElement(*node) ||
         IsHTMLMetaElement(*node) || IsHTMLTitleElement(*node)) {
       next = NodeTraversal::NextSkippingChildren(*node);
       fragment.RemoveNode(node);
diff --git a/third_party/blink/renderer/core/exported/web_layer_test.cc b/third_party/blink/renderer/core/exported/web_layer_test.cc
index 915e9891..ffbd4a4 100644
--- a/third_party/blink/renderer/core/exported/web_layer_test.cc
+++ b/third_party/blink/renderer/core/exported/web_layer_test.cc
@@ -571,6 +571,91 @@
   EXPECT_FALSE(transform_node->transform_changed);
 }
 
+// This test is similar to |DirectTransformPropertyUpdate| but tests that
+// the changed value of a directly updated transform is still set if some other
+// change causes PaintArtifactCompositor to run and do non-direct updates.
+TEST_P(WebLayerListSimTest, DirectTransformPropertyUpdateCausesChange) {
+  // TODO(crbug.com/765003): CAP may make different layerization decisions and
+  // we cannot guarantee that both divs will be composited in this test. When
+  // CAP gets closer to launch, this test should be updated to pass.
+  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+    return;
+
+  InitializeWithHTML(R"HTML(
+      <!DOCTYPE html>
+      <style>
+        html { overflow: hidden; }
+        #outer {
+          width: 100px;
+          height: 100px;
+          will-change: transform;
+          transform: translate(1px, 2px);
+        }
+        #inner {
+          width: 100px;
+          height: 100px;
+          will-change: transform;
+          background: lightblue;
+          transform: translate(3px, 4px);
+        }
+      </style>
+      <div id='outer'>
+        <div id='inner'></div>
+      </div>
+  )HTML");
+
+  Compositor().BeginFrame();
+
+  auto* outer_element = GetElementById("outer");
+  auto* outer_element_layer = ContentLayerAt(ContentLayerCount() - 2);
+  DCHECK_EQ(outer_element_layer->element_id(),
+            CompositorElementIdFromUniqueObjectId(
+                outer_element->GetLayoutObject()->UniqueId(),
+                CompositorElementIdNamespace::kPrimary));
+  auto outer_transform_tree_index = outer_element_layer->transform_tree_index();
+  auto* outer_transform_node =
+      GetPropertyTrees()->transform_tree.Node(outer_transform_tree_index);
+
+  auto* inner_element = GetElementById("inner");
+  auto* inner_element_layer = ContentLayerAt(ContentLayerCount() - 1);
+  DCHECK_EQ(inner_element_layer->element_id(),
+            CompositorElementIdFromUniqueObjectId(
+                inner_element->GetLayoutObject()->UniqueId(),
+                CompositorElementIdNamespace::kPrimary));
+  auto inner_transform_tree_index = inner_element_layer->transform_tree_index();
+  auto* inner_transform_node =
+      GetPropertyTrees()->transform_tree.Node(inner_transform_tree_index);
+
+  // Initially, the transforms should be unchanged.
+  EXPECT_FALSE(outer_transform_node->transform_changed);
+  EXPECT_FALSE(inner_transform_node->transform_changed);
+  EXPECT_FALSE(paint_artifact_compositor()->NeedsUpdate());
+
+  // Modifying the outer transform in a simple way should allow for a direct
+  // update of the outer transform. Modifying the inner transform in a
+  // non-simple way should not allow for a direct update of the inner transform.
+  outer_element->setAttribute(html_names::kStyleAttr,
+                              "transform: translate(5px, 6px)");
+  inner_element->setAttribute(html_names::kStyleAttr,
+                              "transform: rotate(30deg)");
+  UpdateAllLifecyclePhasesExceptPaint();
+  EXPECT_TRUE(outer_transform_node->transform_changed);
+  EXPECT_FALSE(inner_transform_node->transform_changed);
+  EXPECT_TRUE(paint_artifact_compositor()->NeedsUpdate());
+
+  // After a PaintArtifactCompositor update, which was needed due to the inner
+  // element's transform change, both the inner and outer transform nodes
+  // should be marked as changed to ensure they result in damage.
+  UpdateAllLifecyclePhases();
+  EXPECT_TRUE(outer_transform_node->transform_changed);
+  EXPECT_TRUE(inner_transform_node->transform_changed);
+
+  // After a frame the |transform_changed| values should be reset.
+  Compositor().BeginFrame();
+  EXPECT_FALSE(outer_transform_node->transform_changed);
+  EXPECT_FALSE(inner_transform_node->transform_changed);
+}
+
 // This test ensures that the correct transform nodes are created and bits set
 // so that the browser controls movement adjustments needed by bottom-fixed
 // elements will work.
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
index 1e22b76..ba31e537 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -885,7 +885,7 @@
   WebViewImpl* web_view = web_view_helper.InitializeAndLoad(
       base_url_ + "plugin_scroll.html", &plugin_web_frame_client);
   EnablePlugins(web_view, WebSize(300, 300));
-  web_view->SmoothScroll(0, 200, 0);
+  web_view->SmoothScroll(0, 200, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -926,7 +926,7 @@
   WebViewImpl* web_view = web_view_helper.InitializeAndLoad(
       base_url_ + "plugin_scroll.html", &plugin_web_frame_client);
   EnablePlugins(web_view, WebSize(300, 300));
-  web_view->SmoothScroll(0, 200, 0);
+  web_view->SmoothScroll(0, 200, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1020,7 +1020,7 @@
   WebViewImpl* web_view = web_view_helper.InitializeAndLoad(
       base_url_ + "plugin_scroll.html", &plugin_web_frame_client);
   EnablePlugins(web_view, WebSize(300, 300));
-  web_view->SmoothScroll(0, 200, 0);
+  web_view->SmoothScroll(0, 200, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1057,7 +1057,7 @@
   WebViewImpl* web_view = web_view_helper.InitializeAndLoad(
       base_url_ + "plugin_scroll.html", &plugin_web_frame_client);
   EnablePlugins(web_view, WebSize(300, 300));
-  web_view->SmoothScroll(0, 200, 0);
+  web_view->SmoothScroll(0, 200, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1096,7 +1096,7 @@
   web_view->GetSettings()->SetPluginsEnabled(true);
   web_view->MainFrameWidget()->Resize(WebSize(300, 300));
   web_view->SetPageScaleFactor(2);
-  web_view->SmoothScroll(0, 300, 0);
+  web_view->SmoothScroll(0, 300, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1137,7 +1137,7 @@
   web_view->GetSettings()->SetPluginsEnabled(true);
   web_view->MainFrameWidget()->Resize(WebSize(300, 300));
   web_view->SetPageScaleFactor(2);
-  web_view->SmoothScroll(0, 300, 0);
+  web_view->SmoothScroll(0, 300, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1179,7 +1179,7 @@
   web_view->GetSettings()->SetPluginsEnabled(true);
   web_view->MainFrameWidget()->Resize(WebSize(300, 300));
   web_view->SetPageScaleFactor(2);
-  web_view->SmoothScroll(0, 300, 0);
+  web_view->SmoothScroll(0, 300, base::TimeDelta());
   UpdateAllLifecyclePhases(web_view);
   RunPendingTasks();
 
@@ -1362,7 +1362,8 @@
   for (auto& root_document_scroll_to : root_document_scrolls_to) {
     for (auto& iframe_scroll_to : iframe_scrolls_to) {
       web_view->SmoothScroll(root_document_scroll_to.Width(),
-                             root_document_scroll_to.Height(), 0);
+                             root_document_scroll_to.Height(),
+                             base::TimeDelta());
       iframe->SetScrollOffset(iframe_scroll_to);
       UpdateAllLifecyclePhases(web_view);
       RunPendingTasks();
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index b140c50..ef0587c 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -178,17 +178,19 @@
 static const float minScaleDifference = 0.01f;
 static const float doubleTapZoomContentDefaultMargin = 5;
 static const float doubleTapZoomContentMinimumMargin = 2;
-static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
+static constexpr base::TimeDelta kDoubleTapZoomAnimationDuration =
+    base::TimeDelta::FromMilliseconds(250);
 static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
 
-static const double findInPageAnimationDurationInSeconds = 0;
+static constexpr base::TimeDelta kFindInPageAnimationDuration;
 
 // Constants for viewport anchoring on resize.
 static const float viewportAnchorCoordX = 0.5f;
 static const float viewportAnchorCoordY = 0;
 
 // Constants for zooming in on a focused text field.
-static const double scrollAndScaleAnimationDurationInSeconds = 0.2;
+static constexpr base::TimeDelta kScrollAndScaleAnimationDuration =
+    base::TimeDelta::FromMicroseconds(200);
 static const int minReadableCaretHeight = 16;
 static const int minReadableCaretHeightForTextArea = 13;
 static const float minScaleChangeToTriggerZoom = 1.5f;
@@ -615,7 +617,7 @@
 bool WebViewImpl::StartPageScaleAnimation(const IntPoint& target_position,
                                           bool use_anchor,
                                           float new_scale,
-                                          double duration_in_seconds) {
+                                          base::TimeDelta duration) {
   // PageScaleFactor is a property of the main frame only, and only exists when
   // compositing.
   DCHECK(MainFrameImpl());
@@ -626,7 +628,7 @@
   if (!use_anchor) {
     clamped_point =
         visual_viewport.ClampDocumentOffsetAtScale(target_position, new_scale);
-    if (!duration_in_seconds) {
+    if (duration.is_zero()) {
       SetPageScaleFactor(new_scale);
 
       LocalFrameView* view = MainFrameImpl()->GetFrameView();
@@ -649,7 +651,7 @@
   } else {
     AsWidget().client->StartPageScaleAnimation(
         static_cast<gfx::Vector2d>(target_position), use_anchor, new_scale,
-        duration_in_seconds);
+        duration);
   }
   return true;
 }
@@ -1040,11 +1042,11 @@
     IntPoint target_position =
         MainFrameImpl()->GetFrameView()->RootFrameToDocument(
             IntPoint(point_in_root_frame.x(), point_in_root_frame.y()));
-    is_animating = StartPageScaleAnimation(
-        target_position, true, scale, doubleTapZoomAnimationDurationInSeconds);
+    is_animating = StartPageScaleAnimation(target_position, true, scale,
+                                           kDoubleTapZoomAnimationDuration);
   } else {
-    is_animating = StartPageScaleAnimation(
-        scroll, false, scale, doubleTapZoomAnimationDurationInSeconds);
+    is_animating = StartPageScaleAnimation(scroll, false, scale,
+                                           kDoubleTapZoomAnimationDuration);
   }
 
   // TODO(dglazkov): The only reason why we're using isAnimating and not just
@@ -1078,8 +1080,7 @@
       gfx::Point(rect_in_root_frame.x, rect_in_root_frame.y), block_bounds,
       nonUserInitiatedPointPadding, MinimumPageScaleFactor(), scale, scroll);
 
-  StartPageScaleAnimation(scroll, false, scale,
-                          findInPageAnimationDurationInSeconds);
+  StartPageScaleAnimation(scroll, false, scale, kFindInPageAnimationDuration);
 }
 
 #if !defined(OS_MACOSX)
@@ -2191,16 +2192,15 @@
       zoom_into_legible_scale, scale, scroll, need_animation);
   if (need_animation) {
     StartPageScaleAnimation(scroll, false, scale,
-                            scrollAndScaleAnimationDurationInSeconds);
+                            kScrollAndScaleAnimationDuration);
   }
 }
 
 void WebViewImpl::SmoothScroll(int target_x,
                                int target_y,
-                               uint64_t duration_ms) {
+                               base::TimeDelta duration) {
   IntPoint target_position(target_x, target_y);
-  StartPageScaleAnimation(target_position, false, PageScaleFactor(),
-                          (double)duration_ms / 1000);
+  StartPageScaleAnimation(target_position, false, PageScaleFactor(), duration);
 }
 
 void WebViewImpl::ComputeScaleAndScrollForEditableElementRects(
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index 720ea6fc..72c2a7e 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -141,7 +141,9 @@
   void FocusDocumentView(WebFrame*) override;
   void SetInitialFocus(bool reverse) override;
   void ClearFocusedElement() override;
-  void SmoothScroll(int target_x, int target_y, uint64_t duration_ms) override;
+  void SmoothScroll(int target_x,
+                    int target_y,
+                    base::TimeDelta duration) override;
   void AdvanceFocus(bool reverse) override;
   void AdvanceFocusAcrossFrames(WebFocusType,
                                 WebRemoteFrame* from,
@@ -259,7 +261,7 @@
   bool StartPageScaleAnimation(const IntPoint& target_position,
                                bool use_anchor,
                                float new_scale,
-                               double duration_in_seconds);
+                               base::TimeDelta duration);
 
   // Handles context menu events orignated via the the keyboard. These
   // include the VK_APPS virtual key and the Shift+F10 combine. Code is
diff --git a/third_party/blink/renderer/core/frame/viewport_data.h b/third_party/blink/renderer/core/frame/viewport_data.h
index 58569a9..439b0a2 100644
--- a/third_party/blink/renderer/core/frame/viewport_data.h
+++ b/third_party/blink/renderer/core/frame/viewport_data.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIEWPORT_DATA_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIEWPORT_DATA_H_
 
+#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/page/viewport_description.h"
@@ -49,7 +50,7 @@
   mojom::ViewportFit viewport_fit_ = blink::mojom::ViewportFit::kAuto;
   bool force_expand_display_cutout_ = false;
 
-  mojom::blink::DisplayCutoutHostAssociatedPtr display_cutout_host_;
+  mojo::AssociatedRemote<mojom::blink::DisplayCutoutHost> display_cutout_host_;
 };
 
 inline bool ViewportData::ShouldOverrideLegacyDescription(
diff --git a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
index 529c941..3022e68b 100644
--- a/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
@@ -160,7 +160,7 @@
       // See http://msdn2.microsoft.com/en-us/library/ms537628(VS.85).aspx.
       result.Append(
           WebFrameSerializer::GenerateMarkOfTheWebDeclaration(param->url));
-    } else if (IsHTMLBaseElement(*element)) {
+    } else if (IsA<HTMLBaseElement>(*element)) {
       // Comment the BASE tag when serializing dom.
       result.Append("<!--");
     }
@@ -249,7 +249,7 @@
   if (!param->is_html_document)
     return result.ToString();
   // Comment the BASE tag when serializing DOM.
-  if (IsHTMLBaseElement(*element)) {
+  if (IsA<HTMLBaseElement>(*element)) {
     result.Append("-->");
     // Append a new base tag declaration.
     result.Append(GenerateBaseTagDeclaration(param->document->BaseTarget()));
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.cc b/third_party/blink/renderer/core/html/portal/portal_host.cc
index 0754209..706104f 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.cc
+++ b/third_party/blink/renderer/core/html/portal/portal_host.cc
@@ -59,7 +59,7 @@
 }
 
 void PortalHost::OnPortalActivated() {
-  portal_host_ptr_.reset();
+  portal_host_.reset();
 }
 
 void PortalHost::postMessage(ScriptState* script_state,
@@ -127,14 +127,14 @@
 }
 
 mojom::blink::PortalHost& PortalHost::GetPortalHostInterface() {
-  if (!portal_host_ptr_) {
+  if (!portal_host_) {
     DCHECK(GetDocument()->GetFrame());
     GetDocument()
         ->GetFrame()
         ->GetRemoteNavigationAssociatedInterfaces()
-        ->GetInterface(&portal_host_ptr_);
+        ->GetInterface(&portal_host_);
   }
-  return *portal_host_ptr_;
+  return *portal_host_.get();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/portal/portal_host.h b/third_party/blink/renderer/core/html/portal/portal_host.h
index 9fa6c67e..24fa31c5 100644
--- a/third_party/blink/renderer/core/html/portal/portal_host.h
+++ b/third_party/blink/renderer/core/html/portal/portal_host.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_HOST_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_PORTAL_HOST_H_
 
+#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "third_party/blink/public/mojom/portal/portal.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
@@ -65,7 +66,7 @@
  private:
   mojom::blink::PortalHost& GetPortalHostInterface();
 
-  mojom::blink::PortalHostAssociatedPtr portal_host_ptr_;
+  mojo::AssociatedRemote<mojom::blink::PortalHost> portal_host_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn
index 889c30d..78848ded 100644
--- a/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -294,8 +294,6 @@
     "line/word_measurement.h",
     "list_marker_text.cc",
     "list_marker_text.h",
-    "logical_values.cc",
-    "logical_values.h",
     "map_coordinates_flags.h",
     "min_max_size.cc",
     "min_max_size.h",
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index e9d2cece..3ae2331 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/renderer/core/layout/layout_theme.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
 #include "third_party/blink/renderer/core/layout/text_autosizer.h"
@@ -1570,7 +1569,7 @@
     if (child->IsFloating() ||
         (child->IsBox() && ToLayoutBox(child)->CreatesNewFormattingContext())) {
       LayoutUnit float_total_width = float_left_width + float_right_width;
-      EClear c = ResolvedClear(*child_style, style_to_use);
+      EClear c = child_style->Clear(style_to_use);
       if (c == EClear::kBoth || c == EClear::kLeft) {
         max_logical_width = std::max(float_total_width, max_logical_width);
         float_left_width = LayoutUnit();
@@ -1641,7 +1640,7 @@
     }
 
     if (child->IsFloating()) {
-      if (ResolvedFloating(*child_style, style_to_use) == EFloat::kLeft)
+      if (child_style->Floating(style_to_use) == EFloat::kLeft)
         float_left_width += w;
       else
         float_right_width += w;
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc
index db774ae..78aa529 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -51,7 +51,6 @@
 #include "third_party/blink/renderer/core/layout/line/inline_iterator.h"
 #include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
 #include "third_party/blink/renderer/core/layout/line/line_width.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_line_height_metrics.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
 #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
@@ -2193,7 +2192,7 @@
   // require clearance to move past any floats. If that's the case we want to be
   // sure we estimate the correct position including margins after any floats
   // rather than use 'clearance' later which could give us the wrong position.
-  if (grandchild_box->StyleRef().Clear() != EClear::kNone &&
+  if (grandchild_box->StyleRef().HasClear() &&
       child_block_flow->MarginBeforeForChild(*grandchild_box) == 0)
     return;
 
@@ -2876,7 +2875,7 @@
 
   // At least one float is present. We need to perform the clearance
   // computation.
-  EClear clear = ResolvedClear(child->StyleRef(), StyleRef());
+  EClear clear = child->StyleRef().Clear(StyleRef());
   LayoutUnit logical_bottom = LowestFloatLogicalBottom(clear);
 
   // We also clear floats if we are too big to sit on the same line as a float
@@ -3683,7 +3682,7 @@
 
   LayoutUnit float_logical_left;
 
-  if (ResolvedFloating(child_box->StyleRef(), StyleRef()) == EFloat::kLeft) {
+  if (child_box->StyleRef().Floating(StyleRef()) == EFloat::kLeft) {
     LayoutUnit height_remaining_left = LayoutUnit(1);
     LayoutUnit height_remaining_right = LayoutUnit(1);
     float_logical_left = LogicalLeftOffsetForPositioningFloat(
@@ -3740,7 +3739,7 @@
   }
 
   // Create the special object entry & append it to the list
-  EFloat f = ResolvedFloating(float_box.StyleRef(), StyleRef());
+  EFloat f = float_box.StyleRef().Floating(StyleRef());
   DCHECK(f == EFloat::kLeft || f == EFloat::kRight);
   FloatingObject::Type type = f == EFloat::kLeft ? FloatingObject::kFloatLeft
                                                  : FloatingObject::kFloatRight;
@@ -3882,9 +3881,9 @@
   // FIXME Investigate if this can be removed. crbug.com/370006
   child.SetShouldCheckForPaintInvalidation();
 
-  logical_top_margin_edge = std::max(
-      logical_top_margin_edge,
-      LowestFloatLogicalBottom(ResolvedClear(child.StyleRef(), StyleRef())));
+  logical_top_margin_edge =
+      std::max(logical_top_margin_edge,
+               LowestFloatLogicalBottom(child.StyleRef().Clear(StyleRef())));
 
   bool is_paginated = View()->GetLayoutState()->IsPaginated();
   if (is_paginated && !ChildrenInline()) {
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
index bd50e65..c201c41 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -36,7 +36,6 @@
 #include "third_party/blink/renderer/core/layout/line/line_layout_state.h"
 #include "third_party/blink/renderer/core/layout/line/line_width.h"
 #include "third_party/blink/renderer/core/layout/line/word_measurement.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h"
 #include "third_party/blink/renderer/core/layout/vertical_position_cache.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -1719,8 +1718,8 @@
         bool clear_previous_float;
         if (child->IsFloating()) {
           if (prev_float) {
-            EFloat f = ResolvedFloating(prev_float->StyleRef(), style_to_use);
-            EClear c = ResolvedClear(child->StyleRef(), style_to_use);
+            EFloat f = prev_float->StyleRef().Floating(style_to_use);
+            EClear c = child->StyleRef().Clear(style_to_use);
             clear_previous_float =
                 ((f == EFloat::kLeft &&
                   (c == EClear::kBoth || c == EClear::kLeft)) ||
@@ -2212,7 +2211,7 @@
                             ? curr->LastLeafChild()
                             : curr->FirstLeafChild();
   return last_box && last_box->GetLineLayoutItem().IsBR() &&
-         last_box->GetLineLayoutItem().StyleRef().Clear() != EClear::kNone;
+         last_box->GetLineLayoutItem().StyleRef().HasClear();
 }
 
 void LayoutBlockFlow::DetermineEndPosition(LineLayoutState& layout_state,
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 73fc77c..e847325 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -970,8 +970,7 @@
   // We need a special case for <iframe> because they never have
   // hasOverflowClip(). However, they do "implicitly" clip their contents, so
   // we want to allow resizing them also.
-  return (HasOverflowClip() || IsLayoutIFrame()) &&
-         StyleRef().Resize() != EResize::kNone;
+  return (HasOverflowClip() || IsLayoutIFrame()) && StyleRef().HasResize();
 }
 
 int LayoutBox::VerticalScrollbarWidth() const {
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.cc b/third_party/blink/renderer/core/layout/layout_iframe.cc
index ca2683d..16d4025 100644
--- a/third_party/blink/renderer/core/layout/layout_iframe.cc
+++ b/third_party/blink/renderer/core/layout/layout_iframe.cc
@@ -41,7 +41,7 @@
 }
 
 PaintLayerType LayoutIFrame::LayerTypeRequired() const {
-  if (StyleRef().Resize() != EResize::kNone)
+  if (StyleRef().HasResize())
     return kNormalPaintLayer;
   return LayoutEmbeddedContent::LayerTypeRequired();
 }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 8347467..5b3ddd3e 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -2208,7 +2208,8 @@
         layer->DirtyVisibleContentStatus();
     }
 
-    if (IsFloating() && (style_->Floating() != new_style.Floating())) {
+    if (IsFloating() &&
+        (style_->UnresolvedFloating() != new_style.UnresolvedFloating())) {
       // For changes in float styles, we need to conceivably remove ourselves
       // from the floating objects list.
       ToLayoutBox(this)->RemoveFloatingOrPositionedChildFromBlockLists();
diff --git a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
index 982f459d..c17e3bf 100644
--- a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
+++ b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
@@ -39,7 +39,6 @@
 #include "third_party/blink/renderer/core/layout/line/line_width.h"
 #include "third_party/blink/renderer/core/layout/line/trailing_objects.h"
 #include "third_party/blink/renderer/core/layout/line/word_measurement.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/text_run_constructor.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/platform/fonts/character_range.h"
@@ -421,11 +420,11 @@
     // A <br> with clearance always needs a linebox in case the lines below it
     // get dirtied later and need to check for floats to clear - so if we're
     // ignoring spaces, stop ignoring them and add a run for this object.
-    if (ignoring_spaces_ && current_style_->Clear() != EClear::kNone)
+    if (ignoring_spaces_ && current_style_->HasClear())
       EnsureLineBoxInsideIgnoredSpaces(&line_midpoint_state_, br);
 
     if (!line_info_.IsEmpty())
-      clear = ResolvedClear(*current_style_, block_.StyleRef());
+      clear = current_style_->Clear(block_.StyleRef());
   }
   at_end_ = true;
 }
diff --git a/third_party/blink/renderer/core/layout/logical_values.cc b/third_party/blink/renderer/core/layout/logical_values.cc
deleted file mode 100644
index dc275ba..0000000
--- a/third_party/blink/renderer/core/layout/logical_values.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/layout/logical_values.h"
-
-namespace blink {
-
-EClear ResolvedClear(EClear value, TextDirection direction) {
-  switch (value) {
-    case EClear::kInlineStart:
-    case EClear::kInlineEnd: {
-      return IsLtr(direction) == (value == EClear::kInlineStart)
-                 ? EClear::kLeft
-                 : EClear::kRight;
-    }
-    default:
-      return value;
-  }
-}
-
-EFloat ResolvedFloating(EFloat value, TextDirection direction) {
-  switch (value) {
-    case EFloat::kInlineStart:
-    case EFloat::kInlineEnd: {
-      return IsLtr(direction) == (value == EFloat::kInlineStart)
-                 ? EFloat::kLeft
-                 : EFloat::kRight;
-    }
-    default:
-      return value;
-  }
-}
-
-EResize ResolvedResize(EResize value, WritingMode writing_mode) {
-  switch (value) {
-    case EResize::kBlock:
-    case EResize::kInline: {
-      return IsHorizontalWritingMode(writing_mode) == (value == EResize::kBlock)
-                 ? EResize::kVertical
-                 : EResize::kHorizontal;
-    }
-    default:
-      return value;
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/logical_values.h b/third_party/blink/renderer/core/layout/logical_values.h
deleted file mode 100644
index 5d1dee1..0000000
--- a/third_party/blink/renderer/core/layout/logical_values.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LOGICAL_VALUES_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LOGICAL_VALUES_H_
-
-#include "third_party/blink/renderer/core/style/computed_style.h"
-
-namespace blink {
-
-// The following functions resolve CSS logical values and return other ones
-// as-is. They can be called with the value to be resolved and the TextDirection
-// or WritingMode that will be used for that resolution. Alternatively, they
-// also accept two ComputedStyle arguments, the first one to retrieve the value,
-// and the second one to get the TextDirection or WritingMode.
-
-EClear ResolvedClear(EClear, TextDirection);
-inline EClear ResolvedClear(const ComputedStyle& style,
-                            const ComputedStyle& cb_style) {
-  return ResolvedClear(style.Clear(), cb_style.Direction());
-}
-
-EFloat ResolvedFloating(EFloat, TextDirection);
-inline EFloat ResolvedFloating(const ComputedStyle& style,
-                               const ComputedStyle& cb_style) {
-  return ResolvedFloating(style.Floating(), cb_style.Direction());
-}
-
-EResize ResolvedResize(EResize, WritingMode);
-inline EResize ResolvedResize(const ComputedStyle& style,
-                              const ComputedStyle& cb_style) {
-  return ResolvedResize(style.Resize(), cb_style.GetWritingMode());
-}
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LOGICAL_VALUES_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index d82beb0f..8d4eb455 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
@@ -763,7 +762,7 @@
     NGBfcOffset bfc_offset = {ContainerBfcOffset().line_offset,
                               ContainerBfcOffset().block_offset + content_size};
     AdjustToClearance(
-        exclusion_space.ClearanceOffset(ResolvedClear(*item.Style(), Style())),
+        exclusion_space.ClearanceOffset(item.Style()->Clear(Style())),
         &bfc_offset);
     content_size = bfc_offset.block_offset - ContainerBfcOffset().block_offset;
   }
@@ -987,8 +986,8 @@
       continue;
 
     container_builder_.AddAdjoiningObjectTypes(
-        ResolvedFloating(item.GetLayoutObject()->StyleRef().Floating(),
-                         ConstraintSpace().Direction()) == EFloat::kLeft
+        item.GetLayoutObject()->StyleRef().Floating(
+            ConstraintSpace().Direction()) == EFloat::kLeft
             ? kAdjoiningFloatLeft
             : kAdjoiningFloatRight);
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index 912fa83b..37b7eaa 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -13,7 +13,6 @@
 #include "third_party/blink/renderer/core/layout/layout_list_marker.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/layout_text.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_dirty_lines.h"
@@ -1104,7 +1103,7 @@
       EFloat previous_float_type = EFloat::kNone;
       for (const auto& floating_object : floating_objects_) {
         const EClear float_clear =
-            ResolvedClear(floating_object.float_style, floating_object.style);
+            floating_object.float_style.Clear(floating_object.style);
 
         // If this float clears the previous float we start a new "line".
         // This is subtly different to block layout which will only reset either
@@ -1122,8 +1121,8 @@
         // such float should not affect the content size.
         floats_inline_size_ += floating_object.float_inline_max_size_with_margin
                                    .ClampNegativeToZero();
-        previous_float_type = ResolvedFloating(floating_object.float_style,
-                                               floating_object.style);
+        previous_float_type =
+            floating_object.float_style.Floating(floating_object.style);
       }
       max_inline_size =
           std::max(max_inline_size, line_inline_size + floats_inline_size_);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index f708c43..6253874 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -4,7 +4,6 @@
 
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h"
 
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index fcb374b0..be4bc92 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -10,7 +10,6 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
@@ -72,7 +71,7 @@
     NGAdjoiningObjectTypes adjoining_object_types,
     const ComputedStyle& child_style,
     const ComputedStyle& cb_style) {
-  return ToAdjoiningObjectTypes(ResolvedClear(child_style, cb_style)) &
+  return ToAdjoiningObjectTypes(child_style.Clear(cb_style)) &
          adjoining_object_types;
 }
 
@@ -205,7 +204,7 @@
       continue;
 
     const ComputedStyle& child_style = child.Style();
-    const EClear child_clear = ResolvedClear(child_style, Style());
+    const EClear child_clear = child_style.Clear(Style());
     bool child_is_new_fc = child.CreatesNewFormattingContext();
 
     // Conceptually floats and a single new-FC would just get positioned on a
@@ -263,7 +262,7 @@
       // the content area, by e.g., negative margins. Such floats do not affect
       // the content size.
       if (float_inline_size > 0) {
-        if (ResolvedFloating(child_style, Style()) == EFloat::kLeft)
+        if (child_style.Floating(Style()) == EFloat::kLeft)
           float_left_inline_size += float_inline_size;
         else
           float_right_inline_size += float_inline_size;
@@ -1172,7 +1171,7 @@
   // The origin offset is where we should start looking for layout
   // opportunities. It needs to be adjusted by the child's clearance.
   AdjustToClearance(
-      exclusion_space_.ClearanceOffset(ResolvedClear(child.Style(), Style())),
+      exclusion_space_.ClearanceOffset(child.Style().Clear(Style())),
       &origin_offset);
   DCHECK(container_builder_.BfcBlockOffset());
 
@@ -1310,8 +1309,8 @@
     // Set the forced BFC block-offset to the appropriate clearance offset to
     // force this placement of this child.
     if (has_clearance_past_adjoining_floats) {
-      forced_bfc_block_offset = exclusion_space_.ClearanceOffset(
-          ResolvedClear(child.Style(), Style()));
+      forced_bfc_block_offset =
+          exclusion_space_.ClearanceOffset(child.Style().Clear(Style()));
     }
   }
 
@@ -1401,8 +1400,7 @@
   // abort our layout if needed.
   if (!child_bfc_block_offset) {
     DCHECK(is_self_collapsing);
-    if (child_space.HasClearanceOffset() &&
-        child.Style().Clear() != EClear::kNone) {
+    if (child_space.HasClearanceOffset() && child.Style().HasClear()) {
       // This is a self-collapsing child that we collapsed through, so we have
       // to detect clearance manually. See if the child's hypothetical border
       // edge is past the relevant floats. If it's not, we need to apply
@@ -2253,7 +2251,7 @@
                                     : ConstraintSpace().ClearanceOffset();
   if (child.IsBlock()) {
     LayoutUnit child_clearance_offset =
-        exclusion_space_.ClearanceOffset(ResolvedClear(child_style, Style()));
+        exclusion_space_.ClearanceOffset(child_style.Clear(Style()));
     clearance_offset = std::max(clearance_offset, child_clearance_offset);
     builder.SetTextDirection(child_style.Direction());
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
index 662e76a..27334d5e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
@@ -4,7 +4,6 @@
 
 #include "third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h"
 
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
@@ -253,7 +252,7 @@
 
     exclusion_space_.Add(
         NGExclusion::Create(NGBfcRect(start_offset, end_offset),
-                            ResolvedFloating(child_style, Style()), nullptr));
+                            child_style.Floating(Style()), nullptr));
   }
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h b/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
index 0d670953..b0148f5 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
@@ -6,7 +6,6 @@
 #define NGUnpositionedFloat_h
 
 #include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
@@ -41,16 +40,14 @@
   scoped_refptr<const NGLayoutResult> layout_result;
   NGBoxStrut margins;
 
-  bool IsLineLeft(TextDirection direction) const {
-    return ResolvedFloating(node.Style().Floating(), direction) ==
-           EFloat::kLeft;
+  bool IsLineLeft(TextDirection cb_direction) const {
+    return node.Style().Floating(cb_direction) == EFloat::kLeft;
   }
-  bool IsLineRight(TextDirection direction) const {
-    return ResolvedFloating(node.Style().Floating(), direction) ==
-           EFloat::kRight;
+  bool IsLineRight(TextDirection cb_direction) const {
+    return node.Style().Floating(cb_direction) == EFloat::kRight;
   }
-  EClear ClearType(TextDirection direction) const {
-    return ResolvedClear(node.Style().Clear(), direction);
+  EClear ClearType(TextDirection cb_direction) const {
+    return node.Style().Clear(cb_direction);
   }
 };
 
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc
index 7b7a58c8..9a7f3356 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -844,7 +844,7 @@
     data.packed_style_properties_ |=
         (static_cast<unsigned>(style->GetPosition()) << 1);
     data.packed_style_properties_ |=
-        (static_cast<unsigned>(style->Floating()) << 4);
+        (static_cast<unsigned>(style->UnresolvedFloating()) << 4);
     data.packed_style_properties_ |=
         (static_cast<unsigned>(style->Display()) << 7);
     data.packed_style_properties_ |= (style->Width().GetType() << 12);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index 9684cf97..0a9cc07c 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -180,7 +180,7 @@
                                           nullptr));
       // We need enter to activate links, etc. The click should be after the
       // focus in case the site transfers focus upon clicking.
-      interest_element->DispatchSimulatedClick(event);
+      interest_element->DispatchSimulatedClick(event, kSendMouseUpDownEvents);
     }
   }
 
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_test.cc b/third_party/blink/renderer/core/page/spatial_navigation_test.cc
index 63a57e5..88ac29f3 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_test.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_test.cc
@@ -11,8 +11,12 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 #include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
 #include "ui/events/keycodes/dom/dom_key.h"
@@ -712,4 +716,75 @@
   EXPECT_FALSE(b->IsActive());
 }
 
+class FocuslessSpatialNavigationSimTest : public SimTest {
+ public:
+  FocuslessSpatialNavigationSimTest() : use_focusless_mode_(true) {}
+
+  void SetUp() override {
+    SimTest::SetUp();
+    WebView().GetPage()->GetSettings().SetSpatialNavigationEnabled(true);
+  }
+
+  void SimulateKeyPress(int dom_key) {
+    WebKeyboardEvent event{WebInputEvent::kRawKeyDown,
+                           WebInputEvent::kNoModifiers,
+                           WebInputEvent::GetStaticTimeStampForTests()};
+    event.dom_key = dom_key;
+    WebView().MainFrameWidget()->HandleInputEvent(
+        WebCoalescedInputEvent(event));
+
+    if (dom_key == ui::DomKey::ENTER) {
+      event.SetType(WebInputEvent::kChar);
+      WebView().MainFrameWidget()->HandleInputEvent(
+          WebCoalescedInputEvent(event));
+    }
+
+    event.SetType(WebInputEvent::kKeyUp);
+    WebView().MainFrameWidget()->HandleInputEvent(
+        WebCoalescedInputEvent(event));
+  }
+
+  ScopedFocuslessSpatialNavigationForTest use_focusless_mode_;
+};
+
+// Tests that opening a <select> popup works by pressing enter from
+// "interested" mode, without being focused.
+TEST_F(FocuslessSpatialNavigationSimTest, OpenSelectPopup) {
+  // This test requires PagePopup since we're testing opening the <select> drop
+  // down so skip this test on platforms (i.e. Android) that don't use this.
+  if (!RuntimeEnabledFeatures::PagePopupEnabled())
+    return;
+
+  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
+  WebView().MainFrameWidget()->SetFocus(true);
+  WebView().SetIsActive(true);
+
+  SimRequest request("https://example.com/test.html", "text/html");
+  LoadURL("https://example.com/test.html");
+  request.Complete(R"HTML(
+          <!DOCTYPE html>
+          <select id="target">
+            <option>A</option>
+            <option>B</option>
+            <option>C</option>
+          </select>
+      )HTML");
+  Compositor().BeginFrame();
+
+  HTMLSelectElement* select =
+      ToHTMLSelectElement(GetDocument().getElementById("target"));
+  SimulateKeyPress(ui::DomKey::ARROW_DOWN);
+
+  SpatialNavigationController& spat_nav_controller =
+      GetDocument().GetPage()->GetSpatialNavigationController();
+
+  ASSERT_EQ(select, spat_nav_controller.GetInterestedElement());
+  ASSERT_NE(select, GetDocument().ActiveElement());
+  ASSERT_FALSE(select->PopupIsVisible());
+
+  // The enter key should cause the popup to open.
+  SimulateKeyPress(ui::DomKey::ENTER);
+  EXPECT_TRUE(select->PopupIsVisible());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index a9940e5..0eacc969 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1634,10 +1634,9 @@
 }
 
 bool PaintLayer::HasOverflowControls() const {
-  return scrollable_area_ &&
-         (scrollable_area_->HasScrollbar() ||
-          scrollable_area_->ScrollCorner() ||
-          GetLayoutObject().StyleRef().Resize() != EResize::kNone);
+  return scrollable_area_ && (scrollable_area_->HasScrollbar() ||
+                              scrollable_area_->ScrollCorner() ||
+                              GetLayoutObject().StyleRef().HasResize());
 }
 
 void PaintLayer::AppendSingleFragmentIgnoringPagination(
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 1a8150aa..b75eb409 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -77,7 +77,6 @@
 #include "third_party/blink/renderer/core/layout/layout_scrollbar_part.h"
 #include "third_party/blink/renderer/core/layout/layout_theme.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/layout/logical_values.h"
 #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
@@ -340,7 +339,7 @@
   // (b) Both scrollbars are present.
   bool has_horizontal_bar = HorizontalScrollbar();
   bool has_vertical_bar = VerticalScrollbar();
-  bool has_resizer = GetLayoutBox()->StyleRef().Resize() != EResize::kNone;
+  bool has_resizer = GetLayoutBox()->StyleRef().HasResize();
   if ((has_horizontal_bar && has_vertical_bar) ||
       (has_resizer && (has_horizontal_bar || has_vertical_bar))) {
     return CornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
@@ -1700,7 +1699,7 @@
     return false;
 
   IntRect resize_control_rect;
-  if (GetLayoutBox()->StyleRef().Resize() != EResize::kNone) {
+  if (GetLayoutBox()->StyleRef().HasResize()) {
     resize_control_rect =
         ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
                               Layer()->SubpixelAccumulation()),
@@ -1756,7 +1755,7 @@
 IntRect PaintLayerScrollableArea::ResizerCornerRect(
     const IntRect& bounds,
     ResizerHitTestType resizer_hit_test_type) const {
-  if (GetLayoutBox()->StyleRef().Resize() == EResize::kNone)
+  if (!GetLayoutBox()->StyleRef().HasResize())
     return IntRect();
   IntRect corner = CornerRect(bounds);
 
@@ -1836,7 +1835,8 @@
 void PaintLayerScrollableArea::UpdateResizerStyle(
     const ComputedStyle* old_style) {
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && old_style &&
-      old_style->Resize() != GetLayoutBox()->StyleRef().Resize()) {
+      old_style->UnresolvedResize() !=
+          GetLayoutBox()->StyleRef().UnresolvedResize()) {
     // Invalidate the composited scroll corner layer on resize style change.
     if (auto* graphics_layer = LayerForScrollCorner())
       graphics_layer->SetNeedsDisplay();
@@ -1972,9 +1972,8 @@
   bool is_box_sizing_border =
       GetLayoutBox()->StyleRef().BoxSizing() == EBoxSizing::kBorderBox;
 
-  EResize resize =
-      ResolvedResize(GetLayoutBox()->StyleRef(),
-                     GetLayoutBox()->ContainingBlock()->StyleRef());
+  EResize resize = GetLayoutBox()->StyleRef().Resize(
+      GetLayoutBox()->ContainingBlock()->StyleRef());
   if (resize != EResize::kVertical && difference.Width()) {
     if (element->IsFormControlElement()) {
       // Make implicit margins from the theme explicit (see
diff --git a/third_party/blink/renderer/core/paint/scrollable_area_painter.cc b/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
index 22a3963..6bb2c7e7 100644
--- a/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
+++ b/third_party/blink/renderer/core/paint/scrollable_area_painter.cc
@@ -24,7 +24,7 @@
 void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
                                          const IntPoint& paint_offset,
                                          const CullRect& cull_rect) {
-  if (GetScrollableArea().GetLayoutBox()->StyleRef().Resize() == EResize::kNone)
+  if (!GetScrollableArea().GetLayoutBox()->StyleRef().HasResize())
     return;
 
   IntRect abs_rect = GetScrollableArea().ResizerCornerRect(
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index f3cdd57..89ece0a9 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -99,9 +99,11 @@
 class BorderRightColor;
 class BorderTopColor;
 class CaretColor;
+class Clear;
 class Color;
 class ColumnRuleColor;
 class Fill;
+class Float;
 class FloodColor;
 class InternalVisitedBackgroundColor;
 class InternalVisitedBorderBottomColor;
@@ -118,6 +120,7 @@
 class InternalVisitedTextStrokeColor;
 class LightingColor;
 class OutlineColor;
+class Resize;
 class StopColor;
 class Stroke;
 class TextDecorationColor;
@@ -201,9 +204,11 @@
   friend class css_longhand::BorderRightColor;
   friend class css_longhand::BorderTopColor;
   friend class css_longhand::CaretColor;
+  friend class css_longhand::Clear;
   friend class css_longhand::Color;
   friend class css_longhand::ColumnRuleColor;
   friend class css_longhand::Fill;
+  friend class css_longhand::Float;
   friend class css_longhand::FloodColor;
   friend class css_longhand::InternalVisitedBackgroundColor;
   friend class css_longhand::InternalVisitedBorderBottomColor;
@@ -220,6 +225,7 @@
   friend class css_longhand::InternalVisitedTextStrokeColor;
   friend class css_longhand::LightingColor;
   friend class css_longhand::OutlineColor;
+  friend class css_longhand::Resize;
   friend class css_longhand::StopColor;
   friend class css_longhand::Stroke;
   friend class css_longhand::TextDecorationColor;
@@ -1896,7 +1902,26 @@
   bool CanRenderBorderImage() const;
 
   // Float utility functions.
-  bool IsFloating() const { return Floating() != EFloat::kNone; }
+  bool IsFloating() const { return FloatingInternal() != EFloat::kNone; }
+  EFloat UnresolvedFloating() const { return FloatingInternal(); }
+
+  EFloat Floating(const ComputedStyle& cb_style) const {
+    return Floating(cb_style.Direction());
+  }
+
+  EFloat Floating(TextDirection cb_direction) const {
+    const EFloat value = FloatingInternal();
+    switch (value) {
+      case EFloat::kInlineStart:
+      case EFloat::kInlineEnd: {
+        return IsLtr(cb_direction) == (value == EFloat::kInlineStart)
+                   ? EFloat::kLeft
+                   : EFloat::kRight;
+      }
+      default:
+        return value;
+    }
+  }
 
   // Mix-blend-mode utility functions.
   bool HasBlendMode() const { return GetBlendMode() != BlendMode::kNormal; }
@@ -1944,6 +1969,28 @@
             !Bottom().IsAuto());
   }
 
+  // Clear utility functions.
+  bool HasClear() const { return ClearInternal() != EClear::kNone; }
+  EClear UnresolvedClear() const { return ClearInternal(); }
+
+  EClear Clear(const ComputedStyle& cb_style) const {
+    return Clear(cb_style.Direction());
+  }
+
+  EClear Clear(TextDirection cb_direction) const {
+    const EClear value = ClearInternal();
+    switch (value) {
+      case EClear::kInlineStart:
+      case EClear::kInlineEnd: {
+        return IsLtr(cb_direction) == (value == EClear::kInlineStart)
+                   ? EClear::kLeft
+                   : EClear::kRight;
+      }
+      default:
+        return value;
+    }
+  }
+
   // Clip utility functions.
   const Length& ClipLeft() const { return Clip().Left(); }
   const Length& ClipRight() const { return Clip().Right(); }
@@ -2041,6 +2088,25 @@
   void SetCursorList(CursorList*);
   void ClearCursorList();
 
+  // Resize utility functions.
+  bool HasResize() const { return ResizeInternal() != EResize::kNone; }
+  EResize UnresolvedResize() const { return ResizeInternal(); }
+
+  EResize Resize(const ComputedStyle& cb_style) const {
+    EResize value = ResizeInternal();
+    switch (value) {
+      case EResize::kBlock:
+      case EResize::kInline: {
+        return ::blink::IsHorizontalWritingMode(cb_style.GetWritingMode()) ==
+                       (value == EResize::kBlock)
+                   ? EResize::kVertical
+                   : EResize::kHorizontal;
+      }
+      default:
+        return value;
+    }
+  }
+
   // Text decoration utility functions.
   void ApplyTextDecorations(const Color& parent_text_decoration_color,
                             bool override_existing_colors);
@@ -2323,8 +2389,7 @@
   bool HasBoxDecorations() const {
     return HasBorderDecoration() || HasBorderRadius() || HasOutline() ||
            HasEffectiveAppearance() || BoxShadow() ||
-           HasFilterInducingProperty() || HasBackdropFilter() ||
-           Resize() != EResize::kNone;
+           HasFilterInducingProperty() || HasBackdropFilter() || HasResize();
   }
 
   // "Box decoration background" includes all box decorations and backgrounds
@@ -2397,6 +2462,10 @@
   }
 
  private:
+  EClear Clear() const { return ClearInternal(); }
+  EFloat Floating() const { return FloatingInternal(); }
+  EResize Resize() const { return ResizeInternal(); }
+
   void SetInternalVisitedColor(const Color& v) {
     SetInternalVisitedColorInternal(v);
   }
diff --git a/third_party/blink/renderer/devtools/front_end/performance_test_runner/TimelineTestRunner.js b/third_party/blink/renderer/devtools/front_end/performance_test_runner/TimelineTestRunner.js
index 31beced..1a96801 100644
--- a/third_party/blink/renderer/devtools/front_end/performance_test_runner/TimelineTestRunner.js
+++ b/third_party/blink/renderer/devtools/front_end/performance_test_runner/TimelineTestRunner.js
@@ -200,7 +200,7 @@
   const event = root.event;
 
   if (event)
-    callback(event, level);
+    callback(event, level, root);
 
   for (const child of root.children().values())
     PerformanceTestRunner.walkTimelineEventTreeUnderNode(callback, child, (level || 0) + 1);
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp b/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp
index 4827348..e282a629 100644
--- a/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp
+++ b/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp
@@ -69,6 +69,9 @@
   <message name="IDS_DEVTOOLS_290612199861c31d1036b185b4e69b75" desc="Text in Heap Snapshot Data Grids of a profiler tool">
     Summary
   </message>
+  <message name="IDS_DEVTOOLS_2ce2fc341b0bd9219a3634ff43a90bde" desc="Alternate text read when describing the size of a memory allocation and its percentage of heap.">
+    <ph name="THIS_DATA_COLUMNID_">$1s<ex>1 613 680</ex></ph>, <ph name="THIS_DATA_PERCENTCOLUMN_">$2s<ex>44 %</ex></ph>
+  </message>
   <message name="IDS_DEVTOOLS_2d7b69664bc4226fb198124fb707e57c" desc="Text in Heap Profile View of a profiler tool">
     Snapshot <ph name="THIS_NEXTPROFILEUID__">$1s<ex>1</ex></ph>
   </message>
@@ -186,9 +189,6 @@
   <message name="IDS_DEVTOOLS_678d0a4421b60dc59999ac02837496a6" desc="Text in Heap Snapshot Data Grids of a profiler tool">
     Constructor
   </message>
-  <message name="IDS_DEVTOOLS_6861e4e238e968ec0ee3e9d3cb3b893f" desc="Alternate text read when describing the size of a memory allocation in bytes and percentage of heap.">
-    <ph name="THIS_DATA_COLUMNID_">$1s</ph> bytes, <ph name="THIS_DATA_PERCENTCOLUMN_">$2s</ph>
-  </message>
   <message name="IDS_DEVTOOLS_6a5084781ea4e6bf97a2dcd0cda17a1a" desc="Title of an action under the Performance category that can be invoked through the Command Menu">
     Start recording heap allocations
   </message>
diff --git a/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js b/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js
index 188ba138..fdcc33cb 100644
--- a/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js
+++ b/third_party/blink/renderer/devtools/front_end/security/SecurityPanel.js
@@ -47,7 +47,8 @@
     const certificateButton = UI.createTextButton(text, async e => {
       e.consume();
       const names = await SDK.multitargetNetworkManager.getCertificate(origin);
-      InspectorFrontendHost.showCertificateViewer(names);
+      if (names.length > 0)
+        InspectorFrontendHost.showCertificateViewer(names);
     }, 'origin-button');
     UI.ARIAUtils.markAsMenuButton(certificateButton);
     return certificateButton;
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js
index 2667782..376ada7 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js
+++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js
@@ -129,6 +129,22 @@
   }
 
   /**
+   * @protected
+   * @return {!Array<!TimelineModel.TimelineModelFilter>}
+   */
+  filtersWithoutTextFilter() {
+    return [this._taskFilter, ...this._model.filters()];
+  }
+
+  /**
+   * @protected
+   * @return {!Timeline.TimelineFilters.RegExp}
+   */
+  textFilter() {
+    return this._textFilter;
+  }
+
+  /**
    * @return {boolean}
    */
   _exposePercentages() {
@@ -977,7 +993,7 @@
    */
   _buildTree() {
     return new TimelineModel.TimelineProfileTree.BottomUpRootNode(
-        this._modelEvents(), this.filters(), this._startTime, this._endTime,
+        this._modelEvents(), this.textFilter(), this.filtersWithoutTextFilter(), this._startTime, this._endTime,
         this._groupingFunction(this._groupBySetting.get()));
   }
 };
diff --git a/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineProfileTree.js b/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineProfileTree.js
index fa6e010d9..22e1c88 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineProfileTree.js
+++ b/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineProfileTree.js
@@ -273,16 +273,18 @@
 TimelineModel.TimelineProfileTree.BottomUpRootNode = class extends TimelineModel.TimelineProfileTree.Node {
   /**
    * @param {!Array<!SDK.TracingModel.Event>} events
+   * @param {!TimelineModel.TimelineModelFilter} textFilter
    * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
    * @param {number} startTime
    * @param {number} endTime
    * @param {?function(!SDK.TracingModel.Event):string} eventGroupIdCallback
    */
-  constructor(events, filters, startTime, endTime, eventGroupIdCallback) {
+  constructor(events, textFilter, filters, startTime, endTime, eventGroupIdCallback) {
     super('', null);
     /** @type {?Map<string, !TimelineModel.TimelineProfileTree.Node>} */
     this._children = null;
     this._events = events;
+    this._textFilter = textFilter;
     this._filter = e => filters.every(f => f.accept(e));
     this._startTime = startTime;
     this._endTime = endTime;
@@ -299,11 +301,25 @@
   }
 
   /**
+   * @param {!Map<string, !TimelineModel.TimelineProfileTree.Node>} children
+   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
+   */
+  _filterChildren(children) {
+    for (const [id, child] of children) {
+      if (child.event && !this._textFilter.accept(child.event))
+        children.delete(/** @type {string} */ (id));
+    }
+    return children;
+  }
+
+  /**
    * @override
    * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
    */
   children() {
-    return this._children || this._grouppedTopNodes();
+    if (!this._children)
+      this._children = this._filterChildren(this._grouppedTopNodes());
+    return this._children;
   }
 
   /**
@@ -370,10 +386,8 @@
    */
   _grouppedTopNodes() {
     const flatNodes = this._ungrouppedTopNodes();
-    if (!this._eventGroupIdCallback) {
-      this._children = flatNodes;
+    if (!this._eventGroupIdCallback)
       return flatNodes;
-    }
     const groupNodes = new Map();
     for (const node of flatNodes.values()) {
       const groupId = this._eventGroupIdCallback(/** @type {!SDK.TracingModel.Event} */ (node.event));
@@ -385,7 +399,6 @@
       }
       groupNode.addChild(node, node.selfTime, node.selfTime);
     }
-    this._children = groupNodes;
     return groupNodes;
   }
 };
@@ -445,6 +458,7 @@
     this.parent = parent;
     this._root = root;
     this._depth = (parent._depth || 0) + 1;
+    /** @type {?Map<string, !TimelineModel.TimelineProfileTree.Node>} */
     this._cachedChildren = null;
     this._hasChildren = hasChildren;
   }
@@ -525,8 +539,8 @@
       lastTimeMarker = Math.min(e.endTime, endTime);
     }
 
-    this._cachedChildren = nodeById;
-    return nodeById;
+    this._cachedChildren = this._root._filterChildren(nodeById);
+    return this._cachedChildren;
   }
 
   /**
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp
index 0ea8433..bfa706a 100644
--- a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp
+++ b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp
@@ -54,9 +54,6 @@
   <message name="IDS_DEVTOOLS_2c0924faed417c521b57d553c678ec21" desc="Text in the Shortcuts page to explain a keyboard shortcut (step into a function in debugger)">
     Step into
   </message>
-  <message name="IDS_DEVTOOLS_2ce2fc341b0bd9219a3634ff43a90bde" desc="Accessibility label for checkable items in the SoftContextMenu">
-    <ph name="ITEM_LABEL">$1s<ex>Open File</ex></ph>, <ph name="CHECKEDSTATE">$2s<ex>checked</ex></ph>
-  </message>
   <message name="IDS_DEVTOOLS_2d56db467b153fe19f6f059f7f29be97" desc="Hours format in UIUtils">
     <ph name="PH1">$1.1f<ex>2.2</ex></ph> hrs
   </message>
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
index d491d7b..dc70afc3 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc
@@ -9,7 +9,7 @@
 #include "third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h"
 #include "third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h"
 #include "third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_center.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
 
 namespace blink {
 
@@ -27,7 +27,7 @@
   CanvasCaptureMediaStreamTrack* cloned_track =
       MakeGarbageCollected<CanvasCaptureMediaStreamTrack>(*this,
                                                           cloned_component);
-  MediaStreamCenter::Instance().DidCreateMediaStreamTrack(cloned_component);
+  MediaStreamUtils::DidCreateMediaStreamTrack(cloned_component);
   return cloned_track;
 }
 
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
index cf821cb..c2313a9c 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
@@ -22,7 +22,7 @@
 #include "third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source.h"
 #include "third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_center.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
 #include "third_party/blink/renderer/platform/wtf/uuid.h"
 
 namespace blink {
@@ -220,6 +220,15 @@
   UpdateSources(context);
 }
 
+void DidStopMediaStreamSource(const WebMediaStreamSource& source) {
+  if (source.IsNull())
+    return;
+  blink::WebPlatformMediaStreamSource* const platform_source =
+      source.GetPlatformSource();
+  DCHECK(platform_source);
+  platform_source->StopSource();
+}
+
 void MediaElementEventListener::UpdateSources(ExecutionContext* context) {
   for (auto track : media_stream_->getTracks())
     sources_.insert(track->Component()->Source());
@@ -227,7 +236,7 @@
   if (!media_element_->currentSrc().IsEmpty() &&
       !media_element_->IsMediaDataCorsSameOrigin()) {
     for (auto source : sources_)
-      MediaStreamCenter::Instance().DidStopMediaStreamSource(source);
+      DidStopMediaStreamSource(source.Get());
   }
 }
 
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn
index 72d63715..97c8804 100644
--- a/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -41,6 +41,8 @@
     "media_stream_track_content_hint.h",
     "media_stream_track_event.cc",
     "media_stream_track_event.h",
+    "media_stream_utils.cc",
+    "media_stream_utils.h",
     "media_stream_video_capturer_source.cc",
     "media_stream_video_renderer_sink.cc",
     "media_stream_video_renderer_sink.h",
@@ -69,6 +71,7 @@
     "web_media_stream_device_observer.cc",
     "web_media_stream_utils.cc",
     "webaudio_media_stream_audio_sink.cc",
+    "webaudio_media_stream_audio_sink.h",
     "webmediaplayer_ms.cc",
     "webmediaplayer_ms_compositor.cc",
     "webmediaplayer_ms_compositor.h",
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 63aaf4c..de3354c 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -28,6 +28,8 @@
 #include <memory>
 
 #include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -38,16 +40,19 @@
 #include "third_party/blink/renderer/modules/mediastream/apply_constraints_request.h"
 #include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
 #include "third_party/blink/renderer/modules/mediastream/media_track_capabilities.h"
 #include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
 #include "third_party/blink/renderer/modules/mediastream/media_track_settings.h"
 #include "third_party/blink/renderer/modules/mediastream/overconstrained_error.h"
 #include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
+#include "third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_center.h"
 #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -141,6 +146,67 @@
   return ConstraintsSatisfyCondition(ConstraintSetHasImageCapture, constraints);
 }
 
+// Caller must take the ownership of the returned |WebAudioSourceProvider|
+// object.
+std::unique_ptr<WebAudioSourceProvider>
+CreateWebAudioSourceFromMediaStreamTrack(const WebMediaStreamTrack& track,
+                                         int context_sample_rate) {
+  WebPlatformMediaStreamTrack* media_stream_track = track.GetPlatformTrack();
+  if (!media_stream_track) {
+    DLOG(ERROR) << "Native track missing for webaudio source.";
+    return nullptr;
+  }
+
+  WebMediaStreamSource source = track.Source();
+  DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeAudio);
+
+  return std::make_unique<WebAudioMediaStreamAudioSink>(track,
+                                                        context_sample_rate);
+}
+
+void CloneNativeVideoMediaStreamTrack(const WebMediaStreamTrack& original,
+                                      WebMediaStreamTrack clone) {
+  DCHECK(!clone.GetPlatformTrack());
+  WebMediaStreamSource source = clone.Source();
+  DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeVideo);
+  MediaStreamVideoSource* native_source =
+      MediaStreamVideoSource::GetVideoSource(source);
+  DCHECK(native_source);
+  MediaStreamVideoTrack* original_track =
+      MediaStreamVideoTrack::GetVideoTrack(original);
+  DCHECK(original_track);
+  clone.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+      native_source, original_track->adapter_settings(),
+      original_track->noise_reduction(), original_track->is_screencast(),
+      original_track->min_frame_rate(),
+      MediaStreamVideoSource::ConstraintsCallback(), clone.IsEnabled()));
+}
+
+void DidSetMediaStreamTrackEnabled(MediaStreamComponent* component) {
+  const WebMediaStreamTrack track(component);
+  auto* native_track = WebPlatformMediaStreamTrack::GetTrack(track);
+  if (native_track)
+    native_track->SetEnabled(component->Enabled());
+}
+
+void DidCloneMediaStreamTrack(const WebMediaStreamTrack& original,
+                              const WebMediaStreamTrack& clone) {
+  DCHECK(!clone.IsNull());
+  DCHECK(!clone.GetPlatformTrack());
+  DCHECK(!clone.Source().IsNull());
+
+  switch (clone.Source().GetType()) {
+    case WebMediaStreamSource::kTypeAudio:
+      // TODO(crbug.com/704136): Use per thread task runner.
+      MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
+          clone, Thread::MainThread()->GetTaskRunner());
+      break;
+    case WebMediaStreamSource::kTypeVideo:
+      CloneNativeVideoMediaStreamTrack(original, clone);
+      break;
+  }
+}
+
 }  // namespace
 
 MediaStreamTrack* MediaStreamTrack::Create(ExecutionContext* context,
@@ -213,8 +279,7 @@
   component_->SetEnabled(enabled);
 
   if (!Ended())
-    MediaStreamCenter::Instance().DidSetMediaStreamTrackEnabled(
-        component_.Get());
+    DidSetMediaStreamTrackEnabled(component_.Get());
 }
 
 bool MediaStreamTrack::muted() const {
@@ -317,8 +382,7 @@
   MediaStreamTrack* cloned_track = MakeGarbageCollected<MediaStreamTrack>(
       ExecutionContext::From(script_state), cloned_component, ready_state_,
       stopped_);
-  MediaStreamCenter::Instance().DidCloneMediaStreamTrack(Component(),
-                                                         cloned_component);
+  DidCloneMediaStreamTrack(Component(), cloned_component);
   return cloned_track;
 }
 
@@ -697,8 +761,9 @@
 
 std::unique_ptr<AudioSourceProvider> MediaStreamTrack::CreateWebAudioSource(
     int context_sample_rate) {
-  return MediaStreamCenter::Instance().CreateWebAudioSourceFromMediaStreamTrack(
-      Component(), context_sample_rate);
+  return std::make_unique<MediaStreamWebAudioSource>(
+      CreateWebAudioSourceFromMediaStreamTrack(Component(),
+                                               context_sample_rate));
 }
 
 void MediaStreamTrack::RegisterMediaStream(MediaStream* media_stream) {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
new file mode 100644
index 0000000..b508d848
--- /dev/null
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
+
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/public/platform/modules/mediastream/webaudio_media_stream_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+
+namespace blink {
+
+namespace {
+
+void CreateNativeVideoMediaStreamTrack(blink::WebMediaStreamTrack track) {
+  DCHECK(!track.GetPlatformTrack());
+  blink::WebMediaStreamSource source = track.Source();
+  DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
+  blink::MediaStreamVideoSource* native_source =
+      blink::MediaStreamVideoSource::GetVideoSource(source);
+  DCHECK(native_source);
+  track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
+      native_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
+      track.IsEnabled()));
+}
+
+}  // namespace
+
+void MediaStreamUtils::CreateNativeAudioMediaStreamTrack(
+    const blink::WebMediaStreamTrack& track,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+  WebMediaStreamSource source = track.Source();
+  MediaStreamAudioSource* media_stream_source =
+      blink::MediaStreamAudioSource::From(source);
+
+  // At this point, a MediaStreamAudioSource instance must exist. The one
+  // exception is when a WebAudio destination node is acting as a source of
+  // audio.
+  //
+  // TODO(miu): This needs to be moved to an appropriate location. A WebAudio
+  // source should have been created before this method was called so that this
+  // special case code isn't needed here.
+  if (!media_stream_source && source.RequiresAudioConsumer()) {
+    DVLOG(1) << "Creating WebAudio media stream source.";
+    media_stream_source =
+        new blink::WebAudioMediaStreamSource(&source, task_runner);
+    source.SetPlatformSource(
+        base::WrapUnique(media_stream_source));  // Takes ownership.
+
+    blink::WebMediaStreamSource::Capabilities capabilities;
+    capabilities.device_id = source.Id();
+    // TODO(crbug.com/704136): Switch away from std::vector.
+    capabilities.echo_cancellation = std::vector<bool>({false});
+    capabilities.auto_gain_control = std::vector<bool>({false});
+    capabilities.noise_suppression = std::vector<bool>({false});
+    capabilities.sample_size = {
+        media::SampleFormatToBitsPerChannel(media::kSampleFormatS16),  // min
+        media::SampleFormatToBitsPerChannel(media::kSampleFormatS16)   // max
+    };
+    auto parameters = media_stream_source->GetAudioParameters();
+    if (parameters.IsValid()) {
+      capabilities.channel_count = {1, parameters.channels()};
+      capabilities.sample_rate = {parameters.sample_rate(),
+                                  parameters.sample_rate()};
+      capabilities.latency = {parameters.GetBufferDuration().InSecondsF(),
+                              parameters.GetBufferDuration().InSecondsF()};
+    }
+    source.SetCapabilities(capabilities);
+  }
+
+  if (media_stream_source)
+    media_stream_source->ConnectToTrack(track);
+  else
+    LOG(DFATAL) << "WebMediaStreamSource missing its MediaStreamAudioSource.";
+}
+
+// TODO(crbug.com/704136): Change this method to take the task
+// runner instance, and use per thread task runner on the call site.
+void MediaStreamUtils::DidCreateMediaStreamTrack(
+    MediaStreamComponent* component) {
+  WebMediaStreamTrack track(component);
+  DCHECK(!track.IsNull() && !track.GetPlatformTrack());
+  DCHECK(!track.Source().IsNull());
+
+  switch (track.Source().GetType()) {
+    case blink::WebMediaStreamSource::kTypeAudio:
+      CreateNativeAudioMediaStreamTrack(track,
+                                        Thread::MainThread()->GetTaskRunner());
+      break;
+    case blink::WebMediaStreamSource::kTypeVideo:
+      CreateNativeVideoMediaStreamTrack(track);
+      break;
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.h b/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
new file mode 100644
index 0000000..38b365b
--- /dev/null
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_UTILS_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+
+class MediaStreamComponent;
+class WebMediaStreamTrack;
+
+class MediaStreamUtils {
+  STATIC_ONLY(MediaStreamUtils);
+
+ public:
+  static void CreateNativeAudioMediaStreamTrack(
+      const WebMediaStreamTrack&,
+      scoped_refptr<base::SingleThreadTaskRunner>);
+
+  static void DidCreateMediaStreamTrack(MediaStreamComponent*);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_UTILS_H_
diff --git a/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
index d38a444..601c43b 100644
--- a/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc
+++ b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.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 "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h"
+#include "third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h"
 
 #include <string>
 
diff --git a/third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h
similarity index 89%
rename from third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h
rename to third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h
index 60458ea..40633bd 100644
--- a/third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h
+++ b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.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 THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
 
 #include <stddef.h>
 
@@ -16,9 +16,9 @@
 #include "media/base/reentrancy_checker.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
 #include "third_party/blink/public/platform/web_audio_source_provider.h"
-#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
 
 namespace media {
 class AudioBus;
@@ -41,10 +41,7 @@
 // data from the FIFO.
 //
 // Most calls are protected by a lock.
-//
-// TODO(crbug.com/704136): Move this class out of the Blink exposed API
-// when all users of it have been Onion souped.
-class BLINK_MODULES_EXPORT WebAudioMediaStreamAudioSink
+class MODULES_EXPORT WebAudioMediaStreamAudioSink
     : public WebAudioSourceProvider,
       public media::AudioConverter::InputCallback,
       public WebMediaStreamAudioSink {
@@ -120,4 +117,4 @@
 
 }  // namespace blink
 
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBAUDIO_MEDIA_STREAM_AUDIO_SINK_H_
diff --git a/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
index c212c57..16c3b63 100644
--- a/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.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 "third_party/blink/public/web/modules/mediastream/webaudio_media_stream_audio_sink.h"
+#include "third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h"
 
 #include <stddef.h>
 
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
index ec7420f..4e6fef0 100644
--- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
 
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_context.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_node_options.h"
@@ -33,11 +34,22 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_center.h"
 #include "third_party/blink/renderer/platform/wtf/uuid.h"
 
 namespace blink {
 
+namespace {
+
+void DidCreateMediaStreamAndTracks(MediaStreamDescriptor* stream) {
+  for (uint32_t i = 0; i < stream->NumberOfAudioComponents(); ++i)
+    MediaStreamUtils::DidCreateMediaStreamTrack(stream->AudioComponent(i));
+
+  for (uint32_t i = 0; i < stream->NumberOfVideoComponents(); ++i)
+    MediaStreamUtils::DidCreateMediaStreamTrack(stream->VideoComponent(i));
+}
+
+}  // namespace
+
 // WebAudioCapturerSource ignores the channel count beyond 8, so we set the
 // block here to avoid anything can cause the crash.
 static const uint32_t kMaxChannelCount = 8;
@@ -186,8 +198,7 @@
                                   MakeGarbageCollected<MediaStreamDescriptor>(
                                       MediaStreamSourceVector({source_.Get()}),
                                       MediaStreamSourceVector()))) {
-  MediaStreamCenter::Instance().DidCreateMediaStreamAndTracks(
-      stream_->Descriptor());
+  DidCreateMediaStreamAndTracks(stream_->Descriptor());
   SetHandler(
       MediaStreamAudioDestinationHandler::Create(*this, number_of_channels));
 }
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index aaaa915c..2b9e621 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1193,8 +1193,6 @@
     "mediastream/aec_dump_agent_impl.h",
     "mediastream/audio_service_audio_processor_proxy.cc",
     "mediastream/audio_service_audio_processor_proxy.h",
-    "mediastream/media_stream_center.cc",
-    "mediastream/media_stream_center.h",
     "mediastream/media_stream_component.cc",
     "mediastream/media_stream_component.h",
     "mediastream/media_stream_descriptor.cc",
diff --git a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
index 1bc617a..b3849ec 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
@@ -11,11 +11,6 @@
 
 namespace blink {
 
-const char kMediaStreamSourceTab[] = "tab";
-const char kMediaStreamSourceScreen[] = "screen";
-const char kMediaStreamSourceDesktop[] = "desktop";
-const char kMediaStreamSourceSystem[] = "system";
-
 const char WebPlatformMediaStreamSource::kSourceId[] = "sourceId";
 
 WebPlatformMediaStreamSource::WebPlatformMediaStreamSource() {}
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc
index da36bbe..0fd9f40f 100644
--- a/third_party/blink/renderer/platform/exported/platform.cc
+++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -43,7 +43,6 @@
 #include "third_party/blink/public/platform/interface_provider.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
-#include "third_party/blink/public/platform/web_media_stream_center.h"
 #include "third_party/blink/public/platform/web_prerendering_support.h"
 #include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
@@ -341,10 +340,6 @@
   return nullptr;
 }
 
-std::unique_ptr<WebMediaStreamCenter> Platform::CreateMediaStreamCenter() {
-  return nullptr;
-}
-
 std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpSenderCapabilities(
     const WebString& kind) {
   return nullptr;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index fec1a0f6..19638b3 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -419,9 +419,7 @@
   compositor_node.source_node_id = parent_id;
 
   UpdateCcTransformLocalMatrix(compositor_node, transform_node);
-  compositor_node.transform_changed =
-      transform_node.NodeChanged() >=
-      PaintPropertyChangeType::kChangedOnlySimpleValues;
+  compositor_node.transform_changed = transform_node.NodeChangeAffectsRaster();
   compositor_node.flattens_inherited_transform =
       transform_node.FlattensInheritedTransform();
   compositor_node.sorting_context_id = transform_node.RenderingContextId();
@@ -1111,8 +1109,7 @@
   }
   effect_node.blend_mode = blend_mode;
   effect_node.double_sided = !effect.LocalTransformSpace().IsBackfaceHidden();
-  effect_node.effect_changed =
-      effect.NodeChanged() >= PaintPropertyChangeType::kChangedOnlySimpleValues;
+  effect_node.effect_changed = effect.NodeChangeAffectsRaster();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
index b75dca0..58f61b4 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -147,6 +147,10 @@
   }
 
   PaintPropertyChangeType NodeChanged() const { return changed_; }
+  bool NodeChangeAffectsRaster() const {
+    return changed_ != PaintPropertyChangeType::kUnchanged &&
+           changed_ != PaintPropertyChangeType::kChangedOnlyNonRerasterValues;
+  }
 
 #if DCHECK_IS_ON()
   String ToTreeString() const;
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_center.cc b/third_party/blink/renderer/platform/mediastream/media_stream_center.cc
deleted file mode 100644
index 8a767275..0000000
--- a/third_party/blink/renderer/platform/mediastream/media_stream_center.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer
- *    in the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/mediastream/media_stream_center.h"
-
-#include <memory>
-
-#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_audio_source_provider.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_center.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
-#include "third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-
-namespace blink {
-
-MediaStreamCenter& MediaStreamCenter::Instance() {
-  DCHECK(IsMainThread());
-  DEFINE_STATIC_LOCAL(MediaStreamCenter, center, ());
-  return center;
-}
-
-MediaStreamCenter::MediaStreamCenter()
-    : private_(Platform::Current()->CreateMediaStreamCenter()) {}
-
-MediaStreamCenter::~MediaStreamCenter() = default;
-
-void MediaStreamCenter::DidSetMediaStreamTrackEnabled(
-    MediaStreamComponent* component) {
-  if (private_) {
-    if (component->Enabled()) {
-      private_->DidEnableMediaStreamTrack(component);
-    } else {
-      private_->DidDisableMediaStreamTrack(component);
-    }
-  }
-}
-
-void MediaStreamCenter::DidCreateMediaStreamAndTracks(
-    MediaStreamDescriptor* stream) {
-  if (!private_)
-    return;
-
-  for (uint32_t i = 0; i < stream->NumberOfAudioComponents(); ++i)
-    DidCreateMediaStreamTrack(stream->AudioComponent(i));
-
-  for (uint32_t i = 0; i < stream->NumberOfVideoComponents(); ++i)
-    DidCreateMediaStreamTrack(stream->VideoComponent(i));
-}
-
-void MediaStreamCenter::DidCreateMediaStreamTrack(MediaStreamComponent* track) {
-  if (private_)
-    private_->DidCreateMediaStreamTrack(track);
-}
-
-void MediaStreamCenter::DidCloneMediaStreamTrack(MediaStreamComponent* original,
-                                                 MediaStreamComponent* clone) {
-  if (private_)
-    private_->DidCloneMediaStreamTrack(original, clone);
-}
-
-std::unique_ptr<AudioSourceProvider>
-MediaStreamCenter::CreateWebAudioSourceFromMediaStreamTrack(
-    MediaStreamComponent* track,
-    int context_sample_rate) {
-  DCHECK(track);
-  if (private_) {
-    return std::make_unique<MediaStreamWebAudioSource>(
-        base::WrapUnique(private_->CreateWebAudioSourceFromMediaStreamTrack(
-            track, context_sample_rate)));
-  }
-
-  return nullptr;
-}
-
-void MediaStreamCenter::DidStopMediaStreamSource(MediaStreamSource* source) {
-  if (private_)
-    private_->DidStopMediaStreamSource(source);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_center.h b/third_party/blink/renderer/platform/mediastream/media_stream_center.h
deleted file mode 100644
index 21fc18a..0000000
--- a/third_party/blink/renderer/platform/mediastream/media_stream_center.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer
- *    in the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_CENTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_CENTER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class AudioSourceProvider;
-class MediaStreamComponent;
-class MediaStreamDescriptor;
-class MediaStreamSource;
-class WebMediaStreamCenter;
-
-class PLATFORM_EXPORT MediaStreamCenter {
-  USING_FAST_MALLOC(MediaStreamCenter);
-
- public:
-  ~MediaStreamCenter();
-
-  static MediaStreamCenter& Instance();
-
-  void DidCreateMediaStreamTrack(MediaStreamComponent*);
-  void DidCloneMediaStreamTrack(MediaStreamComponent* original,
-                                MediaStreamComponent* clone);
-  void DidSetMediaStreamTrackEnabled(MediaStreamComponent*);
-  std::unique_ptr<AudioSourceProvider> CreateWebAudioSourceFromMediaStreamTrack(
-      MediaStreamComponent*,
-      int context_sample_rate);
-
-  void DidCreateMediaStreamAndTracks(MediaStreamDescriptor*);
-
-  void DidStopMediaStreamSource(MediaStreamSource*);
-
- private:
-  MediaStreamCenter();
-
-  std::unique_ptr<WebMediaStreamCenter> private_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStreamCenter);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_CENTER_H_
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
index 612d380..99b4e523 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_web_audio_source.h
@@ -37,13 +37,14 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
 
 namespace blink {
 
 class WebAudioSourceProvider;
 
-class MediaStreamWebAudioSource : public AudioSourceProvider {
+class PLATFORM_EXPORT MediaStreamWebAudioSource : public AudioSourceProvider {
  public:
   explicit MediaStreamWebAudioSource(std::unique_ptr<WebAudioSourceProvider>);
   ~MediaStreamWebAudioSource() override;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc
index 53db283d9..b7aa797 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_interference_recorder_unittest.cc
@@ -362,14 +362,14 @@
       // When a nested loop is entered, complete the current task.
       recorder_.OnTaskCompleted(queue_a1_.get(), NowTicks());
 
-      const base::TimeTicks start = NowTicks();
+      const base::TimeTicks nested_start = NowTicks();
       {
         ScopedExpectSample expect_sample(this, queue_b1_.get(), kDelay);
-        recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), start);
+        recorder_.OnTaskStarted(queue_b1_.get(), EnqueueOrder(2), nested_start);
       }
       FastForwardBy(8 * kDelay);
-      const base::TimeTicks end = NowTicks();
-      recorder_.OnTaskCompleted(queue_b1_.get(), end);
+      const base::TimeTicks nested_end = NowTicks();
+      recorder_.OnTaskCompleted(queue_b1_.get(), nested_end);
 
       // When a nested loop is exited, resume the task that was running when the
       // nested loop was entered.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index ff1abbab..21dd5471 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3317,6 +3317,10 @@
 crbug.com/785230 external/wpt/css/css-text-decor/text-decoration-thickness-vertical-002.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-span-all-children-height-005.html [ Failure ]
+crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-span-all-children-height-004a.html [ Failure ]
+crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-span-all-children-height-004b.html [ Failure ]
+crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-span-all-children-height-006.html [ Failure ]
 crbug.com/626703 [ Mac10.12 ] external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-sorted-before-dispatch.html [ Timeout ]
 crbug.com/626703 [ Mac10.12 ] external/wpt/mediacapture-fromelement/ended.html [ Timeout ]
 crbug.com/626703 [ Mac10.12 ] external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-pause-on-exit.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index e8096aaf..178b31d 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -57119,6 +57119,54 @@
      {}
     ]
    ],
+   "css/css-multicol/multicol-span-all-children-height-004a.html": [
+    [
+     "css/css-multicol/multicol-span-all-children-height-004a.html",
+     [
+      [
+       "/css/css-multicol/multicol-span-all-children-height-004a-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-multicol/multicol-span-all-children-height-004b.html": [
+    [
+     "css/css-multicol/multicol-span-all-children-height-004b.html",
+     [
+      [
+       "/css/css-multicol/multicol-span-all-children-height-004b-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-multicol/multicol-span-all-children-height-005.html": [
+    [
+     "css/css-multicol/multicol-span-all-children-height-005.html",
+     [
+      [
+       "/css/css-multicol/multicol-span-all-children-height-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-multicol/multicol-span-all-children-height-006.html": [
+    [
+     "css/css-multicol/multicol-span-all-children-height-006.html",
+     [
+      [
+       "/css/css-multicol/multicol-span-all-children-height-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-multicol/multicol-span-all-dynamic-add-001.html": [
     [
      "css/css-multicol/multicol-span-all-dynamic-add-001.html",
@@ -58103,9 +58151,9 @@
      {}
     ]
    ],
-   "css/css-overflow/overflow-body-propagation-001.tentative.html": [
+   "css/css-overflow/overflow-body-propagation-001.html": [
     [
-     "css/css-overflow/overflow-body-propagation-001.tentative.html",
+     "css/css-overflow/overflow-body-propagation-001.html",
      [
       [
        "/css/css-overflow/reference/overflow-body-propagation-ref.html",
@@ -58115,9 +58163,9 @@
      {}
     ]
    ],
-   "css/css-overflow/overflow-body-propagation-002.tentative.html": [
+   "css/css-overflow/overflow-body-propagation-002.html": [
     [
-     "css/css-overflow/overflow-body-propagation-002.tentative.html",
+     "css/css-overflow/overflow-body-propagation-002.html",
      [
       [
        "/css/reference/blank.html",
@@ -58127,9 +58175,9 @@
      {}
     ]
    ],
-   "css/css-overflow/overflow-body-propagation-003.tentative.html": [
+   "css/css-overflow/overflow-body-propagation-003.html": [
     [
-     "css/css-overflow/overflow-body-propagation-003.tentative.html",
+     "css/css-overflow/overflow-body-propagation-003.html",
      [
       [
        "/css/reference/blank.html",
@@ -58139,9 +58187,9 @@
      {}
     ]
    ],
-   "css/css-overflow/overflow-body-propagation-004.tentative.html": [
+   "css/css-overflow/overflow-body-propagation-004.html": [
     [
-     "css/css-overflow/overflow-body-propagation-004.tentative.html",
+     "css/css-overflow/overflow-body-propagation-004.html",
      [
       [
        "/css/css-overflow/reference/overflow-body-no-propagation-ref.html",
@@ -138943,6 +138991,12 @@
    "css/css-inline/parsing/baseline-shift-valid-expected.txt": [
     []
    ],
+   "css/css-inline/parsing/dominant-baseline-computed-expected.txt": [
+    []
+   ],
+   "css/css-inline/parsing/dominant-baseline-valid-expected.txt": [
+    []
+   ],
    "css/css-layout-api/META.yml": [
     []
    ],
@@ -139699,6 +139753,18 @@
    "css/css-multicol/multicol-span-all-children-height-003-ref.html": [
     []
    ],
+   "css/css-multicol/multicol-span-all-children-height-004a-ref.html": [
+    []
+   ],
+   "css/css-multicol/multicol-span-all-children-height-004b-ref.html": [
+    []
+   ],
+   "css/css-multicol/multicol-span-all-children-height-005-ref.html": [
+    []
+   ],
+   "css/css-multicol/multicol-span-all-children-height-006-ref.html": [
+    []
+   ],
    "css/css-multicol/multicol-span-all-dynamic-add-001-ref.html": [
     []
    ],
@@ -161692,6 +161758,9 @@
    "interfaces/largest-contentful-paint.idl": [
     []
    ],
+   "interfaces/layout-instability.idl": [
+    []
+   ],
    "interfaces/longtasks.idl": [
     []
    ],
@@ -202055,6 +202124,24 @@
      {}
     ]
    ],
+   "css/css-fonts/parsing/font-variation-settings-computed.html": [
+    [
+     "css/css-fonts/parsing/font-variation-settings-computed.html",
+     {}
+    ]
+   ],
+   "css/css-fonts/parsing/font-variation-settings-invalid.html": [
+    [
+     "css/css-fonts/parsing/font-variation-settings-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-fonts/parsing/font-variation-settings-valid.html": [
+    [
+     "css/css-fonts/parsing/font-variation-settings-valid.html",
+     {}
+    ]
+   ],
    "css/css-fonts/parsing/font-weight-computed.html": [
     [
      "css/css-fonts/parsing/font-weight-computed.html",
@@ -204291,6 +204378,24 @@
      {}
     ]
    ],
+   "css/css-inline/parsing/dominant-baseline-computed.html": [
+    [
+     "css/css-inline/parsing/dominant-baseline-computed.html",
+     {}
+    ]
+   ],
+   "css/css-inline/parsing/dominant-baseline-invalid.html": [
+    [
+     "css/css-inline/parsing/dominant-baseline-invalid.html",
+     {}
+    ]
+   ],
+   "css/css-inline/parsing/dominant-baseline-valid.html": [
+    [
+     "css/css-inline/parsing/dominant-baseline-valid.html",
+     {}
+    ]
+   ],
    "css/css-layout-api/at-supports-rule.https.html": [
     [
      "css/css-layout-api/at-supports-rule.https.html",
@@ -249847,6 +249952,23 @@
      {}
     ]
    ],
+   "layout-instability/idlharness.window.js": [
+    [
+     "layout-instability/idlharness.window.html",
+     {
+      "script_metadata": [
+       [
+        "script",
+        "/resources/WebIDLParser.js"
+       ],
+       [
+        "script",
+        "/resources/idlharness.js"
+       ]
+      ]
+     }
+    ]
+   ],
    "layout-instability/observe-layout-shift.html": [
     [
      "layout-instability/observe-layout-shift.html",
@@ -354692,11 +354814,11 @@
    "testharness"
   ],
   "css/css-fonts/inheritance-expected.txt": [
-   "7bd35fdf14d89e4ea335f63292caa3414cb998d8",
+   "daf682070e898eebc83ea04dfc762df9f235b0e5",
    "support"
   ],
   "css/css-fonts/inheritance.html": [
-   "f0c46bec5083dd5b7f5bd0d8da49d5fc0ce01d81",
+   "6192e50638c0106abe798d2e5b8f004534646ad5",
    "testharness"
   ],
   "css/css-fonts/language-specific-01.html": [
@@ -355027,6 +355149,18 @@
    "3887ab0cc4b59024544338d2338c3a723fe3b625",
    "testharness"
   ],
+  "css/css-fonts/parsing/font-variation-settings-computed.html": [
+   "0b01320a7f6e2a473a44bc435bfe9507321ce135",
+   "testharness"
+  ],
+  "css/css-fonts/parsing/font-variation-settings-invalid.html": [
+   "b957c31009222be77397b82f7f044594e31d1866",
+   "testharness"
+  ],
+  "css/css-fonts/parsing/font-variation-settings-valid.html": [
+   "fe7f6bf7806891540a5fc495e7568cc5763c59b9",
+   "testharness"
+  ],
   "css/css-fonts/parsing/font-weight-computed.html": [
    "08208e5dd493a42bfdd1b9c0277ca49c151a9937",
    "testharness"
@@ -364755,6 +364889,26 @@
    "8054ebbb39cfc654192aa97e928264d7859319db",
    "testharness"
   ],
+  "css/css-inline/parsing/dominant-baseline-computed-expected.txt": [
+   "0f4bdfd3df99244e20c80e4d5527704b0761b972",
+   "support"
+  ],
+  "css/css-inline/parsing/dominant-baseline-computed.html": [
+   "e844dd71f84712bd2f60cce56ccdda00627ed5ee",
+   "testharness"
+  ],
+  "css/css-inline/parsing/dominant-baseline-invalid.html": [
+   "2c4b76e02698e172c290051892ee08d0b7cf751c",
+   "testharness"
+  ],
+  "css/css-inline/parsing/dominant-baseline-valid-expected.txt": [
+   "9e61cd9a4190b32669709477d3558711d756cc17",
+   "support"
+  ],
+  "css/css-inline/parsing/dominant-baseline-valid.html": [
+   "1a6c7a400cbec8117953389b5c54854991a66ad0",
+   "testharness"
+  ],
   "css/css-layout-api/META.yml": [
    "c85c2d4ccc0b02f3e22ca444952fb7583d96e7c7",
    "support"
@@ -368083,6 +368237,38 @@
    "1f2cbef4ab03b71872bd7b84927ca0681beb56a4",
    "reftest"
   ],
+  "css/css-multicol/multicol-span-all-children-height-004a-ref.html": [
+   "0d6d44cc076a60fd9298096fac92b1e06939871b",
+   "support"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-004a.html": [
+   "366ca33d0785372c1b333268e82f89e1a4cb4059",
+   "reftest"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-004b-ref.html": [
+   "c6412ceaf3de72bd746c7cc060529ed80e891f16",
+   "support"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-004b.html": [
+   "19202323047093362e0e9970e19088394e040174",
+   "reftest"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-005-ref.html": [
+   "d5102e1f42073fa2691a97e0b3924e80ed3e2966",
+   "support"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-005.html": [
+   "33a820d32c5040da78edaf427a0ea6dc4a94d5ab",
+   "reftest"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-006-ref.html": [
+   "e34036b008b6d30fe5784a5519e54b52412590e5",
+   "support"
+  ],
+  "css/css-multicol/multicol-span-all-children-height-006.html": [
+   "dd63cd8716f58c4cae15b894196081607c1cb4fd",
+   "reftest"
+  ],
   "css/css-multicol/multicol-span-all-dynamic-add-001-ref.html": [
    "9f76ea15a0daa7753e76ad9b9a99948988c702d3",
    "support"
@@ -368963,19 +369149,19 @@
    "df1128316f6010f010e6d27c395d7751fa05d7b1",
    "testharness"
   ],
-  "css/css-overflow/overflow-body-propagation-001.tentative.html": [
+  "css/css-overflow/overflow-body-propagation-001.html": [
    "0998fe68e007d5a46ff11d5ff87fdbad12d1dfe2",
    "reftest"
   ],
-  "css/css-overflow/overflow-body-propagation-002.tentative.html": [
+  "css/css-overflow/overflow-body-propagation-002.html": [
    "5991dd52e8b6aec74f55780587f15c2b9399c968",
    "reftest"
   ],
-  "css/css-overflow/overflow-body-propagation-003.tentative.html": [
+  "css/css-overflow/overflow-body-propagation-003.html": [
    "a329a8dfe3e44c92368bf0496897f74ccec5a63a",
    "reftest"
   ],
-  "css/css-overflow/overflow-body-propagation-004.tentative.html": [
+  "css/css-overflow/overflow-body-propagation-004.html": [
    "2ed8d2687a33608e0e70884ad2ea59330d2b09e3",
    "reftest"
   ],
@@ -411400,7 +411586,7 @@
    "testharness"
   ],
   "custom-elements/reactions/HTMLInputElement.html": [
-   "65e33e8411f7d1109a54cecf72c84c96d51f5503",
+   "13d1591b01fdf9b4fcc5b3f89438bff55df75278",
    "testharness"
   ],
   "custom-elements/reactions/HTMLLIElement.html": [
@@ -421192,11 +421378,11 @@
    "manual"
   ],
   "html-media-capture/capture_reflect-expected.txt": [
-   "7ce0a7ed00283bc7b166ae3af8c1e4bec67934f7",
+   "fee75ec8e760262e33c22ac022df4b8f0c2524cd",
    "support"
   ],
   "html-media-capture/capture_reflect.html": [
-   "39f391eb674dd33f2250d00a1fcdd3d509a43a9a",
+   "f593236b5325eb756ee6b43f653a3138cb1d8d6b",
    "testharness"
   ],
   "html-media-capture/capture_video_cancel-manual.html": [
@@ -442156,7 +442342,7 @@
    "support"
   ],
   "interfaces/html.idl": [
-   "5ae46f742922f4c455380745f124769399086eb9",
+   "47abcda810a1f94f5704623db63fdec9805cc9c9",
    "support"
   ],
   "interfaces/image-capture.idl": [
@@ -442183,6 +442369,10 @@
    "f16a7ff812c96ab28f7d3b8d0f1b92d141e552a0",
    "support"
   ],
+  "interfaces/layout-instability.idl": [
+   "1bacea77bcef8913b1df220a29cf35448074707c",
+   "support"
+  ],
   "interfaces/longtasks.idl": [
    "333b842f86e5d41f6f1aab8827cf086356c5a782",
    "support"
@@ -442979,6 +443169,10 @@
    "dabc8068931ff3b15eb4b80481ed2102a7725a62",
    "testharness"
   ],
+  "layout-instability/idlharness.window.js": [
+   "7d97446a57808576722a823f604effa94bb95e76",
+   "testharness"
+  ],
   "layout-instability/observe-layout-shift.html": [
    "8e5624e09a3d92975f315f7601c8cfc474c89c9e",
    "testharness"
@@ -445176,7 +445370,7 @@
    "testharness"
   ],
   "mediacapture-streams/MediaDevices-getUserMedia.https.html": [
-   "70fe67b30f507b065963e1764aea1eddb5bc927b",
+   "693f3bd11cfaa6be7ca21bae110467c265be5a07",
    "testharness"
   ],
   "mediacapture-streams/MediaStream-MediaElement-firstframe.https-expected.txt": [
@@ -480116,7 +480310,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/firefox_android.py": [
-   "b6d7bc8851e0fd9b8cb2745e7360a665152b7cba",
+   "30e53a593cff7ec3fa026c2a4f2495402650c1dc",
    "support"
   ],
   "tools/wptrunner/wptrunner/browsers/ie.py": [
@@ -480372,7 +480566,7 @@
    "support"
   ],
   "tools/wptrunner/wptrunner/wptcommandline.py": [
-   "928a153dbd9d1f9595e55d2b69ddd2447f811754",
+   "87563f3edf09a3bf47bf8395c7bee77a58df52b7",
    "support"
   ],
   "tools/wptrunner/wptrunner/wptlogging.py": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a-ref.html
new file mode 100644
index 0000000..0d6d44c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test Reference: Test the block-size distribution across column-span split in a balancing multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 200px;
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    width: 400px;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <div class="container">
+      <div class="block">block1</div>
+    </div>
+  </article>
+  <div class="column-span">column-span1</div>
+  <article>
+    <div class="container">
+      <div class="block">block2</div>
+    </div>
+  </article>
+  <div class="column-span">column-span2</div>
+  <article>
+    <div class="container" style="height: 50px;">
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a.html
new file mode 100644
index 0000000..366ca33
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004a.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test the block-size distribution across column-span split in a balancing multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-children-height-004a-ref.html">
+  <meta name="assert" content="This test verifies that a block container with a fixed block-size, split by column-span, distributes just enough block-size to hold its children.">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 450px;
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    column-span: all;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <!-- The container is split by the column-spans.
+         a) Before column-span1, it distributes 200px height into two columns,
+            and each column takes 100px height.
+         b) In between column-span1 and column-span2, same distribution as a).
+         c) After column-span2, it has 50px height left, which goes to the first
+            column.
+    -->
+    <div class="container">
+      <!-- Each block spreads its height evenly into two columns, and
+           each column contains 100px height. -->
+      <div class="block">block1</div>
+      <div class="column-span">column-span1</div>
+      <div class="block">block2</div>
+      <div class="column-span">column-span2</div>
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b-ref.html
new file mode 100644
index 0000000..c6412ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test Reference: Test the block-size distribution across column-span split in a balancing multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 200px;
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    width: 400px;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <div class="container">
+      <div class="block">block1</div>
+    </div>
+  </article>
+  <div class="column-span">column-span1</div>
+  <article>
+    <div class="container" style="height: 150px;">
+      <div class="block">block2</div>
+    </div>
+  </article>
+  <div class="column-span">column-span2</div>
+  <article>
+    <div class="container" style="height: 0;">
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b.html
new file mode 100644
index 0000000..1920232
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-004b.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test the block-size distribution across column-span split in a balancing multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-children-height-004b-ref.html">
+  <meta name="assert" content="This test verifies that a block container with a fixed block-size, split by column-span, distributes just enough block-size to hold its children.">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 350px;
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    column-span: all;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <!-- The container is split by the column-spans.
+         a) Before column-span1, it distributes 200px height into two columns,
+            and each column takes 100px height.
+         b) In between column-span1 and column-span2, it has 150px left. The first
+            column takes 100px, and the second column takes 50px.
+    -->
+    <div class="container">
+      <!-- Each block spreads its height evenly into two columns, and
+           each column contains 100px height. -->
+      <div class="block">block1</div>
+      <div class="column-span">column-span1</div>
+      <div class="block">block2</div>
+      <div class="column-span">column-span2</div>
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005-ref.html
new file mode 100644
index 0000000..d5102e1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005-ref.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test Reference: Test the block-size distribution across column-span split in a column-fill:auto multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+
+  <style>
+  article {
+    column-count: 1;
+    width: 200px;
+    background-color: lightgreen;
+  }
+  div.container {
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 100px;
+    background-color: yellow;
+  }
+  div.column-span {
+    width: 200px;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <div class="container">
+      <div class="block">block1</div>
+    </div>
+  </article>
+  <div class="column-span">column-span1</div>
+  <article>
+    <div class="container">
+      <div class="block">block2</div>
+    </div>
+  </article>
+  <div class="column-span">column-span2</div>
+  <article>
+    <div class="container" style="height: 50px;">
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005.html
new file mode 100644
index 0000000..33a820d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-005.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test the block-size distribution across column-span split in a column-fill:auto multicol container</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-children-height-005-ref.html">
+  <meta name="assert" content="This test verifies that a block container with a fixed block-size, split by column-span, distributes just enough block-size to hold its children.">
+
+  <style>
+  article {
+    column-count: 1;
+    column-fill: auto;
+    width: 200px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 250px;
+    background-color: pink;
+  }
+  div.block {
+    width: 100px;
+    height: 100px;
+    background-color: yellow;
+  }
+  div.column-span {
+    column-span: all;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <!-- The container is split by the column-spans.
+         a) Before column-span1, it distributes 100px height into the sole column.
+         b) In between column-span1 and column-span2, same distribution as a).
+         c) After column-span2, it has 50px height left.
+    -->
+    <div class="container">
+      <div class="block">block1</div>
+      <div class="column-span">column-span1</div>
+      <div class="block">block2</div>
+      <div class="column-span">column-span2</div>
+      <div class="block">block3</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006-ref.html
new file mode 100644
index 0000000..e34036b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006-ref.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test Reference: Test the borders drawing for a block split by column-span</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    background-color: pink;
+    border: 20px solid purple;
+  }
+  div.block {
+    /* This block spreads evenly into two columns, each has 100px height. */
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    width: 400px;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <div class="container" style="border-bottom: none; height: 200px;">
+      <div class="block">block1</div>
+    </div>
+  </article>
+  <div class="column-span">column-span1</div>
+  <article>
+    <div class="container" style="border-top: none; height: 50px;">
+      <div class="block">block2</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006.html
new file mode 100644
index 0000000..dd63cd8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-children-height-006.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test the borders drawing for a block split by column-span</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-children-height-006-ref.html">
+  <meta name="assert" content="This test verifies that the borders of block container with a fixed block-size, split by column-span, are skipped on the sides adjacent to column-span.">
+
+  <style>
+  article {
+    column-count: 2;
+    width: 400px;
+    background-color: lightgreen;
+  }
+  div.container {
+    height: 250px;
+    background-color: pink;
+    border: 20px solid purple;
+  }
+  div.block {
+    width: 100px;
+    height: 200px;
+    background-color: yellow;
+  }
+  div.column-span {
+    column-span: all;
+    height: 50px;
+    background-color: lightblue;
+  }
+  </style>
+
+  <article>
+    <div class="container">
+      <div class="block">block1</div>
+      <div class="column-span">column-span1</div>
+      <div class="block">block2</div>
+    </div>
+  </article>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLInputElement.html b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLInputElement.html
index 65e33e84..13d1591 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLInputElement.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLInputElement.html
@@ -20,7 +20,7 @@
         instance['capture'] = 'user';
         const logEntries = element.takeLog();
         assert_array_equals(logEntries.types(), ['attributeChanged']);
-        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'user', namespace: null});
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: null, newValue: 'user', namespace: null});
     }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding new attribute');
 
     test(() => {
@@ -43,7 +43,7 @@
         instance['capture'] = 'asdf';
         const logEntries = element.takeLog();
         assert_array_equals(logEntries.types(), ['attributeChanged']);
-        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'asdf', namespace: null});
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: null, newValue: 'asdf', namespace: null});
     }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding invalid value default');
 
     test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect-expected.txt b/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect-expected.txt
index 7ce0a7e..fee75ec8 100644
--- a/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect-expected.txt
@@ -3,7 +3,7 @@
 FAIL input.capture is "" when the capture attribute is absent assert_equals: expected (string) "" but got (undefined) undefined
 FAIL input.capture is "" when the capture attribute is missing value default assert_equals: expected (string) "" but got (undefined) undefined
 FAIL input.capture is "user" when the capture attribute is user assert_equals: expected (string) "user" but got (undefined) undefined
-FAIL input.capture is "invalid" when the capture attribute is invalid value default assert_equals: expected (string) "invalid" but got (undefined) undefined
+FAIL input.capture is "" when the capture attribute is invalid value default assert_equals: expected (string) "" but got (undefined) undefined
 FAIL input.capture is "environment" when the capture attribute is environment assert_equals: expected (string) "environment" but got (undefined) undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect.html b/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect.html
index 39f391e..f593236b 100644
--- a/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect.html
+++ b/third_party/blink/web_tests/external/wpt/html-media-capture/capture_reflect.html
@@ -53,8 +53,8 @@
       }, 'input.capture is "user" when the capture attribute is user');
 
       test(function() {
-        assert_equals(document.querySelector('#present-invalid').capture, "invalid");
-      }, 'input.capture is "invalid" when the capture attribute is invalid value default');
+        assert_equals(document.querySelector('#present-invalid').capture, "");
+      }, 'input.capture is "" when the capture attribute is invalid value default');
 
       test(function() {
         assert_equals(document.querySelector('#present-environment').capture, "environment");
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/html.idl b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
index 5ae46f74..47abcda 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/html.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/html.idl
@@ -1359,12 +1359,9 @@
   void quadraticCurveTo(unrestricted double cpx, unrestricted double cpy, unrestricted double x, unrestricted double y);
   void bezierCurveTo(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y);
   void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius);
-
   void rect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
   void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
-
   void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
-
 };
 
 [Exposed=(Window,Worker)]
@@ -1582,7 +1579,6 @@
   [Replaceable] readonly attribute WindowProxy self;
   [Unforgeable] readonly attribute Document document;
   attribute DOMString name;
-
   [PutForwards=href, Unforgeable] readonly attribute Location location;
   readonly attribute History history;
   readonly attribute CustomElementRegistry customElements;
@@ -1614,7 +1610,6 @@
 
   // the user agent
   readonly attribute Navigator navigator;
-
   [SecureContext] readonly attribute ApplicationCache applicationCache;
 
   // user prompts
@@ -2375,7 +2370,6 @@
   [CEReactions] attribute [TreatNullAs=EmptyString] DOMString color;
   [CEReactions] attribute DOMString face;
   [CEReactions] attribute DOMString size;
-
 };
 
 partial interface HTMLHeadingElement {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/layout-instability.idl b/third_party/blink/web_tests/external/wpt/interfaces/layout-instability.idl
new file mode 100644
index 0000000..1bacea7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/interfaces/layout-instability.idl
@@ -0,0 +1,10 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content was automatically extracted by Reffy into reffy-reports
+// (https://github.com/tidoust/reffy-reports)
+// Source: Layout Instability API (https://wicg.github.io/layout-instability/)
+
+interface LayoutShift : PerformanceEntry {
+  readonly attribute long value;
+  readonly attribute boolean hadRecentInput;
+  readonly attribute DOMHighResTimeStamp lastInputTime;
+};
diff --git a/third_party/blink/web_tests/external/wpt/layout-instability/idlharness.window.js b/third_party/blink/web_tests/external/wpt/layout-instability/idlharness.window.js
new file mode 100644
index 0000000..7d97446
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/layout-instability/idlharness.window.js
@@ -0,0 +1,16 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+// https://wicg.github.io/layout-instability/
+
+'use strict';
+
+idl_test(
+  ['layout-instability'],
+  ['performance-timeline'],
+  idl_array => {
+    idl_array.add_objects({
+      // LayoutShift: [ TODO ]
+    });
+  }
+);
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html
index 70fe67b..693f3bd1 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html
@@ -49,6 +49,7 @@
       assert_not_equals(found_device, undefined);
       assert_equals(found_device.kind, "videoinput");
       assert_equals(found_device.groupId, device.groupId);
+      stream.getTracks().forEach(t => t.stop());
     }, error => {
       assert_equals(error.name, "OverconstrainedError");
       assert_equals(error.constraint, "groupId");
@@ -71,6 +72,7 @@
       assert_not_equals(found_device, undefined);
       assert_equals(found_device.kind, "audioinput");
       assert_equals(found_device.groupId, device.groupId);
+      stream.getTracks().forEach(t => t.stop());
     }, error => {
       assert_equals(error.name, "OverconstrainedError");
       assert_equals(error.constraint, "groupId");
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/firefox_android.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/firefox_android.py
index b6d7bc88..30e53a59 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/firefox_android.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/browsers/firefox_android.py
@@ -1,7 +1,6 @@
 import os
 
 import moznetwork
-from mozprocess import ProcessHandler
 from mozprofile import FirefoxProfile
 from mozrunner import FennecEmulatorRunner
 
@@ -52,7 +51,8 @@
             "timeout_multiplier": get_timeout_multiplier(test_type,
                                                          run_info_data,
                                                          **kwargs),
-            "leak_check": kwargs["leak_check"],
+            # desktop only
+            "leak_check": False,
             "stylo_threads": kwargs["stylo_threads"],
             "chaos_mode_flags": kwargs["chaos_mode_flags"],
             "config": config,
@@ -145,13 +145,7 @@
                 with open(os.path.join(font_dir, "Ahem.ttf"), "wb") as dest:
                     dest.write(src.read())
 
-        if self.leak_check and kwargs.get("check_leaks", True):
-            self.leak_report_file = os.path.join(self.profile.profile, "runtests_leaks.log")
-            if os.path.exists(self.leak_report_file):
-                os.remove(self.leak_report_file)
-            env["XPCOM_MEM_BLOAT_LOG"] = self.leak_report_file
-        else:
-            self.leak_report_file = None
+        self.leak_report_file = None
 
         if self.ca_certificate_path is not None:
             self.setup_ssl()
@@ -168,9 +162,7 @@
                                            symbols_path=self.symbols_path,
                                            serial=self.device_serial,
                                            # TODO - choose appropriate log dir
-                                           logdir=os.getcwd(),
-                                           process_class=ProcessHandler,
-                                           process_args={"processOutputLine": [self.on_output]})
+                                           logdir=os.getcwd())
 
         self.logger.debug("Starting %s" % self.package_name)
         # connect to a running emulator
@@ -201,11 +193,11 @@
                 except Exception as e:
                     self.logger.warning("Failed to remove forwarded or reversed ports: %s" % e)
             # We assume that stopping the runner prompts the
-            # browser to shut down. This allows the leak log to be written
+            # browser to shut down.
             self.runner.stop()
         self.logger.debug("stopped")
 
     def check_crash(self, process, test):
         if not os.environ.get("MINIDUMP_STACKWALK", "") and self.stackwalk_binary:
             os.environ["MINIDUMP_STACKWALK"] = self.stackwalk_binary
-        return self.runner.check_for_crashes()
+        return bool(self.runner.check_for_crashes(test_name=test))
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
index 928a153..87563f3e 100644
--- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptcommandline.py
@@ -269,7 +269,7 @@
                              help="Defines an extra user preference (overrides those in prefs_root)")
     gecko_group.add_argument("--leak-check", dest="leak_check", action="store_true", default=None,
                              help="Enable leak checking (enabled by default for debug builds, "
-                             "silently ignored for opt)")
+                             "silently ignored for opt, mobile)")
     gecko_group.add_argument("--no-leak-check", dest="leak_check", action="store_false", default=None,
                              help="Disable leak checking")
     gecko_group.add_argument("--stylo-threads", action="store", type=int, default=1,
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time-expected.txt
new file mode 100644
index 0000000..fd8aa045
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time-expected.txt
@@ -0,0 +1,14 @@
+Test filtering in Bottom-Up Timeline Tree View panel.
+
+Initial:
+ BBB selfTime: 80
+  AAA selfTime: 80
+ AAA selfTime: 20
+
+Filtered by 'AAA':
+ AAA selfTime: 20
+
+Filtered by 'BBB':
+ BBB selfTime: 80
+
+
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time.js b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time.js
new file mode 100644
index 0000000..df9b398
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-filtering-self-time.js
@@ -0,0 +1,121 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(
+      `Test filtering in Bottom-Up Timeline Tree View panel.\n`);
+  await TestRunner.loadModule('performance_test_runner');
+  await TestRunner.showPanel('timeline');
+
+  var sessionId = '4.20';
+  var mainThread = 1;
+  var pid = 100;
+
+  var testData = [
+    {
+      'args': {
+        'data': {
+          'sessionId': sessionId,
+          'frames':
+              [{'frame': 'frame1', 'url': 'frameurl', 'name': 'frame-name'}]
+        }
+      },
+      'cat': 'disabled-by-default-devtools.timeline',
+      'name': 'TracingStartedInPage',
+      'ph': 'I',
+      'pid': pid,
+      'tid': mainThread,
+      'ts': 100,
+    },
+    {
+      'name': 'top level event name',
+      'ts': 1000000,
+      'ph': 'B',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'toplevel',
+      'args': {}
+    },
+    {
+      'name': 'TimeStamp',
+      'ts': 1010000,
+      'ph': 'B',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'disabled-by-default-devtools.timeline',
+      'args': {'data': {'message': 'AAA'}}
+    },
+    {
+      'name': 'TimeStamp',
+      'ts': 1020000,
+      'ph': 'B',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'disabled-by-default-devtools.timeline',
+      'args': {'data': {'message': 'BBB'}}
+    },
+    {
+      'name': 'TimeStamp',
+      'ts': 1100000,
+      'ph': 'E',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'disabled-by-default-devtools.timeline',
+      'args': {}
+    },
+    {
+      'name': 'TimeStamp',
+      'ts': 1110000,
+      'ph': 'E',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'disabled-by-default-devtools.timeline',
+      'args': {}
+    },
+    {
+      'name': 'top level event name',
+      'ts': 1120000,
+      'ph': 'E',
+      'tid': mainThread,
+      'pid': pid,
+      'cat': 'toplevel',
+      'args': {}
+    }
+  ];
+
+  var model = PerformanceTestRunner.createPerformanceModelWithEvents(testData);
+  const tabbedPane = UI.panels.timeline._flameChart._detailsView._tabbedPane;
+  tabbedPane.selectTab(Timeline.TimelineDetailsView.Tab.BottomUp);
+  const view = tabbedPane.visibleView;
+
+  view.setModel(model, PerformanceTestRunner.mainTrack());
+  view.updateContents(Timeline.TimelineSelection.fromRange(
+      model.timelineModel().minimumRecordTime(),
+      model.timelineModel().maximumRecordTime()));
+  function printEventMessage(event, level, node) {
+    const text = event.args['data'] && event.args['data']['message'] ?
+        event.args['data']['message'] + ' selfTime: ' + node.selfTime :
+        event.name;
+    TestRunner.addResult(' '.repeat(level) + text);
+  }
+
+  function dumpRecords() {
+    PerformanceTestRunner.walkTimelineEventTreeUnderNode(
+        printEventMessage, view._root);
+    TestRunner.addResult('');
+  }
+
+  TestRunner.addResult('Initial:');
+  dumpRecords();
+
+  TestRunner.addResult(`Filtered by 'AAA':`);
+  view._textFilterUI.setValue('AAA', true);
+  dumpRecords();
+
+  TestRunner.addResult(`Filtered by 'BBB':`);
+  view._textFilterUI.setValue('BBB', true);
+  dumpRecords();
+
+  TestRunner.completeTest();
+})();
diff --git a/tools/binary_size/libsupersize/diff_test.py b/tools/binary_size/libsupersize/diff_test.py
index 93ded26..b5fb2810 100755
--- a/tools/binary_size/libsupersize/diff_test.py
+++ b/tools/binary_size/libsupersize/diff_test.py
@@ -34,8 +34,8 @@
   section_sizes = {'.text': 100, '.bss': 40}
   TEXT = models.SECTION_TEXT
   symbols = [
-      _MakeSym(TEXT, 10, 'a'),
-      _MakeSym(TEXT, 20, 'a'),
+      _MakeSym(models.SECTION_DEX_METHOD, 10, 'a', 'com.Foo#bar()'),
+      _MakeSym(TEXT, 20, 'a', '.Lfoo'),
       _MakeSym(TEXT, 30, 'b'),
       _MakeSym(TEXT, 40, 'b'),
       _MakeSym(TEXT, 50, 'b'),
@@ -155,6 +155,7 @@
     self.assertEquals(0, d.raw_symbols.size)
 
   def testChangedParams(self):
+    # Ensure that params changes match up so long as path doesn't change.
     size_info1 = _CreateSizeInfo()
     size_info1.raw_symbols[0].full_name = 'Foo()'
     size_info1.raw_symbols[0].name = 'Foo'
@@ -165,27 +166,17 @@
     self.assertEquals((0, 0, 0), d.raw_symbols.CountsByDiffStatus()[1:])
     self.assertEquals(0, d.raw_symbols.size)
 
-  def testChangedPaths(self):
+  def testChangedPaths_Native(self):
+    # Ensure that non-globally-unique symbols are not matched when path changes.
     size_info1 = _CreateSizeInfo()
     size_info2 = _CreateSizeInfo()
-    size_info2.raw_symbols[0].object_path = 'asdf'
-    d = diff.Diff(size_info1, size_info2)
-    self.assertEquals((0, 0, 0), d.raw_symbols.CountsByDiffStatus()[1:])
-    self.assertEquals(0, d.raw_symbols.size)
-
-  def testChangedPaths_ChangedParams(self):
-    size_info1 = _CreateSizeInfo()
-    size_info1.raw_symbols[0].full_name = 'Foo()'
-    size_info1.raw_symbols[0].name = 'Foo'
-    size_info2 = _CreateSizeInfo()
-    size_info2.raw_symbols[0].full_name = 'Foo(bool)'
-    size_info2.raw_symbols[0].name = 'Foo'
-    size_info2.raw_symbols[0].object_path = 'asdf'
+    size_info2.raw_symbols[1].object_path = 'asdf'
     d = diff.Diff(size_info1, size_info2)
     self.assertEquals((0, 1, 1), d.raw_symbols.CountsByDiffStatus()[1:])
     self.assertEquals(0, d.raw_symbols.size)
 
   def testChangedPaths_StringLiterals(self):
+    # Ensure that string literals are not matched up.
     size_info1 = _CreateSizeInfo()
     size_info1.raw_symbols[0].full_name = models.STRING_LITERAL_NAME
     size_info2 = _CreateSizeInfo()
@@ -195,6 +186,29 @@
     self.assertEquals((0, 1, 1), d.raw_symbols.CountsByDiffStatus()[1:])
     self.assertEquals(0, d.raw_symbols.size)
 
+  def testChangedPaths_Java(self):
+    # Ensure that Java symbols are matched up.
+    size_info1 = _CreateSizeInfo()
+    size_info2 = _CreateSizeInfo()
+    size_info2.raw_symbols[0].object_path = 'asdf'
+    d = diff.Diff(size_info1, size_info2)
+    self.assertEquals((0, 0, 0), d.raw_symbols.CountsByDiffStatus()[1:])
+    self.assertEquals(0, d.raw_symbols.size)
+
+  def testChangedPaths_ChangedParams(self):
+    # Ensure that path changes are not matched when params also change.
+    size_info1 = _CreateSizeInfo()
+    size_info1.raw_symbols[0].full_name = 'Foo()'
+    size_info1.raw_symbols[0].name = 'Foo'
+    size_info2 = _CreateSizeInfo()
+    size_info2.raw_symbols[0].full_name = 'Foo(bool)'
+    size_info2.raw_symbols[0].name = 'Foo'
+    size_info2.raw_symbols[0].object_path = 'asdf'
+    d = diff.Diff(size_info1, size_info2)
+    self.assertEquals((0, 1, 1), d.raw_symbols.CountsByDiffStatus()[1:])
+    self.assertEquals(0, d.raw_symbols.size)
+
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/tools/binary_size/libsupersize/models.py b/tools/binary_size/libsupersize/models.py
index 26af853..84c35d2f 100644
--- a/tools/binary_size/libsupersize/models.py
+++ b/tools/binary_size/libsupersize/models.py
@@ -367,7 +367,7 @@
     return not (self.IsStringLiteral() or  # "string literal"
                 self.IsOverhead() or  # "Overhead: APK File"
                 self.full_name.startswith('*') or  # "** outlined symbol"
-                '.' in self.full_name)  # ".L__unnamed_1195"
+                (self.IsNative() and '.' in self.full_name))  # ".L__unnamed_11"
 
   def IterLeafSymbols(self):
     yield self
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 8b9f6703..12f331c 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -633,6 +633,7 @@
       # TODO(crbug/597596): Switch this back to debug_trybot when cronet's
       # shared library loading is fixed.
       'android-cronet-arm-dbg': 'android_cronet_debug_static_bot_arm_no_neon',
+      'android-kitkat-arm-coverage-dbg': 'android_debug_static_trybot_java_coverage',
       'android-kitkat-arm-rel': 'android_release_trybot',
       'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_resource_whitelisting',
       'android-oreo-arm64-cts-networkservice-dbg': 'android_debug_trybot_arm64',
@@ -1027,6 +1028,10 @@
       'android', 'debug_static_bot', 'x86',
     ],
 
+    'android_debug_static_trybot_java_coverage': [
+      'android', 'debug_static_trybot', 'strip_debug_info', 'java_coverage',
+    ],
+
     'android_debug_trybot': [
       'android', 'debug_trybot',
     ],
@@ -2110,6 +2115,10 @@
       'mixins': ['debug', 'static', 'minimal_symbols', 'goma'],
     },
 
+    'debug_static_trybot': {
+      'mixins': ['debug_static_bot'],
+    },
+
     'debug_trybot': {
       'mixins': ['debug_bot'],
     },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 6f868092..7baffd5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11518,6 +11518,7 @@
   <int value="3" label="TPM owner delegate not allowed to reset"/>
   <int value="4" label="TPM owner delegate does not exist"/>
   <int value="5" label="Failed to query dictionary attack counter"/>
+  <int value="6" label="PCR0 in wrong state"/>
 </enum>
 
 <enum name="CrosUsbNotificationClosed">
@@ -56693,6 +56694,13 @@
   <int value="12" label="Play install"/>
 </enum>
 
+<enum name="SuggestionEntityDecorationType">
+  <summary>Type of decoration beside entity suggestion.</summary>
+  <int value="0" label="Fallback Icon"/>
+  <int value="1" label="Color Tile"/>
+  <int value="2" label="Image"/>
+</enum>
+
 <enum name="SuggestionIconOrFaviconType">
   <summary>Type of icon shown beside omnibox suggestion.</summary>
   <int value="0" label="Invalid (unknown type)"/>
@@ -63190,16 +63198,160 @@
 <!-- These can be generated by visiting https://bit.ly/2JQr6rB -->
 
   <int value="0" label="Invalid Patch Level"/>
+  <int value="170393600" label="Windows XP (Build 2600.0)"/>
+  <int value="393216000" label="Windows Vista (Build 6000.0)"/>
+  <int value="393216615" label="Windows Vista (Build 6000.615)"/>
+  <int value="393239964" label="Windows Vista (Build 6000.23964)"/>
+  <int value="393347072" label="Windows Vista Service Pack 2 (Build 6002.0)"/>
+  <int value="393347957" label="Windows Vista Service Pack 2 (Build 6002.885)"/>
+  <int value="393371006"
+      label="Windows Vista Service Pack 2 (Build 6002.23934)"/>
+  <int value="498073600" label="Windows 7 (Build 7600.0)"/>
+  <int value="498073839" label="Windows 7 (Build 7600.239)"/>
+  <int value="498073867" label="Windows 7 (Build 7600.267)"/>
+  <int value="498074215" label="Windows 7 (Build 7600.615)"/>
+  <int value="498074485" label="Windows 7 (Build 7600.885)"/>
+  <int value="498075814" label="Windows 7 (Build 7600.2214)"/>
+  <int value="498083606" label="Windows 7 (Build 7600.10006)"/>
+  <int value="498097242" label="Windows 7 (Build 7600.23642)"/>
+  <int value="498097889" label="Windows 7 (Build 7600.24289)"/>
+  <int value="498097985" label="Windows 7 (Build 7600.24385)"/>
+  <int value="498098068" label="Windows 7 (Build 7600.24468)"/>
+  <int value="498098094" label="Windows 7 (Build 7600.24494)"/>
+  <int value="498098096" label="Windows 7 (Build 7600.24496)"/>
+  <int value="498139136" label="Windows 7 Service Pack 1 (Build 7601.0)"/>
+  <int value="498162751" label="Windows 7 Service Pack 1 (Build 7601.23615)"/>
+  <int value="498162778" label="Windows 7 Service Pack 1 (Build 7601.23642)"/>
+  <int value="498162846" label="Windows 7 Service Pack 1 (Build 7601.23710)"/>
+  <int value="498162851" label="Windows 7 Service Pack 1 (Build 7601.23715)"/>
+  <int value="498162877" label="Windows 7 Service Pack 1 (Build 7601.23741)"/>
+  <int value="498162878" label="Windows 7 Service Pack 1 (Build 7601.23742)"/>
+  <int value="498162933" label="Windows 7 Service Pack 1 (Build 7601.23797)"/>
+  <int value="498162934" label="Windows 7 Service Pack 1 (Build 7601.23798)"/>
+  <int value="498162969" label="Windows 7 Service Pack 1 (Build 7601.23833)"/>
+  <int value="498162982" label="Windows 7 Service Pack 1 (Build 7601.23846)"/>
+  <int value="498162998" label="Windows 7 Service Pack 1 (Build 7601.23862)"/>
+  <int value="498163015" label="Windows 7 Service Pack 1 (Build 7601.23879)"/>
+  <int value="498163017" label="Windows 7 Service Pack 1 (Build 7601.23881)"/>
+  <int value="498163043" label="Windows 7 Service Pack 1 (Build 7601.23907)"/>
+  <int value="498163045" label="Windows 7 Service Pack 1 (Build 7601.23909)"/>
+  <int value="498163050" label="Windows 7 Service Pack 1 (Build 7601.23914)"/>
+  <int value="498163051" label="Windows 7 Service Pack 1 (Build 7601.23915)"/>
+  <int value="498163070" label="Windows 7 Service Pack 1 (Build 7601.23934)"/>
+  <int value="498163099" label="Windows 7 Service Pack 1 (Build 7601.23963)"/>
+  <int value="498163100" label="Windows 7 Service Pack 1 (Build 7601.23964)"/>
+  <int value="498163138" label="Windows 7 Service Pack 1 (Build 7601.24002)"/>
+  <int value="498163159" label="Windows 7 Service Pack 1 (Build 7601.24023)"/>
+  <int value="498163191" label="Windows 7 Service Pack 1 (Build 7601.24055)"/>
+  <int value="498163194" label="Windows 7 Service Pack 1 (Build 7601.24058)"/>
+  <int value="498163211" label="Windows 7 Service Pack 1 (Build 7601.24075)"/>
+  <int value="498163212" label="Windows 7 Service Pack 1 (Build 7601.24076)"/>
+  <int value="498163225" label="Windows 7 Service Pack 1 (Build 7601.24089)"/>
+  <int value="498163242" label="Windows 7 Service Pack 1 (Build 7601.24106)"/>
+  <int value="498163266" label="Windows 7 Service Pack 1 (Build 7601.24130)"/>
+  <int value="498163272" label="Windows 7 Service Pack 1 (Build 7601.24136)"/>
+  <int value="498163285" label="Windows 7 Service Pack 1 (Build 7601.24149)"/>
+  <int value="498163286" label="Windows 7 Service Pack 1 (Build 7601.24150)"/>
+  <int value="498163316" label="Windows 7 Service Pack 1 (Build 7601.24180)"/>
+  <int value="498163344" label="Windows 7 Service Pack 1 (Build 7601.24208)"/>
+  <int value="498163350" label="Windows 7 Service Pack 1 (Build 7601.24214)"/>
+  <int value="498163373" label="Windows 7 Service Pack 1 (Build 7601.24237)"/>
+  <int value="498163377" label="Windows 7 Service Pack 1 (Build 7601.24241)"/>
+  <int value="498163397" label="Windows 7 Service Pack 1 (Build 7601.24261)"/>
+  <int value="498163399" label="Windows 7 Service Pack 1 (Build 7601.24263)"/>
+  <int value="498163400" label="Windows 7 Service Pack 1 (Build 7601.24264)"/>
+  <int value="498163425" label="Windows 7 Service Pack 1 (Build 7601.24289)"/>
+  <int value="498163426" label="Windows 7 Service Pack 1 (Build 7601.24290)"/>
+  <int value="498163448" label="Windows 7 Service Pack 1 (Build 7601.24312)"/>
+  <int value="498163470" label="Windows 7 Service Pack 1 (Build 7601.24334)"/>
+  <int value="498163491" label="Windows 7 Service Pack 1 (Build 7601.24355)"/>
+  <int value="498163492" label="Windows 7 Service Pack 1 (Build 7601.24356)"/>
+  <int value="498163519" label="Windows 7 Service Pack 1 (Build 7601.24383)"/>
+  <int value="498163521" label="Windows 7 Service Pack 1 (Build 7601.24385)"/>
   <int value="498163541" label="Windows 7 Service Pack 1 (Build 7601.24405)"/>
+  <int value="498163547" label="Windows 7 Service Pack 1 (Build 7601.24411)"/>
+  <int value="498163553" label="Windows 7 Service Pack 1 (Build 7601.24417)"/>
+  <int value="498163579" label="Windows 7 Service Pack 1 (Build 7601.24443)"/>
+  <int value="498163601" label="Windows 7 Service Pack 1 (Build 7601.24465)"/>
+  <int value="498163604" label="Windows 7 Service Pack 1 (Build 7601.24468)"/>
+  <int value="498163627" label="Windows 7 Service Pack 1 (Build 7601.24491)"/>
+  <int value="498163630" label="Windows 7 Service Pack 1 (Build 7601.24494)"/>
+  <int value="498163632" label="Windows 7 Service Pack 1 (Build 7601.24496)"/>
+  <int value="550502400" label="Windows 8 Preview (Build 8400.0)"/>
+  <int value="602931200" label="Windows 8 (Build 9200.0)"/>
+  <int value="602931251" label="Windows 8 (Build 9200.51)"/>
+  <int value="602931439" label="Windows 8 (Build 9200.239)"/>
+  <int value="602931467" label="Windows 8 (Build 9200.267)"/>
+  <int value="602931607" label="Windows 8 (Build 9200.407)"/>
+  <int value="602931703" label="Windows 8 (Build 9200.503)"/>
+  <int value="602931815" label="Windows 8 (Build 9200.615)"/>
+  <int value="602931852" label="Windows 8 (Build 9200.652)"/>
+  <int value="602932029" label="Windows 8 (Build 9200.829)"/>
+  <int value="602932085" label="Windows 8 (Build 9200.885)"/>
+  <int value="602932116" label="Windows 8 (Build 9200.916)"/>
+  <int value="602932287" label="Windows 8 (Build 9200.1087)"/>
+  <int value="602932618" label="Windows 8 (Build 9200.1418)"/>
+  <int value="602941206" label="Windows 8 (Build 9200.10006)"/>
   <int value="602947584" label="Windows 8 (Build 9200.16384)"/>
+  <int value="602950601" label="Windows 8 (Build 9200.19401)"/>
+  <int value="602953820" label="Windows 8 (Build 9200.22620)"/>
+  <int value="602954001" label="Windows 8 (Build 9200.22801)"/>
+  <int value="629145600" label="Windows 8.1 (Build 9600.0)"/>
+  <int value="629164143" label="Windows 8.1 (Build 9600.18543)"/>
+  <int value="629164219" label="Windows 8.1 (Build 9600.18619)"/>
+  <int value="629164221" label="Windows 8.1 (Build 9600.18621)"/>
+  <int value="629164284" label="Windows 8.1 (Build 9600.18684)"/>
+  <int value="629164287" label="Windows 8.1 (Build 9600.18687)"/>
+  <int value="629164320" label="Windows 8.1 (Build 9600.18720)"/>
+  <int value="629164356" label="Windows 8.1 (Build 9600.18756)"/>
+  <int value="629164378" label="Windows 8.1 (Build 9600.18778)"/>
+  <int value="629164410" label="Windows 8.1 (Build 9600.18810)"/>
+  <int value="629164422" label="Windows 8.1 (Build 9600.18822)"/>
+  <int value="629164433" label="Windows 8.1 (Build 9600.18833)"/>
+  <int value="629164456" label="Windows 8.1 (Build 9600.18856)"/>
+  <int value="629164474" label="Windows 8.1 (Build 9600.18874)"/>
+  <int value="629164494" label="Windows 8.1 (Build 9600.18894)"/>
+  <int value="629164509" label="Windows 8.1 (Build 9600.18909)"/>
+  <int value="629164537" label="Windows 8.1 (Build 9600.18937)"/>
+  <int value="629164564" label="Windows 8.1 (Build 9600.18964)"/>
+  <int value="629164571" label="Windows 8.1 (Build 9600.18971)"/>
+  <int value="629164593" label="Windows 8.1 (Build 9600.18993)"/>
+  <int value="629164594" label="Windows 8.1 (Build 9600.18994)"/>
+  <int value="629164623" label="Windows 8.1 (Build 9600.19023)"/>
+  <int value="629164624" label="Windows 8.1 (Build 9600.19024)"/>
+  <int value="629164636" label="Windows 8.1 (Build 9600.19036)"/>
+  <int value="629164669" label="Windows 8.1 (Build 9600.19069)"/>
+  <int value="629164699" label="Windows 8.1 (Build 9600.19099)"/>
+  <int value="629164702" label="Windows 8.1 (Build 9600.19102)"/>
+  <int value="629164734" label="Windows 8.1 (Build 9600.19134)"/>
+  <int value="629164755" label="Windows 8.1 (Build 9600.19155)"/>
+  <int value="629164756" label="Windows 8.1 (Build 9600.19156)"/>
+  <int value="629164782" label="Windows 8.1 (Build 9600.19182)"/>
+  <int value="629164806" label="Windows 8.1 (Build 9600.19206)"/>
+  <int value="629164835" label="Windows 8.1 (Build 9600.19235)"/>
+  <int value="629164837" label="Windows 8.1 (Build 9600.19237)"/>
+  <int value="629164868" label="Windows 8.1 (Build 9600.19268)"/>
+  <int value="629164896" label="Windows 8.1 (Build 9600.19296)"/>
+  <int value="629164902" label="Windows 8.1 (Build 9600.19302)"/>
   <int value="629164923" label="Windows 8.1 (Build 9600.19323)"/>
+  <int value="629164927" label="Windows 8.1 (Build 9600.19327)"/>
+  <int value="629164932" label="Windows 8.1 (Build 9600.19332)"/>
+  <int value="629164956" label="Windows 8.1 (Build 9600.19356)"/>
+  <int value="629164975" label="Windows 8.1 (Build 9600.19375)"/>
+  <int value="629164977" label="Windows 8.1 (Build 9600.19377)"/>
+  <int value="629164999" label="Windows 8.1 (Build 9600.19399)"/>
+  <int value="629165001" label="Windows 8.1 (Build 9600.19401)"/>
+  <int value="629165004" label="Windows 8.1 (Build 9600.19404)"/>
   <int value="671090283" label="Windows 10 1507 (Build 10240.1643)"/>
   <int value="671090292" label="Windows 10 1507 (Build 10240.1652)"/>
   <int value="671090299" label="Windows 10 1507 (Build 10240.1659)"/>
   <int value="671090359" label="Windows 10 1507 (Build 10240.1719)"/>
   <int value="671090417" label="Windows 10 1507 (Build 10240.1777)"/>
+  <int value="671105024" label="Windows 10 1507 (Build 10240.16384)"/>
+  <int value="671105037" label="Windows 10 1507 (Build 10240.16397)"/>
   <int value="671105045" label="Windows 10 1507 (Build 10240.16405)"/>
   <int value="671105053" label="Windows 10 1507 (Build 10240.16413)"/>
+  <int value="671105070" label="Windows 10 1507 (Build 10240.16430)"/>
   <int value="671105073" label="Windows 10 1507 (Build 10240.16433)"/>
   <int value="671105085" label="Windows 10 1507 (Build 10240.16445)"/>
   <int value="671105103" label="Windows 10 1507 (Build 10240.16463)"/>
@@ -63232,6 +63384,7 @@
   <int value="671106349" label="Windows 10 1507 (Build 10240.17709)"/>
   <int value="671106378" label="Windows 10 1507 (Build 10240.17738)"/>
   <int value="671106381" label="Windows 10 1507 (Build 10240.17741)"/>
+  <int value="671106410" label="Windows 10 1507 (Build 10240.17770)"/>
   <int value="671106437" label="Windows 10 1507 (Build 10240.17797)"/>
   <int value="671106471" label="Windows 10 1507 (Build 10240.17831)"/>
   <int value="671106501" label="Windows 10 1507 (Build 10240.17861)"/>
@@ -63254,6 +63407,7 @@
   <int value="671106858" label="Windows 10 1507 (Build 10240.18218)"/>
   <int value="671106884" label="Windows 10 1507 (Build 10240.18244)"/>
   <int value="671106915" label="Windows 10 1507 (Build 10240.18275)"/>
+  <int value="693764096" label="Windows 10 1511 (Build 10586.0)"/>
   <int value="693764099" label="Windows 10 1511 (Build 10586.3)"/>
   <int value="693764107" label="Windows 10 1511 (Build 10586.11)"/>
   <int value="693764110" label="Windows 10 1511 (Build 10586.14)"/>
@@ -63263,12 +63417,16 @@
   <int value="693764138" label="Windows 10 1511 (Build 10586.42)"/>
   <int value="693764159" label="Windows 10 1511 (Build 10586.63)"/>
   <int value="693764167" label="Windows 10 1511 (Build 10586.71)"/>
+  <int value="693764175" label="Windows 10 1511 (Build 10586.79)"/>
   <int value="693764200" label="Windows 10 1511 (Build 10586.104)"/>
   <int value="693764218" label="Windows 10 1511 (Build 10586.122)"/>
   <int value="693764250" label="Windows 10 1511 (Build 10586.154)"/>
   <int value="693764260" label="Windows 10 1511 (Build 10586.164)"/>
   <int value="693764314" label="Windows 10 1511 (Build 10586.218)"/>
   <int value="693764414" label="Windows 10 1511 (Build 10586.318)"/>
+  <int value="693764434" label="Windows 10 1511 (Build 10586.338)"/>
+  <int value="693764516" label="Windows 10 1511 (Build 10586.420)"/>
+  <int value="693764542" label="Windows 10 1511 (Build 10586.446)"/>
   <int value="693764590" label="Windows 10 1511 (Build 10586.494)"/>
   <int value="693764641" label="Windows 10 1511 (Build 10586.545)"/>
   <int value="693764685" label="Windows 10 1511 (Build 10586.589)"/>
@@ -63292,8 +63450,12 @@
   <int value="693765454" label="Windows 10 1511 (Build 10586.1358)"/>
   <int value="693765513" label="Windows 10 1511 (Build 10586.1417)"/>
   <int value="693765574" label="Windows 10 1511 (Build 10586.1478)"/>
+  <int value="693765636" label="Windows 10 1511 (Build 10586.1540)"/>
+  <int value="943259648" label="Windows 10 1607 (Build 14393.0)"/>
   <int value="943259649" label="Windows 10 1607 (Build 14393.1)"/>
+  <int value="943259658" label="Windows 10 1607 (Build 14393.10)"/>
   <int value="943259699" label="Windows 10 1607 (Build 14393.51)"/>
+  <int value="943259715" label="Windows 10 1607 (Build 14393.67)"/>
   <int value="943259730" label="Windows 10 1607 (Build 14393.82)"/>
   <int value="943259753" label="Windows 10 1607 (Build 14393.105)"/>
   <int value="943259796" label="Windows 10 1607 (Build 14393.148)"/>
@@ -63309,19 +63471,26 @@
   <int value="943260095" label="Windows 10 1607 (Build 14393.447)"/>
   <int value="943260127" label="Windows 10 1607 (Build 14393.479)"/>
   <int value="943260224" label="Windows 10 1607 (Build 14393.576)"/>
+  <int value="943260225" label="Windows 10 1607 (Build 14393.577)"/>
   <int value="943260341" label="Windows 10 1607 (Build 14393.693)"/>
+  <int value="943260374" label="Windows 10 1607 (Build 14393.726)"/>
   <int value="943260601" label="Windows 10 1607 (Build 14393.953)"/>
   <int value="943260617" label="Windows 10 1607 (Build 14393.969)"/>
+  <int value="943260618" label="Windows 10 1607 (Build 14393.970)"/>
   <int value="943260714" label="Windows 10 1607 (Build 14393.1066)"/>
   <int value="943260846" label="Windows 10 1607 (Build 14393.1198)"/>
+  <int value="943260878" label="Windows 10 1607 (Build 14393.1230)"/>
   <int value="943261006" label="Windows 10 1607 (Build 14393.1358)"/>
   <int value="943261026" label="Windows 10 1607 (Build 14393.1378)"/>
+  <int value="943261128" label="Windows 10 1607 (Build 14393.1480)"/>
   <int value="943261180" label="Windows 10 1607 (Build 14393.1532)"/>
   <int value="943261185" label="Windows 10 1607 (Build 14393.1537)"/>
   <int value="943261241" label="Windows 10 1607 (Build 14393.1593)"/>
   <int value="943261261" label="Windows 10 1607 (Build 14393.1613)"/>
+  <int value="943261318" label="Windows 10 1607 (Build 14393.1670)"/>
   <int value="943261363" label="Windows 10 1607 (Build 14393.1715)"/>
   <int value="943261385" label="Windows 10 1607 (Build 14393.1737)"/>
+  <int value="943261418" label="Windows 10 1607 (Build 14393.1770)"/>
   <int value="943261442" label="Windows 10 1607 (Build 14393.1794)"/>
   <int value="943261445" label="Windows 10 1607 (Build 14393.1797)"/>
   <int value="943261532" label="Windows 10 1607 (Build 14393.1884)"/>
@@ -63344,14 +63513,17 @@
   <int value="943262016" label="Windows 10 1607 (Build 14393.2368)"/>
   <int value="943262043" label="Windows 10 1607 (Build 14393.2395)"/>
   <int value="943262044" label="Windows 10 1607 (Build 14393.2396)"/>
+  <int value="943262078" label="Windows 10 1607 (Build 14393.2430)"/>
   <int value="943262105" label="Windows 10 1607 (Build 14393.2457)"/>
   <int value="943262133" label="Windows 10 1607 (Build 14393.2485)"/>
   <int value="943262163" label="Windows 10 1607 (Build 14393.2515)"/>
   <int value="943262199" label="Windows 10 1607 (Build 14393.2551)"/>
+  <int value="943262228" label="Windows 10 1607 (Build 14393.2580)"/>
   <int value="943262256" label="Windows 10 1607 (Build 14393.2608)"/>
   <int value="943262287" label="Windows 10 1607 (Build 14393.2639)"/>
   <int value="943262289" label="Windows 10 1607 (Build 14393.2641)"/>
   <int value="943262313" label="Windows 10 1607 (Build 14393.2665)"/>
+  <int value="943262318" label="Windows 10 1607 (Build 14393.2670)"/>
   <int value="943262372" label="Windows 10 1607 (Build 14393.2724)"/>
   <int value="943262407" label="Windows 10 1607 (Build 14393.2759)"/>
   <int value="943262439" label="Windows 10 1607 (Build 14393.2791)"/>
@@ -63369,16 +63541,22 @@
   <int value="943262704" label="Windows 10 1607 (Build 14393.3056)"/>
   <int value="943262733" label="Windows 10 1607 (Build 14393.3085)"/>
   <int value="943262763" label="Windows 10 1607 (Build 14393.3115)"/>
+  <int value="987168768" label="Windows 10 1703 (Build 15063.0)"/>
+  <int value="987168779" label="Windows 10 1703 (Build 15063.11)"/>
+  <int value="987168781" label="Windows 10 1703 (Build 15063.13)"/>
+  <int value="987168782" label="Windows 10 1703 (Build 15063.14)"/>
   <int value="987168793" label="Windows 10 1703 (Build 15063.25)"/>
   <int value="987168822" label="Windows 10 1703 (Build 15063.54)"/>
   <int value="987168853" label="Windows 10 1703 (Build 15063.85)"/>
   <int value="987168906" label="Windows 10 1703 (Build 15063.138)"/>
+  <int value="987169018" label="Windows 10 1703 (Build 15063.250)"/>
   <int value="987169064" label="Windows 10 1703 (Build 15063.296)"/>
   <int value="987169100" label="Windows 10 1703 (Build 15063.332)"/>
   <int value="987169181" label="Windows 10 1703 (Build 15063.413)"/>
   <int value="987169215" label="Windows 10 1703 (Build 15063.447)"/>
   <int value="987169251" label="Windows 10 1703 (Build 15063.483)"/>
   <int value="987169270" label="Windows 10 1703 (Build 15063.502)"/>
+  <int value="987169308" label="Windows 10 1703 (Build 15063.540)"/>
   <int value="987169376" label="Windows 10 1703 (Build 15063.608)"/>
   <int value="987169400" label="Windows 10 1703 (Build 15063.632)"/>
   <int value="987169442" label="Windows 10 1703 (Build 15063.674)"/>
@@ -63386,6 +63564,7 @@
   <int value="987169494" label="Windows 10 1703 (Build 15063.726)"/>
   <int value="987169497" label="Windows 10 1703 (Build 15063.729)"/>
   <int value="987169554" label="Windows 10 1703 (Build 15063.786)"/>
+  <int value="987169618" label="Windows 10 1703 (Build 15063.850)"/>
   <int value="987169645" label="Windows 10 1703 (Build 15063.877)"/>
   <int value="987169677" label="Windows 10 1703 (Build 15063.909)"/>
   <int value="987169704" label="Windows 10 1703 (Build 15063.936)"/>
@@ -63427,6 +63606,7 @@
   <int value="987170666" label="Windows 10 1703 (Build 15063.1898)"/>
   <int value="987170696" label="Windows 10 1703 (Build 15063.1928)"/>
   <int value="987170723" label="Windows 10 1703 (Build 15063.1955)"/>
+  <int value="1068171279" label="Windows 10 1709 (Build 16299.15)"/>
   <int value="1068171283" label="Windows 10 1709 (Build 16299.19)"/>
   <int value="1068171328" label="Windows 10 1709 (Build 16299.64)"/>
   <int value="1068171346" label="Windows 10 1709 (Build 16299.82)"/>
@@ -63458,6 +63638,7 @@
   <int value="1068171990" label="Windows 10 1709 (Build 16299.726)"/>
   <int value="1068172019" label="Windows 10 1709 (Build 16299.755)"/>
   <int value="1068172049" label="Windows 10 1709 (Build 16299.785)"/>
+  <int value="1068172084" label="Windows 10 1709 (Build 16299.820)"/>
   <int value="1068172110" label="Windows 10 1709 (Build 16299.846)"/>
   <int value="1068172111" label="Windows 10 1709 (Build 16299.847)"/>
   <int value="1068172168" label="Windows 10 1709 (Build 16299.904)"/>
@@ -63469,12 +63650,15 @@
   <int value="1068172351" label="Windows 10 1709 (Build 16299.1087)"/>
   <int value="1068172391" label="Windows 10 1709 (Build 16299.1127)"/>
   <int value="1068172410" label="Windows 10 1709 (Build 16299.1146)"/>
+  <int value="1068172414" label="Windows 10 1709 (Build 16299.1150)"/>
   <int value="1068172446" label="Windows 10 1709 (Build 16299.1182)"/>
   <int value="1068172481" label="Windows 10 1709 (Build 16299.1217)"/>
   <int value="1068172501" label="Windows 10 1709 (Build 16299.1237)"/>
   <int value="1068172503" label="Windows 10 1709 (Build 16299.1239)"/>
   <int value="1068172532" label="Windows 10 1709 (Build 16299.1268)"/>
   <int value="1068172560" label="Windows 10 1709 (Build 16299.1296)"/>
+  <int value="1122893825" label="Windows 10 1803 (Build 17134.1)"/>
+  <int value="1122893829" label="Windows 10 1803 (Build 17134.5)"/>
   <int value="1122893856" label="Windows 10 1803 (Build 17134.32)"/>
   <int value="1122893872" label="Windows 10 1803 (Build 17134.48)"/>
   <int value="1122893883" label="Windows 10 1803 (Build 17134.59)"/>
@@ -63490,6 +63674,8 @@
   <int value="1122894078" label="Windows 10 1803 (Build 17134.254)"/>
   <int value="1122894109" label="Windows 10 1803 (Build 17134.285)"/>
   <int value="1122894110" label="Windows 10 1803 (Build 17134.286)"/>
+  <int value="1122894143" label="Windows 10 1803 (Build 17134.319)"/>
+  <int value="1122894144" label="Windows 10 1803 (Build 17134.320)"/>
   <int value="1122894169" label="Windows 10 1803 (Build 17134.345)"/>
   <int value="1122894200" label="Windows 10 1803 (Build 17134.376)"/>
   <int value="1122894231" label="Windows 10 1803 (Build 17134.407)"/>
@@ -63498,6 +63684,7 @@
   <int value="1122894296" label="Windows 10 1803 (Build 17134.472)"/>
   <int value="1122894347" label="Windows 10 1803 (Build 17134.523)"/>
   <int value="1122894380" label="Windows 10 1803 (Build 17134.556)"/>
+  <int value="1122894414" label="Windows 10 1803 (Build 17134.590)"/>
   <int value="1122894443" label="Windows 10 1803 (Build 17134.619)"/>
   <int value="1122894472" label="Windows 10 1803 (Build 17134.648)"/>
   <int value="1122894501" label="Windows 10 1803 (Build 17134.677)"/>
@@ -63508,20 +63695,26 @@
   <int value="1122894623" label="Windows 10 1803 (Build 17134.799)"/>
   <int value="1122894653" label="Windows 10 1803 (Build 17134.829)"/>
   <int value="1122894682" label="Windows 10 1803 (Build 17134.858)"/>
+  <int value="1122894684" label="Windows 10 1803 (Build 17134.860)"/>
   <int value="1122894709" label="Windows 10 1803 (Build 17134.885)"/>
   <int value="1122894739" label="Windows 10 1803 (Build 17134.915)"/>
   <int value="1164115969" label="Windows 10 1809 (Build 17763.1)"/>
+  <int value="1164115985" label="Windows 10 1809 (Build 17763.17)"/>
   <int value="1164116023" label="Windows 10 1809 (Build 17763.55)"/>
+  <int value="1164116072" label="Windows 10 1809 (Build 17763.104)"/>
   <int value="1164116075" label="Windows 10 1809 (Build 17763.107)"/>
   <int value="1164116102" label="Windows 10 1809 (Build 17763.134)"/>
   <int value="1164116136" label="Windows 10 1809 (Build 17763.168)"/>
   <int value="1164116162" label="Windows 10 1809 (Build 17763.194)"/>
   <int value="1164116163" label="Windows 10 1809 (Build 17763.195)"/>
   <int value="1164116221" label="Windows 10 1809 (Build 17763.253)"/>
+  <int value="1164116256" label="Windows 10 1809 (Build 17763.288)"/>
   <int value="1164116260" label="Windows 10 1809 (Build 17763.292)"/>
   <int value="1164116284" label="Windows 10 1809 (Build 17763.316)"/>
   <int value="1164116316" label="Windows 10 1809 (Build 17763.348)"/>
+  <int value="1164116317" label="Windows 10 1809 (Build 17763.349)"/>
   <int value="1164116347" label="Windows 10 1809 (Build 17763.379)"/>
+  <int value="1164116370" label="Windows 10 1809 (Build 17763.402)"/>
   <int value="1164116372" label="Windows 10 1809 (Build 17763.404)"/>
   <int value="1164116405" label="Windows 10 1809 (Build 17763.437)"/>
   <int value="1164116407" label="Windows 10 1809 (Build 17763.439)"/>
@@ -63534,11 +63727,30 @@
   <int value="1164116561" label="Windows 10 1809 (Build 17763.593)"/>
   <int value="1164116583" label="Windows 10 1809 (Build 17763.615)"/>
   <int value="1164116620" label="Windows 10 1809 (Build 17763.652)"/>
+  <int value="1203372033" label="Windows 10 1903 (Build 18362.1)"/>
+  <int value="1203372062" label="Windows 10 1903 (Build 18362.30)"/>
+  <int value="1203372085" label="Windows 10 1903 (Build 18362.53)"/>
+  <int value="1203372118" label="Windows 10 1903 (Build 18362.86)"/>
+  <int value="1203372145" label="Windows 10 1903 (Build 18362.113)"/>
   <int value="1203372148" label="Windows 10 1903 (Build 18362.116)"/>
   <int value="1203372177" label="Windows 10 1903 (Build 18362.145)"/>
   <int value="1203372207" label="Windows 10 1903 (Build 18362.175)"/>
   <int value="1203372239" label="Windows 10 1903 (Build 18362.207)"/>
   <int value="1203372271" label="Windows 10 1903 (Build 18362.239)"/>
+  <int value="1203372295" label="Windows 10 1903 (Build 18362.263)"/>
+  <int value="1203372296" label="Windows 10 1903 (Build 18362.264)"/>
+  <int value="1203372298" label="Windows 10 1903 (Build 18362.266)"/>
+  <int value="1203372299" label="Windows 10 1903 (Build 18362.267)"/>
+  <int value="1203382032" label="Windows 10 1903 (Build 18362.10000)"/>
+  <int value="1203382037" label="Windows 10 1903 (Build 18362.10005)"/>
+  <int value="1203382038" label="Windows 10 1903 (Build 18362.10006)"/>
+  <int value="1239155688" label="Windows 10 Insider (Build 18908.1000)"/>
+  <int value="1240073192" label="Windows 10 Insider (Build 18922.1000)"/>
+  <int value="1240728552" label="Windows 10 Insider (Build 18932.1000)"/>
+  <int value="1240990696" label="Windows 10 Insider (Build 18936.1000)"/>
+  <int value="1241318377" label="Windows 10 Insider (Build 18941.1001)"/>
+  <int value="1241580521" label="Windows 10 Insider (Build 18945.1001)"/>
+  <int value="1241711592" label="Windows 10 Insider (Build 18947.1000)"/>
 </enum>
 
 <enum name="WindowsToastActivatorCLSIDMismatchReason">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c390eaf..e8a79ea 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -31118,6 +31118,9 @@
 
 <histogram name="Download.DangerousFile.Discard"
     enum="DownloadItem.DangerousFileType" expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>dtrainor@chromium.org</owner>
   <owner>felt@chromium.org</owner>
   <summary>
@@ -31144,6 +31147,9 @@
 
 <histogram name="Download.DangerousFile.UserDiscard"
     enum="DownloadItem.DangerousFileType" expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>dtrainor@chromium.org</owner>
   <owner>felt@chromium.org</owner>
   <summary>
@@ -31262,6 +31268,9 @@
 
 <histogram name="Download.Discard" enum="DownloadItem.DangerType"
     expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>dtrainor@chromium.org</owner>
   <owner>felt@chromium.org</owner>
   <summary>
@@ -32631,6 +32640,9 @@
 
 <histogram name="Download.UserDiscard" enum="DownloadItem.DangerType"
     expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>dtrainor@chromium.org</owner>
   <owner>felt@chromium.org</owner>
   <summary>
@@ -65603,6 +65615,9 @@
 
 <histogram name="MobileDownload.CancelReason" enum="MobileDownloadCancelReason"
     expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>qinmin@chromium.org</owner>
   <summary>Android: Records the reason that a download is canceled.</summary>
 </histogram>
@@ -65633,6 +65648,9 @@
 
 <histogram name="MobileDownload.DuplicateInfobar"
     enum="MobileDownloadDuplicateInfobar" expires_after="M77">
+  <obsolete>
+    Removed in 07/2019.
+  </obsolete>
   <owner>qinmin@chromium.org</owner>
   <summary>
     Android: Records various counts related to the duplicate download infobar.
@@ -68368,8 +68386,8 @@
 </histogram>
 
 <histogram name="Navigation.StartToCommit" units="ms">
-  <owner>csharrison@chromium.org</owner>
   <owner>nasko@chromium.org</owner>
+  <owner>csharrison@chromium.org</owner>
   <summary>
     The time delta between the start of a navigation and the time it is
     committed.
@@ -88649,8 +88667,8 @@
 <histogram name="Omnibox.AnswerInSuggestShown"
     enum="SuggestionAnswerOptionalType" expires_after="M83">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Records number of times an Answer is presented as one of the Omnibox
     Suggestions at the time the user exited the omnibox. Exiting the omnibox
@@ -89039,9 +89057,9 @@
 <histogram name="Omnibox.IconOrFaviconShown" enum="SuggestionIconOrFaviconType"
     expires_after="M83">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>ender@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>ender@chromium.org</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Records suggestions decorated with specific icon or favicon at the time the
     user exited the omnibox. Exiting the omnibox includes navigating (to entered
@@ -89357,10 +89375,28 @@
   </summary>
 </histogram>
 
+<histogram name="Omnibox.RichEntity.DecorationType"
+    enum="SuggestionEntityDecorationType" expires_after="M84">
+  <owner>chrome-android-omnibox-team@google.com</owner>
+  <owner>ender@chromium.org</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
+  <summary>
+    Records, for each entity suggestion (people, music, ...) whether it was
+    decorated with image / color / icon at the time the user exited the omnibox.
+    Exiting the omnibox includes navigation (url or query), pressing back key,
+    locking the phone, clearing the omnibox, closing Chrome, or just screen
+    blacking out due to prolonged inactivity.
+
+    This metric is currently only recorded on Android, though it could be added
+    to the other platforms.
+  </summary>
+</histogram>
+
 <histogram name="Omnibox.RichEntityShown" units="count" expires_after="M84">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Records number of presented Rich Entity suggestions at the time the user
     exited the omnibox. Exiting the omnibox includes navigating (to entered text
@@ -89489,8 +89525,8 @@
 <histogram name="Omnibox.SuggestionUsed.AnswerInSuggest"
     enum="SuggestionAnswerOptionalType" expires_after="M83">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Counts how often omnibox suggestions are used, and in the case an Answer
     suggestion was selected - records the type of an answer.
@@ -89502,9 +89538,9 @@
 <histogram name="Omnibox.SuggestionUsed.IconOrFaviconType"
     enum="SuggestionIconOrFaviconType" expires_after="M83">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>ender@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>ender@chromium.org</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Counts how often omnibox suggestions are used, and in the case a regular
     search / url (not an Answer, Entity or any other specialized) suggestion was
@@ -89658,8 +89694,8 @@
 <histogram name="Omnibox.SuggestionUsed.RichEntity" enum="BooleanUsage"
     expires_after="M84">
   <owner>chrome-android-omnibox-team@google.com</owner>
-  <owner>jdonnelly@google.com</owner>
-  <owner>mpearson@google.com</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>mpearson@chromium.org</owner>
   <summary>
     Whether a Rich Entity omnibox suggestion was selected when the user used the
     omnibox to go somewhere.
@@ -98431,6 +98467,18 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="PerformanceMonitor.EnergyImpact"
+    units="ScaledUnits" expires_after="2020-07-30">
+  <owner>lgrey@chromium.org</owner>
+  <owner>sdy@chromium.org</owner>
+  <summary>
+    (Mac only) A synthetic power use estimate, as displayed in macOS Activity
+    Monitor and the battery menu. This incorporates CPU utilization, idle
+    wakeups, IO, and task QoS level using per-machine-model weights. Divide by
+    100 to match Activity Monitor's scale. Recorded every two minutes.
+  </summary>
+</histogram>
+
 <histogram name="PerformanceMonitor.HighCPU" enum="BooleanHit">
   <owner>oysteine@chromium.org</owner>
   <summary>
@@ -106232,7 +106280,7 @@
 </histogram>
 
 <histogram name="Previews.ServerLitePage.PreresolvedToPreviewServer"
-    enum="Boolean" expires_after="M80">
+    enum="Boolean" expires_after="M81">
   <owner>robertogden@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -106269,7 +106317,7 @@
 </histogram>
 
 <histogram name="Previews.ServerLitePage.ToggledPreresolve" enum="Boolean"
-    expires_after="M80">
+    expires_after="M81">
   <owner>robertogden@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -133480,6 +133528,9 @@
 
 <histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Disallowed"
     units="resource loads" expires_after="M77">
+  <obsolete>
+    Expired in M77, then deprecated in July 2019.
+  </obsolete>
   <owner>engedy@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133491,6 +133542,9 @@
 
 <histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Evaluated"
     units="resource loads" expires_after="M77">
+  <obsolete>
+    Expired in M77, then deprecated in July 2019.
+  </obsolete>
   <owner>engedy@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133503,6 +133557,9 @@
 <histogram
     name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.MatchedRules"
     units="resource loads" expires_after="M78">
+  <obsolete>
+    Expired in M78, then deprecated in July 2019.
+  </obsolete>
   <owner>engedy@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133514,6 +133571,9 @@
 
 <histogram name="SubresourceFilter.DocumentLoad.NumSubresourceLoads.Total"
     units="resource loads" expires_after="M77">
+  <obsolete>
+    Expired in M77, then deprecated in July 2019.
+  </obsolete>
   <owner>engedy@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133562,6 +133622,9 @@
 <histogram
     name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration"
     units="microseconds">
+  <obsolete>
+    Deprecated in July 2019.
+  </obsolete>
   <owner>pkalinnikov@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133576,6 +133639,9 @@
 <histogram
     name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalWallDuration"
     units="microseconds" expires_after="M78">
+  <obsolete>
+    Deprecated in July 2019.
+  </obsolete>
   <owner>pkalinnikov@chromium.org</owner>
   <summary>
     Whenever a document load is finished in a main frame or subframe with
@@ -133784,8 +133850,9 @@
 </histogram>
 
 <histogram name="SubresourceFilter.PageLoad.NumSubresourceLoads.Disallowed"
-    units="resource loads">
-  <owner>pkalinnikov@chromium.org</owner>
+    units="resource loads" expires_after="M85">
+  <owner>csharrison@chromium.org</owner>
+  <owner>jkarlin@chromium.org</owner>
   <summary>
     Whenever a page load is finished with subresource filtering activated,
     records the total number of subresource loads that have been disallowed.
@@ -133795,8 +133862,9 @@
 </histogram>
 
 <histogram name="SubresourceFilter.PageLoad.NumSubresourceLoads.Evaluated"
-    units="resource loads">
-  <owner>pkalinnikov@chromium.org</owner>
+    units="resource loads" expires_after="M85">
+  <owner>csharrison@chromium.org</owner>
+  <owner>jkarlin@chromium.org</owner>
   <summary>
     Whenever a page load is finished with subresource filtering activated,
     records the total number of subresource loads that have been evaluated. This
@@ -133806,8 +133874,9 @@
 </histogram>
 
 <histogram name="SubresourceFilter.PageLoad.NumSubresourceLoads.MatchedRules"
-    units="resource loads" expires_after="M77">
-  <owner>pkalinnikov@chromium.org</owner>
+    units="resource loads" expires_after="M85">
+  <owner>csharrison@chromium.org</owner>
+  <owner>jkarlin@chromium.org</owner>
   <summary>
     Whenever a page load is finished with subresource filtering activated,
     records the total number of subresource loads that have matched filtering
@@ -133817,8 +133886,9 @@
 </histogram>
 
 <histogram name="SubresourceFilter.PageLoad.NumSubresourceLoads.Total"
-    units="resource loads">
-  <owner>pkalinnikov@chromium.org</owner>
+    units="resource loads" expires_after="M85">
+  <owner>csharrison@chromium.org</owner>
+  <owner>jkarlin@chromium.org</owner>
   <summary>
     Whenever a page load is finished with subresource filtering activated,
     records the total number of subresource loads that have gone through the
@@ -165693,6 +165763,7 @@
   <suffix name="WorkerProcess"/>
   <affected-histogram name="PerformanceMonitor.AverageCPU"/>
   <affected-histogram name="PerformanceMonitor.AverageDisk"/>
+  <affected-histogram name="PerformanceMonitor.EnergyImpact"/>
   <affected-histogram name="PerformanceMonitor.HighCPU"/>
   <affected-histogram name="PerformanceMonitor.IdleWakeups"/>
   <affected-histogram name="PerformanceMonitor.PackageExitIdleWakeups"/>
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index b3e847ff..d2b3756 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -192,23 +192,6 @@
   if (atk_object_get_n_accessible_children(atk_object))
     return true;
 
-  // If this node is an anonymous block that is a static text leaf node, it
-  // should also emit events. The heuristic that Orca uses for this is to check
-  // whether or not it has any non-static-text siblings. We duplicate that here
-  // to maintain compatibility.
-  AtkObject* parent = atk_object_get_parent(atk_object);
-  if (!parent)
-    return false;
-
-  int num_siblings = atk_object_get_n_accessible_children(parent);
-  for (int i = 0; i < num_siblings; i++) {
-    AtkObject* sibling = atk_object_ref_accessible_child(parent, i);
-    AtkRole role = atk_object_get_role(sibling);
-    g_object_unref(sibling);
-    if (role != ATK_ROLE_TEXT)
-      return true;
-  }
-
   return false;
 }
 
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index b0ba040..42ca2635 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -765,7 +765,7 @@
     if (placeholder) {
       inline_reply_->textfield()->SetProperty(kTextfieldIndexKey,
                                               static_cast<int>(i));
-      inline_reply_->textfield()->set_placeholder_text(
+      inline_reply_->textfield()->SetPlaceholderText(
           placeholder->empty()
               ? l10n_util::GetStringUTF16(
                     IDS_MESSAGE_CENTER_NOTIFICATION_INLINE_REPLY_PLACEHOLDER)
diff --git a/ui/views/controls/editable_combobox/editable_combobox.cc b/ui/views/controls/editable_combobox/editable_combobox.cc
index 6f498e8..3b1ad64 100644
--- a/ui/views/controls/editable_combobox/editable_combobox.cc
+++ b/ui/views/controls/editable_combobox/editable_combobox.cc
@@ -364,7 +364,7 @@
 }
 
 void EditableCombobox::SelectRange(const gfx::Range& range) {
-  textfield_->SelectRange(range);
+  textfield_->SetSelectedRange(range);
 }
 
 void EditableCombobox::SetAccessibleName(const base::string16& name) {
@@ -415,7 +415,7 @@
 void EditableCombobox::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   node_data->role = ax::mojom::Role::kComboBoxGrouping;
 
-  node_data->SetName(textfield_->accessible_name());
+  node_data->SetName(textfield_->GetAccessibleName());
   node_data->SetValue(GetText());
 }
 
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.h b/ui/views/controls/menu/menu_cocoa_watcher_mac.h
index b39fb3d..f375ae5c 100644
--- a/ui/views/controls/menu/menu_cocoa_watcher_mac.h
+++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.h
@@ -32,6 +32,7 @@
   // Tokens representing the notification observers.
   id observer_token_other_menu_;
   id observer_token_new_window_focus_;
+  id observer_token_app_change_;
 
   DISALLOW_COPY_AND_ASSIGN(MenuCocoaWatcherMac);
 };
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
index b282c290..c5d53055 100644
--- a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
+++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
@@ -27,6 +27,14 @@
               usingBlock:^(NSNotification* notification) {
                 ExecuteCallback();
               }];
+  observer_token_app_change_ =
+      [[[NSWorkspace sharedWorkspace] notificationCenter]
+          addObserverForName:NSWorkspaceDidActivateApplicationNotification
+                      object:nil
+                       queue:nil
+                  usingBlock:^(NSNotification* notification) {
+                    ExecuteCallback();
+                  }];
 }
 
 MenuCocoaWatcherMac::~MenuCocoaWatcherMac() {
@@ -34,6 +42,8 @@
       removeObserver:observer_token_other_menu_];
   [[NSNotificationCenter defaultCenter]
       removeObserver:observer_token_new_window_focus_];
+  [[[NSWorkspace sharedWorkspace] notificationCenter]
+      removeObserver:observer_token_app_change_];
 }
 
 void MenuCocoaWatcherMac::ExecuteCallback() {
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index 39a58b7..d24e39e 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -537,6 +537,13 @@
   return placeholder_text_;
 }
 
+void Textfield::SetPlaceholderText(const base::string16& text) {
+  if (placeholder_text_ == text)
+    return;
+
+  placeholder_text_ = text;
+}
+
 gfx::HorizontalAlignment Textfield::GetHorizontalAlignment() const {
   return GetRenderText()->horizontal_alignment();
 }
@@ -559,7 +566,7 @@
   return GetRenderText()->selection();
 }
 
-void Textfield::SelectRange(const gfx::Range& range) {
+void Textfield::SetSelectedRange(const gfx::Range& range) {
   model_->SelectRange(range);
   UpdateAfterChange(false, true);
 }
@@ -600,6 +607,10 @@
   SchedulePaint();
 }
 
+bool Textfield::GetInvalid() const {
+  return invalid_;
+}
+
 void Textfield::SetInvalid(bool invalid) {
   if (invalid == invalid_)
     return;
@@ -613,6 +624,10 @@
   model_->ClearEditHistory();
 }
 
+base::string16 Textfield::GetAccessibleName() const {
+  return accessible_name_;
+}
+
 void Textfield::SetAccessibleName(const base::string16& name) {
   accessible_name_ = name;
 }
@@ -1601,7 +1616,7 @@
   if (!ImeEditingAllowed() || !range.IsValid())
     return false;
   OnBeforeUserAction();
-  SelectRange(range);
+  SetSelectedRange(range);
   OnAfterUserAction();
   return true;
 }
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index ce24e41..1434b1fb 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -182,11 +182,9 @@
   // Sets the minimum width of the text control. See minimum_width_in_chars_.
   void SetMinimumWidthInChars(int minimum_width);
 
-  // Sets the text to display when empty.
-  void set_placeholder_text(const base::string16& text) {
-    placeholder_text_ = text;
-  }
+  // Gets/Sets the text to display when empty.
   base::string16 GetPlaceholderText() const;
+  void SetPlaceholderText(const base::string16& text);
 
   void set_placeholder_text_color(SkColor color) {
     placeholder_text_color_ = color;
@@ -200,9 +198,9 @@
     placeholder_text_draw_flags_ = flags;
   }
 
-  // Sets whether to indicate the textfield has invalid content.
+  // Gets/Sets whether to indicate the textfield has invalid content.
+  bool GetInvalid() const;
   void SetInvalid(bool invalid);
-  bool invalid() const { return invalid_; }
 
   // Get or set the horizontal alignment used for the button from the underlying
   // RenderText object.
@@ -219,7 +217,7 @@
   const gfx::Range& GetSelectedRange() const;
 
   // Selects the specified logical text range.
-  void SelectRange(const gfx::Range& range);
+  void SetSelectedRange(const gfx::Range& range);
 
   // Gets the text selection model.
   const gfx::SelectionModel& GetSelectionModel() const;
@@ -244,10 +242,10 @@
   // Clears Edit history.
   void ClearEditHistory();
 
-  // Set the accessible name of the text field. If the textfield has a visible
-  // label, use SetAssociatedLabel() instead.
+  // Get/Set the accessible name of the text field. If the textfield has a
+  // visible label, use SetAssociatedLabel() instead.
+  base::string16 GetAccessibleName() const;
   void SetAccessibleName(const base::string16& name);
-  const base::string16& accessible_name() const { return accessible_name_; }
 
   // If the accessible name should be the same as the labelling view's text,
   // use this. It will set the accessible label relationship and copy the
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc
index 1dd7c69..4d0229c 100644
--- a/ui/views/controls/textfield/textfield_unittest.cc
+++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -1166,7 +1166,7 @@
   EXPECT_STR_EQ("abcdefghij", textfield_->GetText());
 
   // Test the delete and backspace keys.
-  textfield_->SelectRange(gfx::Range(5));
+  textfield_->SetSelectedRange(gfx::Range(5));
   for (size_t i = 0; i < 3; i++)
     SendKeyEvent(ui::VKEY_BACK);
   EXPECT_STR_EQ("abfghij", textfield_->GetText());
@@ -1239,7 +1239,7 @@
   for (size_t i = 0; i < base::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
     textfield_->SetText(ASCIIToUTF16("one two three"));
-    textfield_->SelectRange(gfx::Range(2, 6));
+    textfield_->SetSelectedRange(gfx::Range(2, 6));
     // Make selection as - on|e tw|o three.
     SendWordEvent(cases[i].key, cases[i].shift);
     // Verify state is on|o three.
@@ -1264,7 +1264,7 @@
   for (size_t i = 0; i < base::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
     textfield_->SetText(ASCIIToUTF16("one two three"));
-    textfield_->SelectRange(gfx::Range(4));
+    textfield_->SetSelectedRange(gfx::Range(4));
     test_api_->ExecuteTextEditCommand(cases[i].command);
     EXPECT_STR_EQ(cases[i].expected, textfield_->GetText());
   }
@@ -1624,7 +1624,7 @@
   textfield_->SetText(ASCIIToUTF16("hello world"));
 
   // Verify right clicking within the selection does not alter the selection.
-  textfield_->SelectRange(gfx::Range(1, 5));
+  textfield_->SetSelectedRange(gfx::Range(1, 5));
   EXPECT_STR_EQ("ello", textfield_->GetSelectedText());
   const int cursor_y = GetCursorYForTesting();
   MoveMouseTo(gfx::Point(GetCursorPositionX(3), cursor_y));
@@ -1776,7 +1776,7 @@
   base::string16 string;
   ui::OSExchangeData data;
   const gfx::Range kStringRange(6, 12);
-  textfield_->SelectRange(kStringRange);
+  textfield_->SetSelectedRange(kStringRange);
   const gfx::Point kStringPoint(GetCursorPositionX(9), GetCursorYForTesting());
   textfield_->WriteDragDataForView(nullptr, kStringPoint, &data);
   EXPECT_TRUE(data.GetString(&string));
@@ -1791,7 +1791,7 @@
   textfield_->ClearSelection();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
             textfield_->GetDragOperationsForView(nullptr, kStringPoint));
-  textfield_->SelectRange(kStringRange);
+  textfield_->SetSelectedRange(kStringRange);
   // Ensure that password textfields do not support drag operations.
   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
@@ -1825,7 +1825,7 @@
   std::set<ui::ClipboardFormatType> format_types;
 
   // Start dragging "ello".
-  textfield_->SelectRange(gfx::Range(1, 5));
+  textfield_->SetSelectedRange(gfx::Range(1, 5));
   gfx::Point point(GetCursorPositionX(3), cursor_y);
   MoveMouseTo(point);
   PressLeftMouseButton();
@@ -1876,7 +1876,7 @@
   std::set<ui::ClipboardFormatType> format_types;
 
   // Start dragging " worl".
-  textfield_->SelectRange(gfx::Range(5, 10));
+  textfield_->SetSelectedRange(gfx::Range(5, 10));
   gfx::Point point(GetCursorPositionX(7), cursor_y);
   MoveMouseTo(point);
   PressLeftMouseButton();
@@ -1921,7 +1921,7 @@
   const int cursor_y = GetCursorYForTesting();
 
   // Start dragging "worl".
-  textfield_->SelectRange(gfx::Range(6, 10));
+  textfield_->SetSelectedRange(gfx::Range(6, 10));
   gfx::Point point(GetCursorPositionX(8), cursor_y);
   MoveMouseTo(point);
   PressLeftMouseButton();
@@ -2241,7 +2241,7 @@
 TEST_F(TextfieldTest, Yank) {
   InitTextfields(2);
   textfield_->SetText(ASCIIToUTF16("abcdef"));
-  textfield_->SelectRange(gfx::Range(2, 4));
+  textfield_->SetSelectedRange(gfx::Range(2, 4));
 
   // Press Ctrl+Y to yank.
   SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
@@ -2285,12 +2285,12 @@
 
   // Verify deletion in a password textfield does not modify the kill buffer.
   textfield2->SetText(ASCIIToUTF16("hello"));
-  textfield2->SelectRange(gfx::Range(0));
+  textfield2->SetSelectedRange(gfx::Range(0));
   SendKeyPress(ui::VKEY_K, ui::EF_CONTROL_DOWN);
   EXPECT_TRUE(textfield2->GetText().empty());
 
   textfield_->RequestFocus();
-  textfield_->SelectRange(gfx::Range(0));
+  textfield_->SetSelectedRange(gfx::Range(0));
   SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
   EXPECT_STR_EQ("efabefeef", textfield_->GetText());
 }
@@ -2333,7 +2333,7 @@
 
   // Ensure [Shift]+[Delete] is a no-op in case there is no selection.
   textfield_->SetText(ASCIIToUTF16("123"));
-  textfield_->SelectRange(gfx::Range(0));
+  textfield_->SetSelectedRange(gfx::Range(0));
   SendAlternateCut();
   EXPECT_STR_EQ("", GetClipboardText(ui::ClipboardType::kCopyPaste));
   EXPECT_STR_EQ("123", textfield_->GetText());
@@ -2829,9 +2829,9 @@
 
   textfield_->SetText(ASCIIToUTF16("abc def ghi"));
 
-  textfield_->SelectRange(gfx::Range(5, 5));
+  textfield_->SetSelectedRange(gfx::Range(5, 5));
   const gfx::Rect middle_cursor = GetCursorBounds();
-  textfield_->SelectRange(gfx::Range(0, 0));
+  textfield_->SetSelectedRange(gfx::Range(0, 0));
   const gfx::Point beginning = GetCursorBounds().origin();
 
   // Double click, but do not release the left button.
@@ -2947,7 +2947,7 @@
   // contents into the middle of the selection, and move the cursor to the end
   // of the pasted content.
   SetClipboardText(ui::ClipboardType::kCopyPaste, "foo");
-  textfield_->SelectRange(gfx::Range(2, 6));
+  textfield_->SetSelectedRange(gfx::Range(2, 6));
   textfield_->OnMousePressed(middle);
   EXPECT_STR_EQ("0123foo01230123", textfield_->GetText());
   EXPECT_EQ(gfx::Range(7, 7), textfield_->GetSelectedRange());
@@ -2981,7 +2981,7 @@
 
   // Selecting a range of text without any user interaction should not change
   // the clipboard content.
-  textfield_->SelectRange(gfx::Range(0, 3));
+  textfield_->SetSelectedRange(gfx::Range(0, 3));
   EXPECT_STR_EQ("ab ", textfield_->GetSelectedText());
   EXPECT_STR_EQ("ab cd ef", GetClipboardText(ui::ClipboardType::kSelection));
   EXPECT_EQ(ui::ClipboardType::kMaxValue, GetAndResetCopiedToClipboard());
@@ -3039,7 +3039,7 @@
   textfield_->SetText(ASCIIToUTF16("Hello string world"));
 
   // Ensure the textfield will provide selected text for drag data.
-  textfield_->SelectRange(gfx::Range(6, 12));
+  textfield_->SetSelectedRange(gfx::Range(6, 12));
   const gfx::Point kStringPoint(GetCursorPositionX(9), GetCursorYForTesting());
 
   // Enable touch-drag-drop to make long press effective.
@@ -3089,7 +3089,7 @@
   InitTextfield();
   textfield_->SetText(ASCIIToUTF16("abc"));
   EXPECT_TRUE(test_api_->IsCursorBlinkTimerRunning());
-  textfield_->SelectRange(gfx::Range(1, 2));
+  textfield_->SetSelectedRange(gfx::Range(1, 2));
   EXPECT_FALSE(test_api_->IsCursorBlinkTimerRunning());
   textfield_->InsertOrReplaceText(base::ASCIIToUTF16("foo"));
   EXPECT_TRUE(test_api_->IsCursorBlinkTimerRunning());
diff --git a/ui/views/examples/animated_image_view_example.cc b/ui/views/examples/animated_image_view_example.cc
index fc81ae4..1d8cdbe 100644
--- a/ui/views/examples/animated_image_view_example.cc
+++ b/ui/views/examples/animated_image_view_example.cc
@@ -52,7 +52,7 @@
     box->SetFlexForView(image_view_container_, 1);
 
     auto file_chooser = std::make_unique<Textfield>();
-    file_chooser->set_placeholder_text(
+    file_chooser->SetPlaceholderText(
         base::ASCIIToUTF16("Enter path to lottie JSON file"));
     auto file_container = std::make_unique<View>();
     BoxLayout* file_box =
@@ -64,7 +64,7 @@
     file_box->SetFlexForView(file_chooser_, 1);
     AddChildView(std::move(file_container));
 
-    size_input_->set_placeholder_text(
+    size_input_->SetPlaceholderText(
         base::ASCIIToUTF16("Size in dip (Empty for default)"));
     size_input_->set_controller(this);
   }
diff --git a/ui/views/examples/textfield_example.cc b/ui/views/examples/textfield_example.cc
index e1ab1cb..ad966e4 100644
--- a/ui/views/examples/textfield_example.cc
+++ b/ui/views/examples/textfield_example.cc
@@ -46,7 +46,7 @@
   name->set_controller(this);
   auto password = std::make_unique<Textfield>();
   password->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
-  password->set_placeholder_text(ASCIIToUTF16("password"));
+  password->SetPlaceholderText(ASCIIToUTF16("password"));
   password->set_controller(this);
   auto disabled = std::make_unique<Textfield>();
   disabled->SetEnabled(false);
diff --git a/ui/views/examples/vector_example.cc b/ui/views/examples/vector_example.cc
index ec77c79..9637035 100644
--- a/ui/views/examples/vector_example.cc
+++ b/ui/views/examples/vector_example.cc
@@ -54,7 +54,7 @@
     box->SetFlexForView(image_view_container_, 1);
 
     auto file_chooser = std::make_unique<Textfield>();
-    file_chooser->set_placeholder_text(
+    file_chooser->SetPlaceholderText(
         base::ASCIIToUTF16("Enter a file to read"));
     auto file_container = std::make_unique<View>();
     BoxLayout* file_box =
@@ -66,9 +66,9 @@
     file_box->SetFlexForView(file_chooser_, 1);
     AddChildView(std::move(file_container));
 
-    size_input_->set_placeholder_text(base::ASCIIToUTF16("Size in dip"));
+    size_input_->SetPlaceholderText(base::ASCIIToUTF16("Size in dip"));
     size_input_->set_controller(this);
-    color_input_->set_placeholder_text(base::ASCIIToUTF16("Color (AARRGGBB)"));
+    color_input_->SetPlaceholderText(base::ASCIIToUTF16("Color (AARRGGBB)"));
     color_input_->set_controller(this);
   }
 
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
index e0532809..6b85640 100644
--- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc
+++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -292,7 +292,7 @@
     textfield_->OnGestureEvent(&tap);
 
     // Select some text such that one handle is hidden.
-    textfield_->SelectRange(gfx::Range(
+    textfield_->SetSelectedRange(gfx::Range(
         selection_start, static_cast<uint32_t>(textfield_text.length())));
 
     // Check that one selection handle is hidden.
@@ -327,7 +327,7 @@
   textfield_->OnGestureEvent(&tap);
 
   // Test selecting a range.
-  textfield_->SelectRange(gfx::Range(3, 7));
+  textfield_->SetSelectedRange(gfx::Range(3, 7));
   VerifyHandlePositions(false, true, FROM_HERE);
 
   // Test selecting everything.
@@ -365,38 +365,38 @@
   VerifyHandlePositions(false, true, FROM_HERE);
 
   // Test selection range inside one run and starts or ends at run boundary.
-  textfield_->SelectRange(gfx::Range(2, 3));
+  textfield_->SetSelectedRange(gfx::Range(2, 3));
   VerifyHandlePositions(false, true, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(3, 2));
+  textfield_->SetSelectedRange(gfx::Range(3, 2));
   VerifyHandlePositions(false, true, FROM_HERE);
 
   // TODO(mfomitchev): crbug.com/429705
   // The correct behavior for handles in mixed ltr/rtl text line is not known,
   // so passing false for |check_direction| in some of these tests.
-  textfield_->SelectRange(gfx::Range(3, 4));
+  textfield_->SetSelectedRange(gfx::Range(3, 4));
   VerifyHandlePositions(false, false, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(4, 3));
+  textfield_->SetSelectedRange(gfx::Range(4, 3));
   VerifyHandlePositions(false, false, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(3, 6));
+  textfield_->SetSelectedRange(gfx::Range(3, 6));
   VerifyHandlePositions(false, false, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(6, 3));
+  textfield_->SetSelectedRange(gfx::Range(6, 3));
   VerifyHandlePositions(false, false, FROM_HERE);
 
   // Test selection range accross runs.
-  textfield_->SelectRange(gfx::Range(0, 6));
+  textfield_->SetSelectedRange(gfx::Range(0, 6));
   VerifyHandlePositions(false, true, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(6, 0));
+  textfield_->SetSelectedRange(gfx::Range(6, 0));
   VerifyHandlePositions(false, true, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(1, 4));
+  textfield_->SetSelectedRange(gfx::Range(1, 4));
   VerifyHandlePositions(false, true, FROM_HERE);
 
-  textfield_->SelectRange(gfx::Range(4, 1));
+  textfield_->SetSelectedRange(gfx::Range(4, 1));
   VerifyHandlePositions(false, true, FROM_HERE);
 }
 
@@ -410,7 +410,7 @@
   details.set_tap_count(1);
   ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), details);
   textfield_->OnGestureEvent(&tap);
-  textfield_->SelectRange(gfx::Range(3, 7));
+  textfield_->SetSelectedRange(gfx::Range(3, 7));
 
   gfx::Point textfield_origin;
   textfield_->ConvertPointToScreen(&textfield_origin);
@@ -454,7 +454,7 @@
   textfield_->OnGestureEvent(&tap);
 
   // Select [c] from left to right.
-  textfield_->SelectRange(gfx::Range(2, 3));
+  textfield_->SetSelectedRange(gfx::Range(2, 3));
   EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
   VerifyHandlePositions(false, true, FROM_HERE);
 
@@ -472,7 +472,7 @@
   VerifyHandlePositions(true, true, FROM_HERE);
 
   // Select [c] from right to left.
-  textfield_->SelectRange(gfx::Range(3, 2));
+  textfield_->SetSelectedRange(gfx::Range(3, 2));
   EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
   VerifyHandlePositions(false, true, FROM_HERE);
 
@@ -489,7 +489,7 @@
   VerifyHandlePositions(false, true, FROM_HERE);
 
   // Select [\x5e1] from right to left.
-  textfield_->SelectRange(gfx::Range(3, 4));
+  textfield_->SetSelectedRange(gfx::Range(3, 4));
   EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
   // TODO(mfomitchev): crbug.com/429705
   // The correct behavior for handles in mixed ltr/rtl text line is not known,
@@ -518,7 +518,7 @@
   VerifyHandlePositions(true, true, FROM_HERE);
 
   // Select [\x5e1] from left to right.
-  textfield_->SelectRange(gfx::Range(4, 3));
+  textfield_->SetSelectedRange(gfx::Range(4, 3));
   EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
   VerifyHandlePositions(false, false, FROM_HERE);
 
@@ -537,7 +537,7 @@
   VerifyHandlePositions(false, true, FROM_HERE);
 
   // Select [\x05r3] from right to left.
-  textfield_->SelectRange(gfx::Range(5, 6));
+  textfield_->SetSelectedRange(gfx::Range(5, 6));
   EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
   VerifyHandlePositions(false, false, FROM_HERE);
 
@@ -554,7 +554,7 @@
   VerifyHandlePositions(true, true, FROM_HERE);
 
   // Select [\x05r3] from left to right.
-  textfield_->SelectRange(gfx::Range(6, 5));
+  textfield_->SetSelectedRange(gfx::Range(6, 5));
   EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
   VerifyHandlePositions(false, false, FROM_HERE);
 
diff --git a/ui/views/widget/ax_native_widget_mac_unittest.mm b/ui/views/widget/ax_native_widget_mac_unittest.mm
index 33e9012..c6c77c8a 100644
--- a/ui/views/widget/ax_native_widget_mac_unittest.mm
+++ b/ui/views/widget/ax_native_widget_mac_unittest.mm
@@ -414,8 +414,7 @@
 
 TEST_F(AXNativeWidgetMacTest, TextfieldEditableAttributes) {
   Textfield* textfield = AddChildTextfield(GetWidgetBounds().size());
-  textfield->set_placeholder_text(
-      base::SysNSStringToUTF16(kTestPlaceholderText));
+  textfield->SetPlaceholderText(base::SysNSStringToUTF16(kTestPlaceholderText));
   id<NSAccessibility> ax_node = A11yElementAtMidpoint();
 
   // NSAccessibilityInsertionPointLineNumberAttribute.
@@ -439,7 +438,7 @@
   // Select some text in the middle of the textfield.
   const gfx::Range forward_range(2, 6);
   const NSRange ns_range = forward_range.ToNSRange();
-  textfield->SelectRange(forward_range);
+  textfield->SetSelectedRange(forward_range);
   EXPECT_NSEQ([kTestStringValue substringWithRange:ns_range],
               ax_node.accessibilitySelectedText);
   EXPECT_EQ(textfield->GetSelectedText(),
@@ -447,7 +446,7 @@
   EXPECT_EQ(forward_range, gfx::Range(ax_node.accessibilitySelectedTextRange));
 
   const gfx::Range reversed_range(6, 2);
-  textfield->SelectRange(reversed_range);
+  textfield->SetSelectedRange(reversed_range);
   // NSRange has no direction, so these are unchanged from the forward range.
   EXPECT_NSEQ([kTestStringValue substringWithRange:ns_range],
               ax_node.accessibilitySelectedText);
@@ -468,10 +467,10 @@
 
   // Test an RTL string.
   textfield->SetText(base::SysNSStringToUTF16(kTestRTLStringValue));
-  textfield->SelectRange(forward_range);
+  textfield->SetSelectedRange(forward_range);
   EXPECT_EQ(textfield->GetSelectedText(),
             base::SysNSStringToUTF16(ax_node.accessibilitySelectedText));
-  textfield->SelectRange(reversed_range);
+  textfield->SetSelectedRange(reversed_range);
   EXPECT_EQ(textfield->GetSelectedText(),
             base::SysNSStringToUTF16(ax_node.accessibilitySelectedText));
 }
@@ -531,7 +530,7 @@
   textfield->SetReadOnly(false);
 
   // Change the selection text when there is no selected text.
-  textfield->SelectRange(gfx::Range(0, 0));
+  textfield->SetSelectedRange(gfx::Range(0, 0));
   EXPECT_TRUE(AXObjectHandlesSelector(
       ax_node, @selector(setAccessibilitySelectedText:)));
 
@@ -543,7 +542,7 @@
 
   // Replace entire selection.
   gfx::Range test_range(0, [new_string length]);
-  textfield->SelectRange(test_range);
+  textfield->SetSelectedRange(test_range);
   ax_node.accessibilitySelectedText = kTestStringValue;
   EXPECT_NSEQ(kTestStringValue, ax_node.accessibilityValue);
   EXPECT_EQ(base::SysNSStringToUTF16(kTestStringValue), textfield->GetText());
@@ -559,7 +558,7 @@
   textfield->SetText(front + middle + back);
   test_range = gfx::Range(front.length() + middle.length(), front.length());
   new_string = base::SysUTF16ToNSString(front + replacement + back);
-  textfield->SelectRange(test_range);
+  textfield->SetSelectedRange(test_range);
   ax_node.accessibilitySelectedText = base::SysUTF16ToNSString(replacement);
   EXPECT_NSEQ(new_string, ax_node.accessibilityValue);
   EXPECT_EQ(base::SysNSStringToUTF16(new_string), textfield->GetText());
@@ -703,7 +702,7 @@
   EXPECT_NSEQ(@"•••", ax_node.accessibilityValue);
   EXPECT_EQ(3, ax_node.accessibilityNumberOfCharacters);
 
-  textfield->SelectRange(gfx::Range(2, 3));  // Selects "3".
+  textfield->SetSelectedRange(gfx::Range(2, 3));  // Selects "3".
   ax_node.accessibilitySelectedText = @"ab";
   EXPECT_EQ(base::ASCIIToUTF16("12ab"), textfield->GetText());
   EXPECT_NSEQ(@"••••", ax_node.accessibilityValue);