diff --git a/DEPS b/DEPS
index d0beb13f..85a87fb 100644
--- a/DEPS
+++ b/DEPS
@@ -121,11 +121,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': '61b3d1d00057ad0d72a23b961f1191e429932c5b',
+  'skia_revision': '8f37ce5b9f2c139e4bad8e14ed6b884c1510dffd',
   # 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': 'c49505f1389190661532a9305ba0c20546292768',
+  'v8_revision': 'abd39667a5d0a9605b16b053afe18859af116045',
   # 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.
@@ -133,7 +133,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': '60a50cfcb8769ca2f903f8fac3c8d4e7ab5ffdc5',
+  'angle_revision': '04ea03e4e1e1575ee576dafe1793f15fa41e5cc4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -181,7 +181,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': 'ecf56e8e03cd13d93319c53330ea950f7ae7e51d',
+  'catapult_revision': '24bb5c49673beb7c00fdaa58d408a390d47bdc65',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -249,7 +249,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '99ab07063ac358016b637d7f6521a6dd37263f90',
+  'quiche_revision': '23346476fcb2863ac208b4e99edfd7a3aa6d3bcd',
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -679,7 +679,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1716f486f900a76ef3a77d5ef75726d9aef05581',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bdda5e4967f24c46ad4fbb3708ea80703abdec48',
       'condition': 'checkout_linux',
   },
 
@@ -1199,7 +1199,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a2b35635aaef3e9301d69f77f9a0a3fd99291b08',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '95bdf5f39ec67edd3d7fc7313e8bb3b9fcc9706c',
+    Var('webrtc_git') + '/src.git' + '@' + 'bde71044cd4a011486073ba68ad84e606d25aa2d',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1230,7 +1230,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a8894a8cc4e7df548deb79122a49e85251c1a79b',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@96eb27a4c496f74f67ea65f132efc081f878fd7b',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 44d67fd3..4d373c7d 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1050,6 +1050,13 @@
     'ios_clean': {
       'filepath': 'ios/clean/',
     },
+    'ios_flags': {
+      'filepath': 'ios/chrome/browser/about_flags.h|'\
+                  'ios/chrome/browser/about_flags.mm|'\
+                  'ios/chrome/browser/experimental_flags.h|'\
+                  'ios/chrome/browser/experimental_flags.mm|'\
+                  'ios/chrome/browser/resources/Settings.bundle/Experimental.plist',
+    },
     'ios_showcase': {
       'filepath': 'ios/showcase/',
     },
@@ -2253,10 +2260,10 @@
                 'ramyan+watch@chromium.org'],
     'ios': ['ios-reviews@chromium.org'],
     'ios_chrome': ['ios-reviews+chrome@chromium.org',
-                   'noyau+watch@chromium.org',
                    'marq+watch@chromium.org'],
     'ios_clean': ['ios-reviews+clean@chromium.org',
                   'marq+scrutinize@chromium.org'],
+    'ios_flags': ['noyau+watch@chromium.org'],
     'ios_showcase': ['ios-reviews+showcase@chromium.org',
                      'marq+watch@chromium.org'],
     'ios_web': ['ios-reviews+web@chromium.org',
@@ -2337,10 +2344,8 @@
     'nfc': ['mattreynolds+watch@chromium.org'],
     'notifications': ['peter@chromium.org'],
     'nqe': ['tbansal+watch-nqe@chromium.org'],
-    'ntp_snippets': ['ntp-dev+reviews@chromium.org',
-                     'noyau+watch@chromium.org'],
-    'ntp_tiles': ['ntp-dev+reviews@chromium.org',
-                  'noyau+watch@chromium.org'],
+    'ntp_snippets': ['ntp-dev+reviews@chromium.org'],
+    'ntp_tiles': ['ntp-dev+reviews@chromium.org'],
     'offline_items_collection': ['peter@chromium.org'],
     'offline_pages': ['chili+watch@chromium.org',
                       'carlosk+watch@chromium.org',
diff --git a/apps/BUILD.gn b/apps/BUILD.gn
index 75a2adf..bba3724c 100644
--- a/apps/BUILD.gn
+++ b/apps/BUILD.gn
@@ -48,9 +48,6 @@
   if (is_chromeos) {
     deps += [ "//components/user_manager" ]
   }
-
-  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
 }
 
 static_library("test_support") {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 37ff563..9eaf90f 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-4145b27107e2b201d8584bfa47e1c4b110daec55
\ No newline at end of file
+3697400dc0b66d69e8bb1544147bf387ae4e5a81
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index f9ec96f..d13ca12 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-6128814baa17836a13b4a2e90f506fbaa69af7e9
\ No newline at end of file
+fa7ae7dc8664d4089fd890b79358d1db5cfb7fa1
\ No newline at end of file
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 9d2171f1..09559ad7 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -347,9 +347,6 @@
     "trees/ukm_manager.h",
   ]
 
-  # TODO(khushalsagar): Remove once crbug.com/683263 is fixed.
-  configs = [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
   public_deps = [
     "//cc/base",
     "//cc/paint",
@@ -715,9 +712,6 @@
     cflags = [ "/wd4250" ]
   }
 
-  # TODO(khushalsagar): Remove once crbug.com/683263 is fixed.
-  configs = [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
   deps = [
     ":cc",
     ":test_support",
diff --git a/chrome/VERSION b/chrome/VERSION
index 2d0780b..79b3264e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=73
 MINOR=0
-BUILD=3658
+BUILD=3660
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 6409c5c..776acbd83 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -259,7 +259,6 @@
     public static final String OMNIBOX_VOICE_SEARCH_ALWAYS_VISIBLE =
             "OmniboxVoiceSearchAlwaysVisible";
     public static final String PAY_WITH_GOOGLE_V1 = "PayWithGoogleV1";
-    public static final String PASSWORD_SEARCH = "PasswordSearchMobile";
     public static final String PASSWORDS_KEYBOARD_ACCESSORY = "PasswordsKeyboardAccessory";
     public static final String PERMISSION_DELEGATION = "PermissionDelegation";
     public static final String PROGRESS_BAR_THROTTLE = "ProgressBarThrottle";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
index c05e849..5928d3d9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
@@ -26,7 +26,6 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
 import org.chromium.chrome.browser.preferences.ChromeBasePreference;
 import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
@@ -121,7 +120,7 @@
         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
         PasswordManagerHandlerProvider.getInstance().addObserver(this);
 
-        setHasOptionsMenu(ExportFlow.providesPasswordExport() || providesPasswordSearch());
+        setHasOptionsMenu(true); // Password Export might be optional but Search is always present.
 
         if (savedInstanceState == null) return;
 
@@ -139,14 +138,12 @@
         menu.findItem(R.id.export_passwords).setVisible(ExportFlow.providesPasswordExport());
         menu.findItem(R.id.export_passwords).setEnabled(false);
         mSearchItem = menu.findItem(R.id.menu_id_search);
-        mSearchItem.setVisible(providesPasswordSearch());
-        if (providesPasswordSearch()) {
-            mHelpItem = menu.findItem(R.id.menu_id_general_help);
-            SearchUtils.initializeSearchView(mSearchItem, mSearchQuery, getActivity(), (query) -> {
-                maybeRecordTriggeredPasswordSearch(true);
-                filterPasswords(query);
-            });
-        }
+        mSearchItem.setVisible(true);
+        mHelpItem = menu.findItem(R.id.menu_id_general_help);
+        SearchUtils.initializeSearchView(mSearchItem, mSearchQuery, getActivity(), (query) -> {
+            maybeRecordTriggeredPasswordSearch(true);
+            filterPasswords(query);
+        });
     }
 
     /**
@@ -155,7 +152,7 @@
      * @param searchTriggered Whether to log a triggered search or no triggered search.
      */
     private void maybeRecordTriggeredPasswordSearch(boolean searchTriggered) {
-        if (providesPasswordSearch() && !mSearchRecorded) {
+        if (!mSearchRecorded) {
             mSearchRecorded = true;
             RecordHistogram.recordBooleanHistogram(
                     "PasswordManager.Android.PasswordSearchTriggered", searchTriggered);
@@ -470,14 +467,6 @@
         getPreferenceScreen().addPreference(mLinkPref);
     }
 
-    /**
-     * Returns whether the password search feature is ready to use.
-     * @return Returns true if the flag is set.
-     */
-    private boolean providesPasswordSearch() {
-        return ChromeFeatureList.isEnabled(ChromeFeatureList.PASSWORD_SEARCH);
-    }
-
     @VisibleForTesting
     Menu getMenuForTesting() {
         return mMenu;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
index 362204d3..b3dd1e5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
@@ -78,7 +78,6 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MetricsUtils;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.history.HistoryActivity;
 import org.chromium.chrome.browser.history.HistoryManager;
 import org.chromium.chrome.browser.history.StubbedHistoryProvider;
@@ -89,8 +88,6 @@
 import org.chromium.chrome.browser.preferences.PreferencesTest;
 import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 
 import java.io.File;
 import java.io.IOException;
@@ -1498,7 +1495,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     @SuppressWarnings("AlwaysShowAction") // We need to ensure the icon is in the action bar.
     public void testSearchIconVisibleInActionBarWithFeature() throws Exception {
         setPasswordSource(null); // Initialize empty preferences.
@@ -1524,7 +1520,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchTextInOverflowMenuVisibleWithFeature() throws Exception {
         setPasswordSource(null); // Initialize empty preferences.
         SavePasswordsPreferences f =
@@ -1554,7 +1549,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testTriggeringSearchRestoresHelpIcon() throws Exception {
         setPasswordSource(null);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1601,27 +1595,11 @@
     }
 
     /**
-     * Check that the search item is not visible if the Feature is disabled.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    @DisableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
-    public void testSearchIconGoneWithoutFeature() throws Exception {
-        setPasswordSource(null); // Initialize empty preferences.
-        PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
-                SavePasswordsPreferences.class.getName());
-
-        Espresso.onView(withId(R.id.menu_id_search)).check(doesNotExist());
-    }
-
-    /**
      * Check that the search filters the list by name.
      */
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchFiltersByUserName() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1645,7 +1623,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchFiltersByUrl() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1669,7 +1646,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchDisplaysBlankPageIfSearchTurnsUpEmpty() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1703,7 +1679,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchIconClickedHidesExceptionsTemporarily() throws Exception {
         setPasswordExceptions(new String[] {"http://exclu.de", "http://not-inclu.de"});
         final SavePasswordsPreferences savePasswordPreferences =
@@ -1739,7 +1714,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchIconClickedHidesGeneralPrefs() throws Exception {
         setPasswordSource(ZEUS_ON_EARTH);
         final SavePasswordsPreferences prefs =
@@ -1787,7 +1761,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchBarBackButtonRestoresGeneralPrefs() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1816,7 +1789,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchViewCloseIconExistsOnlyToClearQueries() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
@@ -1851,7 +1823,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchIconColorAffectsOnlyLocalSearchDrawable() throws Exception {
         // Open the password preferences and remember the applied color filter.
         final SavePasswordsPreferences f =
@@ -1901,16 +1872,14 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchResultsPersistAfterEntryInspection() throws Exception {
         setPasswordSourceWithMultipleEntries(GREEK_GODS);
         setPasswordExceptions(new String[] {"http://exclu.de", "http://not-inclu.de"});
         ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
         ReauthenticationManager.setScreenLockSetUpOverride(
                 ReauthenticationManager.OverrideState.AVAILABLE);
-        final Preferences prefs =
-                PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
-                        SavePasswordsPreferences.class.getName());
+        PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
+                SavePasswordsPreferences.class.getName());
 
         // Open the search and filter all but "Zeus".
         Espresso.onView(withSearchMenuIdOrText()).perform(click());
@@ -1966,7 +1935,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
     public void testSearchIsRecordedInHistograms() throws Exception {
         MetricsUtils.HistogramDelta triggered_delta = new MetricsUtils.HistogramDelta(
                 "PasswordManager.Android.PasswordSearchTriggered", 1);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index a210f27..1e6d914 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-73.0.3657.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-73.0.3659.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/app_management_strings.grdp b/chrome/app/app_management_strings.grdp
index 27fa67c..dee3d39 100644
--- a/chrome/app/app_management_strings.grdp
+++ b/chrome/app/app_management_strings.grdp
@@ -13,15 +13,18 @@
   <message name="IDS_APP_MANAGEMENT_MORE_APPS" desc="Label for more apps button at bottom of app list card.">
     Show <ph name="NUMBER_OF_MORE_APPS">$1<ex>4</ex></ph> more apps
   </message>
-  <message name="IDS_APP_MANAGEMENT_NOTIFICATIONS" desc="Label for notifications section in app settings page.">
+  <message name="IDS_APP_MANAGEMENT_NOTIFICATIONS" desc="Label for notifications section in the app settings page.">
     Notifications
   </message>
   <message name="IDS_APP_MANAGEMENT_NOTIFICATIONS_SUBLABEL" desc="Sublabel for the Notifications item in the main App Management view">
     <ph name="NUMBER_OF_MORE_APPS">$1<ex>4</ex></ph> apps
   </message>
-  <message name="IDS_APP_MANAGEMENT_PERMISSIONS" desc="Label for permissions section in app settings page.">
+  <message name="IDS_APP_MANAGEMENT_PERMISSIONS" desc="Label for permissions section in the app settings page.">
     Permissions
   </message>
+  <message name="IDS_APP_MANAGEMENT_PIN_TO_SHELF" desc="Label for the pin to shelf button in the app settings page.">
+    Pin to shelf
+  </message>
   <message name="IDS_APP_MANAGEMENT_SEARCH_PROMPT" desc="Prompt in search bar of main app management page.">
     Search apps
   </message>
@@ -31,7 +34,13 @@
   <message name="IDS_APP_MANAGEMENT_TITLE" desc="Title of the app management page.">
     Apps
   </message>
-  <message name="IDS_APP_MANAGEMENT_UNINSTALL" desc="Label for the uninstall button in app settings page.">
+  <message name="IDS_APP_MANAGEMENT_SIZE" desc="Label for the size of an app in the app settings page.">
+    Size: <ph name="APP_SIZE">$1<ex>8.0MB</ex></ph>
+  </message>
+  <message name="IDS_APP_MANAGEMENT_UNINSTALL" desc="Label for the uninstall button in the app settings page.">
     Uninstall
   </message>
+  <message name="IDS_APP_MANAGEMENT_VERSION" desc="Label for version of an app in the app settings page.">
+    Version: <ph name="VERSION">$1<ex>4.0</ex></ph>
+  </message>
 </grit-part>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index efb03695..decb45e1 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2595,9 +2595,6 @@
      flag_descriptions::kPasswordImportDescription, kOsAll,
      FEATURE_VALUE_TYPE(password_manager::features::kPasswordImport)},
 #if defined(OS_ANDROID)
-    {"password-search", flag_descriptions::kPasswordSearchMobileName,
-     flag_descriptions::kPasswordSearchMobileDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(password_manager::features::kPasswordSearchMobile)},
     {"passwords-keyboard-accessory",
      flag_descriptions::kPasswordsKeyboardAccessoryName,
      flag_descriptions::kPasswordsKeyboardAccessoryDescription, kOsAndroid,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 4b74826..d223eca 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -176,7 +176,6 @@
     &omnibox::kHideSteadyStateUrlTrivialSubdomains,
     &omnibox::kQueryInOmnibox,
     &password_manager::features::kGooglePasswordManager,
-    &password_manager::features::kPasswordSearchMobile,
     &password_manager::features::kPasswordsKeyboardAccessory,
     &switches::kSyncSendTabToSelf,
     &translate::kTranslateAndroidManualTrigger,
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index 7e5fff9..8bad9d8 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -1250,6 +1250,49 @@
   EXPECT_EQ(color, orginalcolor);
 }
 
+// Test that an <input> field with a <datalist> has a working drop down even if
+// it was dynamically changed to <input type="password"> temporarily. This is a
+// regression test for crbug.com/918351.
+IN_PROC_BROWSER_TEST_F(
+    AutofillInteractiveTest,
+    OnSelectOptionFromDatalistTurningToPasswordFieldAndBack) {
+  static const char kTestForm[] =
+      "<form action=\"http://www.example.com/\" method=\"POST\">"
+      "  <input list=\"dl\" type=\"search\" id=\"firstname\"><br>"
+      "  <datalist id=\"dl\">"
+      "  <option value=\"Adam\"></option>"
+      "  <option value=\"Bob\"></option>"
+      "  <option value=\"Carl\"></option>"
+      "  </datalist>"
+      "</form>";
+
+  // Load the test page.
+  SetTestUrlResponse(kTestForm);
+  ASSERT_NO_FATAL_FAILURE(
+      ui_test_utils::NavigateToURL(browser(), GetTestUrl()));
+
+  ASSERT_TRUE(content::ExecuteScript(
+      GetWebContents(),
+      "document.getElementById('firstname').type = 'password';"));
+  // At this point, the IsPasswordFieldForAutofill() function returns true and
+  // will continue to return true for the field, even when the type is changed
+  // back to 'search'.
+  ASSERT_TRUE(content::ExecuteScript(
+      GetWebContents(),
+      "document.getElementById('firstname').type = 'search';"));
+
+  // Regression test for crbug.com/918351 whether the datalist becomes available
+  // again.
+  FocusFirstNameField();
+  SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN,
+                       {ObservedUiEvents::kSuggestionShown});
+  SendKeyToDataListPopup(ui::DomKey::ARROW_DOWN);
+  SendKeyToDataListPopup(ui::DomKey::ENTER);
+  // Pressing the down arrow preselects the first item. Pressing it again
+  // selects the second item.
+  ExpectFieldValue("firstname", "Bob");
+}
+
 // Test that a JavaScript oninput event is fired after auto-filling a form.
 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, OnInputAfterAutofill) {
   static const char kOnInputScript[] =
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index c45dd51..a9e45ef 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -244,6 +244,8 @@
         <include name="IDR_APP_MANAGEMENT_ITEM_JS" file="resources\app_management\item.js" type="BINDATA" />
         <include name="IDR_APP_MANAGEMENT_MAIN_VIEW_HTML" file="resources\app_management\main_view.html" type="BINDATA" />
         <include name="IDR_APP_MANAGEMENT_MAIN_VIEW_JS" file="resources\app_management\main_view.js" type="BINDATA" />
+        <include name="IDR_APP_MANAGEMENT_METADATA_VIEW_HTML" file="resources\app_management\metadata_view.html" type="BINDATA" />
+        <include name="IDR_APP_MANAGEMENT_METADATA_VIEW_JS" file="resources\app_management\metadata_view.js" type="BINDATA" />
         <include name="IDR_APP_MANAGEMENT_PWA_PERMISSION_VIEW_HTML" file="resources\app_management\pwa_permission_view.html" type="BINDATA"/>
         <include name="IDR_APP_MANAGEMENT_PWA_PERMISSION_VIEW_JS" file="resources\app_management\pwa_permission_view.js" type="BINDATA"/>
         <include name="IDR_APP_MANAGEMENT_REDUCERS_HTML" file="resources\app_management\reducers.html" type="BINDATA" />
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 8033f55..2a6a5e8 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
@@ -78,7 +78,8 @@
 void BrowsingDataLocalStorageHelper::DeleteOrigin(const GURL& origin_url,
                                                   base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  dom_storage_context_->DeleteLocalStorage(origin_url, std::move(callback));
+  dom_storage_context_->DeleteLocalStorage(url::Origin::Create(origin_url),
+                                           std::move(callback));
 }
 
 //---------------------------------------------------------
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index ad78faf..f68b35a 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2771,11 +2771,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "password-search",
-    "owners": [ "fhorschig" ],
-    "expiry_milestone": 73
-  },
-  {
     "name": "passwords-keyboard-accessory",
     "owners": [ "fhorschig" ],
     "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 92fb0315..b44def0 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1491,10 +1491,6 @@
 const char kPasswordImportDescription[] =
     "Import functionality in password settings.";
 
-const char kPasswordSearchMobileName[] = "Password search";
-const char kPasswordSearchMobileDescription[] =
-    "Search functionality in password settings.";
-
 const char kPasswordsKeyboardAccessoryName[] =
     "Add password-related functions to keyboard accessory";
 const char kPasswordsKeyboardAccessoryDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 5d9838c..2040a504 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -903,9 +903,6 @@
 extern const char kPasswordImportName[];
 extern const char kPasswordImportDescription[];
 
-extern const char kPasswordSearchMobileName[];
-extern const char kPasswordSearchMobileDescription[];
-
 extern const char kPasswordsKeyboardAccessoryName[];
 extern const char kPasswordsKeyboardAccessoryDescription[];
 
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 9e38b8251..373e2e2e 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -644,12 +644,14 @@
   RunTestsInFile("beep_test.js", "test-beep.pdf");
 }
 
+#if defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(PDFAnnotationsTest, AnnotationsFeatureEnabled) {
   RunTestsInFile("annotations_feature_enabled_test.js", "test.pdf");
 }
 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, AnnotationsFeatureDisabled) {
   RunTestsInFile("annotations_feature_disabled_test.js", "test.pdf");
 }
+#endif
 
 // TODO(tsepez): See https://crbug.com/696650.
 IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DISABLED_NoBeep) {
diff --git a/chrome/browser/resources/app_management/BUILD.gn b/chrome/browser/resources/app_management/BUILD.gn
index 2a664556..56d1601 100644
--- a/chrome/browser/resources/app_management/BUILD.gn
+++ b/chrome/browser/resources/app_management/BUILD.gn
@@ -15,6 +15,7 @@
       ":fake_page_handler",
       ":item",
       ":main_view",
+      ":metadata_view",
       ":pwa_permission_view",
       ":reducers",
       ":router",
@@ -46,6 +47,7 @@
       ":actions",
       ":browser_proxy",
       ":main_view",
+      ":metadata_view",
       ":pwa_permission_view",
       ":router",
       ":util",
@@ -94,9 +96,16 @@
     ]
   }
 
+  js_library("metadata_view") {
+    deps = [
+      ":fake_page_handler",
+    ]
+  }
+
   js_library("pwa_permission_view") {
     deps = [
       ":fake_page_handler",
+      ":metadata_view",
     ]
   }
 
diff --git a/chrome/browser/resources/app_management/chrome_app_permission_view.html b/chrome/browser/resources/app_management/chrome_app_permission_view.html
index 701349e..2c1803b 100644
--- a/chrome/browser/resources/app_management/chrome_app_permission_view.html
+++ b/chrome/browser/resources/app_management/chrome_app_permission_view.html
@@ -20,6 +20,7 @@
       <img class="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]">
       <div class="app-title">[[app_.title]]</div>
     </div>
+    <app-management-metadata-view app="[[app_]]"></app-management-metadata-view>
   </template>
   <script src="chrome_app_permission_view.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/app_management/fake_page_handler.js b/chrome/browser/resources/app_management/fake_page_handler.js
index 742c3ad4..32bddd5 100644
--- a/chrome/browser/resources/app_management/fake_page_handler.js
+++ b/chrome/browser/resources/app_management/fake_page_handler.js
@@ -27,6 +27,8 @@
         id: id,
         type: apps.mojom.AppType.kUnknown,
         title: 'App Title',
+        version: '5.1',
+        size: '9.0MB',
         isPinned: apps.mojom.OptionalBool.kUnknown,
       };
 
diff --git a/chrome/browser/resources/app_management/main_view.html b/chrome/browser/resources/app_management/main_view.html
index 5134fd6..77ae2a0 100644
--- a/chrome/browser/resources/app_management/main_view.html
+++ b/chrome/browser/resources/app_management/main_view.html
@@ -79,5 +79,5 @@
       </div>
     </div>
   </template>
-  <script src="chrome://apps/main_view.js"></script>
+  <script src="main_view.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/app_management/metadata_view.html b/chrome/browser/resources/app_management/metadata_view.html
new file mode 100644
index 0000000..22bcecf
--- /dev/null
+++ b/chrome/browser/resources/app_management/metadata_view.html
@@ -0,0 +1,54 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="browser_proxy.html">
+<link rel="import" href="shared_style.html">
+<link rel="import" href="shared_vars.html">
+
+<dom-module id="app-management-metadata-view">
+  <template>
+    <style include="app-management-shared-css">
+    #shelf-switch-row {
+      align-items: center;
+      display: flex;
+      justify-content: space-around;
+      padding-bottom: 20px;
+    }
+
+    #shelf-switch {
+      display: flex;
+      justify-content: space-between;
+    }
+
+    cr-toggle {
+      padding-inline-start: 12px;
+    }
+
+    #metadata-overview {
+      display: flex;
+      flex-direction: column;
+    }
+
+    #metadata-overview > span {
+      text-align: center;
+    }
+
+    .metadata-row {
+      display: flex;
+      justify-content: space-around;
+    }
+    </style>
+    <div id="shelf-switch-row">
+      <span id="shelf-switch" class="header-text">
+        $i18n{pinToShelf}
+        <cr-toggle></cr-toggle>
+      </span>
+    </div>
+
+    <div id="metadata-overview" class="secondary-text">
+      <span>[[versionString_(app)]]</span>
+      <span>[[sizeString_(app)]]</span>
+      <!--TODO(ceciliani): Placeholder for legal declaration-->
+    </div>
+  </template>
+  <script src="metadata_view.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/app_management/metadata_view.js b/chrome/browser/resources/app_management/metadata_view.js
new file mode 100644
index 0000000..55ca71df
--- /dev/null
+++ b/chrome/browser/resources/app_management/metadata_view.js
@@ -0,0 +1,31 @@
+// 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.
+
+Polymer({
+  is: 'app-management-metadata-view',
+
+  properties: {
+    /** @type {appManagement.mojom.App} */
+    app: {
+      type: Object,
+    },
+  },
+
+  /**
+   * @return {string}
+   * @private
+   */
+  versionString_: function(app) {
+    return loadTimeData.getStringF('version', assert(app.version));
+  },
+
+  /**
+   * @return {string}
+   * @private
+   */
+  sizeString_: function(app) {
+    return loadTimeData.getStringF('size', assert(app.size));
+  },
+
+});
diff --git a/chrome/browser/resources/app_management/pwa_permission_view.html b/chrome/browser/resources/app_management/pwa_permission_view.html
index 443f16ca..93f923a 100644
--- a/chrome/browser/resources/app_management/pwa_permission_view.html
+++ b/chrome/browser/resources/app_management/pwa_permission_view.html
@@ -1,6 +1,7 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
 <link rel="import" href="browser_proxy.html">
+<link rel="import" href="metadata_view.html">
 <link rel="import" href="shared_style.html">
 <link rel="import" href="shared_vars.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
@@ -35,7 +36,6 @@
       width: 1px;
     }
     </style>
-
     <div class="permission-view-header">
       <paper-icon-button-light class="icon-arrow-back">
           <button id="closeButton" aria-label="$i18n{back}">
@@ -57,8 +57,7 @@
     <div id="permission-list" class="card-container">
       <span class="permission-row">
         <div class="header-text">$i18n{notifications}</div>
-        <cr-toggle aria-pressed="false" role="button" tabindex="0">
-        </cr-toggle>
+        <cr-toggle></cr-toggle>
       </span>
       <span class="permission-row"
           on-click="toggleListExpanded_">
@@ -71,12 +70,11 @@
             </button>
           </paper-icon-button-light>
           <div class="control-divider"></div>
-          <cr-toggle aria-pressed="false" role="button" tabindex="0"
-              class="left-separated-control">
-          </cr-toggle>
+          <cr-toggle class="left-separated-control"></cr-toggle>
         </span>
       </span>
     </div>
+    <app-management-metadata-view app="[[app_]]"></app-management-metadata-view>
   </template>
   <script src="pwa_permission_view.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 14ff6236..f9df874 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -95,7 +95,7 @@
         <!-- Note that resources included here also must be included in
              print_preview_ui.cc such these resources will be exposed to
              PDF in print preview. -->
-        <include name="IDR_PDF_INDEX_HTML" file="pdf/index.html" allowexternalscript="true" type="BINDATA" />
+        <include name="IDR_PDF_INDEX_HTML" file="pdf/index.html" allowexternalscript="true" type="BINDATA" preprocess="true" />
         <include name="IDR_PDF_INDEX_CSS" file="pdf/index.css" allowexternalscript="true" type="BINDATA" />
         <include name="IDR_PDF_MAIN_JS" file="pdf/main.js" type="BINDATA" />
         <include name="IDR_PDF_PDF_VIEWER_JS" file="pdf/pdf_viewer.js" type="BINDATA" />
@@ -119,8 +119,10 @@
         <include name="IDR_PDF_VIEWER_BOOKMARKS_CONTENT_JS" file="pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js" type="BINDATA" />
         <include name="IDR_PDF_VIEWER_ERROR_SCREEN_HTML" file="pdf/elements/viewer-error-screen/viewer-error-screen.html" type="BINDATA" />
         <include name="IDR_PDF_VIEWER_ERROR_SCREEN_JS" file="pdf/elements/viewer-error-screen/viewer-error-screen.js" type="BINDATA" />
-        <include name="IDR_PDF_VIEWER_INK_HOST_HTML" file="pdf/elements/viewer-ink-host/viewer-ink-host.html" type="BINDATA" />
-        <include name="IDR_PDF_VIEWER_INK_HOST_JS" file="pdf/elements/viewer-ink-host/viewer-ink-host.js" type="BINDATA" />
+        <if expr="chromeos">
+          <include name="IDR_PDF_VIEWER_INK_HOST_HTML" file="pdf/elements/viewer-ink-host/viewer-ink-host.html" type="BINDATA" />
+          <include name="IDR_PDF_VIEWER_INK_HOST_JS" file="pdf/elements/viewer-ink-host/viewer-ink-host.js" type="BINDATA" />
+        </if>
         <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_HTML" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.html" type="BINDATA" />
         <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_JS" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.js" type="BINDATA" flattenhtml="true" />
         <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_HTML" file="pdf/elements/viewer-page-selector/viewer-page-selector.html" type="BINDATA" />
diff --git a/chrome/browser/resources/pdf/BUILD.gn b/chrome/browser/resources/pdf/BUILD.gn
index 547be3d9..c3ae1f48 100644
--- a/chrome/browser/resources/pdf/BUILD.gn
+++ b/chrome/browser/resources/pdf/BUILD.gn
@@ -18,6 +18,9 @@
 }
 
 js_library("browser_api") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+  ]
   externs_list = [
     "$externs_path/chrome_extensions.js",
     "$externs_path/mime_handler_private.js",
diff --git a/chrome/browser/resources/pdf/browser_api.js b/chrome/browser/resources/pdf/browser_api.js
index 75e992d..bb907f14 100644
--- a/chrome/browser/resources/pdf/browser_api.js
+++ b/chrome/browser/resources/pdf/browser_api.js
@@ -102,8 +102,9 @@
    *     has been updated.
    */
   setZoom(zoom) {
-    if (this.zoomBehavior_ != BrowserApi.ZoomBehavior.MANAGE)
-      return Promise.reject(new Error('Viewer does not manage browser zoom.'));
+    assert(
+        this.zoomBehavior_ == BrowserApi.ZoomBehavior.MANAGE,
+        'Viewer does not manage browser zoom.');
     return new Promise((resolve, reject) => {
       chrome.tabs.setZoom(this.streamInfo_.tabId, zoom, resolve);
     });
diff --git a/chrome/browser/resources/pdf/index.html b/chrome/browser/resources/pdf/index.html
index 235875b..28280cd6 100644
--- a/chrome/browser/resources/pdf/index.html
+++ b/chrome/browser/resources/pdf/index.html
@@ -3,7 +3,6 @@
 <head>
   <meta charset="utf-8">
   <link rel="import" href="elements/viewer-error-screen/viewer-error-screen.html">
-  <link rel="import" href="elements/viewer-ink-host/viewer-ink-host.html">
   <link rel="import" href="elements/viewer-page-indicator/viewer-page-indicator.html">
   <link rel="import" href="elements/viewer-page-selector/viewer-page-selector.html">
   <link rel="import" href="elements/viewer-password-screen/viewer-password-screen.html">
@@ -11,6 +10,10 @@
   <link rel="import" href="elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html">
   <link rel="import" href="elements/shared-vars.html">
 
+<if expr="chromeos">
+  <link rel="import" href="elements/viewer-ink-host/viewer-ink-host.html">
+</if>
+
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <link rel="stylesheet" href="index.css">
 </head>
@@ -37,9 +40,10 @@
 <script src="zoom_manager.js"></script>
 <script src="gesture_detector.js"></script>
 <script src="pdf_scripting_api.js"></script>
-<link rel="import" href="chrome://resources/html/load_time_data.html">
-<link rel="import" href="chrome://resources/html/promise_resolver.html">
-<link rel="import" href="chrome://resources/html/util.html">
+<script src="chrome://resources/js/assert.js"></script>
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://resources/js/util.js"></script>
+<script src="chrome://resources/js/promise_resolver.js"></script>
 <script src="browser_api.js"></script>
 <script src="metrics.js"></script>
 <script src="pdf_viewer.js"></script>
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js
index ed5cd49..4b92c1a 100644
--- a/chrome/browser/resources/pdf/pdf_viewer.js
+++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -483,11 +483,7 @@
   annotationModeChanged_: async function(e) {
     const annotationMode = e.detail.value;
     if (annotationMode) {
-      // TODO(dstockwell): add assert lib and replace this with assert
-      if (this.currentController_ != this.pluginController_) {
-        throw new Error(
-            'Plugin controller is not current, cannot enter annotation mode');
-      }
+      assert(this.currentController_ == this.pluginController_);
       // Enter annotation mode.
       // TODO(dstockwell): set plugin read-only, begin transition
       this.updateProgress(0);
@@ -501,11 +497,7 @@
       this.updateProgress(100);
     } else {
       // Exit annotation mode.
-      // TODO(dstockwell): add assert lib and replace this with assert
-      if (this.currentController_ != this.inkController_) {
-        throw new Error(
-            'Ink controller is not current, cannot exit annotation mode');
-      }
+      assert(this.currentController_ == this.inkController_);
       // TODO(dstockwell): set ink read-only, begin transition
       this.updateProgress(0);
       // This runs separately to allow other consumers of `loaded` to queue
@@ -625,18 +617,17 @@
     if (this.loadState_ == loadState) {
       return;
     }
-    if ((loadState == LoadState.SUCCESS || loadState == LoadState.FAILURE) &&
-        this.loadState_ != LoadState.LOADING) {
-      throw new Error('Internal error: invalid loadState transition.');
-    }
-    this.loadState_ = loadState;
     if (loadState == LoadState.SUCCESS) {
+      assert(this.loadState_ == LoadState.LOADING);
       this.loaded_.resolve();
     } else if (loadState == LoadState.FAILED) {
+      assert(this.loadState_ == LoadState.LOADING);
       this.loaded_.reject();
     } else {
+      assert(loadState == LoadState.LOADING);
       this.loaded_ = new PromiseResolver();
     }
+    this.loadState_ = loadState;
   },
 
   /**
@@ -716,9 +707,7 @@
    * @private
    */
   setUserInitiated_: function(userInitiated) {
-    if (this.isUserInitiatedEvent_ == userInitiated) {
-      throw new Error('Trying to set user initiated to current value.');
-    }
+    assert(this.isUserInitiatedEvent_ != userInitiated);
     this.isUserInitiatedEvent_ = userInitiated;
   },
 
@@ -1403,8 +1392,7 @@
         break;
       case 'consumeSaveToken':
         const resolve = this.pendingTokens_.get(message.data.token);
-        if (!this.pendingTokens_.delete(message.data.token))
-          throw new Error('Internal error: save token not found.');
+        assert(this.pendingTokens_.delete(message.data.token));
         resolve(null);
         break;
     }
@@ -1417,15 +1405,14 @@
    * @private
    */
   saveData_(messageData) {
-    if (!(loadTimeData.getBoolean('pdfFormSaveEnabled') ||
-          loadTimeData.getBoolean('pdfAnnotationsEnabled')))
-      throw new Error('Internal error: save not enabled.');
+    assert(
+        loadTimeData.getBoolean('pdfFormSaveEnabled') ||
+        loadTimeData.getBoolean('pdfAnnotationsEnabled'));
 
     // Verify a token that was created by this instance is included to avoid
     // being spammed.
     const resolver = this.pendingTokens_.get(messageData.token);
-    if (!this.pendingTokens_.delete(messageData.token))
-      throw new Error('Internal error: save token not found, abort save.');
+    assert(this.pendingTokens_.delete(messageData.token));
 
     if (!messageData.dataToSave) {
       resolver.reject();
@@ -1440,13 +1427,13 @@
 
     const buffer = messageData.dataToSave;
     const bufView = new Uint8Array(buffer);
-    if (bufView.length > MAX_FILE_SIZE)
-      throw new Error(`File too large to be saved: ${bufView.length} bytes.`);
-    if (bufView.length < MIN_FILE_SIZE ||
-        String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) !=
-            '%PDF') {
-      throw new Error('Not a PDF file.');
-    }
+    assert(
+        bufView.length <= MAX_FILE_SIZE,
+        `File too large to be saved: ${bufView.length} bytes.`);
+    assert(bufView.length >= MIN_FILE_SIZE);
+    assert(
+        String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) ==
+        '%PDF');
 
     resolver.resolve(messageData);
   }
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 5f12698..71f09331 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -441,11 +441,10 @@
    * @private
    */
   setZoomInternal_: function(newZoom) {
-    if (!this.allowedToChangeZoom_) {
-      throw new Error(
-          'Called Viewport.setZoomInternal_ without calling ' +
-          'Viewport.mightZoom_.');
-    }
+    assert(
+        this.allowedToChangeZoom_,
+        'Called Viewport.setZoomInternal_ without calling ' +
+            'Viewport.mightZoom_.');
     // Record the scroll position (relative to the top-left of the window).
     const currentScrollPos = {
       x: this.position.x / this.zoom,
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
index 25e3ecb0..7edc8a5f 100644
--- a/chrome/browser/sessions/session_data_deleter.cc
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -129,7 +129,7 @@
     if (!storage_policy_->IsStorageSessionOnly(usage.origin.GetURL()))
       continue;
     storage_partition->GetDOMStorageContext()->DeleteLocalStorage(
-        usage.origin.GetURL(), base::DoNothing());
+        usage.origin, base::DoNothing());
   }
 }
 
diff --git a/chrome/browser/signin/signin_profile_attributes_updater.cc b/chrome/browser/signin/signin_profile_attributes_updater.cc
index 6ba517a..28b580d8 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater.cc
+++ b/chrome/browser/signin/signin_profile_attributes_updater.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/signin/signin_util.h"
 #include "components/signin/core/browser/account_info.h"
 
 SigninProfileAttributesUpdater::SigninProfileAttributesUpdater(
@@ -59,7 +60,8 @@
   } else {
     entry->SetLocalAuthCredentials(std::string());
     entry->SetAuthInfo(std::string(), base::string16());
-    entry->SetIsSigninRequired(false);
+    if (!signin_util::IsForceSigninEnabled())
+      entry->SetIsSigninRequired(false);
   }
 
   if (old_gaia_id != entry->GetGAIAId())
diff --git a/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc b/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
index 9384be65..c98b7e4 100644
--- a/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
+++ b/chrome/browser/signin/signin_profile_attributes_updater_unittest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/signin/fake_signin_manager_builder.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_util.h"
 #include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
@@ -84,6 +85,7 @@
   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
   ASSERT_FALSE(entry->IsAuthenticated());
+  EXPECT_FALSE(entry->IsSigninRequired());
 
   // Signin.
   AccountTrackerService* account_tracker =
@@ -100,6 +102,7 @@
   signin_manager->SignOut(signin_metrics::SIGNOUT_TEST,
                           signin_metrics::SignoutDelete::IGNORE_METRIC);
   EXPECT_FALSE(entry->IsAuthenticated());
+  EXPECT_FALSE(entry->IsSigninRequired());
 }
 #endif  // !defined(OS_CHROMEOS)
 
@@ -136,3 +139,41 @@
       account_id, GoogleServiceAuthError::AuthErrorNone());
   EXPECT_FALSE(entry->IsAuthError());
 }
+
+#if !defined(OS_CHROMEOS)
+class SigninProfileAttributesUpdaterWithForceSigninTest
+    : public SigninProfileAttributesUpdaterTest {
+  void SetUp() override {
+    signin_util::SetForceSigninForTesting(true);
+    SigninProfileAttributesUpdaterTest::SetUp();
+  }
+
+  void TearDown() override {
+    SigninProfileAttributesUpdaterTest::TearDown();
+    signin_util::ResetForceSigninForTesting();
+  }
+};
+
+TEST_F(SigninProfileAttributesUpdaterWithForceSigninTest, IsSigninRequired) {
+  ProfileAttributesEntry* entry;
+  ASSERT_TRUE(profile_manager_.profile_attributes_storage()
+                  ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
+  EXPECT_FALSE(entry->IsAuthenticated());
+  EXPECT_TRUE(entry->IsSigninRequired());
+
+  SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile_);
+  AccountTrackerService* account_tracker =
+      AccountTrackerServiceFactory::GetForProfile(profile_);
+  std::string account_id =
+      account_tracker->SeedAccountInfo("gaia", "example@email.com");
+  signin_manager->OnExternalSigninCompleted("example@email.com");
+  EXPECT_TRUE(entry->IsAuthenticated());
+  EXPECT_EQ("gaia", entry->GetGAIAId());
+  EXPECT_EQ("example@email.com", base::UTF16ToUTF8(entry->GetUserName()));
+
+  signin_manager->SignOut(signin_metrics::SIGNOUT_TEST,
+                          signin_metrics::SignoutDelete::IGNORE_METRIC);
+  EXPECT_FALSE(entry->IsAuthenticated());
+  EXPECT_TRUE(entry->IsSigninRequired());
+}
+#endif
diff --git a/chrome/browser/sync/test/integration/migration_test.cc b/chrome/browser/sync/test/integration/migration_test.cc
index a56c82a0..955c4ed 100644
--- a/chrome/browser/sync/test/integration/migration_test.cc
+++ b/chrome/browser/sync/test/integration/migration_test.cc
@@ -375,15 +375,18 @@
 
 // Easiest possible test of migration errors: triggers a server
 // migration on one datatype, then modifies some other datatype.
-IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigratePrefsThenModifyBookmark) {
+// TODO(https://crbug.com/918124): Often times out on continuous build.
+IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
+                       DISABLED_MigratePrefsThenModifyBookmark) {
   RunTwoClientMigrationTest(MakeList(syncer::PREFERENCES),
                             MODIFY_BOOKMARK);
 }
 
 // Triggers a server migration on two datatypes, then makes a local
 // modification to one of them.
+// TODO(https://crbug.com/918124): Often times out on continuous build.
 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
-                       MigratePrefsAndBookmarksThenModifyBookmark) {
+                       DISABLED_MigratePrefsAndBookmarksThenModifyBookmark) {
   RunTwoClientMigrationTest(
       MakeList(syncer::PREFERENCES, syncer::BOOKMARKS),
       MODIFY_BOOKMARK);
diff --git a/chrome/browser/ui/webui/app_management/app_management_ui.cc b/chrome/browser/ui/webui/app_management/app_management_ui.cc
index d61bce4..0a3537da 100644
--- a/chrome/browser/ui/webui/app_management/app_management_ui.cc
+++ b/chrome/browser/ui/webui/app_management/app_management_ui.cc
@@ -37,9 +37,12 @@
   source->AddLocalizedString("openSiteSettings",
                              IDS_APP_MANAGEMENT_SITE_SETTING);
   source->AddLocalizedString("permissions", IDS_APP_MANAGEMENT_PERMISSIONS);
+  source->AddLocalizedString("pinToShelf", IDS_APP_MANAGEMENT_PIN_TO_SHELF);
   source->AddLocalizedString("searchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT);
+  source->AddLocalizedString("size", IDS_APP_MANAGEMENT_SIZE);
   source->AddLocalizedString("title", IDS_APP_MANAGEMENT_TITLE);
   source->AddLocalizedString("uninstall", IDS_APP_MANAGEMENT_UNINSTALL);
+  source->AddLocalizedString("version", IDS_APP_MANAGEMENT_VERSION);
 
   source->AddResourcePath("app_management.mojom-lite.js",
                           IDR_APP_MANAGEMENT_MOJO_LITE_JS);
@@ -78,6 +81,10 @@
   source->AddResourcePath("item.js", IDR_APP_MANAGEMENT_ITEM_JS);
   source->AddResourcePath("main_view.html", IDR_APP_MANAGEMENT_MAIN_VIEW_HTML);
   source->AddResourcePath("main_view.js", IDR_APP_MANAGEMENT_MAIN_VIEW_JS);
+  source->AddResourcePath("metadata_view.html",
+                          IDR_APP_MANAGEMENT_METADATA_VIEW_HTML);
+  source->AddResourcePath("metadata_view.js",
+                          IDR_APP_MANAGEMENT_METADATA_VIEW_JS);
   source->AddResourcePath("pwa_permission_view.html",
                           IDR_APP_MANAGEMENT_PWA_PERMISSION_VIEW_HTML);
   source->AddResourcePath("pwa_permission_view.js",
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 1e5839b..8de0071ea 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -348,67 +348,69 @@
     const char* path;
     int id;
   } kPdfResources[] = {
-      {"pdf/browser_api.js", IDR_PDF_BROWSER_API_JS},
-      {"pdf/elements/icons.html", IDR_PDF_ICONS_HTML},
-      {"pdf/elements/shared-vars.html", IDR_PDF_SHARED_VARS_HTML},
-      {"pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html",
-       IDR_PDF_VIEWER_BOOKMARKS_CONTENT_HTML},
-      {"pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js",
-       IDR_PDF_VIEWER_BOOKMARKS_CONTENT_JS},
-      {"pdf/elements/viewer-bookmark/viewer-bookmark.html",
-       IDR_PDF_VIEWER_BOOKMARK_HTML},
-      {"pdf/elements/viewer-bookmark/viewer-bookmark.js",
-       IDR_PDF_VIEWER_BOOKMARK_JS},
-      {"pdf/elements/viewer-error-screen/viewer-error-screen.html",
-       IDR_PDF_VIEWER_ERROR_SCREEN_HTML},
-      {"pdf/elements/viewer-error-screen/viewer-error-screen.js",
-       IDR_PDF_VIEWER_ERROR_SCREEN_JS},
-      {"pdf/elements/viewer-ink-host/viewer-ink-host.html",
-       IDR_PDF_VIEWER_INK_HOST_HTML},
-      {"pdf/elements/viewer-ink-host/viewer-ink-host.js",
-       IDR_PDF_VIEWER_INK_HOST_JS},
-      {"pdf/elements/viewer-page-indicator/viewer-page-indicator.html",
-       IDR_PDF_VIEWER_PAGE_INDICATOR_HTML},
-      {"pdf/elements/viewer-page-indicator/viewer-page-indicator.js",
-       IDR_PDF_VIEWER_PAGE_INDICATOR_JS},
-      {"pdf/elements/viewer-page-selector/viewer-page-selector.html",
-       IDR_PDF_VIEWER_PAGE_SELECTOR_HTML},
-      {"pdf/elements/viewer-page-selector/viewer-page-selector.js",
-       IDR_PDF_VIEWER_PAGE_SELECTOR_JS},
-      {"pdf/elements/viewer-password-screen/viewer-password-screen.html",
-       IDR_PDF_VIEWER_PASSWORD_SCREEN_HTML},
-      {"pdf/elements/viewer-password-screen/viewer-password-screen.js",
-       IDR_PDF_VIEWER_PASSWORD_SCREEN_JS},
-      {"pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html",
-       IDR_PDF_VIEWER_PDF_TOOLBAR_HTML},
-      {"pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js",
-       IDR_PDF_VIEWER_PDF_TOOLBAR_JS},
-      {"pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html",
-       IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_HTML},
-      {"pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js",
-       IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_JS},
-      {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html",
-       IDR_PDF_VIEWER_ZOOM_BUTTON_HTML},
-      {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js",
-       IDR_PDF_VIEWER_ZOOM_BUTTON_JS},
-      {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html",
-       IDR_PDF_VIEWER_ZOOM_SELECTOR_HTML},
-      {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js",
-       IDR_PDF_VIEWER_ZOOM_SELECTOR_JS},
-      {"pdf/gesture_detector.js", IDR_PDF_GESTURE_DETECTOR_JS},
-      {"pdf/index.css", IDR_PDF_INDEX_CSS},
-      {"pdf/index.html", IDR_PDF_INDEX_HTML},
-      {"pdf/main.js", IDR_PDF_MAIN_JS},
-      {"pdf/metrics.js", IDR_PDF_METRICS_JS},
-      {"pdf/navigator.js", IDR_PDF_NAVIGATOR_JS},
-      {"pdf/open_pdf_params_parser.js", IDR_PDF_OPEN_PDF_PARAMS_PARSER_JS},
-      {"pdf/pdf_fitting_type.js", IDR_PDF_PDF_FITTING_TYPE_JS},
-      {"pdf/pdf_scripting_api.js", IDR_PDF_PDF_SCRIPTING_API_JS},
-      {"pdf/pdf_viewer.js", IDR_PDF_PDF_VIEWER_JS},
-      {"pdf/toolbar_manager.js", IDR_PDF_TOOLBAR_MANAGER_JS},
-      {"pdf/viewport.js", IDR_PDF_VIEWPORT_JS},
-      {"pdf/viewport_scroller.js", IDR_PDF_VIEWPORT_SCROLLER_JS},
-      {"pdf/zoom_manager.js", IDR_PDF_ZOOM_MANAGER_JS},
+    {"pdf/browser_api.js", IDR_PDF_BROWSER_API_JS},
+    {"pdf/elements/icons.html", IDR_PDF_ICONS_HTML},
+    {"pdf/elements/shared-vars.html", IDR_PDF_SHARED_VARS_HTML},
+    {"pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html",
+     IDR_PDF_VIEWER_BOOKMARKS_CONTENT_HTML},
+    {"pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js",
+     IDR_PDF_VIEWER_BOOKMARKS_CONTENT_JS},
+    {"pdf/elements/viewer-bookmark/viewer-bookmark.html",
+     IDR_PDF_VIEWER_BOOKMARK_HTML},
+    {"pdf/elements/viewer-bookmark/viewer-bookmark.js",
+     IDR_PDF_VIEWER_BOOKMARK_JS},
+    {"pdf/elements/viewer-error-screen/viewer-error-screen.html",
+     IDR_PDF_VIEWER_ERROR_SCREEN_HTML},
+    {"pdf/elements/viewer-error-screen/viewer-error-screen.js",
+     IDR_PDF_VIEWER_ERROR_SCREEN_JS},
+#if defined(OS_CHROMEOS)
+    {"pdf/elements/viewer-ink-host/viewer-ink-host.html",
+     IDR_PDF_VIEWER_INK_HOST_HTML},
+    {"pdf/elements/viewer-ink-host/viewer-ink-host.js",
+     IDR_PDF_VIEWER_INK_HOST_JS},
+#endif
+    {"pdf/elements/viewer-page-indicator/viewer-page-indicator.html",
+     IDR_PDF_VIEWER_PAGE_INDICATOR_HTML},
+    {"pdf/elements/viewer-page-indicator/viewer-page-indicator.js",
+     IDR_PDF_VIEWER_PAGE_INDICATOR_JS},
+    {"pdf/elements/viewer-page-selector/viewer-page-selector.html",
+     IDR_PDF_VIEWER_PAGE_SELECTOR_HTML},
+    {"pdf/elements/viewer-page-selector/viewer-page-selector.js",
+     IDR_PDF_VIEWER_PAGE_SELECTOR_JS},
+    {"pdf/elements/viewer-password-screen/viewer-password-screen.html",
+     IDR_PDF_VIEWER_PASSWORD_SCREEN_HTML},
+    {"pdf/elements/viewer-password-screen/viewer-password-screen.js",
+     IDR_PDF_VIEWER_PASSWORD_SCREEN_JS},
+    {"pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html",
+     IDR_PDF_VIEWER_PDF_TOOLBAR_HTML},
+    {"pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js",
+     IDR_PDF_VIEWER_PDF_TOOLBAR_JS},
+    {"pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html",
+     IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_HTML},
+    {"pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js",
+     IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_JS},
+    {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html",
+     IDR_PDF_VIEWER_ZOOM_BUTTON_HTML},
+    {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js",
+     IDR_PDF_VIEWER_ZOOM_BUTTON_JS},
+    {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html",
+     IDR_PDF_VIEWER_ZOOM_SELECTOR_HTML},
+    {"pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js",
+     IDR_PDF_VIEWER_ZOOM_SELECTOR_JS},
+    {"pdf/gesture_detector.js", IDR_PDF_GESTURE_DETECTOR_JS},
+    {"pdf/index.css", IDR_PDF_INDEX_CSS},
+    {"pdf/index.html", IDR_PDF_INDEX_HTML},
+    {"pdf/main.js", IDR_PDF_MAIN_JS},
+    {"pdf/metrics.js", IDR_PDF_METRICS_JS},
+    {"pdf/navigator.js", IDR_PDF_NAVIGATOR_JS},
+    {"pdf/open_pdf_params_parser.js", IDR_PDF_OPEN_PDF_PARAMS_PARSER_JS},
+    {"pdf/pdf_fitting_type.js", IDR_PDF_PDF_FITTING_TYPE_JS},
+    {"pdf/pdf_scripting_api.js", IDR_PDF_PDF_SCRIPTING_API_JS},
+    {"pdf/pdf_viewer.js", IDR_PDF_PDF_VIEWER_JS},
+    {"pdf/toolbar_manager.js", IDR_PDF_TOOLBAR_MANAGER_JS},
+    {"pdf/viewport.js", IDR_PDF_VIEWPORT_JS},
+    {"pdf/viewport_scroller.js", IDR_PDF_VIEWPORT_SCROLLER_JS},
+    {"pdf/zoom_manager.js", IDR_PDF_ZOOM_MANAGER_JS},
   };
   for (const auto& resource : kPdfResources)
     source->AddResourcePath(resource.path, resource.id);
diff --git a/chrome/renderer/media/flash_embed_rewrite.cc b/chrome/renderer/media/flash_embed_rewrite.cc
index 9e751175..d990a0f3 100644
--- a/chrome/renderer/media/flash_embed_rewrite.cc
+++ b/chrome/renderer/media/flash_embed_rewrite.cc
@@ -25,6 +25,9 @@
   if (url.DomainIs("youtube.com") || url.DomainIs("youtube-nocookie.com"))
     return RewriteYouTubeFlashEmbedURL(url);
 
+  if (url.DomainIs("dailymotion.com"))
+    return RewriteDailymotionFlashEmbedURL(url);
+
   return GURL();
 }
 
@@ -80,3 +83,20 @@
   RecordYouTubeRewriteUMA(result);
   return corrected_url.ReplaceComponents(r);
 }
+
+GURL FlashEmbedRewrite::RewriteDailymotionFlashEmbedURL(const GURL& url) {
+  // Dailymotion flash embeds are of the form of either:
+  //  - /swf/
+  //  - /swf/video/
+  if (url.path().find("/swf/") != 0)
+    return GURL();
+
+  std::string path = url.path();
+  int replace_length = path.find("/swf/video/") == 0 ? 11 : 5;
+  path.replace(0, replace_length, "/embed/video/");
+
+  url::Replacements<char> r;
+  r.SetPath(path.c_str(), url::Component(0, path.length()));
+
+  return url.ReplaceComponents(r);
+}
diff --git a/chrome/renderer/media/flash_embed_rewrite.h b/chrome/renderer/media/flash_embed_rewrite.h
index 4364ac5..f01f7a6 100644
--- a/chrome/renderer/media/flash_embed_rewrite.h
+++ b/chrome/renderer/media/flash_embed_rewrite.h
@@ -9,6 +9,7 @@
 
 class FlashEmbedRewrite {
  public:
+  // Entry point that will then call a private website-specific method.
   static GURL RewriteFlashEmbedURL(const GURL&);
 
   // Used for UMA. Values should not be reorderer or reused.
@@ -28,7 +29,11 @@
   static const char kFlashYouTubeRewriteUMA[];
 
  private:
+  // YouTube specific method.
   static GURL RewriteYouTubeFlashEmbedURL(const GURL&);
+
+  // Dailymotion specific method.
+  static GURL RewriteDailymotionFlashEmbedURL(const GURL&);
 };
 
 #endif  // CHROME_RENDERER_MEDIA_FLASH_EMBED_REWRITE_H_
diff --git a/chrome/renderer/media/flash_embed_rewrite_unittest.cc b/chrome/renderer/media/flash_embed_rewrite_unittest.cc
index e4ea58b..72480be 100644
--- a/chrome/renderer/media/flash_embed_rewrite_unittest.cc
+++ b/chrome/renderer/media/flash_embed_rewrite_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/metrics/histogram_samples.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -186,16 +185,7 @@
   EXPECT_EQ(total_count, samples->TotalCount());
 }
 
-// Crashes on Mac/Win only. http://crbug.com/879644
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#define MAYBE_YouTubeRewriteEmbedSuccessRewrite \
-  DISABLED_YouTubeRewriteEmbedSuccessRewrite
-#else
-#define MAYBE_YouTubeRewriteEmbedSuccessRewrite \
-  YouTubeRewriteEmbedSuccessRewrite
-#endif
-
-TEST_F(FlashEmbedRewriteTest, MAYBE_YouTubeRewriteEmbedSuccessRewrite) {
+TEST_F(FlashEmbedRewriteTest, YouTubeRewriteEmbedSuccessRewrite) {
   std::unique_ptr<base::HistogramSamples> samples = GetHistogramSamples();
   auto total_count = 0;
   EXPECT_EQ(total_count, samples->TotalCount());
@@ -250,3 +240,53 @@
     EXPECT_EQ(total_count, samples->TotalCount());
   }
 }
+
+TEST_F(FlashEmbedRewriteTest, DailymotionRewriteEmbed) {
+  struct TestData {
+    std::string original;
+    std::string expected;
+  } test_data[] = {
+      // { original, expected }
+      {"http://dailymotion.com", ""},
+      {"http://www.dailymotion.com", ""},
+      {"https://www.dailymotion.com", ""},
+      {"http://www.foo.dailymotion.com", ""},
+      {"https://www.foo.dailymotion.com", ""},
+      // URL isn't using Flash
+      {"http://www.dailymotion.com/embed/video/deadbeef", ""},
+      // URL isn't using Flash, no www
+      {"http://dailymotion.com/embed/video/deadbeef", ""},
+      // URL isn't using Flash, invalid parameter construct
+      {"http://www.dailymotion.com/embed/video/deadbeef&start=4", ""},
+      // URL is using Flash, no www
+      {"http://dailymotion.com/swf/deadbeef",
+       "http://dailymotion.com/embed/video/deadbeef"},
+      // URL is using Flash, is valid, https
+      {"https://www.dailymotion.com/swf/deadbeef",
+       "https://www.dailymotion.com/embed/video/deadbeef"},
+      // URL is using Flash, is valid, http
+      {"http://www.dailymotion.com/swf/deadbeef",
+       "http://www.dailymotion.com/embed/video/deadbeef"},
+      // URL is using Flash, valid
+      {"https://www.foo.dailymotion.com/swf/deadbeef",
+       "https://www.foo.dailymotion.com/embed/video/deadbeef"},
+      // URL is using Flash, is valid, has one parameter
+      {"http://www.dailymotion.com/swf/deadbeef?start=4",
+       "http://www.dailymotion.com/embed/video/deadbeef?start=4"},
+      // URL is using Flash, is valid, has multiple parameters
+      {"http://www.dailymotion.com/swf/deadbeef?start=4&fs=1",
+       "http://www.dailymotion.com/embed/video/deadbeef?start=4&fs=1"},
+      // URL is using Flash, invalid parameter construct, has one parameter
+      {"http://www.dailymotion.com/swf/deadbeef&start=4",
+       "http://www.dailymotion.com/embed/video/deadbeef&start=4"},
+      // Invalid URL.
+      {"http://www.dailymotion.com/abcd/swf/deadbeef", ""},
+      // Uses /swf/video/
+      {"http://www.dailymotion.com/swf/video/deadbeef",
+       "http://www.dailymotion.com/embed/video/deadbeef"}};
+
+  for (const auto& data : test_data) {
+    EXPECT_EQ(GURL(data.expected),
+              FlashEmbedRewrite::RewriteFlashEmbedURL(GURL(data.original)));
+  }
+}
diff --git a/chrome/test/data/webui/print_preview/destination_item_test.js b/chrome/test/data/webui/print_preview/destination_item_test.js
index 7796e4d..be23bad 100644
--- a/chrome/test/data/webui/print_preview/destination_item_test.js
+++ b/chrome/test/data/webui/print_preview/destination_item_test.js
@@ -55,7 +55,7 @@
     test(assert(TestNames.Offline), function() {
       const now = new Date();
       let twoMonthsAgo = new Date(now.getTime());
-      const month = twoMonthsAgo.getMonth() - 2;
+      let month = twoMonthsAgo.getMonth() - 2;
       if (month < 0) {
         month = month + 12;
         twoMonthsAgo.setFullYear(now.getFullYear() - 1);
diff --git a/chromeos/dbus/fake_cicerone_client.cc b/chromeos/dbus/fake_cicerone_client.cc
index f972995..2afb333 100644
--- a/chromeos/dbus/fake_cicerone_client.cc
+++ b/chromeos/dbus/fake_cicerone_client.cc
@@ -170,6 +170,7 @@
   signal.set_owner_id(request.owner_id());
   signal.set_vm_name(request.vm_name());
   signal.set_container_name(request.container_name());
+  signal.set_container_username(request.container_username());
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::BindOnce(&FakeCiceroneClient::NotifyContainerStarted,
                                 base::Unretained(this), std::move(signal)));
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index a0e0f41..638ae0e 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -654,7 +654,14 @@
 
   // Password field elements should only have suggestions shown by the password
   // autofill agent.
-  if (input_element && input_element->IsPasswordFieldForAutofill() &&
+  // The /*disable presubmit*/ comment below is used to disable a presubmit
+  // script that ensures that only IsPasswordFieldForAutofill() is used in this
+  // code (it has to appear between the function name and the parentesis to not
+  // match a regex). In this specific case we are actually interested in whether
+  // the field is currently a password field, not whether it has ever been a
+  // password field.
+  if (input_element &&
+      input_element->IsPasswordField /*disable presubmit*/ () &&
       !query_password_suggestion_) {
     return;
   }
diff --git a/components/omnibox/browser/clipboard_url_provider.cc b/components/omnibox/browser/clipboard_url_provider.cc
index 110ea4e..5d05a7a3 100644
--- a/components/omnibox/browser/clipboard_url_provider.cc
+++ b/components/omnibox/browser/clipboard_url_provider.cc
@@ -155,7 +155,7 @@
       IDS_COPIED_TEXT_FROM_CLIPBOARD, AutocompleteMatch::SanitizeString(text)));
   AutocompleteMatch::ClassifyLocationInString(
       base::string16::npos, 0, match.contents.length(),
-      ACMatchClassification::DIM, &match.contents_class);
+      ACMatchClassification::NONE, &match.contents_class);
 
   match.description.assign(l10n_util::GetStringUTF16(IDS_TEXT_FROM_CLIPBOARD));
   AutocompleteMatch::ClassifyLocationInString(
diff --git a/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1 b/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1
new file mode 100644
index 0000000..25160b9b
--- /dev/null
+++ b/components/omnibox_strings_grdp/IDS_COPIED_TEXT_FROM_CLIPBOARD.png.sha1
@@ -0,0 +1 @@
+b015bfd93d7d6b6c87e140f9e31796dad1d20a3c
\ No newline at end of file
diff --git a/components/omnibox_strings_grdp/IDS_TEXT_FROM_CLIPBOARD.png.sha1 b/components/omnibox_strings_grdp/IDS_TEXT_FROM_CLIPBOARD.png.sha1
new file mode 100644
index 0000000..25160b9b
--- /dev/null
+++ b/components/omnibox_strings_grdp/IDS_TEXT_FROM_CLIPBOARD.png.sha1
@@ -0,0 +1 @@
+b015bfd93d7d6b6c87e140f9e31796dad1d20a3c
\ No newline at end of file
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 17706b9a..ac49cc6 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -42,10 +42,6 @@
 const base::Feature kPasswordImport = {"PasswordImport",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Allows searching for saved passwords in the settings page on mobile devices.
-const base::Feature kPasswordSearchMobile = {"PasswordSearchMobile",
-                                             base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Adds password-related features to the keyboard accessory on mobile devices.
 const base::Feature kPasswordsKeyboardAccessory = {
     "PasswordsKeyboardAccessory", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h
index 4f55df8..59ae47e 100644
--- a/components/password_manager/core/common/password_manager_features.h
+++ b/components/password_manager/core/common/password_manager_features.h
@@ -29,7 +29,6 @@
 extern const base::Feature kNewPasswordFormParsingForSaving;
 extern const base::Feature kOnlyNewParser;
 extern const base::Feature kPasswordImport;
-extern const base::Feature kPasswordSearchMobile;
 extern const base::Feature kPasswordsKeyboardAccessory;
 extern const base::Feature kProtectSyncCredential;
 extern const base::Feature kProtectSyncCredentialOnReauth;
diff --git a/components/zucchini/disassembler.cc b/components/zucchini/disassembler.cc
index b6a2748..897d949 100644
--- a/components/zucchini/disassembler.cc
+++ b/components/zucchini/disassembler.cc
@@ -14,6 +14,10 @@
   return base::nullopt;
 }
 
+/******** EmptyReferenceWriter ********/
+
+void EmptyReferenceWriter::PutNext(Reference /* reference */) {}
+
 /******** ReferenceGroup ********/
 
 std::unique_ptr<ReferenceReader> ReferenceGroup::GetReader(
diff --git a/components/zucchini/disassembler.h b/components/zucchini/disassembler.h
index d60a3f1..52c69a4 100644
--- a/components/zucchini/disassembler.h
+++ b/components/zucchini/disassembler.h
@@ -23,6 +23,12 @@
   base::Optional<Reference> GetNext() override;
 };
 
+// A vacuous EmptyReferenceWriter that does not write.
+class EmptyReferenceWriter : public ReferenceWriter {
+ public:
+  void PutNext(Reference reference) override;
+};
+
 // Disassembler needs to be declared before ReferenceGroup because the latter
 // contains member pointers based on the former, and we use a compiler flag,
 // -fcomplete-member-pointers, which enforces that member pointer base types are
diff --git a/components/zucchini/disassembler_win32.cc b/components/zucchini/disassembler_win32.cc
index 9067ad7d..01c4fde2 100644
--- a/components/zucchini/disassembler_win32.cc
+++ b/components/zucchini/disassembler_win32.cc
@@ -33,9 +33,11 @@
     return false;
 
   const auto* dos_header = source->GetPointer<pe::ImageDOSHeader>();
-  if (!dos_header || (dos_header->e_lfanew & 7) != 0)
+  // For |e_lfanew|, reject on misalignment or overlap with DOS header.
+  if (!dos_header || (dos_header->e_lfanew & 7) != 0 ||
+      dos_header->e_lfanew < 0U + sizeof(pe::ImageDOSHeader)) {
     return false;
-
+  }
   // Offset to PE header is in DOS header.
   *source = std::move(BufferSource(image).Skip(dos_header->e_lfanew));
   // Check 'PE\0\0' magic from PE header.
@@ -120,7 +122,8 @@
 std::unique_ptr<ReferenceReader> DisassemblerWin32<Traits>::MakeReadRelocs(
     offset_t lo,
     offset_t hi) {
-  ParseAndStoreRelocBlocks();
+  if (!ParseAndStoreRelocBlocks())
+    return std::make_unique<EmptyReferenceReader>();
 
   RelocRvaReaderWin32 reloc_rva_reader(image_, reloc_region_,
                                        reloc_block_offsets_, lo, hi);
@@ -155,7 +158,9 @@
 template <class Traits>
 std::unique_ptr<ReferenceWriter> DisassemblerWin32<Traits>::MakeWriteRelocs(
     MutableBufferView image) {
-  ParseAndStoreRelocBlocks();
+  if (!ParseAndStoreRelocBlocks())
+    return std::make_unique<EmptyReferenceWriter>();
+
   return std::make_unique<RelocWriterWin32>(Traits::kRelocType, image,
                                             reloc_region_, reloc_block_offsets_,
                                             translator_);
@@ -187,28 +192,30 @@
   if (!ReadWin32Header<Traits>(image_, &source))
     return false;
 
+  constexpr size_t kDataDirBase =
+      offsetof(typename Traits::ImageOptionalHeader, data_directory);
   auto* coff_header = source.GetPointer<pe::ImageFileHeader>();
-  if (!coff_header ||
-      coff_header->size_of_optional_header <
-          offsetof(typename Traits::ImageOptionalHeader, data_directory)) {
+  if (!coff_header || coff_header->size_of_optional_header < kDataDirBase)
     return false;
-  }
 
+  // |number_of_rva_and_sizes < kImageNumberOfDirectoryEntries| is possible. So
+  // in theory, GetPointer() on ImageOptionalHeader can reach EOF for a tiny PE
+  // file, causing false rejection. However, this should not occur for practical
+  // cases; and rejection is okay for corner cases (e.g., from a fuzzer).
   auto* optional_header =
       source.GetPointer<typename Traits::ImageOptionalHeader>();
   if (!optional_header || optional_header->magic != Traits::kMagic)
     return false;
 
-  const size_t kDataDirBase =
-      offsetof(typename Traits::ImageOptionalHeader, data_directory);
-  size_t size_of_optional_header = coff_header->size_of_optional_header;
-  if (size_of_optional_header < kDataDirBase)
+  // Check |optional_header->number_of_rva_and_sizes|.
+  const size_t data_dir_size =
+      coff_header->size_of_optional_header - kDataDirBase;
+  const size_t num_data_dir = data_dir_size / sizeof(pe::ImageDataDirectory);
+  if (num_data_dir != optional_header->number_of_rva_and_sizes ||
+      num_data_dir * sizeof(pe::ImageDataDirectory) != data_dir_size ||
+      num_data_dir > pe::kImageNumberOfDirectoryEntries) {
     return false;
-
-  const size_t data_dir_bound =
-      (size_of_optional_header - kDataDirBase) / sizeof(pe::ImageDataDirectory);
-  if (optional_header->number_of_rva_and_sizes > data_dir_bound)
-    return false;
+  }
 
   base_relocation_table_ = ReadDataDirectory<Traits>(
       optional_header, pe::kIndexOfBaseRelocationTable);
@@ -293,21 +300,28 @@
 template <class Traits>
 bool DisassemblerWin32<Traits>::ParseAndStoreRelocBlocks() {
   if (has_parsed_relocs_)
-    return true;
+    return reloc_region_.lo() != kInvalidOffset;
+
   has_parsed_relocs_ = true;
   DCHECK(reloc_block_offsets_.empty());
 
   offset_t relocs_offset =
       translator_.RvaToOffset(base_relocation_table_->virtual_address);
   size_t relocs_size = base_relocation_table_->size;
-  reloc_region_ = {relocs_offset, relocs_size};
-  // Reject bogus relocs. Note that empty relocs are allowed!
-  if (!image_.covers(reloc_region_))
+  const BufferRegion temp_reloc_region = {relocs_offset, relocs_size};
+
+  // Reject bogus relocs. It's possible to have no reloc, so this is non-fatal!
+  if (relocs_offset == kInvalidOffset || !image_.covers(temp_reloc_region))
     return false;
 
   // Precompute offsets of all reloc blocks.
-  return RelocRvaReaderWin32::FindRelocBlocks(image_, reloc_region_,
-                                              &reloc_block_offsets_);
+  if (!RelocRvaReaderWin32::FindRelocBlocks(image_, temp_reloc_region,
+                                            &reloc_block_offsets_)) {
+    return false;
+  }
+  // Reassign |reloc_region_| only on success.
+  reloc_region_ = temp_reloc_region;
+  return true;
 }
 
 template <class Traits>
diff --git a/components/zucchini/disassembler_win32.h b/components/zucchini/disassembler_win32.h
index 29033cee..6c7ba91c 100644
--- a/components/zucchini/disassembler_win32.h
+++ b/components/zucchini/disassembler_win32.h
@@ -104,7 +104,7 @@
   AddressTranslator translator_;
 
   // Reference storage.
-  BufferRegion reloc_region_;
+  BufferRegion reloc_region_ = {kInvalidOffset, 0U};
   std::vector<offset_t> reloc_block_offsets_;
   offset_t reloc_end_ = 0;
   std::vector<offset_t> abs32_locations_;
diff --git a/components/zucchini/type_win_pe.h b/components/zucchini/type_win_pe.h
index d385ca7..56996fe 100644
--- a/components/zucchini/type_win_pe.h
+++ b/components/zucchini/type_win_pe.h
@@ -120,6 +120,9 @@
   uint32_t size_of_heap_commit;
   uint32_t loader_flags;
   uint32_t number_of_rva_and_sizes;
+
+  // The number of elements is actually |number_of_rva_and_sizes|, so accesses
+  // to |data_directory| should be checked against the bound.
   ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries];  // 0x60
   /* 0xE0 */
 };
diff --git a/content/browser/appcache/appcache_host.cc b/content/browser/appcache/appcache_host.cc
index 9ff6309d..4df254e 100644
--- a/content/browser/appcache/appcache_host.cc
+++ b/content/browser/appcache/appcache_host.cc
@@ -395,17 +395,17 @@
     DCHECK(cache->owning_group());
     DCHECK(new_master_entry_url_.is_empty());
     DCHECK_EQ(cache->owning_group()->manifest_url(), preferred_manifest_url_);
-    AppCacheGroup* owing_group = cache->owning_group();
+    AppCacheGroup* owning_group = cache->owning_group();
     const char* kFormatString =
         "Document was loaded from Application Cache with manifest %s";
     frontend_->OnLogMessage(
         host_id_, APPCACHE_LOG_INFO,
-        base::StringPrintf(
-            kFormatString, owing_group->manifest_url().spec().c_str()));
+        base::StringPrintf(kFormatString,
+                           owning_group->manifest_url().spec().c_str()));
     AssociateCompleteCache(cache);
-    if (!owing_group->is_obsolete() && !owing_group->is_being_deleted()) {
-      owing_group->StartUpdateWithHost(this);
-      ObserveGroupBeingUpdated(owing_group);
+    if (!owning_group->is_obsolete() && !owning_group->is_being_deleted()) {
+      owning_group->StartUpdateWithHost(this);
+      ObserveGroupBeingUpdated(owning_group);
     }
   } else if (group && !group->is_being_deleted()) {
     // If document was loaded using HTTP GET or equivalent, and, there is a
diff --git a/content/browser/dom_storage/dom_storage_browsertest.cc b/content/browser/dom_storage/dom_storage_browsertest.cc
index 3a87758..851fa350 100644
--- a/content/browser/dom_storage/dom_storage_browsertest.cc
+++ b/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -77,7 +77,7 @@
     return usage;
   }
 
-  void DeletePhysicalOrigin(GURL origin) {
+  void DeletePhysicalOrigin(url::Origin origin) {
     auto* context = BrowserContext::GetDefaultStoragePartition(
                         shell()->web_contents()->GetBrowserContext())
                         ->GetDOMStorageContext();
@@ -157,7 +157,7 @@
   SimpleTest(GetTestUrl("dom_storage", "store_data.html"), kNotIncognito);
   std::vector<StorageUsageInfo> usage = GetUsage();
   ASSERT_EQ(1U, usage.size());
-  DeletePhysicalOrigin(usage[0].origin.GetURL());
+  DeletePhysicalOrigin(usage[0].origin);
   EXPECT_EQ(0U, GetUsage().size());
 }
 
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc
index e455cf03..4d86ecf 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -37,6 +37,7 @@
 #include "content/public/common/content_switches.h"
 #include "sql/database.h"
 #include "third_party/blink/public/common/features.h"
+#include "url/origin.h"
 
 namespace content {
 namespace {
@@ -231,17 +232,17 @@
                      base::RetainedRef(context_), std::move(callback)));
 }
 
-void DOMStorageContextWrapper::DeleteLocalStorage(const GURL& origin,
+void DOMStorageContextWrapper::DeleteLocalStorage(const url::Origin& origin,
                                                   base::OnceClosure callback) {
   DCHECK(context_.get());
   DCHECK(callback);
   if (!legacy_localstorage_path_.empty()) {
     context_->task_runner()->PostShutdownBlockingTask(
         FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
-        base::BindOnce(base::IgnoreResult(&sql::Database::Delete),
-                       legacy_localstorage_path_.Append(
-                           DOMStorageArea::DatabaseFileNameFromOrigin(
-                               url::Origin::Create(origin)))));
+        base::BindOnce(
+            base::IgnoreResult(&sql::Database::Delete),
+            legacy_localstorage_path_.Append(
+                DOMStorageArea::DatabaseFileNameFromOrigin(origin))));
   }
   // base::Unretained is safe here, because the mojo_state_ won't be deleted
   // until a ShutdownAndDelete task has been ran on the mojo_task_runner_, and
@@ -251,7 +252,7 @@
       FROM_HERE,
       base::BindOnce(
           &LocalStorageContextMojo::DeleteStorage,
-          base::Unretained(mojo_state_), url::Origin::Create(origin),
+          base::Unretained(mojo_state_), origin,
           base::BindOnce(&GotMojoCallback, base::ThreadTaskRunnerHandle::Get(),
                          std::move(callback))));
 }
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h
index a66cf7e..dfaec1e4 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -21,7 +21,6 @@
 #include "mojo/public/cpp/bindings/message.h"
 #include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
 #include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
-#include "url/origin.h"
 
 namespace base {
 class FilePath;
@@ -58,7 +57,7 @@
   // DOMStorageContext implementation.
   void GetLocalStorageUsage(GetLocalStorageUsageCallback callback) override;
   void GetSessionStorageUsage(GetSessionStorageUsageCallback callback) override;
-  void DeleteLocalStorage(const GURL& origin,
+  void DeleteLocalStorage(const url::Origin& origin,
                           base::OnceClosure callback) override;
   void PerformLocalStorageCleanup(base::OnceClosure callback) override;
   void DeleteSessionStorage(const SessionStorageUsageInfo& usage_info,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index c5cbb4f..8261046 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -176,8 +176,7 @@
 
     if (infos[i].last_modified >= delete_begin &&
         infos[i].last_modified <= delete_end) {
-      dom_storage_context->DeleteLocalStorage(infos[i].origin.GetURL(),
-                                              barrier);
+      dom_storage_context->DeleteLocalStorage(infos[i].origin, barrier);
     } else {
       barrier.Run();
     }
@@ -229,8 +228,8 @@
                       origin_matcher.Run(storage_origin,
                                          special_storage_policy.get());
     if (can_delete) {
-      dom_storage_context->DeleteLocalStorage(storage_origin,
-                                              std::move(callback));
+      dom_storage_context->DeleteLocalStorage(
+          url::Origin::Create(storage_origin), std::move(callback));
     } else {
       std::move(callback).Run();
     }
diff --git a/content/public/browser/dom_storage_context.h b/content/public/browser/dom_storage_context.h
index 5c1baa06..1bc9bf3 100644
--- a/content/public/browser/dom_storage_context.h
+++ b/content/public/browser/dom_storage_context.h
@@ -10,7 +10,9 @@
 
 #include "base/callback.h"
 
-class GURL;
+namespace url {
+class Origin;
+}
 
 namespace content {
 
@@ -39,7 +41,7 @@
   // Deletes the local storage for the origin of |origin_url|. |callback| is
   // called when the deletion is sent to the database and GetLocalStorageUsage()
   // will not return entries for |origin_url| anymore.
-  virtual void DeleteLocalStorage(const GURL& origin_url,
+  virtual void DeleteLocalStorage(const url::Origin& origin,
                                   base::OnceClosure callback) = 0;
 
   // Removes traces of deleted data from the local storage backend.
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 36acc0d..e76cf57 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -485,6 +485,17 @@
     {"copied-text-behavior", flag_descriptions::kCopiedTextBehaviorName,
      flag_descriptions::kCopiedTextBehaviorName, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(omnibox::kCopiedTextBehavior)},
+    {"new-password-form-parsing-for-saving",
+     flag_descriptions::kNewPasswordFormParsingForSavingName,
+     flag_descriptions::kNewPasswordFormParsingForSavingDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(
+         password_manager::features::kNewPasswordFormParsingForSaving)},
+    {"only-new-password-form-parsing",
+     flag_descriptions::kOnlyNewPasswordFormParsingName,
+     flag_descriptions::kOnlyNewPasswordFormParsingDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(password_manager::features::kOnlyNewParser)},
 };
 
 // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index 4e331cb..7296720 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -273,6 +273,13 @@
     "currently under development. WARNING: when enabled Password Manager might "
     "stop working";
 
+const char kNewPasswordFormParsingForSavingName[] =
+    "New password form parsing for saving passwords";
+const char kNewPasswordFormParsingForSavingDescription[] =
+    "Replaces existing form parsing for saving in password manager with a new "
+    "version, currently under development. WARNING: when enabled, Password "
+    "Manager might stop working";
+
 const char kNonModalDialogsName[] = "Use non-modal JavaScript dialogs";
 const char kNonModalDialogsDescription[] =
     "Presents JavaScript dialogs non-modally so that the user can change tabs "
@@ -295,6 +302,11 @@
     "Elides the path, query, and ref of suggested URLs in the omnibox "
     "dropdown.";
 
+const char kOnlyNewPasswordFormParsingName[] =
+    "Use only new password form parsing";
+const char kOnlyNewPasswordFormParsingDescription[] =
+    "The old password form parsing is disabled";
+
 const char kOutOfWebFullscreenName[] = "Fullscreen implementation out of web";
 const char kOutOfWebFullscreenDescription[] =
     "Use the fullscreen implementation living outside of web. Disable the one "
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 6f69b42..f88c056 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -216,6 +216,11 @@
 extern const char kNewPasswordFormParsingName[];
 extern const char kNewPasswordFormParsingDescription[];
 
+// Title and description for the flag to enable new password form parsing for
+// saving.
+extern const char kNewPasswordFormParsingForSavingName[];
+extern const char kNewPasswordFormParsingForSavingDescription[];
+
 // Title and description for the flag to enable non-modal JavaScript dialogs.
 extern const char kNonModalDialogsName[];
 extern const char kNonModalDialogsDescription[];
@@ -235,6 +240,11 @@
 extern const char kOmniboxUIElideSuggestionUrlAfterHostName[];
 extern const char kOmniboxUIElideSuggestionUrlAfterHostDescription[];
 
+// Title and description for the flag to enable using only new password form
+// parsing.
+extern const char kOnlyNewPasswordFormParsingName[];
+extern const char kOnlyNewPasswordFormParsingDescription[];
+
 // Title and description for the flag to control the out of web implementation
 // of fullscreen.
 extern const char kOutOfWebFullscreenName[];
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn
index c30184c..0b34629 100644
--- a/ios/chrome/browser/ui/settings/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -4,8 +4,6 @@
 
 source_set("cells") {
   sources = [
-    "account_signin_item.h",
-    "account_signin_item.mm",
     "autofill_data_item.h",
     "autofill_data_item.mm",
     "byo_textfield_item.h",
@@ -75,7 +73,6 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
-    "account_signin_item_unittest.mm",
     "autofill_data_item_unittest.mm",
     "byo_textfield_item_unittest.mm",
     "card_multiline_item_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
index acbb77b..70633ec 100644
--- a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
@@ -4,6 +4,8 @@
 
 source_set("legacy") {
   sources = [
+    "legacy_account_signin_item.h",
+    "legacy_account_signin_item.mm",
     "legacy_autofill_data_item.h",
     "legacy_autofill_data_item.mm",
     "legacy_settings_detail_item.h",
@@ -33,6 +35,7 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "legacy_account_signin_item_unittest.mm",
     "legacy_autofill_data_item_unittest.mm",
     "legacy_sync_switch_item_unittest.mm",
   ]
diff --git a/ios/chrome/browser/ui/settings/cells/account_signin_item.h b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h
similarity index 63%
rename from ios/chrome/browser/ui/settings/cells/account_signin_item.h
rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h
index 7197fae..16edca5 100644
--- a/ios/chrome/browser/ui/settings/cells/account_signin_item.h
+++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h
@@ -2,31 +2,31 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_SIGNIN_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_SIGNIN_ITEM_H_
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
 
 #import <UIKit/UIKit.h>
 
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
 
-// AccountSignInItem is an Item that displays an Image, a title text label and a
-// detail text label.
+// LegacyAccountSignInItem is an Item that displays an Image, a title text label
+// and a detail text label.
 // This is intended to be used as an sign in Item which contains a default
 // avatar and information
 // letting the user know that they are not signed in, and that tapping on the
 // Item will allow them
 // to authenticate and sign in.
 
-@interface AccountSignInItem : CollectionViewItem
+@interface LegacyAccountSignInItem : CollectionViewItem
 
 // Item image.
 @property(nonatomic, copy) UIImage* image;
 
 @end
 
-// Cell representation for AccountSignInItem.
-@interface AccountSignInCell : MDCCollectionViewCell
+// Cell representation for LegacyAccountSignInItem.
+@interface LegacyAccountSignInCell : MDCCollectionViewCell
 
 // Cell title.
 @property(nonatomic, readonly, strong) UILabel* textLabel;
@@ -37,4 +37,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_SIGNIN_ITEM_H_
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_ACCOUNT_SIGNIN_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/account_signin_item.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm
similarity index 95%
rename from ios/chrome/browser/ui/settings/cells/account_signin_item.mm
rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm
index 0fb3a67..c2282036 100644
--- a/ios/chrome/browser/ui/settings/cells/account_signin_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
+#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
 
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
@@ -33,14 +33,14 @@
 const CGFloat kDetailTextFontSize = 14;
 }
 
-@implementation AccountSignInItem
+@implementation LegacyAccountSignInItem
 
 @synthesize image = _image;
 
 - (instancetype)initWithType:(NSInteger)type {
   self = [super initWithType:type];
   if (self) {
-    self.cellClass = [AccountSignInCell class];
+    self.cellClass = [LegacyAccountSignInCell class];
     self.accessibilityTraits |= UIAccessibilityTraitButton;
   }
   return self;
@@ -48,7 +48,7 @@
 
 #pragma mark - CollectionViewItem
 
-- (void)configureCell:(AccountSignInCell*)cell {
+- (void)configureCell:(LegacyAccountSignInCell*)cell {
   [super configureCell:cell];
   cell.textLabel.text =
       l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_TITLE);
@@ -59,7 +59,7 @@
 
 @end
 
-@implementation AccountSignInCell
+@implementation LegacyAccountSignInCell
 
 @synthesize textLabel = _textLabel;
 @synthesize detailTextLabel = _detailTextLabel;
diff --git a/ios/chrome/browser/ui/settings/cells/account_signin_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm
similarity index 66%
rename from ios/chrome/browser/ui/settings/cells/account_signin_item_unittest.mm
rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm
index 22905fd..9d5296f7 100644
--- a/ios/chrome/browser/ui/settings/cells/account_signin_item_unittest.mm
+++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
+#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
 
 #import <CoreGraphics/CoreGraphics.h>
 #import <UIKit/UIKit.h>
@@ -18,18 +18,19 @@
 // Tests that the UIImage and UILabels are set properly after a call to
 // |configureCell:|.
 
-using AccountSignInItemTest = PlatformTest;
+using LegacyAccountSignInItemTest = PlatformTest;
 
-TEST_F(AccountSignInItemTest, ImageView) {
-  AccountSignInItem* item = [[AccountSignInItem alloc] initWithType:0];
+TEST_F(LegacyAccountSignInItemTest, ImageView) {
+  LegacyAccountSignInItem* item =
+      [[LegacyAccountSignInItem alloc] initWithType:0];
   UIImage* image = [[UIImage alloc] init];
 
   item.image = image;
 
   id cell = [[[item cellClass] alloc] init];
-  ASSERT_TRUE([cell isMemberOfClass:[AccountSignInCell class]]);
+  ASSERT_TRUE([cell isMemberOfClass:[LegacyAccountSignInCell class]]);
 
-  AccountSignInCell* signInCell = cell;
+  LegacyAccountSignInCell* signInCell = cell;
   EXPECT_FALSE(signInCell.imageView.image);
 
   [item configureCell:cell];
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_consumer.h b/ios/chrome/browser/ui/settings/google_services_settings_consumer.h
index 6d232c4..6793577 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_consumer.h
+++ b/ios/chrome/browser/ui/settings/google_services_settings_consumer.h
@@ -7,14 +7,14 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/table_view/table_view_model.h"
 
 // Consumer protocol for Google services settings.
 @protocol GoogleServicesSettingsConsumer<NSObject>
 
-// Returns the collection view model.
+// Returns the table view model.
 @property(nonatomic, strong, readonly)
-    CollectionViewModel<CollectionViewItem*>* collectionViewModel;
+    TableViewModel<TableViewItem*>* tableViewModel;
 
 // Inserts sections at |sections| indexes. Does nothing if the model is not
 // loaded yet.
@@ -29,7 +29,7 @@
 
 // Reloads only a specific |item|. Does nothing if the model is not loaded
 // yet.
-- (void)reloadItem:(CollectionViewItem*)item;
+- (void)reloadItem:(TableViewItem*)item;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
index 309feec..6d580f6 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
@@ -43,11 +43,10 @@
 @implementation GoogleServicesSettingsCoordinator
 
 - (void)start {
-  UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init];
   GoogleServicesSettingsViewController* viewController =
       [[GoogleServicesSettingsViewController alloc]
-          initWithLayout:layout
-                   style:CollectionViewControllerStyleDefault];
+          initWithTableViewStyle:UITableViewStyleGrouped
+                     appBarStyle:ChromeTableViewControllerStyleNoAppBar];
   viewController.presentationDelegate = self;
   self.viewController = viewController;
   SyncSetupService* syncSetupService =
@@ -62,6 +61,8 @@
   self.mediator.consumer = viewController;
   self.mediator.authService = self.authService;
   self.mediator.commandHandler = self;
+  self.mediator.syncService =
+      ProfileSyncServiceFactory::GetForBrowserState(self.browserState);
   viewController.modelDelegate = self.mediator;
   viewController.serviceDelegate = self.mediator;
   DCHECK(self.navigationController);
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_mediator.h b/ios/chrome/browser/ui/settings/google_services_settings_mediator.h
index 576df88..1cebc7e 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_mediator.h
+++ b/ios/chrome/browser/ui/settings/google_services_settings_mediator.h
@@ -18,6 +18,9 @@
 class PrefService;
 class SyncSetupService;
 
+namespace browser_sync {
+class ProfileSyncService;
+}  // namespace browser_sync
 namespace unified_consent {
 class UnifiedConsentService;
 }  // namespace unified_consent
@@ -34,17 +37,20 @@
 // Command handler.
 @property(nonatomic, weak) id<GoogleServicesSettingsCommandHandler>
     commandHandler;
+// Sync service.
+@property(nonatomic, assign) browser_sync::ProfileSyncService* syncService;
 
 // Designated initializer. All the paramters should not be null.
 // |userPrefService|: preference service from the browser state.
 // |localPrefService|: preference service from the application context.
-- (instancetype)
-initWithUserPrefService:(PrefService*)userPrefService
-       localPrefService:(PrefService*)localPrefService
-       syncSetupService:(SyncSetupService*)syncSetupService
-  unifiedConsentService:
-      (unified_consent::UnifiedConsentService*)unifiedConsentService
-    NS_DESIGNATED_INITIALIZER;
+// |syncSetupService|: allows configuring sync.
+// |unifiedConsentService|: manage the user consent.
+- (instancetype)initWithUserPrefService:(PrefService*)userPrefService
+                       localPrefService:(PrefService*)localPrefService
+                       syncSetupService:(SyncSetupService*)syncSetupService
+                  unifiedConsentService:
+                      (unified_consent::UnifiedConsentService*)
+                          unifiedConsentService NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
 
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
index 11bf8e37..902e6547 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
@@ -7,21 +7,22 @@
 #include "base/auto_reset.h"
 #include "base/mac/foundation_util.h"
 #include "components/autofill/core/common/autofill_prefs.h"
+#include "components/browser_sync/profile_sync_service.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/unified_consent/pref_names.h"
 #include "ios/chrome/browser/pref_names.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_image_detail_text_item.h"
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h"
+#include "ios/chrome/browser/sync/sync_observer_bridge.h"
+#import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h"
+#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_command_handler.h"
 #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h"
 #import "ios/chrome/browser/ui/settings/utils/observable_boolean.h"
 #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -30,7 +31,7 @@
 
 using l10n_util::GetNSString;
 
-typedef NSArray<CollectionViewItem*>* ItemArray;
+typedef NSArray<TableViewItem*>* ItemArray;
 
 namespace {
 
@@ -55,7 +56,11 @@
 
 }  // namespace
 
-@interface GoogleServicesSettingsMediator () <BooleanObserver>
+@interface GoogleServicesSettingsMediator () <BooleanObserver,
+                                              SyncObserverModelBridge> {
+  // Sync observer.
+  std::unique_ptr<SyncObserverBridge> _syncObserver;
+}
 
 // Unified consent service.
 @property(nonatomic, assign)
@@ -96,8 +101,7 @@
 // All the items for the personalized section.
 @property(nonatomic, strong, readonly) ItemArray personalizedItems;
 // Item for the autocomplete wallet feature.
-@property(nonatomic, strong, readonly)
-    LegacySyncSwitchItem* autocompleteWalletItem;
+@property(nonatomic, strong, readonly) SyncSwitchItem* autocompleteWalletItem;
 // All the items for the non-personalized section.
 @property(nonatomic, strong, readonly) ItemArray nonPersonalizedItems;
 
@@ -109,12 +113,12 @@
 
 #pragma mark - Load model
 
-- (instancetype)
-initWithUserPrefService:(PrefService*)userPrefService
-       localPrefService:(PrefService*)localPrefService
-       syncSetupService:(SyncSetupService*)syncSetupService
-  unifiedConsentService:
-      (unified_consent::UnifiedConsentService*)unifiedConsentService {
+- (instancetype)initWithUserPrefService:(PrefService*)userPrefService
+                       localPrefService:(PrefService*)localPrefService
+                       syncSetupService:(SyncSetupService*)syncSetupService
+                  unifiedConsentService:
+                      (unified_consent::UnifiedConsentService*)
+                          unifiedConsentService {
   self = [super init];
   if (self) {
     DCHECK(userPrefService);
@@ -156,9 +160,9 @@
 
 // Loads NonPersonalizedSectionIdentifier section.
 - (void)loadNonPersonalizedSection {
-  CollectionViewModel* model = self.consumer.collectionViewModel;
+  TableViewModel* model = self.consumer.tableViewModel;
   [model addSectionWithIdentifier:NonPersonalizedSectionIdentifier];
-  for (CollectionViewItem* item in self.nonPersonalizedItems) {
+  for (TableViewItem* item in self.nonPersonalizedItems) {
     [model addItem:item
         toSectionWithIdentifier:NonPersonalizedSectionIdentifier];
   }
@@ -173,28 +177,28 @@
 
 - (ItemArray)nonPersonalizedItems {
   if (!_nonPersonalizedItems) {
-    LegacySyncSwitchItem* autocompleteSearchesAndURLsItem = [self
+    SyncSwitchItem* autocompleteSearchesAndURLsItem = [self
         switchItemWithItemType:AutocompleteSearchesAndURLsItemType
                   textStringID:
                       IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_TEXT
                 detailStringID:
                     IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_DETAIL
                       dataType:0];
-    LegacySyncSwitchItem* preloadPagesItem = [self
-        switchItemWithItemType:PreloadPagesItemType
-                  textStringID:
-                      IDS_IOS_GOOGLE_SERVICES_SETTINGS_PRELOAD_PAGES_TEXT
-                detailStringID:
-                    IDS_IOS_GOOGLE_SERVICES_SETTINGS_PRELOAD_PAGES_DETAIL
-                      dataType:0];
-    LegacySyncSwitchItem* improveChromeItem = [self
-        switchItemWithItemType:ImproveChromeItemType
-                  textStringID:
-                      IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT
-                detailStringID:
-                    IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_DETAIL
-                      dataType:0];
-    LegacySyncSwitchItem* betterSearchAndBrowsingItemType = [self
+    SyncSwitchItem* preloadPagesItem =
+        [self switchItemWithItemType:PreloadPagesItemType
+                        textStringID:
+                            IDS_IOS_GOOGLE_SERVICES_SETTINGS_PRELOAD_PAGES_TEXT
+                      detailStringID:
+                          IDS_IOS_GOOGLE_SERVICES_SETTINGS_PRELOAD_PAGES_DETAIL
+                            dataType:0];
+    SyncSwitchItem* improveChromeItem =
+        [self switchItemWithItemType:ImproveChromeItemType
+                        textStringID:
+                            IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT
+                      detailStringID:
+                          IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_DETAIL
+                            dataType:0];
+    SyncSwitchItem* betterSearchAndBrowsingItemType = [self
         switchItemWithItemType:BetterSearchAndBrowsingItemType
                   textStringID:
                       IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_TEXT
@@ -211,13 +215,12 @@
 
 #pragma mark - Private
 
-// Creates a LegacySyncSwitchItem instance.
-- (LegacySyncSwitchItem*)switchItemWithItemType:(NSInteger)itemType
-                                   textStringID:(int)textStringID
-                                 detailStringID:(int)detailStringID
-                                       dataType:(NSInteger)dataType {
-  LegacySyncSwitchItem* switchItem =
-      [[LegacySyncSwitchItem alloc] initWithType:itemType];
+// Creates a SyncSwitchItem instance.
+- (SyncSwitchItem*)switchItemWithItemType:(NSInteger)itemType
+                             textStringID:(int)textStringID
+                           detailStringID:(int)detailStringID
+                                 dataType:(NSInteger)dataType {
+  SyncSwitchItem* switchItem = [[SyncSwitchItem alloc] initWithType:itemType];
   switchItem.text = GetNSString(textStringID);
   if (detailStringID)
     switchItem.detailText = GetNSString(detailStringID);
@@ -226,10 +229,10 @@
 }
 
 // Creates a item to display the sync error.
-- (LegacySettingsImageDetailTextItem*)createSyncErrorItemWithItemType:
+- (SettingsImageDetailTextItem*)createSyncErrorItemWithItemType:
     (NSInteger)itemType {
-  LegacySettingsImageDetailTextItem* syncErrorItem =
-      [[LegacySettingsImageDetailTextItem alloc] initWithType:itemType];
+  SettingsImageDetailTextItem* syncErrorItem =
+      [[SettingsImageDetailTextItem alloc] initWithType:itemType];
   syncErrorItem.text = l10n_util::GetNSString(IDS_IOS_SYNC_ERROR_TITLE);
   syncErrorItem.detailText =
       GetSyncErrorDescriptionForSyncSetupService(self.syncSetupService);
@@ -248,7 +251,7 @@
 // Reloads the sync feedback section. If |notifyConsummer| is YES, the consomer
 // is notified to add or remove the sync error section.
 - (void)updateSyncErrorSectionAndNotifyConsumer:(BOOL)notifyConsummer {
-  CollectionViewModel* model = self.consumer.collectionViewModel;
+  TableViewModel* model = self.consumer.tableViewModel;
   BOOL hasError = NO;
   ItemType type;
   if (self.isAuthenticated) {
@@ -288,7 +291,7 @@
   // Add the sync error item and its section (if it doesn't already exist) and
   // reload them.
   BOOL sectionAdded = NO;
-  LegacySettingsImageDetailTextItem* syncErrorItem =
+  SettingsImageDetailTextItem* syncErrorItem =
       [self createSyncErrorItemWithItemType:type];
   if (![model hasSectionForSectionIdentifier:SyncFeedbackSectionIdentifier]) {
     // Adding the sync error item and its section.
@@ -316,10 +319,10 @@
 
 // Updates the non-personalized section according to the user consent.
 - (void)updateNonPersonalizedSection {
-  for (CollectionViewItem* item in self.nonPersonalizedItems) {
+  for (TableViewItem* item in self.nonPersonalizedItems) {
     ItemType type = static_cast<ItemType>(item.type);
-    LegacySyncSwitchItem* switchItem =
-        base::mac::ObjCCastStrict<LegacySyncSwitchItem>(item);
+    SyncSwitchItem* switchItem =
+        base::mac::ObjCCastStrict<SyncSwitchItem>(item);
     switch (type) {
       case AutocompleteSearchesAndURLsItemType:
         switchItem.on = self.autocompleteSearchPreference.value;
@@ -349,12 +352,13 @@
   DCHECK_EQ(self.consumer, controller);
   [self loadNonPersonalizedSection];
   [self updateSyncErrorSectionAndNotifyConsumer:NO];
+  DCHECK(self.syncService);
+  _syncObserver.reset(new SyncObserverBridge(self, self.syncService));
 }
 
 #pragma mark - GoogleServicesSettingsServiceDelegate
 
-- (void)toggleSwitchItem:(LegacySyncSwitchItem*)switchItem
-               withValue:(BOOL)value {
+- (void)toggleSwitchItem:(SyncSwitchItem*)switchItem withValue:(BOOL)value {
   ItemType type = static_cast<ItemType>(switchItem.type);
   switch (type) {
     case AutocompleteSearchesAndURLsItemType:
@@ -385,24 +389,7 @@
   }
 }
 
-- (BOOL)shouldHighlightItem:(CollectionViewItem*)item {
-  ItemType type = static_cast<ItemType>(item.type);
-  switch (type) {
-    case RestartAuthenticationFlowErrorItemType:
-    case ReauthDialogAsSyncIsInAuthErrorItemType:
-    case ShowPassphraseDialogErrorItemType:
-      return YES;
-      break;
-    case AutocompleteSearchesAndURLsItemType:
-    case PreloadPagesItemType:
-    case ImproveChromeItemType:
-    case BetterSearchAndBrowsingItemType:
-      return NO;
-      break;
-  }
-}
-
-- (void)didSelectItem:(CollectionViewItem*)item {
+- (void)didSelectItem:(TableViewItem*)item {
   ItemType type = static_cast<ItemType>(item.type);
   switch (type) {
     case RestartAuthenticationFlowErrorItemType:
@@ -418,16 +405,21 @@
     case PreloadPagesItemType:
     case ImproveChromeItemType:
     case BetterSearchAndBrowsingItemType:
-      NOTREACHED();
       break;
   }
 }
 
+#pragma mark - SyncObserverModelBridge
+
+- (void)onSyncStateChanged {
+  [self updateSyncErrorSectionAndNotifyConsumer:YES];
+}
+
 #pragma mark - BooleanObserver
 
 - (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean {
   [self updateNonPersonalizedSection];
-  CollectionViewModel* model = self.consumer.collectionViewModel;
+  TableViewModel* model = self.consumer.tableViewModel;
   NSUInteger index =
       [model sectionForSectionIdentifier:NonPersonalizedSectionIdentifier];
   NSIndexSet* sectionIndexToReload = [NSIndexSet indexSetWithIndex:index];
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h b/ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h
index 60fd6c1..9597534 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h
+++ b/ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h
@@ -5,21 +5,17 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SETTINGS_SERVICE_DELEGATE_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SETTINGS_SERVICE_DELEGATE_H_
 
-@class CollectionViewItem;
-@class LegacySyncSwitchItem;
+@class SyncSwitchItem;
+@class TableViewItem;
 
 // Protocol to handle user actions from the Google services settings view.
 @protocol GoogleServicesSettingsServiceDelegate<NSObject>
 
-// Called when the UISwitch from the LegacySyncSwitchItem is toggled.
-- (void)toggleSwitchItem:(LegacySyncSwitchItem*)switchItem
-               withValue:(BOOL)value;
-
-// Returns YES if the item can be highlighted;
-- (BOOL)shouldHighlightItem:(CollectionViewItem*)item;
+// Called when the UISwitch from the SyncSwitchItem is toggled.
+- (void)toggleSwitchItem:(SyncSwitchItem*)switchItem withValue:(BOOL)value;
 
 // Called when cell is tapped.
-- (void)didSelectItem:(CollectionViewItem*)item;
+- (void)didSelectItem:(TableViewItem*)item;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.h b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.h
index b503e5e..5a537de 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.h
+++ b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SETTINGS_VIEW_CONTROLLER_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_SETTINGS_VIEW_CONTROLLER_H_
 
-#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
 
 #import "ios/chrome/browser/ui/settings/google_services_settings_consumer.h"
 
@@ -25,7 +25,7 @@
 
 // View controller to related to Google services settings.
 @interface GoogleServicesSettingsViewController
-    : SettingsRootCollectionViewController<GoogleServicesSettingsConsumer>
+    : SettingsRootTableViewController <GoogleServicesSettingsConsumer>
 
 // Presentation delegate.
 @property(nonatomic, weak)
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm
index 1c4245b..9a6c298a 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm
@@ -5,8 +5,8 @@
 #import "ios/chrome/browser/ui/settings/google_services_settings_view_controller.h"
 
 #include "base/mac/foundation_util.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h"
+#import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h"
+#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_view_controller_model_delegate.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -26,15 +26,11 @@
 
 @implementation GoogleServicesSettingsViewController
 
-- (instancetype)initWithLayout:(UICollectionViewLayout*)layout
-                         style:(CollectionViewControllerStyle)style {
-  self = [super initWithLayout:layout style:style];
-  if (self) {
-    self.collectionViewAccessibilityIdentifier =
-        @"google_services_settings_view_controller";
-    self.title = l10n_util::GetNSString(IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE);
-  }
-  return self;
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  self.tableView.accessibilityIdentifier =
+      @"google_services_settings_view_controller";
+  self.title = l10n_util::GetNSString(IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE);
 }
 
 #pragma mark - Private
@@ -51,21 +47,20 @@
 
 - (void)switchAction:(UISwitch*)sender {
   NSIndexPath* indexPath = [self indexPathForTag:sender.tag];
-  LegacySyncSwitchItem* syncSwitchItem =
-      base::mac::ObjCCastStrict<LegacySyncSwitchItem>(
-          [self.collectionViewModel itemAtIndexPath:indexPath]);
+  SyncSwitchItem* syncSwitchItem = base::mac::ObjCCastStrict<SyncSwitchItem>(
+      [self.tableViewModel itemAtIndexPath:indexPath]);
   [self.serviceDelegate toggleSwitchItem:syncSwitchItem withValue:sender.isOn];
 }
 
-#pragma mark - UICollectionViewDataSource
+#pragma mark - UITableViewDataSource
 
-- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
-                 cellForItemAtIndexPath:(NSIndexPath*)indexPath {
-  UICollectionViewCell* cell =
-      [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
-  if ([cell isKindOfClass:[LegacySyncSwitchCell class]]) {
-    LegacySyncSwitchCell* switchCell =
-        base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell);
+- (UITableViewCell*)tableView:(UITableView*)tableView
+        cellForRowAtIndexPath:(NSIndexPath*)indexPath {
+  UITableViewCell* cell = [super tableView:tableView
+                     cellForRowAtIndexPath:indexPath];
+  if ([cell isKindOfClass:[SettingsSwitchCell class]]) {
+    SettingsSwitchCell* switchCell =
+        base::mac::ObjCCastStrict<SettingsSwitchCell>(cell);
     [switchCell.switchView addTarget:self
                               action:@selector(switchAction:)
                     forControlEvents:UIControlEventValueChanged];
@@ -77,36 +72,40 @@
 #pragma mark - GoogleServicesSettingsConsumer
 
 - (void)insertSections:(NSIndexSet*)sections {
-  if (!self.collectionViewModel) {
+  if (!self.tableViewModel) {
     // No need to reload since the model has not been loaded yet.
     return;
   }
-  [self.collectionView insertSections:sections];
+  [self.tableView insertSections:sections
+                withRowAnimation:UITableViewRowAnimationNone];
 }
 
 - (void)deleteSections:(NSIndexSet*)sections {
-  if (!self.collectionViewModel) {
+  if (!self.tableViewModel) {
     // No need to reload since the model has not been loaded yet.
     return;
   }
-  [self.collectionView deleteSections:sections];
+  [self.tableView deleteSections:sections
+                withRowAnimation:UITableViewRowAnimationNone];
 }
 
 - (void)reloadSections:(NSIndexSet*)sections {
-  if (!self.collectionViewModel) {
+  if (!self.tableViewModel) {
     // No need to reload since the model has not been loaded yet.
     return;
   }
-  [self.collectionView reloadSections:sections];
+  [self.tableView reloadSections:sections
+                withRowAnimation:UITableViewRowAnimationNone];
 }
 
-- (void)reloadItem:(CollectionViewItem*)item {
-  if (!self.collectionViewModel) {
+- (void)reloadItem:(TableViewItem*)item {
+  if (!self.tableViewModel) {
     // No need to reload since the model has not been loaded yet.
     return;
   }
-  NSIndexPath* indexPath = [self.collectionViewModel indexPathForItem:item];
-  [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]];
+  NSIndexPath* indexPath = [self.tableViewModel indexPathForItem:item];
+  [self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
+                        withRowAnimation:UITableViewRowAnimationNone];
 }
 
 #pragma mark - CollectionViewController
@@ -131,36 +130,12 @@
   }
 }
 
-#pragma mark - MDCCollectionViewStylingDelegate
+#pragma mark - UITableViewDelegate
 
-- (CGFloat)collectionView:(UICollectionView*)collectionView
-    cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
-  UIEdgeInsets inset = [self collectionView:collectionView
-                                     layout:collectionView.collectionViewLayout
-                     insetForSectionAtIndex:indexPath.section];
-  CGFloat width =
-      CGRectGetWidth(collectionView.bounds) - inset.left - inset.right;
-  return [item.cellClass cr_preferredHeightForWidth:width forItem:item];
-}
-
-#pragma mark - UICollectionViewDelegate
-
-- (BOOL)collectionView:(UICollectionView*)collectionView
-    shouldHighlightItemAtIndexPath:(NSIndexPath*)indexPath {
-  [super collectionView:collectionView
-      shouldHighlightItemAtIndexPath:indexPath];
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
-  return [self.serviceDelegate shouldHighlightItem:item];
-}
-
-- (void)collectionView:(UICollectionView*)collectionView
-    didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
-  [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
+- (void)tableView:(UITableView*)tableView
+    didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+  [super tableView:tableView didSelectRowAtIndexPath:indexPath];
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
   [self.serviceDelegate didSelectItem:item];
 }
 
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index e70c107..f15b783 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -30,9 +30,9 @@
 #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h"
 #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/ui/payments/cells/price_item.h"
-#import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
+#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_autofill_data_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_image_detail_text_item.h"
@@ -532,8 +532,8 @@
 }
 
 - (CollectionViewItem*)accountSignInItem {
-  AccountSignInItem* accountSignInItem =
-      [[AccountSignInItem alloc] initWithType:ItemTypeAccountSignIn];
+  LegacyAccountSignInItem* accountSignInItem =
+      [[LegacyAccountSignInItem alloc] initWithType:ItemTypeAccountSignIn];
   accountSignInItem.image =
       CircularImageFromImage(ios::GetChromeBrowserProvider()
                                  ->GetSigninResourcesProvider()
diff --git a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
index 51bc8494..575197d8 100644
--- a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
@@ -47,7 +47,7 @@
 #import "ios/chrome/browser/ui/settings/autofill_credit_card_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/autofill_profile_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.h"
-#import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
+#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_switch_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
@@ -487,8 +487,8 @@
         signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS);
     _hasRecordedSigninImpression = YES;
   }
-  AccountSignInItem* signInTextItem =
-      [[AccountSignInItem alloc] initWithType:ItemTypeSignInButton];
+  LegacyAccountSignInItem* signInTextItem =
+      [[LegacyAccountSignInItem alloc] initWithType:ItemTypeSignInButton];
   signInTextItem.accessibilityIdentifier = kSettingsSignInCellId;
   UIImage* image = CircularImageFromImage(ios::GetChromeBrowserProvider()
                                               ->GetSigninResourcesProvider()
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 33c43da..689ed65 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3404,21 +3404,6 @@
             ]
         }
     ],
-    "PasswordManagerSearchSettings": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "PasswordSearchEnabled",
-                    "enable_features": [
-                        "PasswordSearchMobile"
-                    ]
-                }
-            ]
-        }
-    ],
     "PasswordProtectionForEnterprise": [
         {
             "platforms": [
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index a007811..0800660 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -80,26 +80,16 @@
 }
 
 void NGLayoutInputNode::IntrinsicSize(
-    NGLogicalSize* default_intrinsic_size,
     base::Optional<LayoutUnit>* computed_inline_size,
     base::Optional<LayoutUnit>* computed_block_size,
     NGLogicalSize* aspect_ratio) const {
   DCHECK(IsReplaced());
-
-  LayoutSize box_intrinsic_size = box_->IntrinsicSize();
-  // Transform to logical coordinates if needed.
-  if (!Style().IsHorizontalWritingMode())
-    box_intrinsic_size = box_intrinsic_size.TransposedSize();
-  *default_intrinsic_size =
-      NGLogicalSize(box_intrinsic_size.Width(), box_intrinsic_size.Height());
-
   if (ShouldApplySizeContainment()) {
     *computed_inline_size = LayoutUnit();
     *computed_block_size = LayoutUnit();
     *aspect_ratio = NGLogicalSize(LayoutUnit(), LayoutUnit());
     return;
   }
-
   IntrinsicSizingInfo legacy_sizing_info;
 
   ToLayoutReplaced(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
index aad6171..1c28ffa9 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -139,11 +139,8 @@
 
   // Returns intrinsic sizing information for replaced elements.
   // ComputeReplacedSize can use it to compute actual replaced size.
-  // The function arguments return values from LegacyLayout intrinsic size
-  // computations: LayoutReplaced::IntrinsicSizingInfo,
-  // and LayoutReplaced::IntrinsicSize.
-  void IntrinsicSize(NGLogicalSize* default_intrinsic_size,
-                     base::Optional<LayoutUnit>* computed_inline_size,
+  // Corresponds to Legacy's LayoutReplaced::IntrinsicSizingInfo.
+  void IntrinsicSize(base::Optional<LayoutUnit>* computed_inline_size,
                      base::Optional<LayoutUnit>* computed_block_size,
                      NGLogicalSize* aspect_ratio) const;
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index 08d49cd6..9993ff4 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -592,14 +592,12 @@
   DCHECK(node.IsReplaced());
 
   NGLogicalSize replaced_size;
-
-  NGLogicalSize default_intrinsic_size;
   base::Optional<LayoutUnit> computed_inline_size;
   base::Optional<LayoutUnit> computed_block_size;
   NGLogicalSize aspect_ratio;
 
-  node.IntrinsicSize(&default_intrinsic_size, &computed_inline_size,
-                     &computed_block_size, &aspect_ratio);
+  node.IntrinsicSize(&computed_inline_size, &computed_block_size,
+                     &aspect_ratio);
 
   const ComputedStyle& style = node.Style();
   Length inline_length = style.LogicalWidth();
@@ -612,7 +610,7 @@
       if (computed_inline_size.has_value())
         replaced_size.inline_size = computed_inline_size.value();
       else
-        replaced_size.inline_size = default_intrinsic_size.inline_size;
+        replaced_size.inline_size = space.AvailableSize().inline_size;
       replaced_size.inline_size +=
           (ComputeBorders(space, style) + ComputePadding(space, style))
               .InlineSum();
@@ -620,7 +618,7 @@
       // inline_size is computed from block_size.
       replaced_size.inline_size =
           ResolveBlockLength(
-              space, style, block_length, default_intrinsic_size.block_size,
+              space, style, block_length, space.AvailableSize().block_size,
               LengthResolveType::kContentSize, LengthResolvePhase::kLayout) *
           aspect_ratio.inline_size / aspect_ratio.block_size;
     }
@@ -633,26 +631,24 @@
 
   // Compute block size
   if (block_length.IsAuto()) {
-    if (inline_length.IsAuto() || aspect_ratio.IsEmpty()) {
+    if (aspect_ratio.IsEmpty()) {
       // Use intrinsic values if block_size cannot be computed from inline_size.
       if (computed_block_size.has_value())
         replaced_size.block_size = LayoutUnit(computed_block_size.value());
       else
-        replaced_size.block_size = default_intrinsic_size.block_size;
+        replaced_size.block_size = space.AvailableSize().block_size;
       replaced_size.block_size +=
           (ComputeBorders(space, style) + ComputePadding(space, style))
               .BlockSum();
     } else {
       // block_size is computed from inline_size.
-      replaced_size.block_size =
-          ResolveInlineLength(space, style, child_minmax, inline_length,
-                              LengthResolveType::kContentSize,
-                              LengthResolvePhase::kLayout) *
-          aspect_ratio.block_size / aspect_ratio.inline_size;
+      replaced_size.block_size = replaced_size.inline_size *
+                                 aspect_ratio.block_size /
+                                 aspect_ratio.inline_size;
     }
   } else {
     replaced_size.block_size = ResolveBlockLength(
-        space, style, block_length, default_intrinsic_size.block_size,
+        space, style, block_length, space.AvailableSize().block_size,
         LengthResolveType::kContentSize, LengthResolvePhase::kLayout);
   }
   return replaced_size;
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 8731e344..4439a51 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
 #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
 #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
 #include "third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -389,6 +390,22 @@
   }
 }
 
+static void InvalidateChromeClient(
+    const LayoutBoxModelObject& paint_invalidation_container) {
+  if (paint_invalidation_container.GetDocument().Printing() &&
+      !RuntimeEnabledFeatures::PrintBrowserEnabled())
+    return;
+
+  DCHECK(paint_invalidation_container.IsLayoutView());
+  DCHECK(!paint_invalidation_container.IsPaintInvalidationContainer());
+
+  auto* frame_view = paint_invalidation_container.GetFrameView();
+  DCHECK(!frame_view->GetFrame().OwnerLayoutObject());
+  if (auto* client = frame_view->GetChromeClient()) {
+    client->InvalidateRect(IntRect(IntPoint(), frame_view->Size()));
+  }
+}
+
 void PaintInvalidator::UpdateEmptyVisualRectFlag(
     const LayoutObject& object,
     PaintInvalidatorContext& context) {
@@ -514,6 +531,15 @@
         PaintInvalidatorContext::kSubtreeVisualRectUpdate |
         PaintInvalidatorContext::kSubtreeInvalidationChecking;
   }
+
+  // The object is under a frame for WebViewPlugin, SVG images etc. Need to
+  // inform the chrome client of the invalidation so that the client will
+  // initiate painting of the contents.
+  // TODO(wangxianzhu): Do we need this for CAP?
+  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+      !context.paint_invalidation_container->IsPaintInvalidationContainer() &&
+      reason != PaintInvalidationReason::kNone)
+    InvalidateChromeClient(*context.paint_invalidation_container);
 }
 
 void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() {
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
index c2f090c..b8e0e9f 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -16,7 +16,6 @@
 #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
 #include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
 #include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
@@ -69,13 +68,6 @@
   if (VLOG_IS_ON(1))
     showAllPropertyTrees(root_frame_view);
 #endif
-
-  // If the frame is invalidated, we need to inform the frame's chrome client
-  // so that the client will initiate repaint of the contents.
-  if (root_frame_view.GetLayoutView()->Layer()->NeedsRepaint()) {
-    if (auto* client = root_frame_view.GetChromeClient())
-      client->InvalidateRect(IntRect(IntPoint(), root_frame_view.Size()));
-  }
 }
 
 void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
index 61b18bb..65194d1 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -7,6 +7,7 @@
 Bug(none) external/wpt [ Skip ]
 Bug(none) http/tests/devtools/layers/ [ Skip ]
 Bug(none) http/tests/devtools/tracing/ [ Skip ]
+Bug(none) plugins/ [ Skip ]
 Bug(none) printing/ [ Skip ]
 Bug(none) scrollbars/ [ Skip ]
 Bug(none) scrollingcoordinator/ [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 28ff0155..40034ff4 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -84,7 +84,6 @@
 # The following fail only on Mac.
 crbug.com/891427 [ Mac ] virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen-desktop.html [ Pass Failure Timeout Crash ]
 crbug.com/891427 [ Mac ] fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
-crbug.com/891427 [ Mac ] virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
 crbug.com/891427 [ Mac ] virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
 crbug.com/891427 [ Mac ] virtual/user-activation-v2/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
 crbug.com/891427 [ Mac ] virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-scroll-input-field.html [ Pass Failure Timeout Crash ]
@@ -119,6 +118,8 @@
 crbug.com/887140 hdr/color-profile-video.html [ Failure ]
 crbug.com/887140 hdr/video-canvas-alpha.html [ Failure ]
 
+# This was disabled by sheriff on Dec 31. Also failing on Win7, will need more investigation.
+crbug.com/891427 [ Mac Win7 ] virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
 
 # ====== Site Isolation failures from here ======
 # See also third_party/blink/web_tests/virtual/not-site-per-process/README.md
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/resources/helpers.js b/third_party/blink/web_tests/external/wpt/cookie-store/resources/helpers.js
index 98f9ff6..8d5ddde 100644
--- a/third_party/blink/web_tests/external/wpt/cookie-store/resources/helpers.js
+++ b/third_party/blink/web_tests/external/wpt/cookie-store/resources/helpers.js
@@ -14,6 +14,34 @@
 });
 
 /**
+ * @description - Function unregisters any service workers in this scope
+ *                and then creates a new registration. The function returns
+ *                a promise that resolves when the registered service worker
+ *                becomes activated. The resolved promise yields the
+ *                service worker registration
+ * @param {testCase} t - test case to add cleanup functions to
+ */
+self.createServiceWorker = async (t, sw_registration_name, scope_url) => {
+  let registration = await navigator.serviceWorker.getRegistration(scope_url);
+  if (registration)
+    await registration.unregister();
+
+  registration = await navigator.serviceWorker.register(sw_registration_name,
+      {scope_url});
+  t.add_cleanup(() => registration.unregister());
+
+  return new Promise(resolve => {
+    const serviceWorker = registration.installing || registration.active ||
+        registration.waiting;
+    serviceWorker.addEventListener('statechange', event => {
+      if (event.target.state === 'activated') {
+        resolve(serviceWorker);
+      }
+    });
+  })
+}
+
+/**
  * Function that will return a promise that resolves when a message event
  * is fired. Returns a promise that resolves to the message that was received
  */
@@ -22,3 +50,23 @@
     resolve(event.data);
   }, {once: true});
 });
+
+/**
+ * Sends a message via MessageChannel and waits for the response
+ * @param {*} message
+ * @returns {Promise} resolves with the response payload
+ */
+self.sendMessageOverChannel = (message, target) => {
+  return new Promise(function(resolve, reject) {
+    const messageChannel = new MessageChannel();
+    messageChannel.port1.onmessage = event => {
+      if (event.data.error) {
+        reject(event.data.error);
+      } else {
+        resolve(event.data);
+      }
+    };
+
+    target.postMessage(message, [messageChannel.port2]);
+  })
+};
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.js b/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.js
new file mode 100644
index 0000000..ac59b70
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.js
@@ -0,0 +1,13 @@
+self.GLOBAL = {
+  isWindow: () => false,
+  isWorker: () => false,
+};
+
+self.addEventListener('message', async event => {
+  if (event.data.op === 'get-cookies') {
+    const workerCookies = await cookieStore.getAll();
+    event.ports[0].postMessage({ workerCookies }, {
+        domain: event.origin,
+    });
+  }
+});
diff --git a/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.tentative.https.sub.html
new file mode 100644
index 0000000..abc431a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/cookie-store/serviceworker_cookieStore_cross_origin.tentative.https.sub.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<meta charset='utf-8'>
+<title>Async Cookies: cookieStore API in ServiceWorker across origins</title>
+<link rel='help' href='https://github.com/WICG/cookie-store'>
+<link rel='author' href='jarrydg@chromium.org' title='Jarryd Goodman'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='resources/helpers.js'></script>
+<style>iframe {display: none}</style>
+<script>
+'use strict';
+
+const kPath = '/cookie-store/resources/helper_iframe.sub.html';
+const kCorsBase = `https://{{domains[www1]}}:{{ports[https][0]}}`;
+const kCorsUrl = `${kCorsBase}${kPath}`;
+
+promise_test(async t => {
+  const iframe = await createIframe(kCorsUrl, t);
+  assert_true(iframe != null);
+
+  const serviceWorker = await createServiceWorker(t,
+      'serviceworker_cookieStore_cross_origin.js', '/does/not/exist');
+
+
+  iframe.contentWindow.postMessage({
+    opname: 'set-cookie',
+    name: 'cookie-name',
+    value: 'cookie-value',
+  }, kCorsBase);
+  t.add_cleanup(() => {
+    cookieStore.delete('cookie-name');
+  });
+
+  await waitForMessage();
+
+  const { workerCookies } = await sendMessageOverChannel({ op: 'get-cookies' },
+      serviceWorker);
+
+  assert_equals(workerCookies.length, 1);
+  assert_equals(workerCookies[0].name, 'cookie-name');
+  assert_equals(workerCookies[0].value, 'cookie-value');
+}, 'cookieStore.get() in ServiceWorker reads cookie set in cross-origin frame');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/abspos.html b/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/abspos.html
new file mode 100644
index 0000000..fb37bbe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/abspos.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>Intrinsic sizing for &lt;svg&gt;</title>
+<link rel="help" href="https://www.w3.org/TR/SVG2/coords.html">
+<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic-sizes">
+<link rel="match"  href="support/abspos-ref.html">
+<!--
+  SVG embedded inside html has no intrinsic size, but has intrinsic
+  aspect ratio. Inline size is computed as available size of containing block,
+  and block size is derived from aspect ratio.
+-->
+<style>
+#container {
+  width: 200px;
+  height: 300px;
+  position: relative;
+  border: 10px solid black;
+}
+#target {
+  fill: green;
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+}
+</style>
+<div id="container">
+  <svg id="target" viewBox="0 0 50 50"><circle cx="50%" cy="50%" r="50%"></circle></svg>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/support/abspos-ref.html b/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/support/abspos-ref.html
new file mode 100644
index 0000000..6966d8cb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/svg/coordinate-systems/support/abspos-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Intrinsic sizing for &lt;svg&gt;</title>
+<link rel="help" href="https://www.w3.org/TR/SVG2/coords.html">
+<style>
+#container {
+  width: 200px;
+  height: 300px;
+  position: relative;
+  border: 10px solid black;
+}
+#target {
+  fill: green;
+  width: 200px;
+  height: 200px;
+}
+</style>
+<div id="container">
+  <svg id="target" viewBox="0 0 50 50"><circle cx="50%" cy="50%" r="50%"></circle></svg>
+</div>
diff --git a/tools/binary_size/README.md b/tools/binary_size/README.md
index f044898..62a94c6 100644
--- a/tools/binary_size/README.md
+++ b/tools/binary_size/README.md
@@ -242,13 +242,13 @@
 
 ``` bash
 # Creates the data file ./report.ndjson, generated based on ./chrome.size
-tools/binary_size/supersize html_report chrome.size --report-file report.ndjson -v
+tools/binary_size/supersize html_report chrome.size report.ndjson -v
 
 # Includes every symbol in the data file, although it will take longer to load.
-tools/binary_size/supersize html_report chrome.size --report-file report.ndjson --all-symbols
+tools/binary_size/supersize html_report chrome.size report.ndjson --all-symbols
 
 # Create a data file showing a diff between two .size files.
-tools/binary_size/supersize html_report after.size --diff-with before.size --report-file report.ndjson
+tools/binary_size/supersize html_report after.size --diff-with before.size report.ndjson
 ```
 
 ### Usage: start_server
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 0c18789..68f705cd 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -84236,7 +84236,7 @@
 
 <histogram name="Plugin.Flash.YouTubeRewrite" enum="YouTubeRewriteStatus">
   <owner>mlamouri@chromium.org</owner>
-  <owner>kdsilva@google.org</owner>
+  <owner>media-dev@chromium.org</owner>
   <summary>
     Records the YouTube Flash embed rewrite status when attempted.
   </summary>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
index f985237b5..524a746 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
@@ -284,6 +284,7 @@
     var item = new MetadataItem();
     var mimeType = metadata['mimeType'];
     item.contentMimeType = mimeType;
+    item.mediaMimeType = mimeType;
     var trans = {scaleX: 1, scaleY: 1, rotate90: 0};
     if (metadata.rotation) {
       switch (metadata.rotation) {
diff --git a/ui/file_manager/file_manager/foreground/js/task_controller.js b/ui/file_manager/file_manager/foreground/js/task_controller.js
index c92f81b..184fc85 100644
--- a/ui/file_manager/file_manager/foreground/js/task_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/task_controller.js
@@ -411,12 +411,12 @@
 };
 
 /**
- * Returns whether open with command can be executed or not.
- * @return {boolean} True if open with command is executable.
+ * Returns whether show sub-menu command can be executed or not.
+ * @return {boolean} True if show-submenu command is executable.
  */
 TaskController.prototype.canExecuteShowOverflow = function() {
-  // TODO (adanilo@) same logic as more actions now, extend
-  return this.canExecuteMoreActions_;
+  // TODO (adanilo@) extend this for general sub-menu case
+  return this.ui_.shareMenuButton.overflow.firstChild !== null;
 };
 
 /**
diff --git a/ui/native_theme/native_theme_mac.mm b/ui/native_theme/native_theme_mac.mm
index aa21083c..6c7c2bc 100644
--- a/ui/native_theme/native_theme_mac.mm
+++ b/ui/native_theme/native_theme_mac.mm
@@ -190,7 +190,8 @@
     case kColorId_DisabledMenuItemForegroundColor:
       return NSSystemColorToSkColor([NSColor disabledControlTextColor]);
     case kColorId_MenuSeparatorColor:
-      return SkColorSetA(SK_ColorBLACK, 0x26);
+      return SystemDarkModeEnabled() ? SkColorSetA(gfx::kGoogleGrey800, 0xCC)
+                                     : SkColorSetA(SK_ColorBLACK, 0x26);
     case kColorId_MenuBorderColor:
       return SkColorSetA(SK_ColorBLACK, 0x60);
 
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 361ce56..714a80c 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -480,6 +480,8 @@
     "cocoa/bridged_native_widget_host_impl.mm",
     "cocoa/drag_drop_client_mac.h",
     "cocoa/drag_drop_client_mac.mm",
+    "cocoa/text_input_host.h",
+    "cocoa/text_input_host.mm",
     "cocoa/tooltip_manager_mac.h",
     "cocoa/tooltip_manager_mac.mm",
     "controls/button/label_button_label.cc",
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.h b/ui/views/cocoa/bridged_native_widget_host_impl.h
index a27415b0..45f5b4a 100644
--- a/ui/views/cocoa/bridged_native_widget_host_impl.h
+++ b/ui/views/cocoa/bridged_native_widget_host_impl.h
@@ -38,6 +38,7 @@
 
 class BridgedNativeWidgetImpl;
 class NativeWidgetMac;
+class TextInputHost;
 
 // The portion of NativeWidgetMac that lives in the browser process. This
 // communicates to the BridgedNativeWidgetImpl, which interacts with the Cocoa
@@ -86,6 +87,8 @@
     return bridge_factory_host_;
   }
 
+  TextInputHost* text_input_host() const { return text_input_host_.get(); }
+
   // A NSWindow that is guaranteed to exist in this process. If the bridge
   // object for this host is in this process, then this points to the bridge's
   // NSWindow. Otherwise, it mirrors the id and bounds of the child window.
@@ -205,6 +208,8 @@
   static NSView* GetGlobalCaptureView();
 
  private:
+  friend class TextInputHost;
+
   void UpdateCompositorProperties();
   void DestroyCompositor();
   void RankNSViewsRecursive(View* view, std::map<NSView*, int>* rank) const;
@@ -225,6 +230,8 @@
                  gfx::Point* baseline_point) override;
   double SheetPositionY() override;
   views_bridge_mac::DragDropClient* GetDragDropClient() override;
+  ui::TextInputClient* GetTextInputClient() override;
+  void GetHasInputContext(bool* has_text_input_context) override;
 
   // BridgeFactoryHost::Observer:
   void OnBridgeFactoryHostDestroying(BridgeFactoryHost* host) override;
@@ -374,7 +381,10 @@
 
   // The id that may be used to look up the NSView for |root_view_|.
   const uint64_t root_view_id_;
-  views::View* root_view_ = nullptr;  // Weak. Owned by |native_widget_mac_|.
+
+  // Weak. Owned by |native_widget_mac_|.
+  views::View* root_view_ = nullptr;
+
   std::unique_ptr<DragDropClientMac> drag_drop_client_;
 
   // The mojo pointer to a BridgedNativeWidget, which may exist in another
@@ -401,6 +411,7 @@
 
   std::unique_ptr<TooltipManager> tooltip_manager_;
   std::unique_ptr<ui::InputMethod> input_method_;
+  std::unique_ptr<TextInputHost> text_input_host_;
   FocusManager* focus_manager_ = nullptr;  // Weak. Owned by our Widget.
 
   base::string16 window_title_;
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.mm b/ui/views/cocoa/bridged_native_widget_host_impl.mm
index 7e0af7a..4319ee1 100644
--- a/ui/views/cocoa/bridged_native_widget_host_impl.mm
+++ b/ui/views/cocoa/bridged_native_widget_host_impl.mm
@@ -17,6 +17,7 @@
 #include "ui/gfx/geometry/dip_util.h"
 #include "ui/gfx/mac/coordinate_conversion.h"
 #include "ui/native_theme/native_theme_mac.h"
+#include "ui/views/cocoa/text_input_host.h"
 #include "ui/views/cocoa/tooltip_manager_mac.h"
 #include "ui/views/controls/menu/menu_config.h"
 #include "ui/views/controls/menu/menu_controller.h"
@@ -90,6 +91,7 @@
       native_widget_mac_(owner),
       root_view_id_(ui::NSViewIds::GetNewId()),
       accessibility_focus_overrider_(this),
+      text_input_host_(new TextInputHost(this)),
       host_mojo_binding_(this) {
   DCHECK(GetIdToWidgetHostImplMap().find(widget_id_) ==
          GetIdToWidgetHostImplMap().end());
@@ -526,6 +528,10 @@
   return drag_drop_client_.get();
 }
 
+ui::TextInputClient* BridgedNativeWidgetHostImpl::GetTextInputClient() {
+  return text_input_host_->GetTextInputClient();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // BridgedNativeWidgetHostImpl, BridgeFactoryHost::Observer:
 void BridgedNativeWidgetHostImpl::OnBridgeFactoryHostDestroying(
@@ -1129,16 +1135,19 @@
                                                    View* focused_now) {
   ui::InputMethod* input_method =
       native_widget_mac_->GetWidget()->GetInputMethod();
-  if (input_method) {
-    ui::TextInputClient* input_client = input_method->GetTextInputClient();
-    // Sanity check: When focus moves away from the widget (i.e. |focused_now|
-    // is nil), then the textInputClient will be cleared.
-    DCHECK(!!focused_now || !input_client);
-    // TODO(ccameron): TextInputClient is not handled across process borders
-    // yet.
-    if (bridge_impl_)
-      bridge_impl_->SetTextInputClient(input_client);
-  }
+  if (!input_method)
+    return;
+
+  ui::TextInputClient* new_text_input_client =
+      input_method->GetTextInputClient();
+  // Sanity check: When focus moves away from the widget (i.e. |focused_now|
+  // is nil), then the textInputClient will be cleared.
+  DCHECK(!!focused_now || !new_text_input_client);
+  text_input_host_->SetTextInputClient(new_text_input_client);
+}
+
+void BridgedNativeWidgetHostImpl::GetHasInputContext(bool* has_input_context) {
+  return text_input_host_->GetHasInputContext(has_input_context);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/cocoa/bridged_native_widget_unittest.mm b/ui/views/cocoa/bridged_native_widget_unittest.mm
index 055bfff..2d9008b 100644
--- a/ui/views/cocoa/bridged_native_widget_unittest.mm
+++ b/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -26,6 +26,7 @@
 #include "ui/events/test/cocoa_test_event_utils.h"
 #import "ui/gfx/mac/coordinate_conversion.h"
 #import "ui/views/cocoa/bridged_native_widget_host_impl.h"
+#import "ui/views/cocoa/text_input_host.h"
 #include "ui/views/controls/textfield/textfield.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
 #include "ui/views/controls/textfield/textfield_model.h"
@@ -550,7 +551,7 @@
   // schedules a task to flash the cursor, so this requires |message_loop_|.
   textfield->RequestFocus();
 
-  [ns_view_ setTextInputClient:textfield];
+  bridge_host()->text_input_host()->SetTextInputClient(textfield);
 
   // Initialize the dummy text view. Initializing this with NSZeroRect causes
   // weird NSTextView behavior on OSX 10.9.
@@ -930,7 +931,7 @@
   EXPECT_FALSE([ns_view_ inputContext]);
   InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT);
   EXPECT_TRUE([ns_view_ inputContext]);
-  [ns_view_ setTextInputClient:nil];
+  bridge_host()->text_input_host()->SetTextInputClient(nullptr);
   EXPECT_FALSE([ns_view_ inputContext]);
   InstallTextField(test_string, ui::TEXT_INPUT_TYPE_NONE);
   EXPECT_FALSE([ns_view_ inputContext]);
@@ -1339,7 +1340,7 @@
 // Test that we don't crash during an action message even if the TextInputClient
 // is nil. Regression test for crbug.com/615745.
 TEST_F(BridgedNativeWidgetTest, NilTextInputClient) {
-  [ns_view_ setTextInputClient:nil];
+  bridge_host()->text_input_host()->SetTextInputClient(nullptr);
   NSMutableArray* selectors = [NSMutableArray array];
   [selectors addObjectsFromArray:kMoveActions];
   [selectors addObjectsFromArray:kSelectActions];
@@ -1751,7 +1752,7 @@
   bool saw_update_windows = false;
   base::RepeatingClosure update_windows_closure = base::BindRepeating(
       [](bool* saw_update_windows, BridgedContentView* view,
-         Textfield* textfield) {
+         BridgedNativeWidgetHostImpl* host, Textfield* textfield) {
         // Ensure updateWindows is not invoked recursively.
         EXPECT_FALSE(*saw_update_windows);
         *saw_update_windows = true;
@@ -1768,7 +1769,7 @@
         // reacting to InsertChar could theoretically do this, but toolkit-views
         // DCHECKs if there is recursive event dispatch, so call
         // setTextInputClient directly.
-        [view setTextInputClient:textfield];
+        host->text_input_host()->SetTextInputClient(textfield);
 
         // Finally simulate what -[NSApp updateWindows] should _actually_ do,
         // which is to update the input context (from the first responder).
@@ -1777,20 +1778,21 @@
         // Now, the |textfield| set above should have been set again.
         EXPECT_TRUE(g_fake_current_input_context);
       },
-      &saw_update_windows, ns_view_, textfield);
+      &saw_update_windows, ns_view_, bridge_host(), textfield);
 
   SetHandleKeyEventCallback(base::BindRepeating(
-      [](int* saw_return_count, BridgedContentView* view, Textfield* textfield,
+      [](int* saw_return_count, BridgedContentView* view,
+         BridgedNativeWidgetHostImpl* host, Textfield* textfield,
          const ui::KeyEvent& event) {
         if (event.key_code() == ui::VKEY_RETURN) {
           *saw_return_count += 1;
           // Simulate Textfield::OnBlur() by clearing the input method.
           // Textfield needs to be in a Widget to do this normally.
-          [view setTextInputClient:nullptr];
+          host->text_input_host()->SetTextInputClient(nullptr);
         }
         return false;
       },
-      &vkey_return_count, ns_view_));
+      &vkey_return_count, ns_view_, bridge_host()));
 
   // Starting text (just insert it).
   [ns_view_ insertText:@"ㅂ" replacementRange:NSMakeRange(NSNotFound, 0)];
diff --git a/ui/views/cocoa/text_input_host.h b/ui/views/cocoa/text_input_host.h
new file mode 100644
index 0000000..7af58f8a
--- /dev/null
+++ b/ui/views/cocoa/text_input_host.h
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_COCOA_TEXT_INPUT_HOST_H_
+#define UI_VIEWS_COCOA_TEXT_INPUT_HOST_H_
+
+#include "base/macros.h"
+#include "ui/views/views_export.h"
+
+namespace ui {
+class TextInputClient;
+}  // namespace ui
+
+namespace views {
+
+class BridgedNativeWidgetHostImpl;
+
+class VIEWS_EXPORT TextInputHost {
+ public:
+  TextInputHost(BridgedNativeWidgetHostImpl* host_impl);
+  ~TextInputHost();
+
+  // Set the current TextInputClient.
+  void SetTextInputClient(ui::TextInputClient* new_text_input_client);
+
+  // Return true if -[NSView inputContext] should return a non-nil value.
+  void GetHasInputContext(bool* has_input_context);
+
+  // Return a pointer to the host's ui::TextInputClient.
+  // TODO(ccameron): Remove the need for this call.
+  ui::TextInputClient* GetTextInputClient() const;
+
+ private:
+  // Weak. If non-null the TextInputClient of the currently focused views::View
+  // in the hierarchy rooted at the root view of |host_impl_|. Owned by the
+  // focused views::View.
+  ui::TextInputClient* text_input_client_ = nullptr;
+
+  // The TextInputClient about to be set. Requests for a new -inputContext will
+  // use this, but while the input is changing the NSView still needs to service
+  // IME requests using the old |text_input_client_|.
+  ui::TextInputClient* pending_text_input_client_ = nullptr;
+
+  BridgedNativeWidgetHostImpl* const host_impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(TextInputHost);
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_COCOA_TEXT_INPUT_HOST_H_
diff --git a/ui/views/cocoa/text_input_host.mm b/ui/views/cocoa/text_input_host.mm
new file mode 100644
index 0000000..11f7b68
--- /dev/null
+++ b/ui/views/cocoa/text_input_host.mm
@@ -0,0 +1,90 @@
+// 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 "ui/views/cocoa/text_input_host.h"
+
+#include "ui/base/ime/text_input_client.h"
+#include "ui/views/cocoa/bridged_native_widget_host_impl.h"
+#include "ui/views_bridge_mac/bridged_native_widget_impl.h"
+
+namespace views {
+
+TextInputHost::TextInputHost(BridgedNativeWidgetHostImpl* host_impl)
+    : host_impl_(host_impl) {}
+
+TextInputHost::~TextInputHost() {}
+
+ui::TextInputClient* TextInputHost::GetTextInputClient() const {
+  return text_input_client_;
+}
+
+void TextInputHost::SetTextInputClient(
+    ui::TextInputClient* new_text_input_client) {
+  if (pending_text_input_client_ == new_text_input_client)
+    return;
+
+  // This method may cause the IME window to dismiss, which may cause it to
+  // insert text (e.g. to replace marked text with "real" text). That should
+  // happen in the old -inputContext (which AppKit stores a reference to).
+  // Unfortunately, the only way to invalidate the the old -inputContext is to
+  // invoke -[NSApp updateWindows], which also wants a reference to the _new_
+  // -inputContext. So put the new inputContext in |pendingTextInputClient_| and
+  // only use it for -inputContext.
+  ui::TextInputClient* old_text_input_client = text_input_client_;
+
+  // Since dismissing an IME may insert text, a misbehaving IME or a
+  // ui::TextInputClient that acts on InsertChar() to change focus a second time
+  // may invoke -setTextInputClient: recursively; with [NSApp updateWindows]
+  // still on the stack. Calling [NSApp updateWindows] recursively may upset
+  // an IME. Since the rest of this method is only to decide whether to call
+  // updateWindows, and we're already calling it, just bail out.
+  if (text_input_client_ != pending_text_input_client_) {
+    pending_text_input_client_ = new_text_input_client;
+    return;
+  }
+
+  // Start by assuming no need to invoke -updateWindows.
+  text_input_client_ = new_text_input_client;
+  pending_text_input_client_ = new_text_input_client;
+
+  if (host_impl_->bridge_impl_ &&
+      host_impl_->bridge_impl_->NeedsUpdateWindows()) {
+    text_input_client_ = old_text_input_client;
+    [NSApp updateWindows];
+    // Note: |pending_text_input_client_| (and therefore +[NSTextInputContext
+    // currentInputContext] may have changed if called recursively.
+    text_input_client_ = pending_text_input_client_;
+  }
+}
+
+void TextInputHost::GetHasInputContext(bool* has_input_context) {
+  *has_input_context = false;
+
+  // If the textInputClient_ does not exist, return nil since this view does not
+  // conform to NSTextInputClient protocol.
+  if (!pending_text_input_client_)
+    return;
+
+  // If a menu is active, and -[NSView interpretKeyEvents:] asks for the
+  // input context, return nil. This ensures the action message is sent to
+  // the view, rather than any NSTextInputClient a subview has installed.
+  bool has_menu_controller = false;
+  host_impl_->GetHasMenuController(&has_menu_controller);
+  if (has_menu_controller)
+    return;
+
+  // When not in an editable mode, or while entering passwords
+  // (http://crbug.com/23219), we don't want to show IME candidate windows.
+  // Returning nil prevents this view from getting messages defined as part of
+  // the NSTextInputClient protocol.
+  switch (pending_text_input_client_->GetTextInputType()) {
+    case ui::TEXT_INPUT_TYPE_NONE:
+    case ui::TEXT_INPUT_TYPE_PASSWORD:
+      return;
+    default:
+      *has_input_context = true;
+  }
+}
+
+}  // namespace views
diff --git a/ui/views_bridge_mac/bridge_factory_impl.mm b/ui/views_bridge_mac/bridge_factory_impl.mm
index c939c56..6ddab334 100644
--- a/ui/views_bridge_mac/bridge_factory_impl.mm
+++ b/ui/views_bridge_mac/bridge_factory_impl.mm
@@ -77,6 +77,13 @@
     // Drag-drop only doesn't work across mojo yet.
     return nullptr;
   }
+  ui::TextInputClient* GetTextInputClient() override {
+    // Text input doesn't work across mojo yet.
+    return nullptr;
+  }
+  void GetHasInputContext(bool* has_input_context) override {
+    *has_input_context = false;
+  }
 
   mojom::BridgedNativeWidgetHostAssociatedPtr host_ptr_;
   std::unique_ptr<BridgedNativeWidgetImpl> bridge_impl_;
diff --git a/ui/views_bridge_mac/bridged_content_view.h b/ui/views_bridge_mac/bridged_content_view.h
index b10f06b..7c096dd 100644
--- a/ui/views_bridge_mac/bridged_content_view.h
+++ b/ui/views_bridge_mac/bridged_content_view.h
@@ -32,17 +32,6 @@
   // Weak, reset by clearView.
   views::BridgedNativeWidgetImpl* bridge_;
 
-  // Weak. If non-null the TextInputClient of the currently focused View in the
-  // hierarchy rooted at |hostedView_|. Owned by the focused View.
-  // TODO(ccameron): Remove this member.
-  ui::TextInputClient* textInputClient_;
-
-  // The TextInputClient about to be set. Requests for a new -inputContext will
-  // use this, but while the input is changing, |self| still needs to service
-  // IME requests using the old |textInputClient_|.
-  // TODO(ccameron): Remove this member.
-  ui::TextInputClient* pendingTextInputClient_;
-
   // A tracking area installed to enable mouseMoved events.
   ui::ScopedCrTrackingArea cursorTrackingArea_;
 
@@ -62,7 +51,6 @@
 }
 
 @property(readonly, nonatomic) views::BridgedNativeWidgetImpl* bridge;
-@property(assign, nonatomic) ui::TextInputClient* textInputClient;
 @property(assign, nonatomic) BOOL drawMenuBackgroundForBlur;
 
 // Initialize the NSView -> views::View bridge. |viewToHost| must be non-NULL.
@@ -85,6 +73,14 @@
 // or not.
 - (void)updateFullKeyboardAccess;
 
+// The TextInputClient of the currently focused views::View.
+// TODO(ccameron): This cannot be relied on across processes.
+- (ui::TextInputClient*)textInputClient;
+
+// Returns true if it is needed to call -[NSApp updateWindows] while updating
+// the text input client.
+- (bool)needsUpdateWindows;
+
 @end
 
 #endif  // UI_VIEWS_BRIDGE_MAC_BRIDGED_CONTENT_VIEW_H_
diff --git a/ui/views_bridge_mac/bridged_content_view.mm b/ui/views_bridge_mac/bridged_content_view.mm
index 08f50f84..694fbeb 100644
--- a/ui/views_bridge_mac/bridged_content_view.mm
+++ b/ui/views_bridge_mac/bridged_content_view.mm
@@ -270,7 +270,6 @@
 @implementation BridgedContentView
 
 @synthesize bridge = bridge_;
-@synthesize textInputClient = textInputClient_;
 @synthesize drawMenuBackgroundForBlur = drawMenuBackgroundForBlur_;
 
 - (instancetype)initWithBridge:(views::BridgedNativeWidgetImpl*)bridge
@@ -309,6 +308,10 @@
   return self;
 }
 
+- (ui::TextInputClient*)textInputClient {
+  return bridge_ ? bridge_->host_helper()->GetTextInputClient() : nullptr;
+}
+
 - (void)dealloc {
   // By the time |self| is dealloc'd, it should never be in an NSWindow, and it
   // should never be the current input context.
@@ -320,41 +323,13 @@
 }
 
 - (void)clearView {
-  [self setTextInputClient:nullptr];
   bridge_ = nullptr;
   [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
   [cursorTrackingArea_.get() clearOwner];
   [self removeTrackingArea:cursorTrackingArea_.get()];
 }
 
-- (void)setTextInputClient:(ui::TextInputClient*)newTextInputClient {
-  if (pendingTextInputClient_ == newTextInputClient)
-    return;
-
-  // This method may cause the IME window to dismiss, which may cause it to
-  // insert text (e.g. to replace marked text with "real" text). That should
-  // happen in the old -inputContext (which AppKit stores a reference to).
-  // Unfortunately, the only way to invalidate the the old -inputContext is to
-  // invoke -[NSApp updateWindows], which also wants a reference to the _new_
-  // -inputContext. So put the new inputContext in |pendingTextInputClient_| and
-  // only use it for -inputContext.
-  ui::TextInputClient* oldInputClient = textInputClient_;
-
-  // Since dismissing an IME may insert text, a misbehaving IME or a
-  // ui::TextInputClient that acts on InsertChar() to change focus a second time
-  // may invoke -setTextInputClient: recursively; with [NSApp updateWindows]
-  // still on the stack. Calling [NSApp updateWindows] recursively may upset
-  // an IME. Since the rest of this method is only to decide whether to call
-  // updateWindows, and we're already calling it, just bail out.
-  if (textInputClient_ != pendingTextInputClient_) {
-    pendingTextInputClient_ = newTextInputClient;
-    return;
-  }
-
-  // Start by assuming no need to invoke -updateWindows.
-  textInputClient_ = newTextInputClient;
-  pendingTextInputClient_ = newTextInputClient;
-
+- (bool)needsUpdateWindows {
   // If |self| was being used for the input context, and would now report a
   // different input context, manually invoke [NSApp updateWindows]. This is
   // necessary because AppKit holds on to a raw pointer to a NSTextInputContext
@@ -365,7 +340,7 @@
   // the inputContext may change before further event processing.
   NSTextInputContext* current = [NSTextInputContext currentInputContext];
   if (!current)
-    return;
+    return false;
 
   NSTextInputContext* newContext = [self inputContext];
   // If the newContext is non-nil, then it can only be [super inputContext]. So
@@ -373,17 +348,10 @@
   // both cases, there's no need to call -updateWindows.
   if (newContext) {
     DCHECK_EQ(newContext, [super inputContext]);
-    return;
+    return false;
   }
 
-  if (current == [super inputContext]) {
-    DCHECK_NE(oldInputClient, textInputClient_);
-    textInputClient_ = oldInputClient;
-    [NSApp updateWindows];
-    // Note: |pendingTextInputClient_| (and therefore +[NSTextInputContext
-    // currentInputContext] may have changed if called recursively.
-    textInputClient_ = pendingTextInputClient_;
-  }
+  return current == [super inputContext];
 }
 
 // If |point| is classified as a draggable background (HTCAPTION), return nil so
@@ -511,8 +479,10 @@
 
   // If there's an active TextInputClient, schedule the editing command to be
   // performed.
-  if (textInputClient_ && textInputClient_->IsTextEditCommandEnabled(command))
-    textInputClient_->SetTextEditCommandForNextKeyEvent(command);
+  if ([self textInputClient] &&
+          [self textInputClient] -> IsTextEditCommandEnabled(command)) {
+    [self textInputClient] -> SetTextEditCommandForNextKeyEvent(command);
+  }
 
   [self dispatchKeyEvent:&event];
 }
@@ -591,7 +561,7 @@
   }
 
   // Forward the |text| to |textInputClient_| if no menu is active.
-  if (textInputClient_ && ![self hasActiveMenuController]) {
+  if ([self textInputClient] && ![self hasActiveMenuController]) {
     // If a single character is inserted by keyDown's call to
     // interpretKeyEvents: then use InsertChar() to allow editing events to be
     // merged. We use ui::VKEY_UNKNOWN as the key code since it's not feasible
@@ -606,11 +576,11 @@
     // |text|. This is because |keyDownEvent_| will correspond to the event that
     // caused the composition text to be confirmed, say, Return key press.
     if (isCharacterEvent) {
-      textInputClient_->InsertChar(
-          ui::KeyEvent([text characterAtIndex:0], ui::VKEY_UNKNOWN,
-                       ui::DomCode::NONE, ui::EF_NONE));
+      [self textInputClient] -> InsertChar(ui::KeyEvent(
+                                 [text characterAtIndex:0], ui::VKEY_UNKNOWN,
+                                 ui::DomCode::NONE, ui::EF_NONE));
     } else {
-      textInputClient_->InsertText(base::SysNSStringToUTF16(text));
+      [self textInputClient] -> InsertText(base::SysNSStringToUTF16(text));
     }
     // Suppress accelerators that may be bound to this key, since it inserted
     // text instead. But note that IME may follow with -insertNewLine:, which
@@ -791,28 +761,11 @@
 }
 
 - (NSTextInputContext*)inputContext {
-  // If the textInputClient_ does not exist, return nil since this view does not
-  // conform to NSTextInputClient protocol.
-  if (!pendingTextInputClient_)
+  if (!bridge_)
     return nil;
-
-  // If a menu is active, and -[NSView interpretKeyEvents:] asks for the
-  // input context, return nil. This ensures the action message is sent to
-  // the view, rather than any NSTextInputClient a subview has installed.
-  if ([self hasActiveMenuController])
-    return nil;
-
-  // When not in an editable mode, or while entering passwords
-  // (http://crbug.com/23219), we don't want to show IME candidate windows.
-  // Returning nil prevents this view from getting messages defined as part of
-  // the NSTextInputClient protocol.
-  switch (pendingTextInputClient_->GetTextInputType()) {
-    case ui::TEXT_INPUT_TYPE_NONE:
-    case ui::TEXT_INPUT_TYPE_PASSWORD:
-      return nil;
-    default:
-      return [super inputContext];
-  }
+  bool has_text_input_context = false;
+  bridge_->host_helper()->GetHasInputContext(&has_text_input_context);
+  return has_text_input_context ? [super inputContext] : nil;
 }
 
 // NSResponder implementation.
@@ -1244,23 +1197,23 @@
 }
 
 - (void)moveToLeftEndOfLine:(id)sender {
-  IsTextRTL(textInputClient_) ? [self moveToEndOfLine:sender]
-                              : [self moveToBeginningOfLine:sender];
+  IsTextRTL([self textInputClient]) ? [self moveToEndOfLine:sender]
+                                    : [self moveToBeginningOfLine:sender];
 }
 
 - (void)moveToRightEndOfLine:(id)sender {
-  IsTextRTL(textInputClient_) ? [self moveToBeginningOfLine:sender]
-                              : [self moveToEndOfLine:sender];
+  IsTextRTL([self textInputClient]) ? [self moveToBeginningOfLine:sender]
+                                    : [self moveToEndOfLine:sender];
 }
 
 - (void)moveToLeftEndOfLineAndModifySelection:(id)sender {
-  IsTextRTL(textInputClient_)
+  IsTextRTL([self textInputClient])
       ? [self moveToEndOfLineAndModifySelection:sender]
       : [self moveToBeginningOfLineAndModifySelection:sender];
 }
 
 - (void)moveToRightEndOfLineAndModifySelection:(id)sender {
-  IsTextRTL(textInputClient_)
+  IsTextRTL([self textInputClient])
       ? [self moveToBeginningOfLineAndModifySelection:sender]
       : [self moveToEndOfLineAndModifySelection:sender];
 }
@@ -1358,8 +1311,9 @@
   BOOL canRead = [returnType isEqualToString:utf8Type];
   // Valid if (sendType, returnType) is either (string, nil), (nil, string),
   // or (string, string).
-  BOOL valid = textInputClient_ && ((canWrite && (canRead || !returnType)) ||
-                                    (canRead && (canWrite || !sendType)));
+  BOOL valid =
+      [self textInputClient] && ((canWrite && (canRead || !returnType)) ||
+                                 (canRead && (canWrite || !sendType)));
   return valid
              ? self
              : [super validRequestorForSendType:sendType returnType:returnType];
@@ -1373,15 +1327,15 @@
   // either for when it is upgraded.
   DCHECK([types containsObject:NSStringPboardType] ||
          [types containsObject:base::mac::CFToNSCast(kUTTypeUTF8PlainText)]);
-  if (!textInputClient_)
+  if (![self textInputClient])
     return NO;
 
   gfx::Range selectionRange;
-  if (!textInputClient_->GetEditableSelectionRange(&selectionRange))
+  if (![self textInputClient] -> GetEditableSelectionRange(&selectionRange))
     return NO;
 
   base::string16 text;
-  textInputClient_->GetTextFromRange(selectionRange, &text);
+  [self textInputClient] -> GetTextFromRange(selectionRange, &text);
   return [pboard writeObjects:@[ base::SysUTF16ToNSString(text) ]];
 }
 
@@ -1395,7 +1349,7 @@
 
 // NSTextInputClient protocol implementation.
 
-// IMPORTANT: Always null-check |textInputClient_|. It can change (or be
+// IMPORTANT: Always null-check |[self textInputClient]|. It can change (or be
 // cleared) in -setTextInputClient:, which requires informing AppKit that the
 // -inputContext has changed and to update its raw pointer. However, the AppKit
 // method which does that may also spin a nested run loop communicating with an
@@ -1414,7 +1368,7 @@
 
   gfx::Range actual_range;
   base::string16 substring = AttributedSubstringForRangeHelper(
-      textInputClient_, gfx::Range(range), &actual_range);
+      [self textInputClient], gfx::Range(range), &actual_range);
   if (actualRange) {
     // To maintain consistency with NSTextView, return range {0,0} for an out of
     // bounds requested range.
@@ -1480,7 +1434,7 @@
 - (NSRect)firstRectForCharacterRange:(NSRange)range
                          actualRange:(NSRangePointer)actualNSRange {
   gfx::Range actualRange;
-  gfx::Rect rect = GetFirstRectForRangeHelper(textInputClient_,
+  gfx::Rect rect = GetFirstRectForRangeHelper([self textInputClient],
                                               gfx::Range(range), &actualRange);
   if (actualNSRange)
     *actualNSRange = actualRange.ToNSRange();
@@ -1488,45 +1442,46 @@
 }
 
 - (BOOL)hasMarkedText {
-  return textInputClient_ && textInputClient_->HasCompositionText();
+  return
+      [self textInputClient] && [self textInputClient] -> HasCompositionText();
 }
 
 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
-  if (!bridge_ || !textInputClient_)
+  if (!bridge_ || ![self textInputClient])
     return;
 
-  textInputClient_->DeleteRange(gfx::Range(replacementRange));
+  [self textInputClient] -> DeleteRange(gfx::Range(replacementRange));
   [self insertTextInternal:text];
 }
 
 - (NSRange)markedRange {
-  if (!textInputClient_)
+  if (![self textInputClient])
     return NSMakeRange(NSNotFound, 0);
 
   gfx::Range range;
-  textInputClient_->GetCompositionTextRange(&range);
+  [self textInputClient] -> GetCompositionTextRange(&range);
   return range.ToNSRange();
 }
 
 - (NSRange)selectedRange {
-  if (!textInputClient_)
+  if (![self textInputClient])
     return NSMakeRange(NSNotFound, 0);
 
   gfx::Range range;
-  textInputClient_->GetEditableSelectionRange(&range);
+  [self textInputClient] -> GetEditableSelectionRange(&range);
   return range.ToNSRange();
 }
 
 - (void)setMarkedText:(id)text
         selectedRange:(NSRange)selectedRange
      replacementRange:(NSRange)replacementRange {
-  if (!textInputClient_)
+  if (![self textInputClient])
     return;
 
   if ([text isKindOfClass:[NSAttributedString class]])
     text = [text string];
 
-  textInputClient_->DeleteRange(gfx::Range(replacementRange));
+  [self textInputClient] -> DeleteRange(gfx::Range(replacementRange));
   ui::CompositionText composition;
   composition.text = base::SysNSStringToUTF16(text);
   composition.selection = gfx::Range(selectedRange);
@@ -1541,15 +1496,15 @@
   composition.ime_text_spans.push_back(
       ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, [text length],
                       ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT));
-  textInputClient_->SetCompositionText(composition);
+  [self textInputClient] -> SetCompositionText(composition);
   hasUnhandledKeyDownEvent_ = NO;
 }
 
 - (void)unmarkText {
-  if (!textInputClient_)
+  if (![self textInputClient])
     return;
 
-  textInputClient_->ConfirmCompositionText();
+  [self textInputClient] -> ConfirmCompositionText();
   hasUnhandledKeyDownEvent_ = NO;
 }
 
@@ -1565,8 +1520,8 @@
   if (command == ui::TextEditCommand::INVALID_COMMAND)
     return NO;
 
-  if (textInputClient_)
-    return textInputClient_->IsTextEditCommandEnabled(command);
+  if ([self textInputClient])
+    return [self textInputClient] -> IsTextEditCommandEnabled(command);
 
   // views::Label does not implement the TextInputClient interface but still
   // needs to intercept the Copy and Select All menu actions.
diff --git a/ui/views_bridge_mac/bridged_native_widget_host_helper.h b/ui/views_bridge_mac/bridged_native_widget_host_helper.h
index 4a7ec49..2d19cbc 100644
--- a/ui/views_bridge_mac/bridged_native_widget_host_helper.h
+++ b/ui/views_bridge_mac/bridged_native_widget_host_helper.h
@@ -13,6 +13,10 @@
 
 @class NSView;
 
+namespace ui {
+class TextInputClient;
+}  // namespace ui
+
 namespace views_bridge_mac {
 
 class DragDropClient;
@@ -57,6 +61,14 @@
   // Return a pointer to host's DragDropClientMac.
   // TODO(ccameron): Drag-drop behavior needs to be implemented over mojo.
   virtual DragDropClient* GetDragDropClient() = 0;
+
+  // Return a pointer to the host's ui::TextInputClient.
+  // TODO(ccameron): Remove the needs for this call.
+  virtual ui::TextInputClient* GetTextInputClient() = 0;
+
+  // Return true if -[NSView inputContext] should return a non-nil value.
+  // TODO(ccameron): Move this function to the mojo interface.
+  virtual void GetHasInputContext(bool* has_input_context) = 0;
 };
 
 }  // namespace views_bridge_mac
diff --git a/ui/views_bridge_mac/bridged_native_widget_impl.h b/ui/views_bridge_mac/bridged_native_widget_impl.h
index 0b3aeee..d4b0f4fd 100644
--- a/ui/views_bridge_mac/bridged_native_widget_impl.h
+++ b/ui/views_bridge_mac/bridged_native_widget_impl.h
@@ -234,9 +234,9 @@
                           const base::string16& characters_ignoring_modifiers,
                           uint32_t key_code) override;
 
-  // TODO(ccameron): This method exists temporarily as we move all direct access
-  // of TextInputClient out of BridgedContentView.
-  void SetTextInputClient(ui::TextInputClient* text_input_client);
+  // Return true if [NSApp updateWindows] needs to be called after updating the
+  // TextInputClient.
+  bool NeedsUpdateWindows();
 
   // Compute the window and content size, and forward them to |host_|. This will
   // update widget and compositor size.
diff --git a/ui/views_bridge_mac/bridged_native_widget_impl.mm b/ui/views_bridge_mac/bridged_native_widget_impl.mm
index 4f3cfd9..fd5540a 100644
--- a/ui/views_bridge_mac/bridged_native_widget_impl.mm
+++ b/ui/views_bridge_mac/bridged_native_widget_impl.mm
@@ -1180,9 +1180,8 @@
   [bridged_view_ updateTooltipIfRequiredAt:point];
 }
 
-void BridgedNativeWidgetImpl::SetTextInputClient(
-    ui::TextInputClient* text_input_client) {
-  [bridged_view_ setTextInputClient:text_input_client];
+bool BridgedNativeWidgetImpl::NeedsUpdateWindows() {
+  return [bridged_view_ needsUpdateWindows];
 }
 
 void BridgedNativeWidgetImpl::RedispatchKeyEvent(