diff --git a/DEPS b/DEPS
index 407780c..c6af233 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,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': '7944756396607cbe7175c402b5ce988049105c63',
+  'skia_revision': '70e3e9adc57d765cbd1e86d8f54145e1b4a564f4',
   # 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': '749daeaba307ba87f63f603228f73a12733ab07c',
+  'v8_revision': 'd3230cfb7f2df6997c76111740cc9f9bf7289423',
   # 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.
@@ -72,7 +72,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '773ae91d0e0b94d35cbd123441f75d3299e4ad62',
+  'boringssl_revision': '3120950b1e27635ee9b9d167052ce11ce9c96fd4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -235,7 +235,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'e69e1db6a0089106915f93d8c30e1840c16893f8', # commit position 18757
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '3a84a8f001f66a85e8d30342528ed28905f5f88b', # commit position 18782
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS
index feb66bdb..ac3b7238 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -887,18 +887,27 @@
     'payments': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/payments'\
                   '|chrome/android/javatests/src/org/chromium/chrome/browser/payments'\
+                  '|chrome/browser/payments'\
+                  '|chrome/browser/ui/views/payments'\
                   '|chrome/test/data/payments'\
                   '|components/payments'\
-                  '|third_party/WebKit/LayoutTests/payments/'\
-                  '|third_party/WebKit/Source/modules/payments'\
-                  '|ios/web/payments/'\
-                  '|ios/web/public/payments/'\
-                  '|ios/chrome/browser/payments/'
+                  '|content/browser/payments'\
+                  '|content/test/data/payments'\
+                  '|ios/chrome/browser/payments'\
+                  '|ios/chrome/browser/ui/payments'\
+                  '|ios/web/payments'\
+                  '|ios/web/public/payments'\
+                  '|third_party/WebKit/LayoutTests/external/wpt/payment-request'\
+                  '|third_party/WebKit/LayoutTests/http/tests/payments'\
+                  '|third_party/WebKit/LayoutTests/payments'\
+                  '|third_party/WebKit/public/platform/modules/payments'\
+                  '|third_party/WebKit/Source/modules/payments'
     },
     'payments_ios': {
-      'filepath': 'ios/web/payments/'\
-                  '|ios/web/public/payments/'\
-                  '|ios/chrome/browser/payments/'
+      'filepath': 'ios/web/payments'\
+                  '|ios/chrome/browser/payments'\
+                  '|ios/chrome/browser/ui/payments'\
+                  '|ios/web/public/payments'
     },
     'pepper_api': {
       'filepath': 'ppapi/api'\
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.cc b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
index bdde48d3..8f7815280 100644
--- a/android_webview/browser/aw_safe_browsing_resource_throttle.cc
+++ b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "components/safe_browsing/base_resource_throttle.h"
 #include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "content/public/common/resource_type.h"
 #include "net/base/net_errors.h"
@@ -37,10 +38,15 @@
     content::ResourceType resource_type,
     scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
     scoped_refptr<AwSafeBrowsingUIManager> ui_manager)
-    : safe_browsing::BaseResourceThrottle(request,
-                                          resource_type,
-                                          database_manager,
-                                          ui_manager),
+    : safe_browsing::BaseResourceThrottle(
+          request,
+          resource_type,
+          safe_browsing::CreateSBThreatTypeSet(
+              {safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
+               safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+               safe_browsing::SB_THREAT_TYPE_URL_UNWANTED}),
+          database_manager,
+          ui_manager),
       request_(request) {}
 
 AwSafeBrowsingResourceThrottle::~AwSafeBrowsingResourceThrottle() {}
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn
index e9b2f3af..f9d6dbf9 100644
--- a/android_webview/test/embedded_test_server/BUILD.gn
+++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -57,6 +57,8 @@
     ":aw_java_test_native_support",
     "//net:test_support",
   ]
+  configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+  configs += [ "//build/config/android:hide_all_but_jni" ]
 }
 
 android_apk("aw_net_test_support_apk") {
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index 664c269..3db6f13 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -110,30 +110,6 @@
 // enables the IME service (i.e. InputMethodMus) instead.
 const char kUseIMEService[] = "use-ime-service";
 
-// Number of recent accelerometer samples to examine to determine if a power
-// button event was spurious.
-const char kSpuriousPowerButtonWindow[] = "spurious-power-button-window";
-
-// Number of recent acceleration samples that must meet or exceed the threshold
-// in order for a power button event to be considered spurious.
-const char kSpuriousPowerButtonAccelCount[] =
-    "spurious-power-button-accel-count";
-
-// Threshold (in m/s^2, disregarding gravity) that screen acceleration must meet
-// or exceed for a power button event to be considered spurious.
-const char kSpuriousPowerButtonScreenAccel[] =
-    "spurious-power-button-screen-accel";
-
-// Threshold (in m/s^2, disregarding gravity) that keyboard acceleration must
-// meet or exceed for a power button event to be considered spurious.
-const char kSpuriousPowerButtonKeyboardAccel[] =
-    "spurious-power-button-keyboard-accel";
-
-// Change in lid angle (i.e. hinge between keyboard and screen) that must be
-// exceeded for a power button event to be considered spurious.
-const char kSpuriousPowerButtonLidAngleChange[] =
-    "spurious-power-button-lid-angle-change";
-
 // Constrains the pointer movement within a root window on desktop.
 bool ConstrainPointerToRoot() {
   const char kAshConstrainPointerToRoot[] = "ash-constrain-pointer-to-root";
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 66f8266..e3e7337 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -47,11 +47,6 @@
 ASH_EXPORT extern const char kAshShelfColorSchemeDarkVibrant[];
 ASH_EXPORT extern const char kAshTouchHud[];
 ASH_EXPORT extern const char kAuraLegacyPowerButton[];
-ASH_EXPORT extern const char kSpuriousPowerButtonWindow[];
-ASH_EXPORT extern const char kSpuriousPowerButtonAccelCount[];
-ASH_EXPORT extern const char kSpuriousPowerButtonScreenAccel[];
-ASH_EXPORT extern const char kSpuriousPowerButtonKeyboardAccel[];
-ASH_EXPORT extern const char kSpuriousPowerButtonLidAngleChange[];
 ASH_EXPORT extern const char kUseIMEService[];
 
 // True if the pointer (cursor) position should be kept inside root windows.
diff --git a/ash/system/power/tablet_power_button_controller.cc b/ash/system/power/tablet_power_button_controller.cc
index fafda54..0f8dea77 100644
--- a/ash/system/power/tablet_power_button_controller.cc
+++ b/ash/system/power/tablet_power_button_controller.cc
@@ -5,19 +5,13 @@
 #include "ash/system/power/tablet_power_button_controller.h"
 
 #include "ash/accessibility_delegate.h"
-#include "ash/ash_switches.h"
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
 #include "base/time/default_tick_clock.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "ui/chromeos/accelerometer/accelerometer_util.h"
 #include "ui/events/devices/input_device_manager.h"
 #include "ui/events/devices/stylus_state.h"
 #include "ui/events/event.h"
@@ -61,36 +55,6 @@
          maximize_mode_controller->IsMaximizeModeWindowManagerEnabled();
 }
 
-// Returns the value for the command-line switch identified by |name|. Returns 0
-// if the switch was unset or contained a non-float value.
-double GetNumSwitch(const base::CommandLine& command_line,
-                    const std::string& name) {
-  std::string str = command_line.GetSwitchValueASCII(name);
-  if (str.empty())
-    return 0.0;
-
-  double value = 0.0;
-  if (!base::StringToDouble(str, &value)) {
-    LOG(WARNING) << "Failed to parse value \"" << str << "\" from switch "
-                 << "--" << name << " as float";
-    return 0.0;
-  }
-  return value;
-}
-
-// Computes the lid angle based on readings from accelerometers in the screen
-// and keyboard panels.
-float GetLidAngle(const gfx::Vector3dF& screen,
-                  const gfx::Vector3dF& keyboard) {
-  constexpr gfx::Vector3dF kHingeVector(1.0f, 0.0f, 0.0f);
-  float lid_angle = 180.0f - gfx::ClockwiseAngleBetweenVectorsInDegrees(
-                                 keyboard, screen, kHingeVector);
-  if (lid_angle < 0.0f)
-    lid_angle += 360.0f;
-
-  return lid_angle;
-}
-
 }  // namespace
 
 TabletPowerButtonController::TestApi::TestApi(
@@ -109,26 +73,10 @@
   controller_->shutdown_timer_.Stop();
 }
 
-bool TabletPowerButtonController::TestApi::IsObservingAccelerometerReader(
-    chromeos::AccelerometerReader* reader) const {
-  DCHECK(reader);
-  return controller_->accelerometer_scoped_observer_.IsObserving(reader);
-}
-
-void TabletPowerButtonController::TestApi::ParseSpuriousPowerButtonSwitches(
-    const base::CommandLine& command_line) {
-  controller_->ParseSpuriousPowerButtonSwitches(command_line);
-}
-
-bool TabletPowerButtonController::TestApi::IsSpuriousPowerButtonEvent() const {
-  return controller_->IsSpuriousPowerButtonEvent();
-}
-
 TabletPowerButtonController::TabletPowerButtonController(
     LockStateController* controller)
     : tick_clock_(new base::DefaultTickClock()),
       controller_(controller),
-      accelerometer_scoped_observer_(this),
       weak_ptr_factory_(this) {
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
       this);
@@ -139,7 +87,6 @@
     ui::InputDeviceManager::GetInstance()->AddObserver(this);
   Shell::Get()->PrependPreTargetHandler(this);
 
-  ParseSpuriousPowerButtonSwitches(*base::CommandLine::ForCurrentProcess());
   GetInitialBacklightsForcedOff();
 }
 
@@ -160,11 +107,6 @@
     bool down,
     const base::TimeTicks& timestamp) {
   if (down) {
-    if ((power_button_down_was_spurious_ = IsSpuriousPowerButtonEvent())) {
-      LOG(WARNING) << "Ignoring spurious power button down event";
-      return;
-    }
-
     force_off_on_button_up_ = true;
     // When the system resumes in response to the power button being pressed,
     // Chrome receives powerd's SuspendDone signal and notification that the
@@ -179,10 +121,6 @@
     SetDisplayForcedOff(false);
     StartShutdownTimer();
   } else {
-    // Don't process the up event if we previously ignored the down event.
-    if (power_button_down_was_spurious_)
-      return;
-
     // When power button is released, cancel shutdown animation whenever it is
     // still cancellable.
     if (controller_->CanCancelShutdownAnimation())
@@ -207,25 +145,6 @@
   }
 }
 
-void TabletPowerButtonController::OnAccelerometerUpdated(
-    scoped_refptr<const chromeos::AccelerometerUpdate> update) {
-  const gfx::Vector3dF screen = ui::ConvertAccelerometerReadingToVector3dF(
-      update->get(chromeos::ACCELEROMETER_SOURCE_SCREEN));
-  const gfx::Vector3dF keyboard = ui::ConvertAccelerometerReadingToVector3dF(
-      update->get(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD));
-
-  DCHECK_GT(max_accelerometer_samples_, 0u);
-  if (accelerometer_samples_.size() < max_accelerometer_samples_) {
-    accelerometer_samples_.push_back(std::make_pair(screen, keyboard));
-    last_accelerometer_sample_index_ = accelerometer_samples_.size() - 1;
-  } else {
-    last_accelerometer_sample_index_ =
-        (last_accelerometer_sample_index_ + 1) % max_accelerometer_samples_;
-    accelerometer_samples_[last_accelerometer_sample_index_] =
-        std::make_pair(screen, keyboard);
-  }
-}
-
 void TabletPowerButtonController::PowerManagerRestarted() {
   chromeos::DBusThreadManager::Get()
       ->GetPowerManagerClient()
@@ -294,114 +213,6 @@
   tick_clock_ = std::move(tick_clock);
 }
 
-void TabletPowerButtonController::ParseSpuriousPowerButtonSwitches(
-    const base::CommandLine& command_line) {
-  // Support being called multiple times from tests.
-  max_accelerometer_samples_ = 0;
-  accelerometer_samples_.clear();
-  accelerometer_scoped_observer_.RemoveAll();
-
-  int window = static_cast<int>(
-      GetNumSwitch(command_line, switches::kSpuriousPowerButtonWindow));
-  if (window <= 0)
-    return;
-
-  max_accelerometer_samples_ = static_cast<size_t>(window);
-  accelerometer_samples_.reserve(max_accelerometer_samples_);
-  accelerometer_scoped_observer_.Add(
-      chromeos::AccelerometerReader::GetInstance());
-
-  spurious_accel_count_ = static_cast<size_t>(
-      GetNumSwitch(command_line, switches::kSpuriousPowerButtonAccelCount));
-  spurious_screen_accel_ =
-      GetNumSwitch(command_line, switches::kSpuriousPowerButtonScreenAccel);
-  spurious_keyboard_accel_ =
-      GetNumSwitch(command_line, switches::kSpuriousPowerButtonKeyboardAccel);
-  spurious_lid_angle_change_ =
-      GetNumSwitch(command_line, switches::kSpuriousPowerButtonLidAngleChange);
-}
-
-bool TabletPowerButtonController::IsSpuriousPowerButtonEvent() const {
-  if (max_accelerometer_samples_ <= 0)
-    return false;
-
-  // Number of screen and keyboard accelerations exceeding the threshold.
-  size_t num_big_screen_accels = 0;
-  size_t num_big_keyboard_accels = 0;
-
-  // The last lid angle that we saw.
-  float last_angle = 0.0f;
-  // The current distance (in degrees) that we've traveled from the starting
-  // angle and the max distance that we've seen so far.
-  float cur_angle_dist = 0.0f, max_angle_dist = 0.0f;
-
-  std::string screen_debug, keyboard_debug, angle_debug;
-
-  // Get the index of the oldest pair of samples.
-  const size_t start =
-      accelerometer_samples_.size() == max_accelerometer_samples_
-          ? (last_accelerometer_sample_index_ + 1) % max_accelerometer_samples_
-          : 0;
-  for (size_t i = 0; i < accelerometer_samples_.size(); ++i) {
-    const auto& pair =
-        accelerometer_samples_[(start + i) % max_accelerometer_samples_];
-    const gfx::Vector3dF& screen = pair.first;
-    const gfx::Vector3dF& keyboard = pair.second;
-
-    const float screen_accel = std::abs(screen.Length() - kGravity);
-    if (spurious_screen_accel_ > 0 && screen_accel >= spurious_screen_accel_)
-      num_big_screen_accels++;
-
-    const float keyboard_accel = std::abs(keyboard.Length() - kGravity);
-    if (spurious_keyboard_accel_ > 0 &&
-        keyboard_accel >= spurious_keyboard_accel_) {
-      num_big_keyboard_accels++;
-    }
-
-    float angle = GetLidAngle(screen, keyboard);
-    if (i > 0u) {
-      // Lid angle readings are computed based on the screen and keyboard
-      // acceleration vectors and can be noisy. Compute the minimum angle
-      // difference between the previous reading and the current one and use it
-      // to maintain a running total of how far the lid has traveled, also
-      // keeping track of the max distance from the start that we've seen.
-      float min_diff = angle - last_angle;
-      if (min_diff < -180.0f)
-        min_diff += 360.0f;
-      else if (min_diff > 180.0f)
-        min_diff -= 360.0f;
-
-      cur_angle_dist += min_diff;
-      max_angle_dist =
-          std::min(std::max(max_angle_dist, std::abs(cur_angle_dist)), 360.0f);
-    }
-    last_angle = angle;
-
-    if (VLOG_IS_ON(1)) {
-      screen_debug = base::StringPrintf("%0.1f", screen_accel) +
-                     (screen_debug.empty() ? "" : " " + screen_debug);
-      keyboard_debug = base::StringPrintf("%0.1f", keyboard_accel) +
-                       (keyboard_debug.empty() ? "" : " " + keyboard_debug);
-      angle_debug = base::IntToString(static_cast<int>(angle + 0.5)) +
-                    (angle_debug.empty() ? "" : " " + angle_debug);
-    }
-  }
-
-  VLOG(1) << "Screen accelerations (" << num_big_screen_accels << " big): "
-          << "[" << screen_debug << "]";
-  VLOG(1) << "Keyboard accelerations (" << num_big_keyboard_accels << " big): "
-          << "[" << keyboard_debug << "]";
-  VLOG(1) << "Lid angles (" << base::StringPrintf("%0.1f", max_angle_dist)
-          << " degrees): [" << angle_debug << "]";
-
-  return (spurious_screen_accel_ > 0 &&
-          num_big_screen_accels >= spurious_accel_count_) ||
-         (spurious_keyboard_accel_ > 0 &&
-          num_big_keyboard_accels >= spurious_accel_count_) ||
-         (spurious_lid_angle_change_ > 0 &&
-          max_angle_dist >= spurious_lid_angle_change_);
-}
-
 void TabletPowerButtonController::SetDisplayForcedOff(bool forced_off) {
   if (backlights_forced_off_ == forced_off)
     return;
diff --git a/ash/system/power/tablet_power_button_controller.h b/ash/system/power/tablet_power_button_controller.h
index ab89f72..69d32cc1 100644
--- a/ash/system/power/tablet_power_button_controller.h
+++ b/ash/system/power/tablet_power_button_controller.h
@@ -6,26 +6,17 @@
 #define ASH_SYSTEM_POWER_TABLET_POWER_BUTTON_CONTROLLER_H_
 
 #include <memory>
-#include <utility>
 
 #include "ash/ash_export.h"
 #include "ash/shell_observer.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/scoped_observer.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chromeos/accelerometer/accelerometer_reader.h"
-#include "chromeos/accelerometer/accelerometer_types.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "ui/events/devices/input_device_event_observer.h"
 #include "ui/events/event_handler.h"
-#include "ui/gfx/geometry/vector3d_f.h"
-
-namespace base {
-class CommandLine;
-}  // namespace base
 
 namespace ash {
 
@@ -34,8 +25,7 @@
 // Handles power button events on convertible/tablet device. This class is
 // instantiated and used in PowerButtonController.
 class ASH_EXPORT TabletPowerButtonController
-    : public chromeos::AccelerometerReader::Observer,
-      public chromeos::PowerManagerClient::Observer,
+    : public chromeos::PowerManagerClient::Observer,
       public ShellObserver,
       public ui::EventHandler,
       public ui::InputDeviceEventObserver {
@@ -52,26 +42,12 @@
     // Emulates |shutdown_timer_| timeout.
     void TriggerShutdownTimeout();
 
-    // Returns true if |controller_| is observing |reader|.
-    bool IsObservingAccelerometerReader(
-        chromeos::AccelerometerReader* reader) const;
-
-    // Calls |controller_|'s ParseSpuriousPowerButtonSwitches() method.
-    void ParseSpuriousPowerButtonSwitches(
-        const base::CommandLine& command_line);
-
-    // Calls |controller_|'s IsSpuriousPowerButtonEvent() method.
-    bool IsSpuriousPowerButtonEvent() const;
-
    private:
     TabletPowerButtonController* controller_;  // Not owned.
 
     DISALLOW_COPY_AND_ASSIGN(TestApi);
   };
 
-  // Public for tests.
-  static constexpr float kGravity = 9.80665f;
-
   explicit TabletPowerButtonController(LockStateController* controller);
   ~TabletPowerButtonController() override;
 
@@ -82,10 +58,6 @@
   // Handles a power button event.
   void OnPowerButtonEvent(bool down, const base::TimeTicks& timestamp);
 
-  // Overridden from chromeos::AccelerometerReader::Observer:
-  void OnAccelerometerUpdated(
-      scoped_refptr<const chromeos::AccelerometerUpdate> update) override;
-
   // Overridden from chromeos::PowerManagerClient::Observer:
   void PowerManagerRestarted() override;
   void BrightnessChanged(int level, bool user_initiated) override;
@@ -108,15 +80,6 @@
   void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
 
  private:
-  // Parses command-line switches that provide settings used to attempt to
-  // ignore accidental power button presses by looking at accelerometer data.
-  void ParseSpuriousPowerButtonSwitches(const base::CommandLine& command_line);
-
-  // Returns true if the device's accelerometers have reported enough recent
-  // movement that we should consider a power button event that was just
-  // received to be accidental and ignore it.
-  bool IsSpuriousPowerButtonEvent() const;
-
   // Updates the power manager's backlights-forced-off state and enables or
   // disables the touchscreen. No-op if |backlights_forced_off_| already equals
   // |forced_off|.
@@ -153,10 +116,6 @@
   // True if the screen was off when the power button was pressed.
   bool screen_off_when_power_button_down_ = false;
 
-  // True if the last power button down event was deemed spurious and ignored as
-  // a result.
-  bool power_button_down_was_spurious_ = false;
-
   // Time source for performed action times.
   std::unique_ptr<base::TickClock> tick_clock_;
 
@@ -176,30 +135,6 @@
 
   LockStateController* controller_;  // Not owned.
 
-  ScopedObserver<chromeos::AccelerometerReader, TabletPowerButtonController>
-      accelerometer_scoped_observer_;
-
-  // Number of recent screen and keyboard accelerometer samples to retain.
-  size_t max_accelerometer_samples_ = 0;
-
-  // Circular buffer of recent (screen, keyboard) accelerometer samples.
-  std::vector<std::pair<gfx::Vector3dF, gfx::Vector3dF>> accelerometer_samples_;
-  size_t last_accelerometer_sample_index_ = 0;
-
-  // Number of acceleration readings in |accelerometer_samples_| that must
-  // exceed the threshold in order for a power button event to be considered
-  // spurious.
-  size_t spurious_accel_count_ = 0;
-
-  // Thresholds for screen and keyboard accelerations (excluding gravity). See
-  // |spurious_accel_count_|.
-  float spurious_screen_accel_ = 0;
-  float spurious_keyboard_accel_ = 0;
-
-  // Threshold for the lid angle change seen within |accelerometer_samples_|
-  // in order for a power button event to be considered spurious.
-  float spurious_lid_angle_change_ = 0;
-
   base::WeakPtrFactory<TabletPowerButtonController> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TabletPowerButtonController);
diff --git a/ash/system/power/tablet_power_button_controller_unittest.cc b/ash/system/power/tablet_power_button_controller_unittest.cc
index f3f0ffc..526c9349 100644
--- a/ash/system/power/tablet_power_button_controller_unittest.cc
+++ b/ash/system/power/tablet_power_button_controller_unittest.cc
@@ -35,18 +35,6 @@
 // A non-zero brightness used for test.
 constexpr int kNonZeroBrightness = 10;
 
-// Vector pointing up (e.g. keyboard in clamshell).
-constexpr gfx::Vector3dF kUpVector = {0, 0,
-                                      TabletPowerButtonController::kGravity};
-
-// Vector pointing down (e.g. keyboard in tablet sitting on table).
-constexpr gfx::Vector3dF kDownVector = {0, 0,
-                                        -TabletPowerButtonController::kGravity};
-
-// Vector pointing sideways (e.g. screen in 90-degree clamshell).
-constexpr gfx::Vector3dF kSidewaysVector = {
-    0, TabletPowerButtonController::kGravity, 0};
-
 void CopyResult(bool* dest, bool src) {
   *dest = src;
 }
@@ -69,7 +57,7 @@
     AshTestBase::SetUp();
     // Trigger an accelerometer update so that |tablet_controller_| can be
     // initialized.
-    SendAccelerometerUpdate(kSidewaysVector, kUpVector);
+    SendAccelerometerUpdate();
     tablet_controller_ = Shell::Get()
                              ->power_button_controller()
                              ->tablet_power_button_controller_for_test();
@@ -99,23 +87,11 @@
   }
 
  protected:
-  // Sends an update with screen and keyboard accelerometer readings to
-  // PowerButtonController, and also |tablet_controller_| if it's non-null and
-  // has registered as an observer.
-  void SendAccelerometerUpdate(const gfx::Vector3dF& screen,
-                               const gfx::Vector3dF& keyboard) {
+  void SendAccelerometerUpdate() {
     scoped_refptr<chromeos::AccelerometerUpdate> update(
         new chromeos::AccelerometerUpdate());
-    update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, screen.x(), screen.y(),
-                screen.z());
-    update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, keyboard.x(),
-                keyboard.y(), keyboard.z());
-
+    update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, 1.0f, 0.0f, 0.0f);
     Shell::Get()->power_button_controller()->OnAccelerometerUpdated(update);
-
-    if (test_api_ && test_api_->IsObservingAccelerometerReader(
-                         chromeos::AccelerometerReader::GetInstance()))
-      tablet_controller_->OnAccelerometerUpdated(update);
   }
 
   void PressPowerButton() {
@@ -158,14 +134,14 @@
   }
 
   // Ownership is passed on to chromeos::DBusThreadManager.
-  chromeos::FakePowerManagerClient* power_manager_client_ = nullptr;
+  chromeos::FakePowerManagerClient* power_manager_client_;
 
-  LockStateController* lock_state_controller_ = nullptr;      // Not owned.
-  TabletPowerButtonController* tablet_controller_ = nullptr;  // Not owned.
+  LockStateController* lock_state_controller_;      // Not owned.
+  TabletPowerButtonController* tablet_controller_;  // Not owned.
   std::unique_ptr<TabletPowerButtonController::TestApi> test_api_;
   std::unique_ptr<LockStateControllerTestApi> lock_state_test_api_;
-  base::SimpleTestTickClock* tick_clock_ = nullptr;  // Not owned.
-  TestShellDelegate* shell_delegate_ = nullptr;      // Not owned.
+  base::SimpleTestTickClock* tick_clock_;  // Not owned.
+  TestShellDelegate* shell_delegate_;      // Not owned.
   ui::test::EventGenerator* generator_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(TabletPowerButtonControllerTest);
@@ -554,7 +530,7 @@
   Shell::Get()
       ->power_button_controller()
       ->ResetTabletPowerButtonControllerForTest();
-  SendAccelerometerUpdate(kSidewaysVector, kSidewaysVector);
+  SendAccelerometerUpdate();
 
   // Check that the local state of touchscreen enabled state is in line with
   // backlights forced off state.
@@ -574,91 +550,13 @@
                            ->tablet_power_button_controller_for_test();
   EXPECT_FALSE(tablet_controller_);
 
-  SendAccelerometerUpdate(kSidewaysVector, kSidewaysVector);
+  SendAccelerometerUpdate();
   tablet_controller_ = Shell::Get()
                            ->power_button_controller()
                            ->tablet_power_button_controller_for_test();
   EXPECT_TRUE(tablet_controller_);
 }
 
-TEST_F(TabletPowerButtonControllerTest, IgnoreSpuriousEventsForAcceleration) {
-  base::CommandLine cl(base::CommandLine::NO_PROGRAM);
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonWindow, "3");
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonAccelCount, "2");
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonKeyboardAccel, "4.5");
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonScreenAccel, "8.0");
-  test_api_->ParseSpuriousPowerButtonSwitches(cl);
-  ASSERT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Vectors with varying amounts of acceleration beyond gravity.
-  static constexpr gfx::Vector3dF kVector0 = {
-      0, 0, TabletPowerButtonController::kGravity};
-  static constexpr gfx::Vector3dF kVector3 = {
-      0, 0, TabletPowerButtonController::kGravity + 3};
-  static constexpr gfx::Vector3dF kVector5 = {
-      0, 0, TabletPowerButtonController::kGravity + 5};
-  static constexpr gfx::Vector3dF kVector9 = {
-      0, 0, TabletPowerButtonController::kGravity + 9};
-
-  // Send two keyboard readings with vectors that exceed the threshold after
-  // subtracting gravity.
-  SendAccelerometerUpdate(kVector0, kVector5);
-  SendAccelerometerUpdate(kVector0, kVector9);
-  EXPECT_TRUE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Now send two more keyboard readings that are close to gravity. We only have
-  // one large reading saved now, so we should permit power button events again.
-  SendAccelerometerUpdate(kVector0, kVector0);
-  SendAccelerometerUpdate(kVector0, kVector0);
-  EXPECT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Send a few large screen vectors and check that the button is again blocked.
-  SendAccelerometerUpdate(kVector9, kVector0);
-  SendAccelerometerUpdate(kVector9, kVector0);
-  EXPECT_TRUE(test_api_->IsSpuriousPowerButtonEvent());
-}
-
-TEST_F(TabletPowerButtonControllerTest, IgnoreSpuriousEventsForLidAngle) {
-  base::CommandLine cl(base::CommandLine::NO_PROGRAM);
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonWindow, "5");
-  cl.AppendSwitchASCII(switches::kSpuriousPowerButtonLidAngleChange, "200");
-  test_api_->ParseSpuriousPowerButtonSwitches(cl);
-  ASSERT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Send two updates in tablet mode with the screen facing up and the keyboard
-  // facing down (i.e. 360 degrees between the two).
-  SendAccelerometerUpdate(kUpVector, kDownVector);
-  SendAccelerometerUpdate(kUpVector, kDownVector);
-  EXPECT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Now keep the screen facing up and report the keyboard as being sideways, as
-  // if it's been rotated 90 degrees.
-  SendAccelerometerUpdate(kUpVector, kSidewaysVector);
-  EXPECT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Make the keyboard also face up (180 degrees from start).
-  SendAccelerometerUpdate(kUpVector, kUpVector);
-  EXPECT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Now make the screen face sideways, completing the 270-degree change to
-  // a clamshell orientation. We've exceeded the threshold over the last four
-  // samples, so events should be ignored.
-  SendAccelerometerUpdate(kSidewaysVector, kUpVector);
-  EXPECT_TRUE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // Make the screen travel 90 more degrees so the lid is closed (360 degrees
-  // from start).
-  SendAccelerometerUpdate(kDownVector, kUpVector);
-  EXPECT_TRUE(test_api_->IsSpuriousPowerButtonEvent());
-
-  // After two more closed samples, the 5-sample buffer just contains a
-  // 180-degree transition, so events should be accepted again.
-  SendAccelerometerUpdate(kDownVector, kUpVector);
-  EXPECT_TRUE(test_api_->IsSpuriousPowerButtonEvent());
-  SendAccelerometerUpdate(kDownVector, kUpVector);
-  EXPECT_FALSE(test_api_->IsSpuriousPowerButtonEvent());
-}
-
 // Tests that when backlights get forced off due to tablet power button, media
 // sessions should be suspended.
 TEST_F(TabletPowerButtonControllerTest, SuspendMediaSessions) {
diff --git a/base/android/jni_generator/SampleForTests_jni.golden b/base/android/jni_generator/SampleForTests_jni.golden
index 7b384252..e50583ab 100644
--- a/base/android/jni_generator/SampleForTests_jni.golden
+++ b/base/android/jni_generator/SampleForTests_jni.golden
@@ -482,24 +482,35 @@
     },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsInnerClassSize = arraysize(kMethodsInnerClass);
+}  // namespace android
+}  // namespace base
+
+JNI_REGISTRATION_EXPORT bool
+    RegisterNative_org_chromium_example_jni_1generator_SampleForTests(JNIEnv*
+    env) {
+
+  const int kMethodsInnerClassSize =
+      arraysize(base::android::kMethodsInnerClass);
 
   if (env->RegisterNatives(InnerClass_clazz(env),
-                           kMethodsInnerClass,
+                           base::android::kMethodsInnerClass,
                            kMethodsInnerClassSize) < 0) {
     jni_generator::HandleRegistrationError(
         env, InnerClass_clazz(env), __FILE__);
     return false;
   }
 
-  const int kMethodsSampleForTestsSize = arraysize(kMethodsSampleForTests);
+  const int kMethodsSampleForTestsSize =
+      arraysize(base::android::kMethodsSampleForTests);
 
   if (env->RegisterNatives(SampleForTests_clazz(env),
-                           kMethodsSampleForTests,
+                           base::android::kMethodsSampleForTests,
                            kMethodsSampleForTestsSize) < 0) {
     jni_generator::HandleRegistrationError(
         env, SampleForTests_clazz(env), __FILE__);
@@ -509,7 +520,4 @@
   return true;
 }
 
-}  // namespace android
-}  // namespace base
-
 #endif  // org_chromium_example_jni_generator_SampleForTests_JNI
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 3818009..8249fc9e 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -401,7 +401,7 @@
 
 
 def IsMainDexJavaClass(contents):
-  """Returns "true" if the class is annotated with "@MainDex", "false" if not.
+  """Returns True if the class is annotated with "@MainDex", False if not.
 
   JNI registration doesn't always need to be completed for non-browser processes
   since most Java code is only used by the browser process. Classes that are
@@ -409,8 +409,17 @@
   to force JNI registration.
   """
   re_maindex = re.compile(r'@MainDex[\s\S]*class({|[\s\S]*{)')
-  found = re.search(re_maindex, contents)
-  return 'true' if found else 'false'
+  return bool(re.search(re_maindex, contents))
+
+
+def GetBinaryClassName(fully_qualified_class):
+  """Returns a string concatenating the Java package and class."""
+  return fully_qualified_class.replace('_', '_1').replace('/', '_')
+
+
+def GetRegistrationFunctionName(fully_qualified_class):
+  """Returns the register name with a given class."""
+  return 'RegisterNative_' + GetBinaryClassName(fully_qualified_class)
 
 
 def GetStaticCastForReturnType(return_type):
@@ -620,7 +629,6 @@
           is_constructor=True)]
     self.called_by_natives = MangleCalledByNatives(self.jni_params,
                                                    self.called_by_natives)
-
     self.constant_fields = []
     re_constant_field = re.compile('.*?public static final int (?P<name>.*?);')
     re_constant_field_value = re.compile(
@@ -673,13 +681,12 @@
     jni_namespace = ExtractJNINamespace(contents) or options.namespace
     natives = ExtractNatives(contents, options.ptr_type)
     called_by_natives = ExtractCalledByNatives(self.jni_params, contents)
-    maindex = IsMainDexJavaClass(contents)
     if len(natives) == 0 and len(called_by_natives) == 0:
       raise SyntaxError('Unable to find any JNI methods for %s.' %
                         fully_qualified_class)
     inl_header_file_generator = InlHeaderFileGenerator(
         jni_namespace, fully_qualified_class, natives, called_by_natives, [],
-        self.jni_params, options, maindex)
+        self.jni_params, options)
     self.content = inl_header_file_generator.GetContent()
 
   @classmethod
@@ -715,8 +722,7 @@
   """Generates an inline header file for JNI integration."""
 
   def __init__(self, namespace, fully_qualified_class, natives,
-               called_by_natives, constant_fields, jni_params, options,
-               maindex='false'):
+               called_by_natives, constant_fields, jni_params, options):
     self.namespace = namespace
     self.fully_qualified_class = fully_qualified_class
     self.class_name = self.fully_qualified_class.split('/')[-1]
@@ -724,7 +730,6 @@
     self.called_by_natives = called_by_natives
     self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
     self.constant_fields = constant_fields
-    self.maindex = maindex
     self.jni_params = jni_params
     self.options = options
 
@@ -766,8 +771,9 @@
 
 // Step 3: RegisterNatives.
 $JNI_NATIVE_METHODS
-$REGISTER_NATIVES
+$REGISTER_NATIVES_EMPTY
 $CLOSE_NAMESPACE
+$REGISTER_NATIVES
 
 #endif  // ${HEADER_GUARD}
 """)
@@ -779,8 +785,9 @@
         'METHOD_STUBS': self.GetMethodStubsString(),
         'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
         'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
-        'REGISTER_NATIVES': self.GetRegisterNativesString(),
+        'REGISTER_NATIVES_EMPTY': self.GetOriginalRegisterNativesString(),
         'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
+        'REGISTER_NATIVES': self.GetRegisterNativesString(),
         'HEADER_GUARD': self.header_guard,
         'INCLUDES': self.GetIncludesString(),
     }
@@ -829,14 +836,19 @@
     return '\n'.join(ret)
 
   def SubstituteNativeMethods(self, template):
-    """Substitutes JAVA_CLASS and KMETHODS in the provided template."""
+    """Substitutes NAMESPACE, JAVA_CLASS and KMETHODS in the provided
+    template."""
     ret = []
     all_classes = self.GetUniqueClasses(self.natives)
     all_classes[self.class_name] = self.fully_qualified_class
     for clazz in all_classes:
       kmethods = self.GetKMethodsString(clazz)
+      namespace_str = ''
+      if self.namespace:
+        namespace_str = self.namespace + '::'
       if kmethods:
-        values = {'JAVA_CLASS': clazz,
+        values = {'NAMESPACE': namespace_str,
+                  'JAVA_CLASS': clazz,
                   'KMETHODS': kmethods}
         ret += [template.substitute(values)]
     if not ret: return ''
@@ -853,32 +865,38 @@
 """)
     return self.SubstituteNativeMethods(template)
 
+  # TODO(agrieve): Remove this function when deleting original registers.
+  # https://crbug.com/683256.
+  def GetOriginalRegisterNativesString(self):
+    """Return the code for original RegisterNatives"""
+    natives = self.GetRegisterNativesImplString()
+    if not natives:
+      return ''
+
+    return """
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
+static bool RegisterNativesImpl(JNIEnv* env) {
+  return true;
+}
+"""
+
   def GetRegisterNativesString(self):
     """Returns the code for RegisterNatives."""
     natives = self.GetRegisterNativesImplString()
     if not natives:
       return ''
-
     template = Template("""\
-${REGISTER_NATIVES_SIGNATURE} {
-${EARLY_EXIT}
+JNI_REGISTRATION_EXPORT bool ${REGISTER_NAME}(JNIEnv* env) {
 ${NATIVES}
   return true;
 }
 """)
-    signature = 'static bool RegisterNativesImpl(JNIEnv* env)'
-    early_exit = ''
-    if self.options.native_exports_optional:
-      early_exit = """\
-  if (jni_generator::ShouldSkipJniRegistration(%s))
-    return true;
-""" % self.maindex
-
-    values = {'REGISTER_NATIVES_SIGNATURE': signature,
-              'EARLY_EXIT': early_exit,
-              'NATIVES': natives,
-             }
-
+    values = {
+        'REGISTER_NAME':
+            GetRegistrationFunctionName(self.fully_qualified_class),
+        'NATIVES': natives
+    }
     return template.substitute(values)
 
   def GetRegisterNativesImplString(self):
@@ -887,10 +905,11 @@
       return ''
 
     template = Template("""\
-  const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
+  const int kMethods${JAVA_CLASS}Size =
+      arraysize(${NAMESPACE}kMethods${JAVA_CLASS});
 
   if (env->RegisterNatives(${JAVA_CLASS}_clazz(env),
-                           kMethods${JAVA_CLASS},
+                           ${NAMESPACE}kMethods${JAVA_CLASS},
                            kMethods${JAVA_CLASS}Size) < 0) {
     jni_generator::HandleRegistrationError(
         env, ${JAVA_CLASS}_clazz(env), __FILE__);
@@ -974,7 +993,7 @@
     """
     template = Template("Java_${JAVA_NAME}_native${NAME}")
 
-    java_name = self.fully_qualified_class.replace('_', '_1').replace('/', '_')
+    java_name = GetBinaryClassName(self.fully_qualified_class)
     if native.java_class_name:
       java_name += '_00024' + native.java_class_name
 
@@ -1314,19 +1333,21 @@
     print e
     sys.exit(1)
   if output_file:
-    if not os.path.exists(os.path.dirname(os.path.abspath(output_file))):
-      os.makedirs(os.path.dirname(os.path.abspath(output_file)))
-    if options.optimize_generation and os.path.exists(output_file):
-      with file(output_file, 'r') as f:
-        existing_content = f.read()
-        if existing_content == content:
-          return
-    with file(output_file, 'w') as f:
-      f.write(content)
+    WriteOutput(output_file, content)
   else:
     print content
 
 
+def WriteOutput(output_file, content):
+  if os.path.exists(output_file):
+    with open(output_file) as f:
+      existing_content = f.read()
+      if existing_content == content:
+        return
+  with open(output_file, 'w') as f:
+    f.write(content)
+
+
 def GetScriptName():
   script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
   base_index = 0
@@ -1363,10 +1384,6 @@
   option_parser.add_option('--output_dir',
                            help='The output directory. Must be used with '
                            '--input')
-  option_parser.add_option('--optimize_generation', type="int",
-                           default=0, help='Whether we should optimize JNI '
-                           'generation by not regenerating files if they have '
-                           'not changed.')
   option_parser.add_option('--script_name', default=GetScriptName(),
                            help='The name of this script in the generated '
                            'header.')
diff --git a/base/android/jni_generator/jni_generator_helper.h b/base/android/jni_generator/jni_generator_helper.h
index 3062806..53629a657 100644
--- a/base/android/jni_generator/jni_generator_helper.h
+++ b/base/android/jni_generator/jni_generator_helper.h
@@ -30,6 +30,13 @@
 #define JNI_GENERATOR_EXPORT extern "C" __attribute__((visibility("default")))
 #endif
 
+// Used to export JNI registration functions.
+#if defined(COMPONENT_BUILD)
+#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default")))
+#else
+#define JNI_REGISTRATION_EXPORT
+#endif
+
 namespace jni_generator {
 
 inline void HandleRegistrationError(JNIEnv* env,
@@ -42,12 +49,14 @@
   base::android::CheckException(env);
 }
 
+// TODO(estevenson): Remove this function since all natives are registered
+// together. Currently gvr-android-sdk stil calls it.
+// https://crbug.com/664306.
 inline bool ShouldSkipJniRegistration(bool is_maindex_class) {
   switch (base::android::GetJniRegistrationType()) {
     case base::android::ALL_JNI_REGISTRATION:
       return false;
     case base::android::NO_JNI_REGISTRATION:
-      // TODO(estevenson): Change this to a DCHECK.
       return true;
     case base::android::SELECTIVE_JNI_REGISTRATION:
       return !is_maindex_class;
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index d667a47..41e617f 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -967,33 +967,6 @@
                                              test_options)
     self.assertGoldenTextEquals(h.GetContent())
 
-  def testMainDexFile(self):
-    test_data = """
-    package org.chromium.example.jni_generator;
-
-    @MainDex
-    class Test {
-        private static native int nativeStaticMethod(long nativeTest, int arg1);
-    }
-    """
-    options = TestOptions()
-    jni_from_java = jni_generator.JNIFromJavaSource(
-      test_data, 'org/chromium/foo/Bar', options)
-    self.assertGoldenTextEquals(jni_from_java.GetContent())
-
-  def testNonMainDexFile(self):
-    test_data = """
-    package org.chromium.example.jni_generator;
-
-    class Test {
-        private static native int nativeStaticMethod(long nativeTest, int arg1);
-    }
-    """
-    options = TestOptions()
-    jni_from_java = jni_generator.JNIFromJavaSource(
-      test_data, 'org/chromium/foo/Bar', options)
-    self.assertGoldenTextEquals(jni_from_java.GetContent())
-
   def testMainDexAnnotation(self):
     mainDexEntries = [
       '@MainDex public class Test {',
@@ -1021,7 +994,7 @@
       '@MainDex public class Test extends Testable<java.io.Serializable> {',
     ]
     for entry in mainDexEntries:
-      self.assertEquals("true", IsMainDexJavaClass(entry))
+      self.assertEquals(True, IsMainDexJavaClass(entry))
 
   def testNoMainDexAnnotation(self):
     noMainDexEntries = [
@@ -1031,7 +1004,7 @@
       'public class Test extends BaseTest {'
     ]
     for entry in noMainDexEntries:
-      self.assertEquals("false", IsMainDexJavaClass(entry))
+      self.assertEquals(False, IsMainDexJavaClass(entry))
 
   def testNativeExportsOnlyOption(self):
     test_data = """
diff --git a/base/android/jni_generator/jni_registration_generator.py b/base/android/jni_generator/jni_registration_generator.py
new file mode 100755
index 0000000..febb5b7
--- /dev/null
+++ b/base/android/jni_generator/jni_registration_generator.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generate JNI registration entry points
+
+Creates a header file with two static functions: RegisterMainDexNatives() and
+RegisterNonMainDexNatives(). Together, these will use manual JNI registration
+to register all native methods that exist within an application."""
+
+import argparse
+import jni_generator
+import os
+import string
+import sys
+from util import build_utils
+
+
+def GenerateJNIHeader(java_file_paths, output_file, args):
+  """Generate a header file including two registration functions.
+
+  Forward declares all JNI registration functions created by jni_generator.py.
+  Calls the functions in RegisterMainDexNatives() if they are main dex. And
+  calls them in RegisterNonMainDexNatives() if they are non-main dex.
+
+  Args:
+      java_file_paths: A list of java file paths.
+      output_file: A relative path to output file.
+      args: All input arguments.
+  """
+  registration_dict = {
+      'FORWARD_DECLARATIONS': '',
+      'REGISTER_MAIN_DEX_NATIVES': '',
+      'REGISTER_NON_MAIN_DEX_NATIVES': ''
+  }
+  # Sort the file list to make sure the order is deterministic.
+  java_file_paths.sort()
+  for path in java_file_paths:
+    if path in args.no_register_java:
+      continue
+    with open(path) as f:
+      contents = f.read()
+    natives = jni_generator.ExtractNatives(contents, 'long')
+    if len(natives) == 0:
+      continue
+    fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
+        path, contents)
+    main_dex = jni_generator.IsMainDexJavaClass(contents)
+    header_generator = HeaderGenerator(
+        fully_qualified_class, registration_dict, main_dex)
+    registration_dict = header_generator.GetContent()
+
+  header_content = CreateFromDict(registration_dict)
+  if output_file:
+    jni_generator.WriteOutput(output_file, header_content)
+  else:
+    print header_content
+
+
+def CreateFromDict(registration_dict):
+  """Returns the content of the header file."""
+
+  template = string.Template("""\
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+// This file is autogenerated by
+//     base/android/jni_generator/jni_registration_generator.py
+// Please do not change its content.
+
+#ifndef HEADER_GUARD
+#define HEADER_GUARD
+
+#include <jni.h>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+// Step 1: Forward declaration.
+${FORWARD_DECLARATIONS}
+
+// Step 2: Main dex and non-main dex registration functions.
+
+bool RegisterMainDexNatives(JNIEnv* env) {
+${REGISTER_MAIN_DEX_NATIVES}
+
+  return true;
+}
+
+bool RegisterNonMainDexNatives(JNIEnv* env) {
+${REGISTER_NON_MAIN_DEX_NATIVES}
+
+  return true;
+}
+
+#endif  // HEADER_GUARD
+""")
+  if len(registration_dict['FORWARD_DECLARATIONS']) == 0:
+    return ''
+  return jni_generator.WrapOutput(template.substitute(registration_dict))
+
+
+class HeaderGenerator(object):
+  """Generates an inline header file for JNI registration."""
+
+  def __init__(self, fully_qualified_class, registration_dict, main_dex):
+    self.fully_qualified_class = fully_qualified_class
+    self.class_name = self.fully_qualified_class.split('/')[-1]
+    self.registration_dict = registration_dict
+    self.main_dex = main_dex
+
+  def GetContent(self):
+    self._AddForwardDeclaration()
+    self._AddRegisterNatives()
+    return self.registration_dict
+
+  def _AddForwardDeclaration(self):
+    """Add the content of the forward declaration to the dictionary."""
+    template = string.Template('JNI_REGISTRATION_EXPORT bool ${METHOD_NAME}('
+                               'JNIEnv* env);\n')
+    value = {
+        'METHOD_NAME':
+            jni_generator.GetRegistrationFunctionName(
+                self.fully_qualified_class)
+    }
+    self.registration_dict['FORWARD_DECLARATIONS'] += template.substitute(value)
+
+  def _AddRegisterNatives(self):
+    """Add the body of the RegisterNativesImpl method to the dictionary."""
+    template = string.Template("""
+if (!${REGISTER_NAME}(env))
+  return false;
+""")
+    value = {
+        'REGISTER_NAME':
+            jni_generator.GetRegistrationFunctionName(
+                self.fully_qualified_class)
+    }
+    register_body = template.substitute(value)
+    if self.main_dex:
+      self.registration_dict['REGISTER_MAIN_DEX_NATIVES'] += register_body
+    else:
+      self.registration_dict['REGISTER_NON_MAIN_DEX_NATIVES'] += register_body
+
+
+def main(argv):
+  arg_parser = argparse.ArgumentParser()
+  build_utils.AddDepfileOption(arg_parser)
+
+  arg_parser.add_argument('--sources_files',
+                          help='A list of .sources files which contain Java '
+                          'file paths. Must be used with --output.')
+  arg_parser.add_argument('--output',
+                          help='The output file path.')
+  arg_parser.add_argument('--no_register_java',
+                          help='A list of Java files which should be ignored '
+                          'by the parser.')
+  args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:]))
+  args.sources_files = build_utils.ParseGnList(args.sources_files)
+
+  if args.sources_files:
+    java_file_paths = []
+    for f in args.sources_files:
+      # java_file_paths stores each Java file path as a string.
+      java_file_paths += build_utils.ReadSourcesList(f)
+  else:
+    print '\nError: Must specify --sources_files.'
+    return 1
+  output_file = args.output
+  GenerateJNIHeader(java_file_paths, output_file, args)
+
+  if args.depfile:
+    build_utils.WriteDepfile(args.depfile, output_file)
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/base/android/jni_generator/testInnerClassNatives.golden b/base/android/jni_generator/testInnerClassNatives.golden
index 20b8830..363f916 100644
--- a/base/android/jni_generator/testInnerClassNatives.golden
+++ b/base/android/jni_generator/testInnerClassNatives.golden
@@ -51,11 +51,16 @@
     },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+  const int kMethodsMyInnerClassSize =
+      arraysize(kMethodsMyInnerClass);
 
   if (env->RegisterNatives(MyInnerClass_clazz(env),
                            kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
index 67352e7..6c07b58 100644
--- a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
+++ b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
@@ -67,9 +67,13 @@
 "I", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeInit) },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
+
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
 
   const int kMethodsMyOtherInnerClassSize =
       arraysize(kMethodsMyOtherInnerClass);
@@ -82,7 +86,8 @@
     return false;
   }
 
-  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+  const int kMethodsTestJniSize =
+      arraysize(kMethodsTestJni);
 
   if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
diff --git a/base/android/jni_generator/testInnerClassNativesMultiple.golden b/base/android/jni_generator/testInnerClassNativesMultiple.golden
index 7807efa..add5ac9 100644
--- a/base/android/jni_generator/testInnerClassNativesMultiple.golden
+++ b/base/android/jni_generator/testInnerClassNativesMultiple.golden
@@ -74,9 +74,13 @@
     },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
+
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
 
   const int kMethodsMyOtherInnerClassSize =
       arraysize(kMethodsMyOtherInnerClass);
@@ -89,7 +93,8 @@
     return false;
   }
 
-  const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
+  const int kMethodsMyInnerClassSize =
+      arraysize(kMethodsMyInnerClass);
 
   if (env->RegisterNatives(MyInnerClass_clazz(env),
                            kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testMainDexFile.golden b/base/android/jni_generator/testMainDexFile.golden
deleted file mode 100644
index cbb2a7d..0000000
--- a/base/android/jni_generator/testMainDexFile.golden
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_generator.py
-// For
-//     org/chromium/foo/Bar
-
-#ifndef org_chromium_foo_Bar_JNI
-#define org_chromium_foo_Bar_JNI
-
-#include <jni.h>
-
-#include "base/android/jni_generator/jni_generator_helper.h"
-
-#include "base/android/jni_int_wrapper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kBarClassPath[] = "org/chromium/foo/Bar";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0;
-#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz)
-
-}  // namespace
-
-// Step 2: method stubs.
-JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv*
-    env, jobject jcaller,
-    jlong nativeTest,
-    jint arg1) {
-  Test* native = reinterpret_cast<Test*>(nativeTest);
-  CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0);
-  return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env,
-      jcaller), arg1);
-}
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsBar[] = {
-    { "nativeStaticMethod",
-"("
-"J"
-"I"
-")"
-"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) },
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(true))
-    return true;
-
-  const int kMethodsBarSize = arraysize(kMethodsBar);
-
-  if (env->RegisterNatives(Bar_clazz(env),
-                           kMethodsBar,
-                           kMethodsBarSize) < 0) {
-    jni_generator::HandleRegistrationError(
-        env, Bar_clazz(env), __FILE__);
-    return false;
-  }
-
-  return true;
-}
-
-#endif  // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
index 0eecb5a..03aac48e 100644
--- a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
@@ -75,11 +75,16 @@
 "V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsFooSize = arraysize(kMethodsFoo);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) {
+
+  const int kMethodsFooSize =
+      arraysize(kMethodsFoo);
 
   if (env->RegisterNatives(Foo_clazz(env),
                            kMethodsFoo,
diff --git a/base/android/jni_generator/testNatives.golden b/base/android/jni_generator/testNatives.golden
index 3362c928..0bfbe04 100644
--- a/base/android/jni_generator/testNatives.golden
+++ b/base/android/jni_generator/testNatives.golden
@@ -320,11 +320,16 @@
     },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+  const int kMethodsTestJniSize =
+      arraysize(kMethodsTestJni);
 
   if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
diff --git a/base/android/jni_generator/testNativesLong.golden b/base/android/jni_generator/testNativesLong.golden
index ec029ce3..201a066 100644
--- a/base/android/jni_generator/testNativesLong.golden
+++ b/base/android/jni_generator/testNativesLong.golden
@@ -46,11 +46,16 @@
 "V", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeDestroy) },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+  const int kMethodsTestJniSize =
+      arraysize(kMethodsTestJni);
 
   if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
diff --git a/base/android/jni_generator/testNonMainDexFile.golden b/base/android/jni_generator/testNonMainDexFile.golden
deleted file mode 100644
index 533241e..0000000
--- a/base/android/jni_generator/testNonMainDexFile.golden
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_generator.py
-// For
-//     org/chromium/foo/Bar
-
-#ifndef org_chromium_foo_Bar_JNI
-#define org_chromium_foo_Bar_JNI
-
-#include <jni.h>
-
-#include "base/android/jni_generator/jni_generator_helper.h"
-
-#include "base/android/jni_int_wrapper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kBarClassPath[] = "org/chromium/foo/Bar";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0;
-#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz)
-
-}  // namespace
-
-// Step 2: method stubs.
-JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv*
-    env, jobject jcaller,
-    jlong nativeTest,
-    jint arg1) {
-  Test* native = reinterpret_cast<Test*>(nativeTest);
-  CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0);
-  return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env,
-      jcaller), arg1);
-}
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsBar[] = {
-    { "nativeStaticMethod",
-"("
-"J"
-"I"
-")"
-"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) },
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
-
-  const int kMethodsBarSize = arraysize(kMethodsBar);
-
-  if (env->RegisterNatives(Bar_clazz(env),
-                           kMethodsBar,
-                           kMethodsBarSize) < 0) {
-    jni_generator::HandleRegistrationError(
-        env, Bar_clazz(env), __FILE__);
-    return false;
-  }
-
-  return true;
-}
-
-#endif  // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testSingleJNIAdditionalImport.golden b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
index ef618da8..a367ae7 100644
--- a/base/android/jni_generator/testSingleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
@@ -69,11 +69,16 @@
 "V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) },
 };
 
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
 static bool RegisterNativesImpl(JNIEnv* env) {
-  if (jni_generator::ShouldSkipJniRegistration(false))
-    return true;
+  return true;
+}
 
-  const int kMethodsFooSize = arraysize(kMethodsFoo);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) {
+
+  const int kMethodsFooSize =
+      arraysize(kMethodsFoo);
 
   if (env->RegisterNatives(Foo_clazz(env),
                            kMethodsFoo,
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h
index e1dfd4f..1e35639 100644
--- a/base/task_scheduler/task_scheduler_impl.h
+++ b/base/task_scheduler/task_scheduler_impl.h
@@ -30,10 +30,6 @@
 #include "base/task_scheduler/task_tracker_posix.h"
 #endif
 
-#if defined(OS_WIN)
-#include "base/win/com_init_check_hook.h"
-#endif
-
 namespace base {
 
 class HistogramBase;
@@ -103,15 +99,6 @@
   AtomicFlag join_for_testing_returned_;
 #endif
 
-#if defined(OS_WIN)
-// The check below cannot be &&'ed with defined(OS_WIN) since the preprocessor
-// will find that the macro is undefined even if defined(OS_WIN) is not true.
-#if COM_INIT_CHECK_HOOK_ENABLED()
-  // Provides COM initialization verification for supported builds.
-  base::win::ComInitCheckHook com_init_check_hook_;
-#endif
-#endif
-
   DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImpl);
 };
 
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py
index e7bf827..ba2311a 100755
--- a/build/android/gradle/generate_gradle.py
+++ b/build/android/gradle/generate_gradle.py
@@ -211,7 +211,7 @@
 
   def JavaFiles(self):
     if self._java_files is None:
-      java_sources_file = self.Gradle().get('java_sources_file')
+      java_sources_file = self.DepsInfo().get('java_sources_file')
       java_files = []
       if java_sources_file:
         java_sources_file = _RebasePath(java_sources_file)
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index c085176..6eab4b2 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -413,7 +413,7 @@
     gradle['android_manifest'] = options.android_manifest
   if options.type in ('java_binary', 'java_library', 'android_apk'):
     if options.java_sources_file:
-      gradle['java_sources_file'] = options.java_sources_file
+      deps_info['java_sources_file'] = options.java_sources_file
     if options.bundled_srcjars:
       gradle['bundled_srcjars'] = (
           build_utils.ParseGnList(options.bundled_srcjars))
@@ -436,6 +436,14 @@
         gradle['dependent_java_projects'].append(c['path'])
 
 
+  if options.type == 'android_apk':
+    config['jni'] = {}
+    all_java_sources = [c['java_sources_file'] for c in all_library_deps
+                        if 'java_sources_file' in c]
+    if options.java_sources_file:
+      all_java_sources.append(options.java_sources_file)
+    config['jni']['all_source'] = all_java_sources
+
   if (options.type in ('java_binary', 'java_library')):
     deps_info['requires_android'] = options.requires_android
     deps_info['supports_android'] = options.supports_android
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 38032b768..ceffd063 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -192,7 +192,6 @@
         "--depfile",
         rebase_path(depfile, root_build_dir),
         "--input_file={{source}}",
-        "--optimize_generation=1",
         "--ptr_type=long",
         "--output_dir",
         rebase_path(jni_output_dir, root_build_dir),
@@ -302,7 +301,6 @@
           rebase_path(jar_file, root_build_dir),
           "--input_file",
           class,
-          "--optimize_generation=1",
           "--ptr_type=long",
           "--output_dir",
           rebase_path(jni_output_dir, root_build_dir),
@@ -334,6 +332,61 @@
     }
   }
 
+  # Declare a jni registration target.
+  #
+  # This target generates a header file calling JNI registration functions
+  # created by generate_jni and generate_jar_jni.
+  #
+  # See base/android/jni_generator/jni_registration_generator.py for more info
+  # about the format of the header file.
+  #
+  # Variables
+  #   target: The Apk target to generate registrations for.
+  #   output: Path to the generated .h file.
+  #   exception_files: List of .java files that should be ignored when searching
+  #   for native methods. (optional)
+  #
+  # Example
+  #   generate_jni_registration("chrome_jni_registration") {
+  #     target = ":chrome_public_apk"
+  #     output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+  #     exception_files = [
+  #       "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+  #       "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+  #       "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+  #     ]
+  #   }
+  template("generate_jni_registration") {
+    action(target_name) {
+      forward_variables_from(invoker, [ "testonly" ])
+      _build_config = get_label_info(invoker.target, "target_gen_dir") + "/" +
+                      get_label_info(invoker.target, "name") + ".build_config"
+      _rebased_build_config = rebase_path(_build_config, root_build_dir)
+
+      _rebase_exception_java_files =
+          rebase_path(invoker.exception_files, root_build_dir)
+
+      script = "//base/android/jni_generator/jni_registration_generator.py"
+      deps = [
+        "${invoker.target}__build_config",
+      ]
+      inputs = [
+        _build_config,
+      ]
+      outputs = [
+        invoker.output,
+      ]
+
+      args = [
+        # This is a list of .sources files.
+        "--sources_files=@FileArg($_rebased_build_config:jni:all_source)",
+        "--output",
+        rebase_path(invoker.output, root_build_dir),
+        "--no_register_java=$_rebase_exception_java_files",
+      ]
+    }
+  }
+
   # Declare a target for c-preprocessor-generated java files
   #
   # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 1bb7d1ce..eb5167d 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -681,6 +681,7 @@
     "../browser/android/chrome_entry_point.cc",
   ]
   deps = [
+    ":chrome_jni_registration($default_toolchain)",
     "//build/config:exe_and_shlib_deps",
     "//chrome:chrome_android_core",
   ]
@@ -705,8 +706,30 @@
 }
 
 # Ensure that .pak files are built only once (build them in the default
-# toolchain).
+# toolchain). The central header file calling JNI registration functions
+# is generated from Java code so it just needs to be generated once.
 if (current_toolchain == default_toolchain) {
+  generate_jni_registration("chrome_jni_registration") {
+    target = ":chrome_public_apk"
+    output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+    exception_files = [
+      "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+    ]
+  }
+
+  generate_jni_registration("chrome_sync_shell_jni_registration") {
+    testonly = true
+    target = ":chrome_sync_shell_apk"
+    output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+    exception_files = [
+      "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+    ]
+  }
+
   if (enable_resource_whitelist_generation) {
     generate_resource_whitelist("monochrome_resource_whitelist") {
       # Always use the 32-bit library's whitelist since the 64-bit one is
@@ -802,12 +825,13 @@
 shared_library("chrome_sync_shell") {
   testonly = true
   sources = [
-    "../browser/android/chrome_entry_point.cc",
+    "../browser/android/chrome_sync_shell_entry_point.cc",
     "../browser/android/chrome_sync_shell_main_delegate.cc",
     "../browser/android/chrome_sync_shell_main_delegate.h",
     "../browser/android/chrome_sync_shell_main_delegate_initializer.cc",
   ]
   deps = [
+    ":chrome_sync_shell_jni_registration($default_toolchain)",
     "//build/config:exe_and_shlib_deps",
     "//chrome:chrome_android_core",
     "//components/sync",
@@ -888,6 +912,9 @@
   apk_name = "ChromeSyncShell"
   shared_libraries = [ ":chrome_sync_shell" ]
 
+  # This exists here rather than in chrome_sync_shell_test_apk for JNI
+  # registration to be able to find the native side functions.
+  java_files = [ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java" ]
   deps = [
     ":chrome_sync_shell_apk_template_resources",
 
@@ -895,6 +922,7 @@
     # but that code is stripped out via proguard. Adding this deps adds
     # usages and prevents removal of the proto code.
     "//components/sync:test_support_proto_java",
+    "//third_party/android_protobuf:protobuf_nano_javalib",
   ]
 }
 
@@ -988,11 +1016,23 @@
   }
 }
 
-android_library("chrome_sync_shell_test_apk_java") {
-  testonly = true
-
-  # From java_sources.jni.
-  java_files = sync_shell_test_java_sources
+instrumentation_test_apk("chrome_sync_shell_test_apk") {
+  apk_name = "ChromeSyncShellTest"
+  apk_under_test = ":chrome_sync_shell_apk"
+  android_manifest = chrome_sync_shell_test_apk_manifest
+  android_manifest_dep = ":chrome_sync_shell_test_apk_manifest"
+  java_files = [
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
+    "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java",
+  ]
 
   deps = [
     "//base:base_java",
@@ -1008,21 +1048,9 @@
     "//components/sync/android:sync_java",
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_protobuf:protobuf_nano_javalib",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/android_tools:android_support_v7_appcompat_java",
     "//ui/android:ui_java",
   ]
-}
-
-instrumentation_test_apk("chrome_sync_shell_test_apk") {
-  apk_name = "ChromeSyncShellTest"
-  apk_under_test = ":chrome_sync_shell_apk"
-  android_manifest = chrome_sync_shell_test_apk_manifest
-  android_manifest_dep = ":chrome_sync_shell_test_apk_manifest"
-  deps = [
-    ":chrome_sync_shell_test_apk_java",
-    "//third_party/android_support_test_runner:runner_java",
-  ]
   proguard_enabled = !is_java_debug
 }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 464c9825..4c9366e 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -319,7 +319,9 @@
             android:theme="@style/MainTheme"
             android:exported="false"
             {{ self.chrome_activity_common() }}
-            {{ self.supports_video_persistence() }} >
+            {{ self.supports_video_persistence() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity"
             android:theme="@style/MainTheme"
@@ -328,7 +330,9 @@
             android:persistableMode="persistNever"
             android:autoRemoveFromRecents="false"
             {{ self.chrome_activity_common() }}
-            {{ self.supports_video_persistence() }} >
+            {{ self.supports_video_persistence() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         {% for i in range(10) %}
         <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity{{ i }}"
@@ -339,7 +343,9 @@
             android:persistableMode="persistNever"
             android:taskAffinity=""
             {{ self.chrome_activity_common() }}
-            {{ self.supports_video_persistence() }} >
+            {{ self.supports_video_persistence() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         {% endfor %}
 
@@ -359,7 +365,19 @@
             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode"
             android:hardwareAccelerated="false"
             {% endblock %}
-            >
+        >
+            <!--
+              Daydream api categorizes an activity to three categories: Cardboard only, hybrid
+              or Daydream. It does so by testing if intents can be resolved by the activity
+              that requests it.
+            -->
+            {% block supports_vr %}
+            <intent-filter>
+                <action android:name="org.chromium.chrome.browser.dummy.action" />
+                <category android:name="com.google.intent.category.DAYDREAM" />
+                <category android:name="com.google.intent.category.CARDBOARD" />
+            </intent-filter>
+            {% endblock %}
         </activity>
         <activity android:name="org.chromium.chrome.browser.ChromeTabbedActivity2"
             android:theme="@style/TabbedModeTheme"
@@ -367,7 +385,9 @@
             android:taskAffinity="{{ manifest_package }}.ChromeTabbedActivity2"
             android:launchMode="singleTask"
             {{ self.chrome_activity_common() }}
-            {{ self.supports_video_persistence() }}>
+            {{ self.supports_video_persistence() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         <activity android:name="org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity"
             android:theme="@style/TabbedModeTheme"
@@ -492,7 +512,9 @@
             android:documentLaunchMode="intoExisting"
             android:persistableMode="persistNever"
             {{ self.supports_video_persistence() }}
-            {{ self.chrome_activity_common() }}>
+            {{ self.chrome_activity_common() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         <activity-alias android:name="com.google.android.apps.chrome.webapps.WebappActivity"
             android:targetActivity="org.chromium.chrome.browser.webapps.WebappActivity"
@@ -508,7 +530,9 @@
             android:persistableMode="persistNever"
             android:taskAffinity="{{ manifest_package }}.webapps.WebappActivity{{ i }}"
             {{ self.supports_video_persistence() }}
-            {{ self.chrome_activity_common() }}>
+            {{ self.chrome_activity_common() }}
+        >
+           {{ self.supports_vr() }}
         </activity>
         <activity-alias android:name="com.google.android.apps.chrome.webapps.WebappActivity{{ i }}"
             android:targetActivity="org.chromium.chrome.browser.webapps.WebappActivity{{ i }}"
@@ -524,7 +548,9 @@
             android:documentLaunchMode="intoExisting"
             android:persistableMode="persistNever"
             {{ self.supports_video_persistence() }}
-            {{ self.chrome_activity_common() }}>
+            {{ self.chrome_activity_common() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         {% for i in range(10) %}
         <activity android:name="org.chromium.chrome.browser.webapps.WebApkActivity{{ i }}"
@@ -535,7 +561,9 @@
             android:persistableMode="persistNever"
             android:taskAffinity="{{ manifest_package }}.webapps.WebApkActivity{{ i }}"
             {{ self.supports_video_persistence() }}
-            {{ self.chrome_activity_common() }}>
+            {{ self.chrome_activity_common() }}
+        >
+            {{ self.supports_vr() }}
         </activity>
         {% endfor %}
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS
index 0fa03f1..f0d805c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS
@@ -6,4 +6,4 @@
 per-file PaymentRequestMetrics.java=sebsg@chromium.org
 per-file PaymentResponseHelper.java=sebsg@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 4b44c09..b072e2d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -178,6 +178,7 @@
             getInstance(activity);
             assert sInstance != null;
             if (sInstance == null) return;
+            assert !sInstance.mInVr;
             sInstance.mDonSucceeded = true;
             if (sInstance.mPaused) {
                 if (sInstance.mInVrAtChromeLaunch == null) sInstance.mInVrAtChromeLaunch = false;
@@ -415,16 +416,23 @@
         }
     }
 
-    private static PendingIntent getEnterVrPendingIntent(ChromeActivity activity) {
+    // We need a custom Intent for entering VR in order to support VR in Custom Tabs. Custom Tabs
+    // are not a singleInstance activity, so they cannot be resumed through Activity PendingIntents,
+    // which is the typical way Daydream resumes your Activity. Instead, we use a broadcast intent
+    // and then use the broadcast to bring ourselves back to the foreground.
+    /* package */ static PendingIntent getEnterVrPendingIntent(ChromeActivity activity) {
         if (sVrBroadcastReceiver != null) sVrBroadcastReceiver.unregister();
         IntentFilter filter = new IntentFilter(VR_ENTRY_RESULT_ACTION);
-        sVrBroadcastReceiver = new VrBroadcastReceiver(activity);
-        activity.registerReceiver(sVrBroadcastReceiver, filter);
-
+        VrBroadcastReceiver receiver = new VrBroadcastReceiver(activity);
+        // If we set sVrBroadcastReceiver then use it in registerReceiver, findBugs considers this
+        // a thread-safety issue since it thinks the receiver isn't fully initialized before being
+        // exposed to other threads. This isn't actually an issue in this case, but we need to set
+        // sVrBroadcastReceiver after we're done using it here to fix the compile error.
+        activity.registerReceiver(receiver, filter);
+        sVrBroadcastReceiver = receiver;
         Intent vrIntent = new Intent(VR_ENTRY_RESULT_ACTION);
         vrIntent.setPackage(activity.getPackageName());
-        return PendingIntent.getBroadcast(activity, 0, vrIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+        return PendingIntent.getBroadcast(activity, 0, vrIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     /**
@@ -669,11 +677,6 @@
         removeOverlayView();
     }
 
-    private boolean launchInVr() {
-        assert mActivity != null && mVrSupportLevel != VR_NOT_AVAILABLE;
-        return mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity));
-    }
-
     private void onAutopresentIntent() {
         // Autopresent intents are only expected from trusted first party apps while
         // we're not in vr.
@@ -779,21 +782,7 @@
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
         if (mInVr) return ENTER_VR_NOT_NECESSARY;
         if (!canEnterVr(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
-
-        if (mVrSupportLevel == VR_CARDBOARD || !isDaydreamCurrentViewer()) {
-            // Avoid using launchInVr which would trigger DON flow regardless current viewer type
-            // due to the lack of support for unexported activities.
-            enterVr(false);
-        } else {
-            // LANDSCAPE orientation is needed before we can safely enter VR. DON can make sure that
-            // the device is at LANDSCAPE orientation once it is finished. So here we use SENSOR to
-            // avoid forcing LANDSCAPE orientation in order to have a smoother transition.
-            setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
-            if (!launchInVr()) {
-                restoreWindowMode();
-                return ENTER_VR_CANCELLED;
-            }
-        }
+        enterVr(false);
         return ENTER_VR_REQUESTED;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index a6c2d01..f10b515 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -19,7 +19,6 @@
 import android.view.View;
 import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.widget.FrameLayout;
-import android.widget.FrameLayout.LayoutParams;
 
 import com.google.vr.ndk.base.AndroidCompat;
 import com.google.vr.ndk.base.GvrLayout;
@@ -130,6 +129,11 @@
         mDelegate = delegate;
         mTabModelSelector = tabModelSelector;
 
+        // This overrides the default intent created by GVR to return to Chrome when the DON flow
+        // is triggered by resuming the GvrLayout, which is the usual way Daydream apps enter VR.
+        // See VrShellDelegate#getEnterVrPendingIntent for why we need to do this.
+        setReentryIntent(VrShellDelegate.getEnterVrPendingIntent(activity));
+
         mReprojectedRendering = setAsyncReprojectionEnabled(true);
         if (mReprojectedRendering) {
             // No need render to a Surface if we're reprojected. We'll be rendering with surfaceless
@@ -725,9 +729,9 @@
     public void removeWindowAndroidChangedObserver(WindowAndroidChangedObserver observer) {}
 
     /**
-     * Sets the runnable that will be run when VrShellImpl's dispatchTouchEvent
+     * Sets the callback that will be run when VrShellImpl's dispatchTouchEvent
      * is run and the parent consumed the event.
-     * @param runnable The Runnable that will be run
+     * @param callback The Callback to be run.
      */
     @VisibleForTesting
     public void setOnDispatchTouchEventForTesting(OnDispatchTouchEventCallback callback) {
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index c46949ec5..2c2e877 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1809,20 +1809,6 @@
   "junit/src/org/chromium/chrome/browser/widget/selection/SelectionDelegateTest.java",
 ]
 
-sync_shell_test_java_sources = [
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
-  "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java",
-]
-
 # Only used for testing, should not be shipped to end users.
 if (enable_offline_pages_harness) {
   chrome_java_sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 13ea874..9ec24e72 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -508,45 +508,6 @@
      cc::switches::kCompositedLayerBorders},
     {flag_descriptions::kUiShowCompositedLayerBordersAll,
      cc::switches::kUIShowCompositedLayerBorders, ""}};
-
-const FeatureEntry::Choice kSpuriousPowerButtonWindowChoices[] = {
-    {"0", "", ""},
-    {"5", ash::switches::kSpuriousPowerButtonWindow, "5"},
-    {"10", ash::switches::kSpuriousPowerButtonWindow, "10"},
-    {"15", ash::switches::kSpuriousPowerButtonWindow, "15"},
-    {"20", ash::switches::kSpuriousPowerButtonWindow, "20"},
-};
-const FeatureEntry::Choice kSpuriousPowerButtonAccelCountChoices[] = {
-    {"0", "", ""},
-    {"1", ash::switches::kSpuriousPowerButtonAccelCount, "1"},
-    {"2", ash::switches::kSpuriousPowerButtonAccelCount, "2"},
-    {"3", ash::switches::kSpuriousPowerButtonAccelCount, "3"},
-    {"4", ash::switches::kSpuriousPowerButtonAccelCount, "4"},
-    {"5", ash::switches::kSpuriousPowerButtonAccelCount, "5"},
-};
-const FeatureEntry::Choice kSpuriousPowerButtonScreenAccelChoices[] = {
-    {"0", "", ""},
-    {"0.2", ash::switches::kSpuriousPowerButtonScreenAccel, "0.2"},
-    {"0.4", ash::switches::kSpuriousPowerButtonScreenAccel, "0.4"},
-    {"0.6", ash::switches::kSpuriousPowerButtonScreenAccel, "0.6"},
-    {"0.8", ash::switches::kSpuriousPowerButtonScreenAccel, "0.8"},
-    {"1.0", ash::switches::kSpuriousPowerButtonScreenAccel, "1.0"},
-};
-const FeatureEntry::Choice kSpuriousPowerButtonKeyboardAccelChoices[] = {
-    {"0", "", ""},
-    {"0.2", ash::switches::kSpuriousPowerButtonKeyboardAccel, "0.2"},
-    {"0.4", ash::switches::kSpuriousPowerButtonKeyboardAccel, "0.4"},
-    {"0.6", ash::switches::kSpuriousPowerButtonKeyboardAccel, "0.6"},
-    {"0.8", ash::switches::kSpuriousPowerButtonKeyboardAccel, "0.8"},
-    {"1.0", ash::switches::kSpuriousPowerButtonKeyboardAccel, "1.0"},
-};
-const FeatureEntry::Choice kSpuriousPowerButtonLidAngleChangeChoices[] = {
-    {"0", "", ""},
-    {"45", ash::switches::kSpuriousPowerButtonLidAngleChange, "45"},
-    {"90", ash::switches::kSpuriousPowerButtonLidAngleChange, "90"},
-    {"135", ash::switches::kSpuriousPowerButtonLidAngleChange, "135"},
-    {"180", ash::switches::kSpuriousPowerButtonLidAngleChange, "180"},
-};
 #endif  // OS_CHROMEOS
 
 const FeatureEntry::Choice kV8CacheOptionsChoices[] = {
@@ -1380,26 +1341,6 @@
      kOsCrOS,
      SINGLE_VALUE_TYPE(
          proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery)},
-    {"spurious-power-button-window",
-     flag_descriptions::kSpuriousPowerButtonWindowName,
-     flag_descriptions::kSpuriousPowerButtonWindowDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kSpuriousPowerButtonWindowChoices)},
-    {"spurious-power-button-accel-count",
-     flag_descriptions::kSpuriousPowerButtonAccelCountName,
-     flag_descriptions::kSpuriousPowerButtonAccelCountDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kSpuriousPowerButtonAccelCountChoices)},
-    {"spurious-power-button-screen-accel",
-     flag_descriptions::kSpuriousPowerButtonScreenAccelName,
-     flag_descriptions::kSpuriousPowerButtonScreenAccelDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kSpuriousPowerButtonScreenAccelChoices)},
-    {"spurious-power-button-keyboard-accel",
-     flag_descriptions::kSpuriousPowerButtonKeyboardAccelName,
-     flag_descriptions::kSpuriousPowerButtonKeyboardAccelDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kSpuriousPowerButtonKeyboardAccelChoices)},
-    {"spurious-power-button-lid-angle-change",
-     flag_descriptions::kSpuriousPowerButtonLidAngleChangeName,
-     flag_descriptions::kSpuriousPowerButtonLidAngleChangeDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kSpuriousPowerButtonLidAngleChangeChoices)},
 #endif  // OS_CHROMEOS
 #if defined(USE_ASH)
     {"ash-disable-night-light", flag_descriptions::kDisableNightLightName,
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS
index bb55a8c..8f032b7 100644
--- a/chrome/browser/android/DEPS
+++ b/chrome/browser/android/DEPS
@@ -2,6 +2,7 @@
   "-components/devtools_bridge",
   "+cc/layers/layer.h",
   "+cc/output/context_provider.h",
+  "+chrome_jni_registration/chrome_jni_registration.h",
   "+components/doodle",
   "+components/ntp_snippets",
   "+components/spellcheck/browser",
diff --git a/chrome/browser/android/chrome_entry_point.cc b/chrome/browser/android/chrome_entry_point.cc
index ee46cd6c..079358b 100644
--- a/chrome/browser/android/chrome_entry_point.cc
+++ b/chrome/browser/android/chrome_entry_point.cc
@@ -7,6 +7,7 @@
 #include "base/android/library_loader/library_loader_hooks.h"
 #include "base/bind.h"
 #include "chrome/app/android/chrome_jni_onload.h"
+#include "chrome/browser/android/chrome_jni_registration.h"
 
 namespace {
 
@@ -23,6 +24,19 @@
   // Java side and only register a subset of JNI methods.
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+
+  if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+    if (!RegisterNonMainDexNatives(env)) {
+      return -1;
+    }
+  }
+
+  if (!RegisterMainDexNatives(env)) {
+    return -1;
+  }
+
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (base::android::IsSelectiveJniRegistrationEnabled(env)) {
     base::android::SetJniRegistrationType(
         base::android::SELECTIVE_JNI_REGISTRATION);
diff --git a/chrome/browser/android/chrome_sync_shell_entry_point.cc b/chrome/browser/android/chrome_sync_shell_entry_point.cc
new file mode 100644
index 0000000..e14ea511
--- /dev/null
+++ b/chrome/browser/android/chrome_sync_shell_entry_point.cc
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_utils.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/bind.h"
+#include "chrome/app/android/chrome_jni_onload.h"
+#include "chrome/browser/android/chrome_sync_shell_jni_registration.h"
+
+namespace {
+
+bool NativeInit() {
+  return android::OnJNIOnLoadInit();
+}
+
+}  // namespace
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+  // By default, all JNI methods are registered. However, since render processes
+  // don't need very much Java code, we enable selective JNI registration on the
+  // Java side and only register a subset of JNI methods.
+  base::android::InitVM(vm);
+  JNIEnv* env = base::android::AttachCurrentThread();
+
+  if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+    if (!RegisterNonMainDexNatives(env)) {
+      return -1;
+    }
+  }
+
+  if (!RegisterMainDexNatives(env)) {
+    return -1;
+  }
+
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
+  if (base::android::IsSelectiveJniRegistrationEnabled(env)) {
+    base::android::SetJniRegistrationType(
+        base::android::SELECTIVE_JNI_REGISTRATION);
+  }
+  if (!android::OnJNIOnLoadRegisterJNI(env)) {
+    return -1;
+  }
+  base::android::SetNativeInitializationHook(NativeInit);
+  return JNI_VERSION_1_4;
+}
diff --git a/chrome/browser/android/payments/OWNERS b/chrome/browser/android/payments/OWNERS
index 45a6ddd0..3955084d 100644
--- a/chrome/browser/android/payments/OWNERS
+++ b/chrome/browser/android/payments/OWNERS
@@ -2,4 +2,4 @@
 mathp@chromium.org
 rouslan@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
index 3b42f7c..f45abfa 100644
--- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
+++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -110,7 +110,7 @@
     js_checker().ExecuteAsync(set_machine_name);
     js_checker().ExecuteAsync(set_username);
     js_checker().ExecuteAsync(set_password);
-    js_checker().Evaluate(
+    js_checker().ExecuteAsync(
         "document.querySelector('#oauth-enroll-ad-join-ui /deep/ "
         "#button').fire('tap')");
     ExecutePendingJavaScript();
@@ -161,7 +161,7 @@
   }
 
   void SetupActiveDirectoryJSNotifications() {
-    js_checker().Evaluate(
+    js_checker().ExecuteAsync(
         "var testShowStep = login.OAuthEnrollmentScreen.showStep;"
         "login.OAuthEnrollmentScreen.showStep = function(step) {"
         "  testShowStep(step);"
@@ -170,7 +170,7 @@
         "    window.domAutomationController.send('ShowSpinnerScreen');"
         "  }"
         "}");
-    js_checker().Evaluate(
+    js_checker().ExecuteAsync(
         "var testInvalidateAd = login.OAuthEnrollmentScreen.invalidateAd;"
         "login.OAuthEnrollmentScreen.invalidateAd = function(machineName, "
         "user, errorState) {"
@@ -319,9 +319,8 @@
 // Directory domain join screen. Verifies the domain join screen is displayed.
 // Submits Active Directory credentials. Verifies that the AuthpolicyClient
 // calls us back with the correct realm.
-// TODO(crbug.com/735621): Flaky.
 IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentTest,
-                       DISABLED_TestActiveDirectoryEnrollment_Success) {
+                       TestActiveDirectoryEnrollment_Success) {
   ShowEnrollmentScreen();
   DisableAttributePromptUpdate();
   SetupActiveDirectoryJoin();
@@ -350,9 +349,8 @@
 // Directory domain join screen. Verifies the domain join screen is displayed.
 // Submits Active Directory different incorrect credentials. Verifies that the
 // correct error is displayed.
-// TODO(crbug.com/735621): Flaky.
 IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentTest,
-                       DISABLED_TestActiveDirectoryEnrollment_UIErrors) {
+                       TestActiveDirectoryEnrollment_UIErrors) {
   ShowEnrollmentScreen();
   SetupActiveDirectoryJoin();
   SubmitEnrollmentCredentials();
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 3c819cc9..a9087e8 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -136,7 +136,8 @@
 void IdentityGetAuthTokenFunction::OnReceivedPrimaryAccountInfo(
     const std::set<std::string>& scopes,
     const std::string& extension_gaia_id,
-    const base::Optional<AccountInfo>& account_info) {
+    const base::Optional<AccountInfo>& account_info,
+    const ::identity::AccountState& account_state) {
   std::string primary_gaia_id;
   if (account_info)
     primary_gaia_id = account_info->gaia;
@@ -161,13 +162,14 @@
 
   // The extension is using the primary account.
   OnReceivedExtensionAccountInfo(true /* primary account */, scopes,
-                                 account_info);
+                                 account_info, account_state);
 }
 
 void IdentityGetAuthTokenFunction::OnReceivedExtensionAccountInfo(
     bool is_primary_account,
     const std::set<std::string>& scopes,
-    const base::Optional<AccountInfo>& account_info) {
+    const base::Optional<AccountInfo>& account_info,
+    const ::identity::AccountState& account_state) {
   std::string account_id;
   if (account_info)
     account_id = account_info->account_id;
@@ -200,7 +202,7 @@
   }
 #endif
 
-  if (!HasLoginToken()) {
+  if (!account_state.has_refresh_token) {
     if (!should_prompt_for_signin_) {
       CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
       return;
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
index e766df0..ee23b26 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -12,6 +12,7 @@
 #include "extensions/browser/extension_function_histogram_value.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
 #include "google_apis/gaia/oauth2_token_service.h"
+#include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/interfaces/identity_manager.mojom.h"
 
 namespace extensions {
@@ -116,7 +117,8 @@
   void OnReceivedPrimaryAccountInfo(
       const std::set<std::string>& scopes,
       const std::string& extension_gaia_id,
-      const base::Optional<AccountInfo>& account_info);
+      const base::Optional<AccountInfo>& account_info,
+      const identity::AccountState& account_state);
 
   // Called when the AccountInfo that this instance should use is available.
   // |is_primary_account| is a bool specifying whether the account being used is
@@ -125,7 +127,8 @@
   void OnReceivedExtensionAccountInfo(
       bool is_primary_account,
       const std::set<std::string>& scopes,
-      const base::Optional<AccountInfo>& account_info);
+      const base::Optional<AccountInfo>& account_info,
+      const identity::AccountState& account_state);
 
   // ExtensionFunction:
   bool RunAsync() override;
diff --git a/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.cc b/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.cc
index 7f02b16..10578ac 100644
--- a/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.cc
@@ -43,7 +43,8 @@
 }
 
 void IdentityGetProfileUserInfoFunction::OnReceivedPrimaryAccountInfo(
-    const base::Optional<AccountInfo>& account_info) {
+    const base::Optional<AccountInfo>& account_info,
+    const identity::AccountState& account_state) {
   DCHECK(extension()->permissions_data()->HasAPIPermission(
       APIPermission::kIdentityEmail));
 
diff --git a/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h b/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h
index f340bffc..ad9536a7 100644
--- a/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h
+++ b/chrome/browser/extensions/api/identity/identity_get_profile_user_info_function.h
@@ -8,6 +8,7 @@
 #include "chrome/browser/extensions/chrome_extension_function.h"
 #include "components/signin/core/browser/account_info.h"
 #include "extensions/browser/extension_function_histogram_value.h"
+#include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/interfaces/identity_manager.mojom.h"
 
 namespace extensions {
@@ -23,7 +24,8 @@
  private:
   ~IdentityGetProfileUserInfoFunction() override;
   void OnReceivedPrimaryAccountInfo(
-      const base::Optional<AccountInfo>& account_info);
+      const base::Optional<AccountInfo>& account_info,
+      const identity::AccountState& account_state);
 
   // UIThreadExtensionFunction implementation.
   ExtensionFunction::ResponseAction Run() override;
diff --git a/chrome/browser/extensions/api/vpn_provider/OWNERS b/chrome/browser/extensions/api/vpn_provider/OWNERS
index c83fa211..a913a05 100644
--- a/chrome/browser/extensions/api/vpn_provider/OWNERS
+++ b/chrome/browser/extensions/api/vpn_provider/OWNERS
@@ -1,3 +1,2 @@
-kaliamoorthi@chromium.org
 bartfab@chromium.org
 emaxx@chromium.org
diff --git a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
index 849fcaa..01c64f77 100644
--- a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
+++ b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
@@ -16,6 +16,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 
 namespace extensions {
 
@@ -106,8 +107,8 @@
   std::unique_ptr<SafeBrowsingCheck> safe_browsing_check(
       new SafeBrowsingCheck(std::vector<GURL>(), extension_id_hashes, client,
                             safe_browsing::EXTENSIONBLACKLIST,
-                            std::vector<safe_browsing::SBThreatType>(
-                                1, safe_browsing::SB_THREAT_TYPE_EXTENSION)));
+                            safe_browsing::CreateSBThreatTypeSet(
+                                {safe_browsing::SB_THREAT_TYPE_EXTENSION})));
 
   for (size_t i = 0; i < extension_ids_vector.size(); ++i) {
     const std::string& extension_id = extension_ids_vector[i];
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 0714a23..e88f4d37 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3049,37 +3049,6 @@
     "If enabled and the device supports ARC, the user will be asked to update "
     "the encryption of user data when the user signs in.";
 
-// Spurious power button detection
-
-const char kSpuriousPowerButtonWindowName[] = "Spurious power button window";
-const char kSpuriousPowerButtonWindowDescription[] =
-    "Number of recent accelerometer samples to examine to determine if a power "
-    "button event was spurious.";
-
-const char kSpuriousPowerButtonAccelCountName[] =
-    "Spurious power button acceleration count";
-const char kSpuriousPowerButtonAccelCountDescription[] =
-    "Number of recent acceleration samples that must meet or exceed exceed the "
-    "threshold in order for a power button event to be considered spurious.";
-
-const char kSpuriousPowerButtonScreenAccelName[] =
-    "Spurious power button screen acceleration threshold";
-const char kSpuriousPowerButtonScreenAccelDescription[] =
-    "Threshold (in m/s^2, disregarding gravity) that screen acceleration must "
-    "meet or exceed for a power button event to be considered spurious.";
-
-const char kSpuriousPowerButtonKeyboardAccelName[] =
-    "Spurious power button keyboard acceleration threshold";
-const char kSpuriousPowerButtonKeyboardAccelDescription[] =
-    "Threshold (in m/s^2, disregarding gravity) that keyboard acceleration "
-    "must meet or exceed for a power button event to be considered spurious.";
-
-const char kSpuriousPowerButtonLidAngleChangeName[] =
-    "Spurious power button lid angle change threshold";
-const char kSpuriousPowerButtonLidAngleChangeDescription[] =
-    "Change in lid angle (i.e. hinge between keyboard and screen) that must be "
-    "met or exceeded for a power button event to be considered spurious.";
-
 #endif  // #if defined(OS_CHROMEOS)
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index e5a1429..89342fc 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1367,17 +1367,6 @@
 extern const char kSmartVirtualKeyboardName[];
 extern const char kSmartVirtualKeyboardDescription[];
 
-extern const char kSpuriousPowerButtonWindowName[];
-extern const char kSpuriousPowerButtonWindowDescription[];
-extern const char kSpuriousPowerButtonAccelCountName[];
-extern const char kSpuriousPowerButtonAccelCountDescription[];
-extern const char kSpuriousPowerButtonScreenAccelName[];
-extern const char kSpuriousPowerButtonScreenAccelDescription[];
-extern const char kSpuriousPowerButtonKeyboardAccelName[];
-extern const char kSpuriousPowerButtonKeyboardAccelDescription[];
-extern const char kSpuriousPowerButtonLidAngleChangeName[];
-extern const char kSpuriousPowerButtonLidAngleChangeDescription[];
-
 extern const char kTeamDrivesName[];
 extern const char kTeamDrivesDescription[];
 
diff --git a/chrome/browser/loader/safe_browsing_resource_throttle.cc b/chrome/browser/loader/safe_browsing_resource_throttle.cc
index fb99b3f..af05fb9 100644
--- a/chrome/browser/loader/safe_browsing_resource_throttle.cc
+++ b/chrome/browser/loader/safe_browsing_resource_throttle.cc
@@ -15,6 +15,7 @@
 #include "components/safe_browsing_db/util.h"
 #include "components/safe_browsing_db/v4_feature_list.h"
 #include "components/safe_browsing_db/v4_local_database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/resource_request_info.h"
@@ -56,10 +57,15 @@
     const net::URLRequest* request,
     content::ResourceType resource_type,
     safe_browsing::SafeBrowsingService* sb_service)
-    : safe_browsing::BaseResourceThrottle(request,
-                                          resource_type,
-                                          sb_service->database_manager(),
-                                          sb_service->ui_manager()) {}
+    : safe_browsing::BaseResourceThrottle(
+          request,
+          resource_type,
+          safe_browsing::CreateSBThreatTypeSet(
+              {safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
+               safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+               safe_browsing::SB_THREAT_TYPE_URL_UNWANTED}),
+          sb_service->database_manager(),
+          sb_service->ui_manager()) {}
 
 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() {}
 
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
index 531e3f4..6c3e609 100644
--- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc
+++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -262,7 +262,6 @@
 // static
 bool RemoteMediaPlayerBridge::RegisterRemoteMediaPlayerBridge(JNIEnv* env) {
   bool ret = RegisterNativesImpl(env);
-  DCHECK(g_RemoteMediaPlayerBridge_clazz);
   return ret;
 }
 
diff --git a/chrome/browser/media/android/router/media_router_android_bridge.cc b/chrome/browser/media/android/router/media_router_android_bridge.cc
index e56bbb59..4c57cde 100644
--- a/chrome/browser/media/android/router/media_router_android_bridge.cc
+++ b/chrome/browser/media/android/router/media_router_android_bridge.cc
@@ -29,7 +29,6 @@
 // static
 bool MediaRouterAndroidBridge::Register(JNIEnv* env) {
   bool ret = RegisterNativesImpl(env);
-  DCHECK(g_ChromeMediaRouter_clazz);
   return ret;
 }
 
diff --git a/chrome/browser/payments/android/OWNERS b/chrome/browser/payments/android/OWNERS
index 827c44ed..79f712f 100644
--- a/chrome/browser/payments/android/OWNERS
+++ b/chrome/browser/payments/android/OWNERS
@@ -1,3 +1,3 @@
 per-file journey_logger_android*=sebsg@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/chrome/browser/prerender/prerender_test_utils.cc b/chrome/browser/prerender/prerender_test_utils.cc
index fb07027..8471c97 100644
--- a/chrome/browser/prerender/prerender_test_utils.cc
+++ b/chrome/browser/prerender/prerender_test_utils.cc
@@ -26,6 +26,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
@@ -275,8 +276,10 @@
 
 FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager() {}
 
-bool FakeSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& gurl,
-                                                     Client* client) {
+bool FakeSafeBrowsingDatabaseManager::CheckBrowseUrl(
+    const GURL& gurl,
+    const safe_browsing::SBThreatTypeSet& threat_types,
+    Client* client) {
   if (bad_urls_.find(gurl.spec()) == bad_urls_.end() ||
       bad_urls_[gurl.spec()] == safe_browsing::SB_THREAT_TYPE_SAFE) {
     return true;
@@ -312,9 +315,11 @@
 
 void FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone(const GURL& gurl,
                                                            Client* client) {
-  std::vector<safe_browsing::SBThreatType> expected_threats;
-  expected_threats.push_back(safe_browsing::SB_THREAT_TYPE_URL_MALWARE);
-  expected_threats.push_back(safe_browsing::SB_THREAT_TYPE_URL_PHISHING);
+  safe_browsing::SBThreatTypeSet expected_threats =
+      safe_browsing::CreateSBThreatTypeSet(
+          {safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
+           safe_browsing::SB_THREAT_TYPE_URL_PHISHING});
+
   // TODO(nparker): Replace SafeBrowsingCheck w/ a call to
   // client->OnCheckBrowseUrlResult()
   safe_browsing::LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
diff --git a/chrome/browser/prerender/prerender_test_utils.h b/chrome/browser/prerender/prerender_test_utils.h
index 55d889b..227ba7b6 100644
--- a/chrome/browser/prerender/prerender_test_utils.h
+++ b/chrome/browser/prerender/prerender_test_utils.h
@@ -69,7 +69,9 @@
   // (in which that result will be communicated back via a call into the
   // client, and false will be returned).
   // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
-  bool CheckBrowseUrl(const GURL& gurl, Client* client) override;
+  bool CheckBrowseUrl(const GURL& gurl,
+                      const safe_browsing::SBThreatTypeSet& threat_types,
+                      Client* client) override;
 
   void SetThreatTypeForUrl(const GURL& url,
                            safe_browsing::SBThreatType threat_type) {
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index 847f14c..b4d7c76 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -44,6 +44,7 @@
 #include "components/safe_browsing/csd.pb.h"
 #include "components/safe_browsing_db/database_manager.h"
 #include "components/safe_browsing_db/test_database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/download_danger_type.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/test/mock_download_item.h"
@@ -234,7 +235,7 @@
   LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
       new LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck(
           arg0, std::vector<SBFullHash>(), arg1, BINURL,
-          std::vector<SBThreatType>(1, SB_THREAT_TYPE_URL_BINARY_MALWARE));
+          CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_BINARY_MALWARE}));
   for (size_t i = 0; i < check->url_results.size(); ++i)
     check->url_results[i] = threat_type;
   BrowserThread::PostTask(
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc
index 8b5114b..aced726 100644
--- a/chrome/browser/safe_browsing/local_database_manager.cc
+++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -10,6 +10,7 @@
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/command_line.h"
+#include "base/containers/flat_set.h"
 #include "base/debug/leak_tracker.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
@@ -36,7 +37,6 @@
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/common/safebrowsing_switches.h"
 #include "components/safe_browsing_db/util.h"
-#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -70,7 +70,7 @@
 }
 
 bool IsExpectedThreat(const SBThreatType threat_type,
-                      const std::vector<SBThreatType>& expected_threats) {
+                      const SBThreatTypeSet& expected_threats) {
   return base::ContainsValue(expected_threats, threat_type);
 }
 
@@ -199,7 +199,7 @@
     const std::vector<SBFullHash>& full_hashes,
     Client* client,
     ListType check_type,
-    const std::vector<SBThreatType>& expected_threats)
+    const SBThreatTypeSet& expected_threats)
     : urls(urls),
       url_results(urls.size(), SB_THREAT_TYPE_SAFE),
       url_metadata(urls.size()),
@@ -350,7 +350,7 @@
   std::unique_ptr<SafeBrowsingCheck> check =
       base::MakeUnique<SafeBrowsingCheck>(
           url_chain, std::vector<SBFullHash>(), client, BINURL,
-          std::vector<SBThreatType>(1, SB_THREAT_TYPE_URL_BINARY_MALWARE));
+          CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_BINARY_MALWARE}));
   std::vector<SBPrefix> prefixes;
   SafeBrowsingDatabase::GetDownloadUrlPrefixes(url_chain, &prefixes);
   StartSafeBrowsingCheck(
@@ -378,7 +378,7 @@
   std::unique_ptr<SafeBrowsingCheck> check =
       base::MakeUnique<SafeBrowsingCheck>(
           std::vector<GURL>(), extension_id_hashes, client, EXTENSIONBLACKLIST,
-          std::vector<SBThreatType>(1, SB_THREAT_TYPE_EXTENSION));
+          CreateSBThreatTypeSet({SB_THREAT_TYPE_EXTENSION}));
   StartSafeBrowsingCheck(
       std::move(check),
       base::Bind(&LocalSafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread,
@@ -393,8 +393,8 @@
   if (!enabled_ || !CanCheckUrl(url))
     return true;
 
-  std::vector<SBThreatType> expected_threats = {
-      SB_THREAT_TYPE_BLACKLISTED_RESOURCE};
+  SBThreatTypeSet expected_threats =
+      CreateSBThreatTypeSet({SB_THREAT_TYPE_BLACKLISTED_RESOURCE});
 
   if (!MakeDatabaseAvailable()) {
     QueuedCheck queued_check(RESOURCEBLACKLIST, client, url, expected_threats,
@@ -488,20 +488,19 @@
   return database_->IsCsdWhitelistKillSwitchOn();
 }
 
-bool LocalSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& url,
-                                                      Client* client) {
+bool LocalSafeBrowsingDatabaseManager::CheckBrowseUrl(
+    const GURL& url,
+    const SBThreatTypeSet& expected_threats,
+    Client* client) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!expected_threats.empty());
+  DCHECK(SBThreatTypeSetIsValidForCheckBrowseUrl(expected_threats));
   if (!enabled_)
     return true;
 
   if (!CanCheckUrl(url))
     return true;
 
-  std::vector<SBThreatType> expected_threats;
-  expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
-  expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
-  expected_threats.push_back(SB_THREAT_TYPE_URL_UNWANTED);
-
   const base::TimeTicks start = base::TimeTicks::Now();
   if (!MakeDatabaseAvailable()) {
     QueuedCheck queued_check(MALWARE,  // or PHISH
@@ -729,7 +728,7 @@
     const ListType check_type,
     Client* client,
     const GURL& url,
-    const std::vector<SBThreatType>& expected_threats,
+    const SBThreatTypeSet& expected_threats,
     const base::TimeTicks& start)
     : check_type(check_type),
       client(client),
@@ -1008,7 +1007,8 @@
     // If CheckUrl() determines the URL is safe immediately, it doesn't call the
     // client's handler function (because normally it's being directly called by
     // the client).  Since we're not the client, we have to convey this result.
-    if (check.client && CheckBrowseUrl(check.url, check.client)) {
+    if (check.client &&
+        CheckBrowseUrl(check.url, check.expected_threats, check.client)) {
       SafeBrowsingCheck sb_check(std::vector<GURL>(1, check.url),
                                  std::vector<SBFullHash>(), check.client,
                                  check.check_type, check.expected_threats);
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h
index 0ed5804c..eb5f242 100644
--- a/chrome/browser/safe_browsing/local_database_manager.h
+++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -31,6 +31,7 @@
 #include "components/safe_browsing_db/database_manager.h"
 #include "components/safe_browsing_db/safebrowsing.pb.h"
 #include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -65,7 +66,7 @@
                       const std::vector<SBFullHash>& full_hashes,
                       Client* client,
                       ListType check_type,
-                      const std::vector<SBThreatType>& expected_threats);
+                      const SBThreatTypeSet& expected_threats);
     ~SafeBrowsingCheck();
 
     // Either |urls| or |full_hashes| is used to lookup database. |*_results|
@@ -86,7 +87,7 @@
     bool need_get_hash;
     base::TimeTicks start;  // When check was sent to SB service.
     ListType check_type;    // See comment in constructor.
-    std::vector<SBThreatType> expected_threats;
+    SBThreatTypeSet expected_threats;
     std::vector<SBPrefix> prefix_hits;
     std::vector<SBFullHashResult> cache_hits;
 
@@ -119,7 +120,9 @@
   bool CanCheckResourceType(content::ResourceType resource_type) const override;
   bool CanCheckUrl(const GURL& url) const override;
 
-  bool CheckBrowseUrl(const GURL& url, Client* client) override;
+  bool CheckBrowseUrl(const GURL& url,
+                      const SBThreatTypeSet& threat_types,
+                      Client* client) override;
   bool CheckUrlForSubresourceFilter(const GURL& url, Client* client) override;
   bool CheckDownloadUrl(const std::vector<GURL>& url_chain,
                         Client* client) override;
@@ -170,14 +173,14 @@
     QueuedCheck(const ListType check_type,
                 Client* client,
                 const GURL& url,
-                const std::vector<SBThreatType>& expected_threats,
+                const SBThreatTypeSet& expected_threats,
                 const base::TimeTicks& start);
     QueuedCheck(const QueuedCheck& other);
     ~QueuedCheck();
     ListType check_type;
     Client* client;
     GURL url;
-    std::vector<SBThreatType> expected_threats;
+    SBThreatTypeSet expected_threats;
     base::TimeTicks start;  // When check was queued.
   };
 
diff --git a/chrome/browser/safe_browsing/local_database_manager_unittest.cc b/chrome/browser/safe_browsing/local_database_manager_unittest.cc
index 4f3d93a4..888ac2a 100644
--- a/chrome/browser/safe_browsing/local_database_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/local_database_manager_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/safe_browsing_db/v4_get_hash_protocol_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/safe_browsing_db/v4_test_util.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
@@ -35,12 +36,20 @@
   };
 
   bool RunSBHashTest(const ListType list_type,
-                     const std::vector<SBThreatType>& expected_threats,
+                     const SBThreatTypeSet& expected_threats,
                      const std::vector<std::string>& result_lists);
-  bool RunUrlTest(
-      const GURL& url, ListType list_type,
-      const std::vector<SBThreatType>& expected_threats,
-      const std::vector<HostListPair>& host_list_results);
+  bool RunUrlTest(const GURL& url,
+                  ListType list_type,
+                  const SBThreatTypeSet& expected_threats,
+                  const std::vector<HostListPair>& host_list_results);
+
+  // Constant values used in tests.
+  const SBThreatTypeSet malware_threat_ =
+      CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_BINARY_MALWARE});
+  const SBThreatTypeSet multiple_threats_ = CreateSBThreatTypeSet(
+      {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_URL_PHISHING});
+  const SBThreatTypeSet unwanted_threat_ =
+      CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_UNWANTED});
 
  private:
   bool RunTest(std::unique_ptr<
@@ -52,7 +61,7 @@
 
 bool LocalDatabaseManagerTest::RunSBHashTest(
     const ListType list_type,
-    const std::vector<SBThreatType>& expected_threats,
+    const SBThreatTypeSet& expected_threats,
     const std::vector<std::string>& result_lists) {
   const SBFullHash same_full_hash = {};
   std::unique_ptr<LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck> check(
@@ -70,8 +79,9 @@
 }
 
 bool LocalDatabaseManagerTest::RunUrlTest(
-    const GURL& url, ListType list_type,
-    const std::vector<SBThreatType>& expected_threats,
+    const GURL& url,
+    ListType list_type,
+    const SBThreatTypeSet& expected_threats,
     const std::vector<HostListPair>& host_list_results) {
   std::unique_ptr<LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck> check(
       new LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck(
@@ -102,22 +112,16 @@
 }
 
 TEST_F(LocalDatabaseManagerTest, CheckCorrespondsListTypeForHash) {
-  std::vector<SBThreatType> malware_threat(1,
-                                           SB_THREAT_TYPE_URL_BINARY_MALWARE);
-  EXPECT_FALSE(RunSBHashTest(BINURL, malware_threat, {kMalwareList}));
-  EXPECT_TRUE(RunSBHashTest(BINURL, malware_threat, {kBinUrlList}));
+  EXPECT_FALSE(RunSBHashTest(BINURL, malware_threat_, {kMalwareList}));
+  EXPECT_TRUE(RunSBHashTest(BINURL, malware_threat_, {kBinUrlList}));
 
   // Check for multiple threats
-  std::vector<SBThreatType> multiple_threats;
-  multiple_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
-  multiple_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
-  EXPECT_FALSE(RunSBHashTest(MALWARE, multiple_threats, {kBinUrlList}));
-  EXPECT_TRUE(RunSBHashTest(MALWARE, multiple_threats, {kMalwareList}));
+  EXPECT_FALSE(RunSBHashTest(MALWARE, multiple_threats_, {kBinUrlList}));
+  EXPECT_TRUE(RunSBHashTest(MALWARE, multiple_threats_, {kMalwareList}));
 
   // Check for multiple hash hits
-  std::vector<SBThreatType> unwanted_threat = {SB_THREAT_TYPE_URL_UNWANTED};
   std::vector<std::string> hash_hits = {kMalwareList, kUnwantedUrlList};
-  EXPECT_TRUE(RunSBHashTest(UNWANTEDURL, unwanted_threat, hash_hits));
+  EXPECT_TRUE(RunSBHashTest(UNWANTEDURL, unwanted_threat_, hash_hits));
 }
 
 TEST_F(LocalDatabaseManagerTest, CheckCorrespondsListTypeForUrl) {
@@ -129,22 +133,17 @@
   const std::vector<HostListPair> binurl_list_result =
       {{host2, kBinUrlList}};
 
-  std::vector<SBThreatType> malware_threat =
-      {SB_THREAT_TYPE_URL_BINARY_MALWARE};
-  EXPECT_FALSE(RunUrlTest(url, BINURL, malware_threat, malware_list_result));
-  EXPECT_TRUE(RunUrlTest(url, BINURL, malware_threat, binurl_list_result));
+  EXPECT_FALSE(RunUrlTest(url, BINURL, malware_threat_, malware_list_result));
+  EXPECT_TRUE(RunUrlTest(url, BINURL, malware_threat_, binurl_list_result));
 
   // Check for multiple expected threats
-  std::vector<SBThreatType> multiple_threats =
-      {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_URL_PHISHING};
-  EXPECT_FALSE(RunUrlTest(url, MALWARE, multiple_threats, binurl_list_result));
-  EXPECT_TRUE(RunUrlTest(url, MALWARE, multiple_threats, malware_list_result));
+  EXPECT_FALSE(RunUrlTest(url, MALWARE, multiple_threats_, binurl_list_result));
+  EXPECT_TRUE(RunUrlTest(url, MALWARE, multiple_threats_, malware_list_result));
 
   // Check for multiple database hits
-  std::vector<SBThreatType> unwanted_threat = {SB_THREAT_TYPE_URL_UNWANTED};
   std::vector<HostListPair> multiple_results = {
     {host1, kMalwareList}, {host2, kUnwantedUrlList}};
-  EXPECT_TRUE(RunUrlTest(url, UNWANTEDURL, unwanted_threat, multiple_results));
+  EXPECT_TRUE(RunUrlTest(url, UNWANTEDURL, unwanted_threat_, multiple_results));
 }
 
 TEST_F(LocalDatabaseManagerTest, GetUrlSeverestThreatType) {
diff --git a/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc b/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
index 67e38a72..3a59a17 100644
--- a/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
+++ b/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/safe_browsing/safe_browsing_url_checker_impl.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
 #include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index dc3f6d7..111a544 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -42,6 +42,7 @@
 #include "components/safe_browsing_db/database_manager.h"
 #include "components/safe_browsing_db/test_database_manager.h"
 #include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/core/controller_client.h"
 #include "components/security_interstitials/core/metrics_helper.h"
 #include "components/security_interstitials/core/urls.h"
@@ -98,7 +99,9 @@
   // Otherwise it returns false, and "client" is called asynchronously with the
   // result when it is ready.
   // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
-  bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
+  bool CheckBrowseUrl(const GURL& gurl,
+                      const SBThreatTypeSet& threat_types,
+                      Client* client) override {
     if (badurls.find(gurl.spec()) == badurls.end() ||
         badurls.at(gurl.spec()) == SB_THREAT_TYPE_SAFE)
       return true;
@@ -111,12 +114,11 @@
   }
 
   void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
-    std::vector<SBThreatType> expected_threats;
+    SBThreatTypeSet expected_threats = CreateSBThreatTypeSet(
+        {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_URL_PHISHING,
+         SB_THREAT_TYPE_URL_UNWANTED});
     // TODO(nparker): Remove ref to LocalSafeBrowsingDatabase by calling
     // client->OnCheckBrowseUrlResult(..) directly.
-    expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
-    expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
-    expected_threats.push_back(SB_THREAT_TYPE_URL_UNWANTED);
     LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
         std::vector<GURL>(1, gurl),
         std::vector<SBFullHash>(),
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index ed2c88a..a38a9c9 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -1145,7 +1145,12 @@
     // The async CheckDone() hook will not be called when we have a synchronous
     // safe signal, handle it right away.
     bool synchronous_safe_signal =
-        safe_browsing_service_->database_manager()->CheckBrowseUrl(url, this);
+        safe_browsing_service_->database_manager()->CheckBrowseUrl(
+            url,
+            CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_PHISHING,
+                                   SB_THREAT_TYPE_URL_MALWARE,
+                                   SB_THREAT_TYPE_URL_UNWANTED}),
+            this);
     if (synchronous_safe_signal) {
       threat_type_ = SB_THREAT_TYPE_SAFE;
       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/safe_browsing/safe_browsing_url_checker_impl.cc b/chrome/browser/safe_browsing/safe_browsing_url_checker_impl.cc
index 405d493..397709f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_url_checker_impl.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_url_checker_impl.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/prerender/prerender_contents.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "net/base/load_flags.h"
@@ -145,8 +146,15 @@
     // TODO(yzshen): Consider moving CanCheckResourceType() to the renderer
     // side. That would save some IPCs. It requires a method on the
     // SafeBrowsing mojo interface to query all supported resource types.
+    // TODO(ricea):  SB_THREAT_TYPE_URL_UNWANTED should not be included for
+    // Android WebView.
     if (!database_manager_->CanCheckResourceType(resource_type_) ||
-        database_manager_->CheckBrowseUrl(urls_[next_index_], this)) {
+        database_manager_->CheckBrowseUrl(
+            urls_[next_index_],
+            CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_PHISHING,
+                                   SB_THREAT_TYPE_URL_MALWARE,
+                                   SB_THREAT_TYPE_URL_UNWANTED}),
+            this)) {
       std::move(callbacks_[next_index_]).Run(true);
       next_index_++;
       continue;
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc
index ca2da83..f96fdb65 100644
--- a/chrome/browser/supervised_user/supervised_user_interstitial.cc
+++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/infobars/core/infobar.h"
@@ -186,6 +187,10 @@
     supervised_user_error_page::FilteringBehaviorReason reason) {
   bool is_child_account = profile->IsChild();
 
+  bool is_deprecated =
+      !is_child_account &&
+      !base::FeatureList::IsEnabled(features::kSupervisedUserCreation);
+
   SupervisedUserService* supervised_user_service =
       SupervisedUserServiceFactory::GetForProfile(profile);
 
@@ -206,7 +211,8 @@
   return supervised_user_error_page::BuildHtml(
       allow_access_requests, profile_image_url, profile_image_url2, custodian,
       custodian_email, second_custodian, second_custodian_email,
-      is_child_account, reason, g_browser_process->GetApplicationLocale());
+      is_child_account, is_deprecated, reason,
+      g_browser_process->GetApplicationLocale());
 }
 
 std::string SupervisedUserInterstitial::GetHTMLContents() {
@@ -251,13 +257,17 @@
       base::UTF8ToUTF16(supervised_user_service->GetSecondCustodianName());
 
   if (command == "\"feedback\"") {
+    bool is_child_account = profile_->IsChild();
+    bool is_deprecated =
+        base::FeatureList::IsEnabled(features::kSupervisedUserCreation);
     base::string16 reason =
         l10n_util::GetStringUTF16(supervised_user_error_page::GetBlockMessageID(
-            reason_, true, second_custodian.empty()));
+            reason_, is_child_account, is_deprecated,
+            second_custodian.empty()));
     std::string message = l10n_util::GetStringFUTF8(
         IDS_BLOCK_INTERSTITIAL_DEFAULT_FEEDBACK_TEXT, reason);
 #if defined(OS_ANDROID)
-    DCHECK(profile_->IsChild());
+    DCHECK(is_child_account);
     ReportChildAccountFeedback(web_contents_, message, url_);
 #else
     chrome::ShowFeedbackPage(chrome::FindBrowserWithWebContents(web_contents_),
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index 4479e4b..866e483 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -466,14 +467,16 @@
       token_service->LoadCredentials(
           supervised_users::kSupervisedUserPseudoEmail);
 
-      permissions_creators_.push_back(
-          base::MakeUnique<PermissionRequestCreatorSync>(
-              GetSettingsService(),
-              SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
-                  profile_),
-              ProfileSyncServiceFactory::GetForProfile(profile_),
-              GetSupervisedUserName(),
-              profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
+      if (base::FeatureList::IsEnabled(features::kSupervisedUserCreation)) {
+        permissions_creators_.push_back(base::MakeUnique<
+                                        PermissionRequestCreatorSync>(
+            GetSettingsService(),
+            SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
+                profile_),
+            ProfileSyncServiceFactory::GetForProfile(profile_),
+            GetSupervisedUserName(),
+            profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
+      }
 
       SetupSync();
 #else
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm
index 10b5c8b..49ebfca 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm
@@ -49,6 +49,8 @@
                             configuration:configuration])) {
     // "Add Page..." has no "node" so this may be NULL.
     node_ = node;
+    urlFieldEditor_.reset([[DialogTextFieldEditor alloc] init]);
+    nameFieldEditor_.reset([[DialogTextFieldEditor alloc] init]);
   }
   return self;
 }
@@ -83,25 +85,19 @@
 }
 
 - (void)windowWillClose:(NSNotification*)notification {
-  // Force the field editors to resign the first responder so that they'll
-  // be removed from the view hierarchy and its delegate be set to nil.
-  [[self window] endEditingFor:urlField_];
-  [[self window] endEditingFor:nameTextField_];
+  [urlFieldEditor_ setFieldEditor:NO];
+  [nameFieldEditor_ setFieldEditor:NO];
 
+  urlFieldEditor_.reset();
+  nameFieldEditor_.reset();
   [super windowWillClose:notification];
 }
 
 - (id)windowWillReturnFieldEditor:(NSWindow*)sender toObject:(id)obj {
-  if (obj == urlField_) {
-    if (!urlFieldEditor_)
-      urlFieldEditor_.reset([[DialogTextFieldEditor alloc] init]);
+  if (obj == urlField_)
     return urlFieldEditor_.get();
-  } else if (obj == nameTextField_) {
-    if (!nameFieldEditor_)
-      nameFieldEditor_.reset([[DialogTextFieldEditor alloc] init]);
-
+  else if (obj == nameTextField_)
     return nameFieldEditor_.get();
-  }
 
   return nil;
 }
diff --git a/chrome/browser/ui/views/payments/OWNERS b/chrome/browser/ui/views/payments/OWNERS
index bfd9731..2ef2393 100644
--- a/chrome/browser/ui/views/payments/OWNERS
+++ b/chrome/browser/ui/views/payments/OWNERS
@@ -2,4 +2,4 @@
 mathp@chromium.org
 rouslan@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
index 9c5f0ca..f4123b4 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -447,7 +447,7 @@
   std::string allow_access_requests_string;
   if (net::GetValueForKeyInQuery(url, "allow_access_requests",
                                  &allow_access_requests_string)) {
-    allow_access_requests = allow_access_requests_string == "0";
+    allow_access_requests = allow_access_requests_string == "1";
   }
 
   bool is_child_account = false;
@@ -457,6 +457,12 @@
     is_child_account = is_child_account_string == "1";
   }
 
+  bool is_deprecated = false;
+  std::string is_deprecated_string;
+  if (net::GetValueForKeyInQuery(url, "is_deprecated", &is_deprecated_string)) {
+    is_deprecated = is_deprecated_string == "1" && !is_child_account;
+  }
+
   std::string custodian;
   net::GetValueForKeyInQuery(url, "custodian", &custodian);
   std::string second_custodian;
@@ -487,5 +493,6 @@
   return supervised_user_error_page::BuildHtml(
       allow_access_requests, profile_image_url, profile_image_url2, custodian,
       custodian_email, second_custodian, second_custodian_email,
-      is_child_account, reason, g_browser_process->GetApplicationLocale());
+      is_child_account, is_deprecated, reason,
+      g_browser_process->GetApplicationLocale());
 }
diff --git a/chrome/browser/ui/webui/settings_utils_linux.cc b/chrome/browser/ui/webui/settings_utils_linux.cc
index f72fa4d..26a72ee 100644
--- a/chrome/browser/ui/webui/settings_utils_linux.cc
+++ b/chrome/browser/ui/webui/settings_utils_linux.cc
@@ -11,6 +11,8 @@
 #include "base/files/file_util.h"
 #include "base/nix/xdg_util.h"
 #include "base/process/launch.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "content/public/browser/browser_thread.h"
@@ -39,7 +41,7 @@
 
 // The URL for Linux proxy configuration help when not running under a
 // supported desktop environment.
-const char kLinuxProxyConfigUrl[] = "about:linux-proxy-config";
+constexpr char kLinuxProxyConfigUrl[] = "about:linux-proxy-config";
 
 // Show the proxy config URL in the given tab.
 void ShowLinuxProxyConfigUrl(int render_process_id, int render_view_id) {
@@ -60,7 +62,7 @@
 
 // Start the given proxy configuration utility.
 bool StartProxyConfigUtil(const char* const command[]) {
-  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+  base::ThreadRestrictions::AssertIOAllowed();
   // base::LaunchProcess() returns true ("success") if the fork()
   // succeeds, but not necessarily the exec(). We'd like to be able to
   // use StartProxyConfigUtil() to search possible options and stop on
@@ -86,7 +88,7 @@
 // failure to do so, show the Linux proxy config URL in a new tab instead.
 void DetectAndStartProxyConfigUtil(int render_process_id,
                                    int render_view_id) {
-  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+  base::ThreadRestrictions::AssertIOAllowed();
   std::unique_ptr<base::Environment> env(base::Environment::Create());
 
   bool launched = false;
@@ -135,8 +137,8 @@
 namespace settings_utils {
 
 void ShowNetworkProxySettings(content::WebContents* web_contents) {
-  BrowserThread::PostTask(
-      BrowserThread::FILE, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
       base::BindOnce(&DetectAndStartProxyConfigUtil,
                      web_contents->GetRenderProcessHost()->GetID(),
                      web_contents->GetRenderViewHost()->GetRoutingID()));
diff --git a/chrome/browser/ui/webui/settings_utils_win.cc b/chrome/browser/ui/webui/settings_utils_win.cc
index 938389e..7badcf5 100644
--- a/chrome/browser/ui/webui/settings_utils_win.cc
+++ b/chrome/browser/ui/webui/settings_utils_win.cc
@@ -13,19 +13,17 @@
 #include "base/macros.h"
 #include "base/path_service.h"
 #include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/cryptuiapi_shim.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/platform_font_win.h"
 #include "ui/shell_dialogs/base_shell_dialog_win.h"
 #include "ui/views/win/hwnd_util.h"
 
-using content::BrowserThread;
-
 namespace settings_utils {
 
 namespace {
@@ -98,10 +96,9 @@
 }
 
 void ShowNetworkProxySettings(content::WebContents* web_contents) {
-  DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::FILE));
-  BrowserThread::PostTask(BrowserThread::FILE,
-                          FROM_HERE,
-                          base::Bind(&OpenConnectionDialogCallback));
+  base::PostTaskWithTraits(FROM_HERE,
+                           {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+                           base::Bind(&OpenConnectionDialogCallback));
 }
 
 void ShowManageSSLCertificates(content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/webui/version_handler.cc b/chrome/browser/ui/webui/version_handler.cc
index d95e8df..e061d1c3 100644
--- a/chrome/browser/ui/webui/version_handler.cc
+++ b/chrome/browser/ui/webui/version_handler.cc
@@ -12,6 +12,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/thread_restrictions.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
@@ -33,7 +35,7 @@
 void GetFilePaths(const base::FilePath& profile_path,
                   base::string16* exec_path_out,
                   base::string16* profile_path_out) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
+  base::ThreadRestrictions::AssertIOAllowed();
 
   base::FilePath executable_path = base::MakeAbsoluteFilePath(
       base::CommandLine::ForCurrentProcess()->GetProgram());
@@ -78,8 +80,8 @@
   // OnGotFilePaths.
   base::string16* exec_path_buffer = new base::string16;
   base::string16* profile_path_buffer = new base::string16;
-  content::BrowserThread::PostTaskAndReply(
-      content::BrowserThread::FILE, FROM_HERE,
+  base::PostTaskWithTraitsAndReply(
+      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
       base::BindOnce(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(),
                      base::Unretained(exec_path_buffer),
                      base::Unretained(profile_path_buffer)),
diff --git a/chrome/browser/ui/webui/voice_search_ui.cc b/chrome/browser/ui/webui/voice_search_ui.cc
index 6e3882b6..c80ce793 100644
--- a/chrome/browser/ui/webui/voice_search_ui.cc
+++ b/chrome/browser/ui/webui/voice_search_ui.cc
@@ -16,6 +16,8 @@
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -105,9 +107,8 @@
 }
 
 void AddSharedModulePlatformsOnFileThread(base::ListValue* list,
-                                          const base::FilePath& path,
-                                          base::Closure callback) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
+                                          const base::FilePath& path) {
+  base::ThreadRestrictions::AssertIOAllowed();
 
   if (!path.empty()) {
     // Display available platforms for shared module.
@@ -125,10 +126,6 @@
               files.empty() ? ASCIIToUTF16("undefined") : files);
     AddLineBreak(list);
   }
-
-  content::BrowserThread::PostTask(content::BrowserThread::UI,
-                                   FROM_HERE,
-                                   callback);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -202,12 +199,12 @@
         path = extension->path();
     }
     base::ListValue* raw_list = list.get();
-    content::BrowserThread::PostTask(
-        content::BrowserThread::FILE, FROM_HERE,
-        base::Bind(&AddSharedModulePlatformsOnFileThread, raw_list, path,
-                   base::Bind(&VoiceSearchDomHandler::ReturnVoiceSearchInfo,
-                              weak_factory_.GetWeakPtr(),
-                              base::Passed(std::move(list)))));
+    base::PostTaskWithTraitsAndReply(
+        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
+        base::BindOnce(&AddSharedModulePlatformsOnFileThread, raw_list, path),
+        base::BindOnce(&VoiceSearchDomHandler::ReturnVoiceSearchInfo,
+                       weak_factory_.GetWeakPtr(),
+                       base::Passed(std::move(list))));
   }
 
   // Adds information regarding the system and chrome version info to list.
diff --git a/chrome/test/data/extensions/api_test/vpn_provider/OWNERS b/chrome/test/data/extensions/api_test/vpn_provider/OWNERS
index c83fa211..a913a05 100644
--- a/chrome/test/data/extensions/api_test/vpn_provider/OWNERS
+++ b/chrome/test/data/extensions/api_test/vpn_provider/OWNERS
@@ -1,3 +1,2 @@
-kaliamoorthi@chromium.org
 bartfab@chromium.org
 emaxx@chromium.org
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index 08cbad2c..93f65e7 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -481,6 +481,15 @@
 }
 
 if (is_android) {
+  generate_jni_registration("cast_shell_jni_registration") {
+    target = ":cast_shell_apk"
+    output = "$root_gen_dir/chromecast/android/${target_name}.h"
+    exception_files = [
+      "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+    ]
+  }
   android_assets("cast_shell_apk_assets") {
     assert(v8_use_external_startup_data)
 
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn
index 1d29974..321a3d2 100644
--- a/chromecast/android/BUILD.gn
+++ b/chromecast/android/BUILD.gn
@@ -27,6 +27,7 @@
   deps = [
     ":platform_jni_loader",
     "//base",
+    "//chromecast:cast_shell_jni_registration",
     "//chromecast:cast_shell_lib",
     "//chromecast:chromecast_features",
     "//chromecast/app",
diff --git a/chromecast/app/android/cast_jni_loader.cc b/chromecast/app/android/cast_jni_loader.cc
index 79a32fe..73b829bb 100644
--- a/chromecast/app/android/cast_jni_loader.cc
+++ b/chromecast/app/android/cast_jni_loader.cc
@@ -6,6 +6,7 @@
 #include "base/android/library_loader/library_loader_hooks.h"
 #include "base/bind.h"
 #include "chromecast/android/cast_jni_registrar.h"
+#include "chromecast/android/cast_shell_jni_registration.h"
 #include "chromecast/android/platform_jni_loader.h"
 #include "chromecast/app/cast_main_delegate.h"
 #include "chromecast/browser/android/jni_registrar.h"
@@ -42,6 +43,12 @@
 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+  if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+    return -1;
+  }
+
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
       !NativeInit()) {
     return -1;
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 5e727a3..2fdc2d87 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -25,6 +25,16 @@
   jni_package = "cronet"
 }
 
+generate_jni_registration("cronet_jni_registration") {
+  target = ":cronet_sample_apk"
+  output = "$root_gen_dir/components/cronet/android/${target_name}.h"
+  exception_files = [
+    "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+  ]
+}
+
 java_cpp_enum("effective_connection_type_java") {
   sources = [
     "//net/nqe/effective_connection_type.h",
@@ -165,6 +175,7 @@
     deps = [
       ":cronet_android_cert_proto",
       ":cronet_jni_headers",
+      ":cronet_jni_registration",
       ":cronet_version_header",
       "//base",
       "//base/third_party/dynamic_annotations",
@@ -529,6 +540,9 @@
   ]
 
   include_dirs = [ _cronet_version_header_include_dir ]
+
+  configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+  configs += [ "//build/config/android:hide_all_but_jni" ]
 }
 
 android_resources("cronet_test_apk_resources") {
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc
index 72c416e..b7aa07a 100644
--- a/components/cronet/android/cronet_library_loader.cc
+++ b/components/cronet/android/cronet_library_loader.cc
@@ -19,6 +19,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/statistics_recorder.h"
 #include "components/cronet/android/cronet_bidirectional_stream_adapter.h"
+#include "components/cronet/android/cronet_jni_registration.h"
 #include "components/cronet/android/cronet_upload_data_stream_adapter.h"
 #include "components/cronet/android/cronet_url_request_adapter.h"
 #include "components/cronet/android/cronet_url_request_context_adapter.h"
@@ -84,6 +85,11 @@
 jint CronetOnLoad(JavaVM* vm, void* reserved) {
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+  if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+    return -1;
+  }
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (!RegisterJNI(env) || !NativeInit()) {
     return -1;
   }
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index fc7021b2..549b6fc 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -742,8 +742,8 @@
   FormStructure pending_structure(pending->form_data);
   FormStructure observed_structure(observed.form_data);
 
-  if (pending_structure.FormSignatureAsStr() !=
-      observed_structure.FormSignatureAsStr()) {
+  if (pending_structure.form_signature() !=
+      observed_structure.form_signature()) {
     // Only upload if this is the first time the password has been used.
     // Otherwise the credentials have been used on the same field before so
     // they aren't from an account creation form.
diff --git a/components/payments/OWNERS b/components/payments/OWNERS
index 2ff5e3b3..1a9e64d 100644
--- a/components/payments/OWNERS
+++ b/components/payments/OWNERS
@@ -1,4 +1,4 @@
 mathp@chromium.org
 rouslan@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/payments/android/OWNERS b/components/payments/android/OWNERS
index e39fa27..55cc03e 100644
--- a/components/payments/android/OWNERS
+++ b/components/payments/android/OWNERS
@@ -1,3 +1,3 @@
 gogerald@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/payments/content/OWNERS b/components/payments/content/OWNERS
index 913eb47b..b30e98fc 100644
--- a/components/payments/content/OWNERS
+++ b/components/payments/content/OWNERS
@@ -1,3 +1,3 @@
 per-file payment_response_helper*=sebsg@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/payments/content/android/OWNERS b/components/payments/content/android/OWNERS
index e39fa27..55cc03e 100644
--- a/components/payments/content/android/OWNERS
+++ b/components/payments/content/android/OWNERS
@@ -1,3 +1,3 @@
 gogerald@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/payments/core/OWNERS b/components/payments/core/OWNERS
index 396d240..a54ecb4 100644
--- a/components/payments/core/OWNERS
+++ b/components/payments/core/OWNERS
@@ -1,4 +1,4 @@
 per-file journey_logger*=sebsg@chromium.org
 per-file address_normalizer*=sebsg@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/payments/mojom/OWNERS b/components/payments/mojom/OWNERS
index 82559c92..503dfd2 100644
--- a/components/payments/mojom/OWNERS
+++ b/components/payments/mojom/OWNERS
@@ -1,4 +1,4 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/components/safe_browsing/base_resource_throttle.cc b/components/safe_browsing/base_resource_throttle.cc
index ff2ebeb..63907f2b 100644
--- a/components/safe_browsing/base_resource_throttle.cc
+++ b/components/safe_browsing/base_resource_throttle.cc
@@ -4,6 +4,8 @@
 
 #include "components/safe_browsing/base_resource_throttle.h"
 
+#include <utility>
+
 #include "base/metrics/histogram_macros.h"
 #include "base/trace_event/trace_event.h"
 #include "base/values.h"
@@ -69,10 +71,12 @@
 BaseResourceThrottle::BaseResourceThrottle(
     const net::URLRequest* request,
     content::ResourceType resource_type,
+    SBThreatTypeSet threat_types,
     scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
     scoped_refptr<BaseUIManager> ui_manager)
     : ui_manager_(ui_manager),
       threat_type_(SB_THREAT_TYPE_SAFE),
+      threat_types_(std::move(threat_types)),
       database_manager_(database_manager),
       request_(request),
       state_(STATE_NONE),
@@ -345,7 +349,7 @@
   UMA_HISTOGRAM_ENUMERATION("SB2.ResourceTypes2.Checked", resource_type_,
                             content::RESOURCE_TYPE_LAST_TYPE);
 
-  if (database_manager_->CheckBrowseUrl(url, this)) {
+  if (database_manager_->CheckBrowseUrl(url, threat_types_, this)) {
     threat_type_ = SB_THREAT_TYPE_SAFE;
     ui_manager_->LogPauseDelay(base::TimeDelta());  // No delay.
     return true;
diff --git a/components/safe_browsing/base_resource_throttle.h b/components/safe_browsing/base_resource_throttle.h
index 154913f..62938ca 100644
--- a/components/safe_browsing/base_resource_throttle.h
+++ b/components/safe_browsing/base_resource_throttle.h
@@ -13,6 +13,7 @@
 #include "base/timer/timer.h"
 #include "components/safe_browsing/base_ui_manager.h"
 #include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "content/public/browser/resource_throttle.h"
 #include "content/public/common/resource_type.h"
@@ -69,8 +70,8 @@
   BaseResourceThrottle(
       const net::URLRequest* request,
       content::ResourceType resource_type,
-      scoped_refptr<SafeBrowsingDatabaseManager>
-          database_manager,
+      SBThreatTypeSet threat_types,
+      scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
       scoped_refptr<BaseUIManager> ui_manager);
 
   ~BaseResourceThrottle() override;
@@ -168,6 +169,7 @@
   GURL unchecked_redirect_url_;
   GURL url_being_checked_;
 
+  const SBThreatTypeSet threat_types_;
   scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
   const net::URLRequest* request_;
 
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn
index 28fd0e30..33eb8e5 100644
--- a/components/safe_browsing_db/BUILD.gn
+++ b/components/safe_browsing_db/BUILD.gn
@@ -113,6 +113,7 @@
     ":database_manager",
     ":safe_browsing_api_handler",
     ":v4_get_hash_protocol_manager",
+    ":v4_protocol_manager_util",
     "//base:base",
     "//components/variations",
     "//content/public/browser",
@@ -164,6 +165,7 @@
   ]
   deps = [
     ":database_manager",
+    ":v4_protocol_manager_util",
     "//base:base",
     "//net",
   ]
@@ -374,6 +376,7 @@
   deps = [
     ":v4_database",
     ":v4_local_database_manager",
+    ":v4_protocol_manager_util",
     ":v4_test_util",
     "//base",
     "//base/test:test_support",
diff --git a/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc b/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
index 841d18c..3acd9a41 100644
--- a/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
+++ b/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
@@ -10,8 +10,10 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
+#include "base/containers/flat_set.h"
 #include "base/metrics/histogram_macros.h"
 #include "components/safe_browsing_db/safe_browsing_api_handler_util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "jni/SafeBrowsingApiBridge_jni.h"
 
@@ -57,9 +59,9 @@
 }
 
 // Convert a vector of SBThreatTypes to JavaIntArray of Java threat types.
-ScopedJavaLocalRef<jintArray> SBThreatTypesToJavaArray(
+ScopedJavaLocalRef<jintArray> SBThreatTypeSetToJavaArray(
     JNIEnv* env,
-    const std::vector<SBThreatType>& threat_types) {
+    const SBThreatTypeSet& threat_types) {
   DCHECK(threat_types.size() > 0);
   int int_threat_types[threat_types.size()];
   int* itr = &int_threat_types[0];
@@ -151,7 +153,7 @@
 void SafeBrowsingApiHandlerBridge::StartURLCheck(
     const SafeBrowsingApiHandler::URLCheckCallbackMeta& callback,
     const GURL& url,
-    const std::vector<SBThreatType>& threat_types) {
+    const SBThreatTypeSet& threat_types) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (!CheckApiIsSupported()) {
@@ -168,14 +170,12 @@
 
   DVLOG(1) << "Starting check " << callback_id << " for URL " << url;
 
-  // Default threat types, to support upstream code that doesn't yet set them.
-  std::vector<SBThreatType> local_threat_types(threat_types);
-  DCHECK(!local_threat_types.empty());
+  DCHECK(!threat_types.empty());
 
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec());
   ScopedJavaLocalRef<jintArray> j_threat_types =
-      SBThreatTypesToJavaArray(env, local_threat_types);
+      SBThreatTypeSetToJavaArray(env, threat_types);
 
   Java_SafeBrowsingApiBridge_startUriLookup(env, j_api_handler_, callback_id,
                                             j_url, j_threat_types);
diff --git a/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.h b/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.h
index 678437a..40eda4d 100644
--- a/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.h
+++ b/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.h
@@ -15,6 +15,7 @@
 #include "base/android/jni_android.h"
 #include "base/macros.h"
 #include "components/safe_browsing_db/safe_browsing_api_handler.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "url/gurl.h"
 
 namespace safe_browsing {
@@ -28,7 +29,7 @@
   // Makes Native->Java call to check the URL against Safe Browsing lists.
   void StartURLCheck(const URLCheckCallbackMeta& callback,
                      const GURL& url,
-                     const std::vector<SBThreatType>& threat_types) override;
+                     const SBThreatTypeSet& threat_types) override;
 
  private:
   // Creates the j_api_handler_ if it hasn't been already.  If the API is not
diff --git a/components/safe_browsing_db/database_manager.h b/components/safe_browsing_db/database_manager.h
index c6f655e..56331a0 100644
--- a/components/safe_browsing_db/database_manager.h
+++ b/components/safe_browsing_db/database_manager.h
@@ -18,6 +18,7 @@
 #include "base/memory/ref_counted.h"
 #include "components/safe_browsing_db/hit_report.h"
 #include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "content/public/common/resource_type.h"
 #include "url/gurl.h"
 
@@ -132,9 +133,11 @@
   // Called on the IO thread to check if the given url is safe or not.  If we
   // can synchronously determine that the url is safe, CheckUrl returns true.
   // Otherwise it returns false, and "client" is called asynchronously with the
-  // result when it is ready.
-  virtual bool CheckBrowseUrl(const GURL& url, Client* client) = 0;
-
+  // result when it is ready. The URL will only be checked for the threat types
+  // in |threat_types|.
+  virtual bool CheckBrowseUrl(const GURL& url,
+                              const SBThreatTypeSet& threat_types,
+                              Client* client) = 0;
 
   // Check if the prefix for |url| is in safebrowsing download add lists.
   // Result will be passed to callback in |client|.
diff --git a/components/safe_browsing_db/remote_database_manager.cc b/components/safe_browsing_db/remote_database_manager.cc
index 287defc..6106e44c 100644
--- a/components/safe_browsing_db/remote_database_manager.cc
+++ b/components/safe_browsing_db/remote_database_manager.cc
@@ -13,6 +13,7 @@
 #include "base/timer/elapsed_timer.h"
 #include "components/safe_browsing_db/safe_browsing_api_handler.h"
 #include "components/safe_browsing_db/v4_get_hash_protocol_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/variations/variations_associated_data.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -181,9 +182,13 @@
   return true;
 }
 
-bool RemoteSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& url,
-                                                       Client* client) {
+bool RemoteSafeBrowsingDatabaseManager::CheckBrowseUrl(
+    const GURL& url,
+    const SBThreatTypeSet& threat_types,
+    Client* client) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!threat_types.empty());
+  DCHECK(SBThreatTypeSetIsValidForCheckBrowseUrl(threat_types));
   if (!enabled_)
     return true;
 
@@ -202,8 +207,7 @@
   DCHECK(api_handler) << "SafeBrowsingApiHandler was never constructed";
   api_handler->StartURLCheck(
       base::Bind(&ClientRequest::OnRequestDoneWeak, req->GetWeakPtr()), url,
-      {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_URL_PHISHING,
-       SB_THREAT_TYPE_URL_UNWANTED});
+      threat_types);
 
   LogPendingChecks(current_requests_.size());
   current_requests_.push_back(req.release());
@@ -249,7 +253,8 @@
   DCHECK(api_handler) << "SafeBrowsingApiHandler was never constructed";
   api_handler->StartURLCheck(
       base::Bind(&ClientRequest::OnRequestDoneWeak, req->GetWeakPtr()), url,
-      {SB_THREAT_TYPE_SUBRESOURCE_FILTER, SB_THREAT_TYPE_URL_PHISHING});
+      CreateSBThreatTypeSet(
+          {SB_THREAT_TYPE_SUBRESOURCE_FILTER, SB_THREAT_TYPE_URL_PHISHING}));
 
   LogPendingChecks(current_requests_.size());
   current_requests_.push_back(req.release());
diff --git a/components/safe_browsing_db/remote_database_manager.h b/components/safe_browsing_db/remote_database_manager.h
index eb329f2..87e4c3d 100644
--- a/components/safe_browsing_db/remote_database_manager.h
+++ b/components/safe_browsing_db/remote_database_manager.h
@@ -43,7 +43,9 @@
   bool CanCheckResourceType(content::ResourceType resource_type) const override;
   bool CanCheckUrl(const GURL& url) const override;
   bool ChecksAreAlwaysAsync() const override;
-  bool CheckBrowseUrl(const GURL& url, Client* client) override;
+  bool CheckBrowseUrl(const GURL& url,
+                      const SBThreatTypeSet& threat_types,
+                      Client* client) override;
   bool CheckDownloadUrl(const std::vector<GURL>& url_chain,
                         Client* client) override;
   bool CheckExtensionIDs(const std::set<std::string>& extension_ids,
diff --git a/components/safe_browsing_db/remote_database_manager_unittest.cc b/components/safe_browsing_db/remote_database_manager_unittest.cc
index 284b335..08b9a58 100644
--- a/components/safe_browsing_db/remote_database_manager_unittest.cc
+++ b/components/safe_browsing_db/remote_database_manager_unittest.cc
@@ -22,7 +22,7 @@
  public:
   void StartURLCheck(const URLCheckCallbackMeta& callback,
                      const GURL& url,
-                     const std::vector<SBThreatType>& threat_types) override {}
+                     const SBThreatTypeSet& threat_types) override {}
 };
 
 }  // namespace
diff --git a/components/safe_browsing_db/safe_browsing_api_handler.h b/components/safe_browsing_db/safe_browsing_api_handler.h
index fa01a60..f2e7aba 100644
--- a/components/safe_browsing_db/safe_browsing_api_handler.h
+++ b/components/safe_browsing_db/safe_browsing_api_handler.h
@@ -13,6 +13,7 @@
 
 #include "base/callback.h"
 #include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "url/gurl.h"
 
 namespace safe_browsing {
@@ -30,7 +31,7 @@
   // Makes Native->Java call and invokes callback when check is done.
   virtual void StartURLCheck(const URLCheckCallbackMeta& callback,
                              const GURL& url,
-                             const std::vector<SBThreatType>& threat_types) = 0;
+                             const SBThreatTypeSet& threat_types) = 0;
 
   virtual ~SafeBrowsingApiHandler() {}
 
diff --git a/components/safe_browsing_db/test_database_manager.cc b/components/safe_browsing_db/test_database_manager.cc
index cdca0b0..1876666 100644
--- a/components/safe_browsing_db/test_database_manager.cc
+++ b/components/safe_browsing_db/test_database_manager.cc
@@ -33,8 +33,10 @@
   return false;
 }
 
-bool TestSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& url,
-                                                     Client* client) {
+bool TestSafeBrowsingDatabaseManager::CheckBrowseUrl(
+    const GURL& url,
+    const SBThreatTypeSet& threat_types,
+    Client* client) {
   NOTIMPLEMENTED();
   return true;
 }
diff --git a/components/safe_browsing_db/test_database_manager.h b/components/safe_browsing_db/test_database_manager.h
index 37598e60..a006e1b2 100644
--- a/components/safe_browsing_db/test_database_manager.h
+++ b/components/safe_browsing_db/test_database_manager.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 
 namespace safe_browsing {
 
@@ -25,7 +26,9 @@
   bool CanCheckResourceType(content::ResourceType resource_type) const override;
   bool CanCheckUrl(const GURL& url) const override;
   bool ChecksAreAlwaysAsync() const override;
-  bool CheckBrowseUrl(const GURL& url, Client* client) override;
+  bool CheckBrowseUrl(const GURL& url,
+                      const SBThreatTypeSet& threat_types,
+                      Client* client) override;
   AsyncMatch CheckCsdWhitelistUrl(const GURL& url, Client* client) override;
   bool CheckDownloadUrl(const std::vector<GURL>& url_chain,
                         Client* client) override;
diff --git a/components/safe_browsing_db/v4_local_database_manager.cc b/components/safe_browsing_db/v4_local_database_manager.cc
index 7b3dd18..fca4f97 100644
--- a/components/safe_browsing_db/v4_local_database_manager.cc
+++ b/components/safe_browsing_db/v4_local_database_manager.cc
@@ -112,6 +112,34 @@
   }
 }
 
+// This is only valid for types that are passed to GetBrowseUrl().
+ListIdentifier GetUrlIdFromSBThreatType(SBThreatType sb_threat_type) {
+  switch (sb_threat_type) {
+    case SB_THREAT_TYPE_URL_MALWARE:
+      return GetUrlMalwareId();
+
+    case SB_THREAT_TYPE_URL_PHISHING:
+      return GetUrlSocEngId();
+
+    case SB_THREAT_TYPE_URL_UNWANTED:
+      return GetUrlUwsId();
+
+    default:
+      NOTREACHED();
+      // Compiler requires a return statement here.
+      return GetUrlMalwareId();
+  }
+}
+
+StoresToCheck CreateStoresToCheckFromSBThreatTypeSet(
+    const SBThreatTypeSet& threat_types) {
+  StoresToCheck stores_to_check;
+  for (SBThreatType sb_threat_type : threat_types) {
+    stores_to_check.insert(GetUrlIdFromSBThreatType(sb_threat_type));
+  }
+  return stores_to_check;
+}
+
 }  // namespace
 
 V4LocalDatabaseManager::PendingCheck::PendingCheck(
@@ -217,8 +245,12 @@
   return false;
 }
 
-bool V4LocalDatabaseManager::CheckBrowseUrl(const GURL& url, Client* client) {
+bool V4LocalDatabaseManager::CheckBrowseUrl(const GURL& url,
+                                            const SBThreatTypeSet& threat_types,
+                                            Client* client) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!threat_types.empty());
+  DCHECK(SBThreatTypeSetIsValidForCheckBrowseUrl(threat_types));
 
   if (!enabled_ || !CanCheckUrl(url)) {
     return true;
@@ -226,7 +258,7 @@
 
   std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>(
       client, ClientCallbackType::CHECK_BROWSE_URL,
-      StoresToCheck({GetUrlMalwareId(), GetUrlSocEngId(), GetUrlUwsId()}),
+      CreateStoresToCheckFromSBThreatTypeSet(threat_types),
       std::vector<GURL>(1, url));
 
   return HandleCheck(std::move(check));
diff --git a/components/safe_browsing_db/v4_local_database_manager.h b/components/safe_browsing_db/v4_local_database_manager.h
index b82d9a8..a6b1533 100644
--- a/components/safe_browsing_db/v4_local_database_manager.h
+++ b/components/safe_browsing_db/v4_local_database_manager.h
@@ -42,7 +42,9 @@
   bool CanCheckResourceType(content::ResourceType resource_type) const override;
   bool CanCheckUrl(const GURL& url) const override;
   bool ChecksAreAlwaysAsync() const override;
-  bool CheckBrowseUrl(const GURL& url, Client* client) override;
+  bool CheckBrowseUrl(const GURL& url,
+                      const SBThreatTypeSet& threat_types,
+                      Client* client) override;
   AsyncMatch CheckCsdWhitelistUrl(const GURL& url, Client* client) override;
   bool CheckDownloadUrl(const std::vector<GURL>& url_chain,
                         Client* client) override;
diff --git a/components/safe_browsing_db/v4_local_database_manager_unittest.cc b/components/safe_browsing_db/v4_local_database_manager_unittest.cc
index 504bc21..f40d341 100644
--- a/components/safe_browsing_db/v4_local_database_manager_unittest.cc
+++ b/components/safe_browsing_db/v4_local_database_manager_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/safe_browsing_db/v4_database.h"
+#include "components/safe_browsing_db/v4_protocol_manager_util.h"
 #include "components/safe_browsing_db/v4_test_util.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "crypto/sha2.h"
@@ -384,6 +385,10 @@
     WaitForTasksOnTaskRunner();
   }
 
+  const SBThreatTypeSet usual_threat_types_ = CreateSBThreatTypeSet(
+      {SB_THREAT_TYPE_URL_PHISHING, SB_THREAT_TYPE_URL_MALWARE,
+       SB_THREAT_TYPE_URL_UNWANTED});
+
   base::ScopedTempDir base_dir_;
   ExtendedReportingLevel extended_reporting_level_;
   ExtendedReportingLevelCallback erl_callback_;
@@ -420,7 +425,7 @@
   WaitForTasksOnTaskRunner();
   // Both the stores are empty right now so CheckBrowseUrl should return true.
   EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
-      GURL("http://example.com/a/"), nullptr));
+      GURL("http://example.com/a/"), usual_threat_types_, nullptr));
 }
 
 TEST_F(V4LocalDatabaseManagerTest, TestCheckBrowseUrlWithFakeDbReturnsMatch) {
@@ -435,7 +440,8 @@
   ReplaceV4Database(store_and_hash_prefixes);
 
   const GURL url_bad("https://" + url_bad_no_scheme);
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url_bad, nullptr));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      url_bad, usual_threat_types_, nullptr));
 
   // Wait for PerformFullHashCheck to complete.
   WaitForTasksOnTaskRunner();
@@ -571,7 +577,7 @@
   ForceDisableLocalDatabaseManager();
 
   EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
-      GURL("http://example.com/a/"), nullptr));
+      GURL("http://example.com/a/"), usual_threat_types_, nullptr));
 }
 
 TEST_F(V4LocalDatabaseManagerTest, TestGetSeverestThreatTypeAndMetadata) {
@@ -625,7 +631,7 @@
   const GURL url("https://www.example.com/");
   TestClient client(SB_THREAT_TYPE_SAFE, url);
   EXPECT_TRUE(GetQueuedChecks().empty());
-  v4_local_database_manager_->CheckBrowseUrl(url, &client);
+  v4_local_database_manager_->CheckBrowseUrl(url, usual_threat_types_, &client);
   // The database is unavailable so the check should get queued.
   EXPECT_EQ(1ul, GetQueuedChecks().size());
 
@@ -634,7 +640,7 @@
   EXPECT_TRUE(GetQueuedChecks().empty());
 
   ResetV4Database();
-  v4_local_database_manager_->CheckBrowseUrl(url, &client);
+  v4_local_database_manager_->CheckBrowseUrl(url, usual_threat_types_, &client);
   // The database is unavailable so the check should get queued.
   EXPECT_EQ(1ul, GetQueuedChecks().size());
 
@@ -663,7 +669,8 @@
   // Test that a request flows through to the callback.
   {
     TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
-    EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url_bad, &client));
+    EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+        url_bad, usual_threat_types_, &client));
     EXPECT_FALSE(client.on_check_browse_url_result_called_);
     WaitForTasksOnTaskRunner();
     EXPECT_TRUE(client.on_check_browse_url_result_called_);
@@ -672,7 +679,8 @@
   // Test that cancel prevents the callback from being called.
   {
     TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
-    EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url_bad, &client));
+    EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+        url_bad, usual_threat_types_, &client));
     v4_local_database_manager_->CancelCheck(&client);
     EXPECT_FALSE(client.on_check_browse_url_result_called_);
     WaitForTasksOnTaskRunner();
@@ -688,8 +696,10 @@
   TestClient client1(SB_THREAT_TYPE_SAFE, url,
                      v4_local_database_manager_.get());
   TestClient client2(SB_THREAT_TYPE_SAFE, url);
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client1));
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client2));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      url, usual_threat_types_, &client1));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      url, usual_threat_types_, &client2));
   EXPECT_EQ(2ul, GetQueuedChecks().size());
   EXPECT_FALSE(client1.on_check_browse_url_result_called_);
   EXPECT_FALSE(client2.on_check_browse_url_result_called_);
@@ -714,7 +724,8 @@
 
   const GURL url_bad("https://" + url_bad_no_scheme);
   // The fake database returns a matched hash prefix.
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url_bad, nullptr));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      url_bad, usual_threat_types_, nullptr));
 
   EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
       v4_local_database_manager_));
@@ -738,7 +749,8 @@
   ReplaceV4Database(store_and_hash_prefixes);
 
   const GURL url_bad("https://" + url_bad_no_scheme);
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url_bad, nullptr));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      url_bad, usual_threat_types_, nullptr));
   v4_local_database_manager_->StopOnIOThread(true);
 
   // Release the V4LocalDatabaseManager object right away before the callback
@@ -889,7 +901,8 @@
   GURL second_url("http://example.com/");
   TestClient client(SB_THREAT_TYPE_SAFE, first_url);
   // The fake database returns a matched hash prefix.
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(first_url, &client));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      first_url, usual_threat_types_, &client));
 
   // That check gets queued. Now, let's cancel the check. After this, we should
   // not receive a call for |OnCheckBrowseUrlResult| with |first_url|.
@@ -897,7 +910,8 @@
 
   // Now, re-use that client but for |second_url|.
   client.expected_urls.assign(1, second_url);
-  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(second_url, &client));
+  EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
+      second_url, usual_threat_types_, &client));
 
   // Wait for PerformFullHashCheck to complete.
   WaitForTasksOnTaskRunner();
diff --git a/components/safe_browsing_db/v4_protocol_manager_util.cc b/components/safe_browsing_db/v4_protocol_manager_util.cc
index 63a9e90..5153d4a 100644
--- a/components/safe_browsing_db/v4_protocol_manager_util.cc
+++ b/components/safe_browsing_db/v4_protocol_manager_util.cc
@@ -172,6 +172,21 @@
   return base::HashInts(first, second);
 }
 
+bool SBThreatTypeSetIsValidForCheckBrowseUrl(const SBThreatTypeSet& set) {
+  for (SBThreatType type : set) {
+    switch (type) {
+      case SB_THREAT_TYPE_URL_PHISHING:
+      case SB_THREAT_TYPE_URL_MALWARE:
+      case SB_THREAT_TYPE_URL_UNWANTED:
+        break;
+
+      default:
+        return false;
+    }
+  }
+  return true;
+}
+
 bool ListIdentifier::operator==(const ListIdentifier& other) const {
   return platform_type_ == other.platform_type_ &&
          threat_entry_type_ == other.threat_entry_type_ &&
diff --git a/components/safe_browsing_db/v4_protocol_manager_util.h b/components/safe_browsing_db/v4_protocol_manager_util.h
index b8d2b11..2f345d9 100644
--- a/components/safe_browsing_db/v4_protocol_manager_util.h
+++ b/components/safe_browsing_db/v4_protocol_manager_util.h
@@ -8,6 +8,7 @@
 // A class that implements the stateless methods used by the GetHashUpdate and
 // GetFullHash stubby calls made by Chrome using the SafeBrowsing V4 protocol.
 
+#include <initializer_list>
 #include <memory>
 #include <ostream>
 #include <string>
@@ -15,6 +16,7 @@
 #include <unordered_set>
 #include <vector>
 
+#include "base/containers/flat_set.h"
 #include "base/gtest_prod_util.h"
 #include "base/strings/string_piece.h"
 #include "components/safe_browsing_db/safebrowsing.pb.h"
@@ -123,6 +125,20 @@
   SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING,
 };
 
+using SBThreatTypeSet = base::flat_set<SBThreatType>;
+
+// Return true if |set| only contains types that are valid for CheckBrowseUrl().
+// Intended for use in DCHECK().
+bool SBThreatTypeSetIsValidForCheckBrowseUrl(const SBThreatTypeSet& set);
+
+// Shorthand for creating an SBThreatTypeSet from a list of SBThreatTypes. Use
+// like CreateSBThreatTypeSet({SB_THREAT_TYPE_URL_PHISHING,
+//                             SB_THREAT_TYPE_URL_MALWARE})
+inline SBThreatTypeSet CreateSBThreatTypeSet(
+    std::initializer_list<SBThreatType> set) {
+  return SBThreatTypeSet(set, base::KEEP_FIRST_OF_DUPES);
+}
+
 // The information required to uniquely identify each list the client is
 // interested in maintaining and downloading from the SafeBrowsing servers.
 // For example, for digests of Malware binaries on Windows:
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js
index 6b9abf4..e6786f6b 100644
--- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js
+++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js
@@ -46,7 +46,8 @@
 }
 
 function initialize() {
-  if (loadTimeData.getBoolean('allowAccessRequests')) {
+  var allowAccessRequests = loadTimeData.getBoolean('allowAccessRequests');
+  if (allowAccessRequests) {
     $('request-access-button').onclick = function(event) {
       $('request-access-button').hidden = true;
       if (window.domAutomationController) {
@@ -61,7 +62,7 @@
   var avatarURL1x = loadTimeData.getString('avatarURL1x');
   var avatarURL2x = loadTimeData.getString('avatarURL2x');
   var custodianName = loadTimeData.getString('custodianName');
-  if (custodianName) {
+  if (custodianName && allowAccessRequests) {
     $('custodians-information').hidden = false;
     if (avatarURL1x) {
       $('custodian-avatar-img').style.content =
diff --git a/components/supervised_user_error_page/supervised_user_error_page.cc b/components/supervised_user_error_page/supervised_user_error_page.cc
index e098c062..7baabc9 100644
--- a/components/supervised_user_error_page/supervised_user_error_page.cc
+++ b/components/supervised_user_error_page/supervised_user_error_page.cc
@@ -39,7 +39,14 @@
 
 int GetBlockMessageID(FilteringBehaviorReason reason,
                       bool is_child_account,
+                      bool is_deprecated,
                       bool single_parent) {
+  if (is_deprecated) {
+    // The deprecation message is specific to Supervised Users.
+    DCHECK(!is_child_account);
+    return IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED;
+  }
+
   switch (reason) {
     case DEFAULT:
       if (!is_child_account)
@@ -74,6 +81,7 @@
                       const std::string& second_custodian,
                       const std::string& second_custodian_email,
                       bool is_child_account,
+                      bool is_deprecated,
                       FilteringBehaviorReason reason,
                       const std::string& app_locale) {
   base::DictionaryValue strings;
@@ -117,9 +125,10 @@
   }
   strings.SetString("blockPageHeader", block_header);
   strings.SetString("blockPageMessage", block_message);
-  strings.SetString("blockReasonMessage",
-                    l10n_util::GetStringUTF16(GetBlockMessageID(
-                        reason, is_child_account, second_custodian.empty())));
+  strings.SetString(
+      "blockReasonMessage",
+      l10n_util::GetStringUTF16(GetBlockMessageID(
+          reason, is_child_account, is_deprecated, second_custodian.empty())));
   strings.SetString("blockReasonHeader", l10n_util::GetStringUTF16(
                                              IDS_SUPERVISED_USER_BLOCK_HEADER));
   bool show_feedback = ReasonIsAutomatic(reason);
diff --git a/components/supervised_user_error_page/supervised_user_error_page.h b/components/supervised_user_error_page/supervised_user_error_page.h
index 66456f2b..4bb6708 100644
--- a/components/supervised_user_error_page/supervised_user_error_page.h
+++ b/components/supervised_user_error_page/supervised_user_error_page.h
@@ -23,6 +23,7 @@
 int GetBlockMessageID(
     supervised_user_error_page::FilteringBehaviorReason reason,
     bool is_child_account,
+    bool is_deprecated,
     bool single_parent);
 
 std::string BuildHtml(bool allow_access_requests,
@@ -33,6 +34,7 @@
                       const std::string& second_custodian,
                       const std::string& second_custodian_email,
                       bool is_child_account,
+                      bool is_deprecated,
                       FilteringBehaviorReason reason,
                       const std::string& app_locale);
 
diff --git a/components/supervised_user_error_page/supervised_user_error_page_android.cc b/components/supervised_user_error_page/supervised_user_error_page_android.cc
index b430dd5..ee7e3c1 100644
--- a/components/supervised_user_error_page/supervised_user_error_page_android.cc
+++ b/components/supervised_user_error_page/supervised_user_error_page_android.cc
@@ -29,6 +29,7 @@
       result->stringParams["Second custodian"],
       result->stringParams["Second custodian email"],
       result->intParams["Is child account"],
+      /* is_deprecated = */ false,
       static_cast<FilteringBehaviorReason>(result->intParams["Reason"]),
       app_locale);
 }
diff --git a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
index 41a6049..b2f432d0 100644
--- a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
+++ b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
@@ -18,6 +18,7 @@
 struct BlockMessageIDTestParameter {
   FilteringBehaviorReason reason;
   bool is_child_account;
+  bool is_deprecated;
   bool single_parent;
   int expected_result;
 };
@@ -29,24 +30,36 @@
   BlockMessageIDTestParameter param = GetParam();
   EXPECT_EQ(param.expected_result,
             GetBlockMessageID(param.reason, param.is_child_account,
-                              param.single_parent))
+                              param.is_deprecated, param.single_parent))
       << "reason = " << param.reason
       << " is_child_account = " << param.is_child_account
       << " single parent = " << param.single_parent;
 }
 
 BlockMessageIDTestParameter block_message_id_test_params[] = {
-    {DEFAULT, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT},
-    {DEFAULT, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT},
-    {DEFAULT, true, true, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_SINGLE_PARENT},
-    {DEFAULT, true, false, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_MULTI_PARENT},
+    {DEFAULT, false, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT},
+    {DEFAULT, false, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT},
+    {DEFAULT, false, true, false,
+     IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED},
+    {DEFAULT, false, true, true,
+     IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED},
+    {DEFAULT, true, false, true, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_SINGLE_PARENT},
+    {DEFAULT, true, false, false, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_MULTI_PARENT},
     // SafeSites is not enabled for supervised users.
-    {ASYNC_CHECKER, true, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
-    {ASYNC_CHECKER, true, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
-    {MANUAL, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL},
-    {MANUAL, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL},
-    {MANUAL, true, true, IDS_CHILD_BLOCK_MESSAGE_MANUAL_SINGLE_PARENT},
-    {MANUAL, true, false, IDS_CHILD_BLOCK_MESSAGE_MANUAL_MULTI_PARENT},
+    {ASYNC_CHECKER, true, false, true,
+     IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
+    {ASYNC_CHECKER, true, false, false,
+     IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
+    {MANUAL, false, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL},
+    {MANUAL, false, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL},
+    {MANUAL, false, true, false,
+     IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED},
+    {MANUAL, false, true, true,
+     IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED},
+    {MANUAL, true, false, true, IDS_CHILD_BLOCK_MESSAGE_MANUAL_SINGLE_PARENT},
+    {MANUAL, true, false, false, IDS_CHILD_BLOCK_MESSAGE_MANUAL_MULTI_PARENT},
+    // |is_child_account| and |is_deprecated| are mutually exclusive, so skip
+    // test cases where both are true.
 };
 
 INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
@@ -62,6 +75,7 @@
   const std::string& second_custodian;
   const std::string& second_custodian_email;
   bool is_child_account;
+  bool is_deprecated;
   FilteringBehaviorReason reason;
   bool has_two_parents;
 };
@@ -75,7 +89,7 @@
       param.allow_access_requests, param.profile_image_url,
       param.profile_image_url2, param.custodian, param.custodian_email,
       param.second_custodian, param.second_custodian_email,
-      param.is_child_account, param.reason, "");
+      param.is_child_account, param.is_deprecated, param.reason, "");
   // The result should contain the original HTML (with $i18n{} replacements)
   // plus scripts that plug values into it. The test can't easily check that the
   // scripts are correct, but can check that the output contains the expected
@@ -186,16 +200,16 @@
 }
 
 BuildHtmlTestParameter build_html_test_parameter[] = {
-    {true, "url1", "url2", "custodian", "custodian_email", "", "", true,
+    {true, "url1", "url2", "custodian", "custodian_email", "", "", true, false,
      DEFAULT, false},
     {true, "url1", "url2", "custodian", "custodian_email", "custodian2",
-     "custodian2_email", true, DEFAULT, true},
+     "custodian2_email", true, false, DEFAULT, true},
     {false, "url1", "url2", "custodian", "custodian_email", "custodian2",
-     "custodian2_email", true, DEFAULT, true},
+     "custodian2_email", true, false, DEFAULT, true},
     {true, "url1", "url2", "custodian", "custodian_email", "custodian2",
-     "custodian2_email", false, DEFAULT, true},
+     "custodian2_email", false, false, DEFAULT, true},
     {true, "url1", "url2", "custodian", "custodian_email", "custodian2",
-     "custodian2_email", true, ASYNC_CHECKER, true},
+     "custodian2_email", true, false, ASYNC_CHECKER, true},
 };
 
 INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
diff --git a/components/supervised_user_error_page_strings.grdp b/components/supervised_user_error_page_strings.grdp
index 264f4d6..d8d589a4 100644
--- a/components/supervised_user_error_page_strings.grdp
+++ b/components/supervised_user_error_page_strings.grdp
@@ -79,5 +79,8 @@
       <message name="IDS_SUPERVISED_USER_NOT_SIGNED_IN" desc="Message to be shown to a supervised user who is not signed in to Chrome">
         Please start and sign in to Chrome so that Chrome can check whether you are allowed to access this site.
       </message>
+      <message name="IDS_BLOCK_INTERSTITIAL_MESSAGE_SUPERVISED_USERS_DEPRECATED" desc="Message to be shown to a supervised user to inform them that the feature is deprecated.">
+        Supervised users are deprecated. Restrictions remain in place and cannot be changed by the custodian after September 30, 2017.
+      </message>
 
 </grit-part>
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index a4a9672..38f162a2 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -472,13 +472,13 @@
   VISIT(is_bookmarked);
 }
 
-VISIT_PROTO_FIELDS(const sync_pb::FieldTrialEvent::FieldTrial& proto) {
+VISIT_PROTO_FIELDS(const sync_pb::FieldTrial::FieldTrialPair& proto) {
   VISIT(name_id);
   VISIT(group_id);
 }
 
-VISIT_PROTO_FIELDS(const sync_pb::FieldTrialEvent& proto) {
-  VISIT_REP(field_trials);
+VISIT_PROTO_FIELDS(const sync_pb::FieldTrial& proto) {
+  VISIT_REP(field_trial_pairs);
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::GcmChannelFlags& proto) {
@@ -877,10 +877,10 @@
   VISIT(event_time_usec);
   VISIT(navigation_id);
   VISIT(session_id);
-  VISIT(test);
+  VISIT(test_event);
   VISIT(field_trial_event);
-  VISIT(language_detection);
-  VISIT(translation);
+  VISIT(language_detection_event);
+  VISIT(translation_event);
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics::Test& proto) {}
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto
index 8bc41a7..a2648f0b 100644
--- a/components/sync/protocol/user_event_specifics.proto
+++ b/components/sync/protocol/user_event_specifics.proto
@@ -13,12 +13,12 @@
 
 package sync_pb;
 
-message FieldTrialEvent {
-  message FieldTrial {
+message FieldTrial {
+  message FieldTrialPair {
     optional fixed32 name_id = 1;
     optional fixed32 group_id = 2;
   }
-  repeated FieldTrial field_trials = 1;
+  repeated FieldTrialPair field_trial_pairs = 1;
 }
 
 // Language detection output.
@@ -88,9 +88,9 @@
   message Test {}
 
   oneof event {
-    Test test = 8;
-    FieldTrialEvent field_trial_event = 9;
-    LanguageDetection language_detection = 10;
-    Translation translation = 11;
+    Test test_event = 8;
+    FieldTrial field_trial_event = 9;
+    LanguageDetection language_detection_event = 10;
+    Translation translation_event = 11;
   }
 }
diff --git a/components/translate/core/common/language_detection_logging_helper.cc b/components/translate/core/common/language_detection_logging_helper.cc
index b98ae85..1f29dc3 100644
--- a/components/translate/core/common/language_detection_logging_helper.cc
+++ b/components/translate/core/common/language_detection_logging_helper.cc
@@ -31,8 +31,8 @@
   if (details.adopted_language != details.cld_language) {
     lang_detection.set_adopted_language_code(details.adopted_language);
   }
-  *specifics->mutable_language_detection() = lang_detection;
+  *specifics->mutable_language_detection_event() = lang_detection;
   return specifics;
 }
 
-}  // namespace translate
\ No newline at end of file
+}  // namespace translate
diff --git a/components/translate/core/common/language_detection_logging_helper_unittest.cc b/components/translate/core/common/language_detection_logging_helper_unittest.cc
index c22a0ee0..fc9c7eba 100644
--- a/components/translate/core/common/language_detection_logging_helper_unittest.cc
+++ b/components/translate/core/common/language_detection_logging_helper_unittest.cc
@@ -29,7 +29,7 @@
       ConstructLanguageDetectionEvent(navigation_id, details);
   // Expect the navigation id is correctly set.
   EXPECT_EQ(user_event->navigation_id(), navigation_id);
-  EXPECT_EQ(user_event->language_detection().SerializeAsString(),
+  EXPECT_EQ(user_event->language_detection_event().SerializeAsString(),
             lang_detection.SerializeAsString());
 }
 
@@ -49,8 +49,8 @@
       ConstructLanguageDetectionEvent(100, details);
   // Expect the navigation id is correctly set.
   EXPECT_EQ(user_event->navigation_id(), 100);
-  EXPECT_EQ(user_event->language_detection().SerializeAsString(),
+  EXPECT_EQ(user_event->language_detection_event().SerializeAsString(),
             lang_detection.SerializeAsString());
 }
 
-}  // namespace translate
\ No newline at end of file
+}  // namespace translate
diff --git a/components/translate/core/common/translation_logging_helper.cc b/components/translate/core/common/translation_logging_helper.cc
index 8b31b643..f0d4c1c 100644
--- a/components/translate/core/common/translation_logging_helper.cc
+++ b/components/translate/core/common/translation_logging_helper.cc
@@ -22,7 +22,7 @@
   // TODO(renjieliu): Revisit this field when the best way to identify
   // navigations is determined.
   specifics->set_navigation_id(navigation_id);
-  auto* const translation = specifics->mutable_translation();
+  auto* const translation = specifics->mutable_translation_event();
   translation->set_from_language_code(translate_event.source_language());
   translation->set_to_language_code(translate_event.target_language());
   switch (translate_event.event_type()) {
@@ -73,4 +73,4 @@
   }
   return true;
 }
-}  // namespace translate
\ No newline at end of file
+}  // namespace translate
diff --git a/components/translate/core/common/translation_logging_helper_unittest.cc b/components/translate/core/common/translation_logging_helper_unittest.cc
index d25247b..62046de 100644
--- a/components/translate/core/common/translation_logging_helper_unittest.cc
+++ b/components/translate/core/common/translation_logging_helper_unittest.cc
@@ -42,7 +42,8 @@
       navigation_id, translation_event, &user_specifics);
   EXPECT_TRUE(needs_logging);
   EXPECT_EQ(user_specifics.navigation_id(), navigation_id);
-  EqualTranslationProto(user_translation_event, user_specifics.translation());
+  EqualTranslationProto(user_translation_event,
+                        user_specifics.translation_event());
 }
 
 // Tests that if user change the target language, the event is MANUAL.
@@ -65,7 +66,8 @@
       navigation_id, translation_event, &user_specifics);
   EXPECT_TRUE(needs_logging);
   EXPECT_EQ(user_specifics.navigation_id(), navigation_id);
-  EqualTranslationProto(user_translation_event, user_specifics.translation());
+  EqualTranslationProto(user_translation_event,
+                        user_specifics.translation_event());
 }
 
 // Tests that we don't build unnecessary events.
@@ -84,4 +86,4 @@
   EXPECT_FALSE(needs_logging);
 }
 
-}  // namespace translate
\ No newline at end of file
+}  // namespace translate
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 7bdb162..2a511cb 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -95,10 +95,6 @@
 
 #endif  // OS_POSIX
 
-#if defined(USE_NSS_CERTS)
-#include "crypto/nss_util.h"
-#endif
-
 #if !defined(CHROME_MULTIPLE_DLL_BROWSER)
 #include "content/public/gpu/content_gpu_client.h"
 #include "content/public/renderer/content_renderer_client.h"
@@ -599,10 +595,6 @@
     }
 #endif
 
-#if defined(USE_NSS_CERTS)
-    crypto::EarlySetupForNSSInit();
-#endif
-
     RegisterPathProvider();
     RegisterContentSchemes(true);
 
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index 7b10ed8..81ed0b6d 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -27,8 +27,6 @@
 #include "content/browser/service_worker/embedded_worker_test_helper.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
 #include "content/browser/service_worker/service_worker_storage.h"
 #include "content/browser/storage_partition_impl.h"
 #include "content/public/browser/background_sync_parameters.h"
@@ -447,28 +445,7 @@
 }
 
 TEST_F(BackgroundSyncManagerTest, RegisterWithoutLiveSWRegistration) {
-  // Get a provider host which is used to install the service worker.
-  ASSERT_TRUE(sw_registration_1_->active_version());
-  ASSERT_FALSE(sw_registration_1_->waiting_version());
-  ASSERT_FALSE(sw_registration_1_->installing_version());
-  ServiceWorkerProviderHost* provider_host =
-      sw_registration_1_->active_version()->provider_host();
-  ASSERT_TRUE(provider_host);
-  int process_id = provider_host->process_id();
-  int provider_id = provider_host->provider_id();
-
-  // Remove the registration handle registered on the dispatcher host.
-  ServiceWorkerDispatcherHost* dispatcher_host =
-      helper_->context()->GetDispatcherHost(process_id);
-  ServiceWorkerRegistrationHandle* handle =
-      dispatcher_host->FindRegistrationHandle(provider_id,
-                                              sw_registration_1_->id());
-  dispatcher_host->OnDecrementRegistrationRefCount(handle->handle_id());
-
-  // Ensure |sw_registration_1_| is the last reference to the registration.
-  ASSERT_TRUE(sw_registration_1_->HasOneRef());
   sw_registration_1_ = nullptr;
-
   EXPECT_FALSE(Register(sync_options_1_));
   EXPECT_EQ(BACKGROUND_SYNC_STATUS_NO_SERVICE_WORKER, callback_status_);
 }
diff --git a/content/browser/payments/OWNERS b/content/browser/payments/OWNERS
index 0b80e87..81e0787 100644
--- a/content/browser/payments/OWNERS
+++ b/content/browser/payments/OWNERS
@@ -1,4 +1,4 @@
 jinho.bang@samsung.com
 rouslan@chromium.org
 
-# COMPONENT: UI>Browser>Autofill>Payments
+# COMPONENT: UI>Browser>Payments
diff --git a/content/browser/payments/payment_app_content_unittest_base.cc b/content/browser/payments/payment_app_content_unittest_base.cc
index 6d35a9aa..37294f6 100644
--- a/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/content/browser/payments/payment_app_content_unittest_base.cc
@@ -28,13 +28,11 @@
 namespace {
 
 void RegisterServiceWorkerCallback(bool* called,
-                                   int64_t* out_registration_id,
                                    ServiceWorkerStatusCode status,
                                    const std::string& status_message,
                                    int64_t registration_id) {
   EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
   *called = true;
-  *out_registration_id = registration_id;
 }
 
 void UnregisterServiceWorkerCallback(bool* called,
@@ -43,11 +41,6 @@
   *called = true;
 }
 
-void StopWorkerCallback(bool* called, ServiceWorkerStatusCode status) {
-  EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
-  *called = true;
-}
-
 }  // namespace
 
 class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
@@ -58,24 +51,21 @@
         last_sw_registration_id_(kInvalidServiceWorkerRegistrationId) {}
   ~PaymentAppForWorkerTestHelper() override {}
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     ServiceWorkerVersion* version =
         context()->GetLiveVersion(service_worker_version_id);
     last_sw_registration_id_ = version->registration_id();
     last_sw_scope_ = scope;
     EmbeddedWorkerTestHelper::OnStartWorker(
         embedded_worker_id, service_worker_version_id, scope, script_url,
-        pause_after_download, std::move(request), std::move(instance_host),
-        std::move(provider_info));
+        pause_after_download, std::move(request), std::move(instance_host));
   }
 
   void OnPaymentRequestEvent(
@@ -121,23 +111,9 @@
     const GURL& sw_script_url) {
   // Register service worker for payment manager.
   bool called = false;
-  int64_t registration_id;
   worker_helper_->context()->RegisterServiceWorker(
       scope_url, sw_script_url, nullptr,
-      base::Bind(&RegisterServiceWorkerCallback, &called, &registration_id));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(called);
-
-  // Ensure the worker used for installation has stopped.
-  called = false;
-  ServiceWorkerRegistration* registration =
-      worker_helper_->context()->GetLiveRegistration(registration_id);
-  EXPECT_TRUE(registration);
-  EXPECT_TRUE(registration->active_version());
-  EXPECT_FALSE(registration->waiting_version());
-  EXPECT_FALSE(registration->installing_version());
-  registration->active_version()->StopWorker(
-      base::Bind(&StopWorkerCallback, &called));
+      base::Bind(&RegisterServiceWorkerCallback, &called));
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(called);
 
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 38d7534e..7ac9818 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -440,7 +440,6 @@
 
 void EmbeddedWorkerInstance::Start(
     std::unique_ptr<EmbeddedWorkerStartParams> params,
-    ProviderInfoGetter provider_info_getter,
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
     const StatusCallback& callback) {
   restart_count_++;
@@ -457,8 +456,6 @@
   status_ = EmbeddedWorkerStatus::STARTING;
   starting_phase_ = ALLOCATING_PROCESS;
   network_accessed_for_script_ = false;
-  provider_info_getter_ = std::move(provider_info_getter);
-
   for (auto& observer : listener_list_)
     observer.OnStarting();
 
@@ -471,6 +468,7 @@
       mojo::MakeRequest(&client_);
   client_.set_connection_error_handler(
       base::Bind(&CallDetach, base::Unretained(this)));
+
   pending_dispatcher_request_ = std::move(dispatcher_request);
 
   inflight_start_task_.reset(
@@ -596,13 +594,10 @@
   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info;
   instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info));
 
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
-      std::move(provider_info_getter_).Run(process_id());
-
+  DCHECK(pending_dispatcher_request_.is_pending());
   client_->StartWorker(*params, std::move(pending_dispatcher_request_),
-                       std::move(host_ptr_info), std::move(provider_info));
+                       std::move(host_ptr_info));
   registry_->BindWorkerToProcess(process_id(), embedded_worker_id());
-
   OnStartWorkerMessageSent();
   // Once the start worker message is received, renderer side will prepare a
   // shadow page for getting worker script.
@@ -706,10 +701,20 @@
     devtools_proxy_->NotifyWorkerVersionDoomed();
 }
 
-void EmbeddedWorkerInstance::OnThreadStarted(int thread_id) {
+void EmbeddedWorkerInstance::OnThreadStarted(int thread_id, int provider_id) {
   if (!context_ || !inflight_start_task_)
     return;
 
+  ServiceWorkerProviderHost* provider_host =
+      context_->GetProviderHost(process_id(), provider_id);
+  if (!provider_host) {
+    bad_message::ReceivedBadMessage(
+        process_id(), bad_message::SWDH_WORKER_SCRIPT_LOAD_NO_HOST);
+    return;
+  }
+
+  provider_host->SetReadyToSendMessagesToWorker(thread_id);
+
   TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LAUNCHING_WORKER_THREAD",
                                   this);
   // Renderer side has started to evaluate the loaded worker script.
@@ -806,8 +811,6 @@
 }
 
 void EmbeddedWorkerInstance::Detach() {
-  if (status() == EmbeddedWorkerStatus::STOPPED)
-    return;
   registry_->DetachWorker(process_id(), embedded_worker_id());
   OnDetached();
 }
@@ -889,6 +892,7 @@
   // Abort an inflight start task.
   inflight_start_task_.reset();
 
+  client_.reset();
   instance_host_binding_.Close();
   devtools_proxy_.reset();
   process_handle_.reset();
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index db7fae8d..737417c8 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -71,10 +71,6 @@
     STARTING_PHASE_MAX_VALUE,
   };
 
-  using ProviderInfoGetter =
-      base::OnceCallback<mojom::ServiceWorkerProviderInfoForStartWorkerPtr(
-          int /* process_id */)>;
-
   class Listener {
    public:
     virtual ~Listener() {}
@@ -112,10 +108,8 @@
   // STOPPED status. |callback| is invoked after the worker script has been
   // started and evaluated, or when an error occurs.
   // |params| should be populated with service worker version info needed
-  // to start the worker. |provider_info_getter| is called when this instance
-  // allocates a process and is ready to send a StartWorker message.
+  // to start the worker.
   void Start(std::unique_ptr<EmbeddedWorkerStartParams> params,
-             ProviderInfoGetter provider_info_getter,
              mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
              const StatusCallback& callback);
 
@@ -234,7 +228,7 @@
   void OnScriptLoaded() override;
   // Notifies the corresponding provider host that the thread has started and is
   // ready to receive messages.
-  void OnThreadStarted(int thread_id) override;
+  void OnThreadStarted(int thread_id, int provider_id) override;
   void OnScriptLoadFailed() override;
   // Fires the callback passed to Start().
   void OnScriptEvaluated(bool success) override;
@@ -289,10 +283,7 @@
   std::unique_ptr<EmbeddedWorkerInstance::WorkerProcessHandle> process_handle_;
   int thread_id_;
 
-  // |client_| is used to send messages to the renderer process. The browser
-  // process should not disconnect the pipe because other associated interfaces
-  // may be using it. The renderer process will disconnect the pipe when
-  // appropriate.
+  // |client_| is used to send messages to the renderer process.
   mojom::EmbeddedWorkerInstanceClientPtr client_;
 
   // Binding for EmbeddedWorkerInstanceHost, runs on IO thread.
@@ -302,9 +293,6 @@
   // a mojo struct.
   mojom::ServiceWorkerEventDispatcherRequest pending_dispatcher_request_;
 
-  // This is set at Start and used on SendStartWorker.
-  ProviderInfoGetter provider_info_getter_;
-
   // Whether devtools is attached or not.
   bool devtools_attached_;
 
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index cbe3047..450fbeb3 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -44,30 +44,6 @@
 
 }  // namespace
 
-class ProviderHostEndpoints : public mojom::ServiceWorkerProviderHost {
- public:
-  ProviderHostEndpoints() : binding_(this) {}
-
-  ~ProviderHostEndpoints() override {}
-
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr CreateProviderInfoPtr() {
-    DCHECK(!binding_.is_bound());
-    DCHECK(!client_.is_bound());
-    // Just keep the endpoints.
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
-        mojom::ServiceWorkerProviderInfoForStartWorker::New();
-    binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info));
-    provider_info->client_request = mojo::MakeRequest(&client_);
-    return provider_info;
-  }
-
- private:
-  mojom::ServiceWorkerProviderAssociatedPtr client_;
-  mojo::AssociatedBinding<mojom::ServiceWorkerProviderHost> binding_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProviderHostEndpoints);
-};
-
 class EmbeddedWorkerInstanceTest : public testing::Test,
                                    public EmbeddedWorkerInstance::Listener {
  protected:
@@ -106,7 +82,7 @@
     RecordEvent(DETACHED, old_status);
   }
 
-  bool OnMessageReceived(const IPC::Message&) override { return false; }
+  bool OnMessageReceived(const IPC::Message& message) override { return false; }
 
   void SetUp() override {
     helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
@@ -122,7 +98,7 @@
     std::unique_ptr<EmbeddedWorkerStartParams> params =
         CreateStartParams(id, pattern, url);
     worker->Start(
-        std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+        std::move(params), CreateEventDispatcher(),
         base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     return status;
@@ -140,18 +116,6 @@
     return params;
   }
 
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr CreateProviderInfo(
-      int /* process_id */) {
-    provider_host_endpoints_.emplace_back(
-        base::MakeUnique<ProviderHostEndpoints>());
-    return provider_host_endpoints_.back()->CreateProviderInfoPtr();
-  }
-
-  EmbeddedWorkerInstance::ProviderInfoGetter CreateProviderInfoGetter() {
-    return base::BindOnce(&EmbeddedWorkerInstanceTest::CreateProviderInfo,
-                          base::Unretained(this));
-  }
-
   mojom::ServiceWorkerEventDispatcherRequest CreateEventDispatcher() {
     dispatchers_.emplace_back();
     return mojo::MakeRequest(&dispatchers_.back());
@@ -173,7 +137,6 @@
   }
 
   std::vector<mojom::ServiceWorkerEventDispatcherPtr> dispatchers_;
-  std::vector<std::unique_ptr<ProviderHostEndpoints>> provider_host_endpoints_;
 
   TestBrowserThreadBundle thread_bundle_;
   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
@@ -190,16 +153,14 @@
   StalledInStartWorkerHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
   ~StalledInStartWorkerHelper() override {}
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     if (force_stall_in_start_) {
       // Prepare for OnStopWorker().
       instance_host_ptr_map_[embedded_worker_id].Bind(std::move(instance_host));
@@ -208,8 +169,7 @@
     }
     EmbeddedWorkerTestHelper::OnStartWorker(
         embedded_worker_id, service_worker_version_id, scope, script_url,
-        pause_after_download, std::move(request), std::move(instance_host),
-        std::move(provider_info));
+        pause_after_download, std::move(request), std::move(instance_host));
   }
 
   void OnStopWorker(int embedded_worker_id) override {
@@ -254,7 +214,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(service_worker_version_id, pattern, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
   run_loop.Run();
@@ -311,7 +271,7 @@
     std::unique_ptr<EmbeddedWorkerStartParams> params =
         CreateStartParams(service_worker_version_id, pattern, url);
     worker->Start(
-        std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+        std::move(params), CreateEventDispatcher(),
         base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -336,7 +296,7 @@
     std::unique_ptr<EmbeddedWorkerStartParams> params =
         CreateStartParams(service_worker_version_id, pattern, url);
     worker->Start(
-        std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+        std::move(params), CreateEventDispatcher(),
         base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
     run_loop.Run();
@@ -417,7 +377,7 @@
     std::unique_ptr<EmbeddedWorkerStartParams> params =
         CreateStartParams(version_id1, pattern, url);
     worker1->Start(
-        std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+        std::move(params), CreateEventDispatcher(),
         base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -430,7 +390,7 @@
     std::unique_ptr<EmbeddedWorkerStartParams> params =
         CreateStartParams(version_id2, pattern, url);
     worker2->Start(
-        std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+        std::move(params), CreateEventDispatcher(),
         base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
     run_loop.Run();
     EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -468,7 +428,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
   worker->Detach();
   base::RunLoop().RunUntilIdle();
@@ -501,7 +461,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
@@ -541,7 +501,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
   worker->Stop();
   base::RunLoop().RunUntilIdle();
@@ -564,7 +524,7 @@
   std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop);
   params = CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
   run_loop->Run();
 
@@ -616,7 +576,7 @@
       CreateStartParams(version_id, scope, url);
   params->pause_after_download = true;
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
@@ -646,7 +606,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, base::Bind(&base::DoNothing)));
   base::RunLoop().RunUntilIdle();
 
@@ -679,7 +639,7 @@
 
   params = CreateStartParams(version_id, scope, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
   run_loop->Run();
 
@@ -710,7 +670,7 @@
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, pattern, url);
   worker->Start(
-      std::move(params), CreateProviderInfoGetter(), CreateEventDispatcher(),
+      std::move(params), CreateEventDispatcher(),
       base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
   run_loop.Run();
 
@@ -744,8 +704,7 @@
   // Attempt to start the worker.
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, pattern, url);
-  worker->Start(std::move(params), CreateProviderInfoGetter(),
-                CreateEventDispatcher(),
+  worker->Start(std::move(params), CreateEventDispatcher(),
                 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
@@ -764,10 +723,11 @@
       : EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient(helper) {}
 
  private:
-  void StartWorker(const EmbeddedWorkerStartParams&,
-                   mojom::ServiceWorkerEventDispatcherRequest,
-                   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo,
-                   mojom::ServiceWorkerProviderInfoForStartWorkerPtr) override {
+  void StartWorker(
+      const EmbeddedWorkerStartParams& /* unused */,
+      mojom::ServiceWorkerEventDispatcherRequest /* unused */,
+      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo /* unused */)
+      override {
     helper_->mock_instance_clients()->clear();
   }
 };
@@ -792,8 +752,7 @@
   // Attempt to start the worker.
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, pattern, url);
-  worker->Start(std::move(params), CreateProviderInfoGetter(),
-                CreateEventDispatcher(),
+  worker->Start(std::move(params), CreateEventDispatcher(),
                 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
@@ -849,8 +808,7 @@
       std::make_pair(blink::WebConsoleMessage::kLevelVerbose, "");
   std::unique_ptr<EmbeddedWorkerStartParams> params =
       CreateStartParams(version_id, pattern, url);
-  worker->Start(std::move(params), CreateProviderInfoGetter(),
-                CreateEventDispatcher(),
+  worker->Start(std::move(params), CreateEventDispatcher(),
                 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   worker->AddMessageToConsole(test_message.first, test_message.second);
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index 9ab90132..3485ac19 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -73,8 +73,7 @@
 void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
     const EmbeddedWorkerStartParams& params,
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
-    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host) {
   if (!helper_)
     return;
 
@@ -86,8 +85,7 @@
   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
 
   helper_->OnStartWorkerStub(params, std::move(dispatcher_request),
-                             std::move(instance_host),
-                             std::move(provider_info));
+                             std::move(instance_host));
 }
 
 void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StopWorker() {
@@ -292,6 +290,7 @@
       wrapper_(new ServiceWorkerContextWrapper(browser_context_.get())),
       mock_instance_clients_next_index_(0),
       next_thread_id_(0),
+      next_provider_id_(1000),
       mock_render_process_id_(render_process_host_->GetID()),
       new_mock_render_process_id_(new_render_process_host_->GetID()),
       weak_factory_(this) {
@@ -396,8 +395,7 @@
     const GURL& script_url,
     bool pause_after_download,
     mojom::ServiceWorkerEventDispatcherRequest request,
-    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host) {
   EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
   ASSERT_TRUE(worker);
   MockServiceWorkerEventDispatcher::Create(AsWeakPtr(), worker->thread_id(),
@@ -407,9 +405,6 @@
       service_worker_version_id;
   embedded_worker_id_instance_host_ptr_map_[embedded_worker_id].Bind(
       std::move(instance_host));
-  ServiceWorkerRemoteProviderEndpoint* provider_endpoint =
-      &embedded_worker_id_remote_provider_map_[embedded_worker_id];
-  provider_endpoint->BindWithProviderInfo(std::move(provider_info));
 
   SimulateWorkerReadyForInspection(embedded_worker_id);
   SimulateWorkerScriptCached(embedded_worker_id);
@@ -419,7 +414,8 @@
 }
 
 void EmbeddedWorkerTestHelper::OnResumeAfterDownload(int embedded_worker_id) {
-  SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
+  SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id,
+                              GetNextProviderId());
   SimulateWorkerScriptEvaluated(embedded_worker_id, true /* success */);
   SimulateWorkerStarted(embedded_worker_id);
 }
@@ -580,12 +576,22 @@
 
 void EmbeddedWorkerTestHelper::SimulateWorkerThreadStarted(
     int thread_id,
-    int embedded_worker_id) {
+    int embedded_worker_id,
+    int provider_id) {
   EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
   ASSERT_TRUE(worker);
   ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
+
+  // Prepare a provider host to be used by following OnThreadStarted().
+  std::unique_ptr<ServiceWorkerProviderHost> host =
+      CreateProviderHostForServiceWorkerContext(
+          worker->process_id(), provider_id, true /* is_parent_frame_secure */,
+          context()->AsWeakPtr(),
+          &embedded_worker_id_remote_provider_map_[embedded_worker_id]);
+  context()->AddProviderHost(std::move(host));
+
   embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
-      ->OnThreadStarted(thread_id);
+      ->OnThreadStarted(thread_id, provider_id);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -625,8 +631,7 @@
 void EmbeddedWorkerTestHelper::OnStartWorkerStub(
     const EmbeddedWorkerStartParams& params,
     mojom::ServiceWorkerEventDispatcherRequest request,
-    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host) {
   EmbeddedWorkerInstance* worker =
       registry()->GetWorker(params.embedded_worker_id);
   ASSERT_TRUE(worker);
@@ -636,8 +641,7 @@
       base::Bind(&EmbeddedWorkerTestHelper::OnStartWorker, AsWeakPtr(),
                  params.embedded_worker_id, params.service_worker_version_id,
                  params.scope, params.script_url, params.pause_after_download,
-                 base::Passed(&request), base::Passed(&instance_host),
-                 base::Passed(&provider_info)));
+                 base::Passed(&request), base::Passed(&instance_host)));
 }
 
 void EmbeddedWorkerTestHelper::OnResumeAfterDownloadStub(
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h
index 3038c9e..b94ffebb 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -83,8 +83,7 @@
     void StartWorker(
         const EmbeddedWorkerStartParams& params,
         mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
-        mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-        mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
+        mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host)
         override;
     void StopWorker() override;
     void ResumeAfterDownload() override;
@@ -115,7 +114,7 @@
   // IPC::Listener implementation.
   bool OnMessageReceived(const IPC::Message& msg) override;
 
-  // Registers a Mojo endpoint object derived from
+  // Register a mojo endpoint object derived from
   // MockEmbeddedWorkerInstanceClient.
   void RegisterMockInstanceClient(
       std::unique_ptr<MockEmbeddedWorkerInstanceClient> client);
@@ -148,6 +147,7 @@
   void ShutdownContext();
 
   int GetNextThreadId() { return next_thread_id_++; }
+  int GetNextProviderId() { return next_provider_id_++; }
 
   int mock_render_process_id() const { return mock_render_process_id_; }
   MockRenderProcessHost* mock_render_process_host() {
@@ -180,8 +180,7 @@
       const GURL& script_url,
       bool pause_after_download,
       mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info);
+      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host);
   virtual void OnResumeAfterDownload(int embedded_worker_id);
   // StopWorker IPC handler routed through MockEmbeddedWorkerInstanceClient.
   // This calls SimulateWorkerStopped() by default.
@@ -252,7 +251,9 @@
   void SimulateWorkerReadyForInspection(int embedded_worker_id);
   void SimulateWorkerScriptCached(int embedded_worker_id);
   void SimulateWorkerScriptLoaded(int embedded_worker_id);
-  void SimulateWorkerThreadStarted(int thread_id, int embedded_worker_id);
+  void SimulateWorkerThreadStarted(int thread_id,
+                                   int embedded_worker_id,
+                                   int provider_id);
   void SimulateWorkerScriptEvaluated(int embedded_worker_id, bool success);
   void SimulateWorkerStarted(int embedded_worker_id);
   void SimulateWorkerStopped(int embedded_worker_id);
@@ -266,8 +267,7 @@
   void OnStartWorkerStub(
       const EmbeddedWorkerStartParams& params,
       mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info);
+      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host);
   void OnResumeAfterDownloadStub(int embedded_worker_id);
   void OnStopWorkerStub(int embedded_worker_id);
   void OnMessageToWorkerStub(int thread_id,
@@ -344,6 +344,7 @@
   size_t mock_instance_clients_next_index_;
 
   int next_thread_id_;
+  int next_provider_id_;
   int mock_render_process_id_;
   int new_mock_render_process_id_;
 
diff --git a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
index 927788c..d83152d0 100644
--- a/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
+++ b/content/browser/service_worker/foreign_fetch_request_handler_unittest.cc
@@ -171,6 +171,17 @@
   }
 
   void CreateServiceWorkerTypeProviderHost() {
+    remote_endpoints_.emplace_back();
+    std::unique_ptr<ServiceWorkerProviderHost> host =
+        CreateProviderHostForServiceWorkerContext(
+            helper_->mock_render_process_id(), kMockProviderId,
+            true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
+            &remote_endpoints_.back());
+    EXPECT_FALSE(
+        context()->GetProviderHost(host->process_id(), host->provider_id()));
+    provider_host_ = host->AsWeakPtr();
+    context()->AddProviderHost(std::move(host));
+
     // Create another worker whose requests will be intercepted by the foreign
     // fetch event handler.
     scoped_refptr<ServiceWorkerRegistration> registration =
@@ -193,16 +204,7 @@
         base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
     base::RunLoop().RunUntilIdle();
 
-    remote_endpoints_.emplace_back();
-    std::unique_ptr<ServiceWorkerProviderHost> host =
-        CreateProviderHostForServiceWorkerContext(
-            helper_->mock_render_process_id(),
-            true /* is_parent_frame_secure */, version.get(),
-            helper_->context()->AsWeakPtr(), &remote_endpoints_.back());
-    EXPECT_FALSE(
-        context()->GetProviderHost(host->process_id(), host->provider_id()));
-    provider_host_ = host->AsWeakPtr();
-    context()->AddProviderHost(std::move(host));
+    provider_host_->running_hosted_version_ = version;
   }
 
  private:
diff --git a/content/browser/service_worker/link_header_support_unittest.cc b/content/browser/service_worker/link_header_support_unittest.cc
index e019f193..e77c68d9 100644
--- a/content/browser/service_worker/link_header_support_unittest.cc
+++ b/content/browser/service_worker/link_header_support_unittest.cc
@@ -106,6 +106,17 @@
   }
 
   void CreateServiceWorkerProviderHost() {
+    remote_endpoints_.emplace_back();
+    std::unique_ptr<ServiceWorkerProviderHost> host =
+        CreateProviderHostForServiceWorkerContext(
+            render_process_id(), kMockProviderId,
+            true /* is_parent_frame_secure */, context()->AsWeakPtr(),
+            &remote_endpoints_.back());
+    provider_host_ = host->AsWeakPtr();
+    EXPECT_FALSE(
+        context()->GetProviderHost(host->process_id(), host->provider_id()));
+    context()->AddProviderHost(std::move(host));
+
     scoped_refptr<ServiceWorkerRegistration> registration =
         new ServiceWorkerRegistration(GURL("https://host/scope"), 1L,
                                       context()->AsWeakPtr());
@@ -113,15 +124,7 @@
         registration.get(), GURL("https://host/script.js"), 1L,
         context()->AsWeakPtr());
 
-    remote_endpoints_.emplace_back();
-    std::unique_ptr<ServiceWorkerProviderHost> host =
-        CreateProviderHostForServiceWorkerContext(
-            render_process_id(), true /* is_parent_frame_secure */,
-            version.get(), context()->AsWeakPtr(), &remote_endpoints_.back());
-    provider_host_ = host->AsWeakPtr();
-    EXPECT_FALSE(
-        context()->GetProviderHost(host->process_id(), host->provider_id()));
-    context()->AddProviderHost(std::move(host));
+    provider_host_->running_hosted_version_ = version;
   }
 
   std::unique_ptr<net::URLRequest> CreateRequest(const GURL& request_url,
diff --git a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
index c2a599a..5f08d23 100644
--- a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
@@ -90,11 +90,12 @@
   void SetUpProvider() {
     std::unique_ptr<ServiceWorkerProviderHost> host =
         CreateProviderHostForServiceWorkerContext(
-            helper_->mock_render_process_id(),
-            true /* is_parent_frame_secure */, version_.get(),
-            context()->AsWeakPtr(), &remote_endpoint_);
+            helper_->mock_render_process_id(), 1 /* provider_id */,
+            true /* is_parent_frame_secure */, context()->AsWeakPtr(),
+            &remote_endpoint_);
     provider_host_ = host->AsWeakPtr();
     context()->AddProviderHost(std::move(host));
+    provider_host_->running_hosted_version_ = version_;
   }
 
   std::unique_ptr<net::URLRequest> CreateRequest(const GURL& url) {
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc
index 4742d1a..6f36f03 100644
--- a/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -21,7 +21,6 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_storage.h"
 #include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/browser/service_worker/service_worker_version.h"
 #include "content/common/service_worker/embedded_worker_messages.h"
 #include "content/common/service_worker/service_worker_messages.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -179,16 +178,13 @@
   const std::vector<Message>& events() const { return events_; }
 
  protected:
-  void StartWorker(
-      const EmbeddedWorkerStartParams& params,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void StartWorker(const EmbeddedWorkerStartParams& params,
+                   mojom::ServiceWorkerEventDispatcherRequest request,
+                   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                       instance_host) override {
     events_.push_back(Message::StartWorker);
     EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
-        params, std::move(request), std::move(instance_host),
-        std::move(provider_info));
+        params, std::move(request), std::move(instance_host));
   }
 
   void StopWorker() override {
@@ -224,13 +220,15 @@
   EXPECT_TRUE(called);
 
   ASSERT_EQ(2UL, helper_->dispatched_events()->size());
-  ASSERT_EQ(1UL, client->events().size());
+  ASSERT_EQ(2UL, client->events().size());
   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker,
             client->events()[0]);
   EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install,
             helper_->dispatched_events()->at(0));
   EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Activate,
             helper_->dispatched_events()->at(1));
+  EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StopWorker,
+            client->events()[1]);
 
   EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
 
@@ -327,13 +325,15 @@
   EXPECT_TRUE(called);
 
   ASSERT_EQ(2UL, helper_->dispatched_events()->size());
-  ASSERT_EQ(1UL, client->events().size());
+  ASSERT_EQ(2UL, client->events().size());
   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker,
             client->events()[0]);
   EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install,
             helper_->dispatched_events()->at(0));
   EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Activate,
             helper_->dispatched_events()->at(1));
+  EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StopWorker,
+            client->events()[1]);
 
   EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
 
@@ -609,28 +609,13 @@
           context()->AsWeakPtr(), &remote_endpoints.back());
   host3->SetDocumentUrl(kOrigin1);
 
-  // Host4 (provider_id < -1): process_id=2, origin2, for ServiceWorker.
-  // Since the provider host is created via
-  // CreateProviderHostForServiceWorkerContext, the provider_id is not a fixed
-  // number.
-  scoped_refptr<ServiceWorkerRegistration> registration =
-      base::MakeRefCounted<ServiceWorkerRegistration>(
-          GURL("http://www.example.com/test/"), 1L /* registration_id */,
-          helper_->context()->AsWeakPtr());
-  scoped_refptr<ServiceWorkerVersion> version =
-      base::MakeRefCounted<ServiceWorkerVersion>(
-          registration.get(), GURL("http://www.example.com/test/script_url"),
-          1L /* version_id */, helper_->context()->AsWeakPtr());
-  helper_->SimulateAddProcessToPattern(
-      GURL("http://www.example.com/test/script_url"), kRenderProcessId2);
+  // Host4 (provider_id=4): process_id=2, origin2, for ServiceWorker.
   remote_endpoints.emplace_back();
   std::unique_ptr<ServiceWorkerProviderHost> host4 =
       CreateProviderHostForServiceWorkerContext(
-          kRenderProcessId2, true /* is_parent_frame_secure */, version.get(),
+          kRenderProcessId2, provider_id++, true /* is_parent_frame_secure */,
           context()->AsWeakPtr(), &remote_endpoints.back());
   host4->SetDocumentUrl(kOrigin2);
-  const int host4_provider_id = host4->provider_id();
-  EXPECT_LT(host4_provider_id, kInvalidServiceWorkerProviderId);
 
   ServiceWorkerProviderHost* host1_raw = host1.get();
   ServiceWorkerProviderHost* host2_raw = host2.get();
@@ -676,7 +661,7 @@
   context()->RemoveProviderHost(kRenderProcessId1, 1);
   context()->RemoveProviderHost(kRenderProcessId2, 2);
   context()->RemoveProviderHost(kRenderProcessId2, 3);
-  context()->RemoveProviderHost(kRenderProcessId2, host4_provider_id);
+  context()->RemoveProviderHost(kRenderProcessId2, 4);
 }
 
 class ServiceWorkerContextRecoveryTest
@@ -723,10 +708,9 @@
                  true /* expect_active */));
   base::RunLoop().RunUntilIdle();
 
-  // Next handle ids should be 1 (the next call should return 2) because
-  // registered worker should have taken ID 0.
-  EXPECT_EQ(1, context()->GetNewServiceWorkerHandleId());
-  EXPECT_EQ(1, context()->GetNewRegistrationHandleId());
+  // Next handle ids should be 0 (the next call should return 1).
+  EXPECT_EQ(0, context()->GetNewServiceWorkerHandleId());
+  EXPECT_EQ(0, context()->GetNewRegistrationHandleId());
 
   context()->ScheduleDeleteAndStartOver();
 
@@ -769,10 +753,9 @@
                  true /* expect_active */));
   base::RunLoop().RunUntilIdle();
 
-  // The new context should take over next handle ids. ID 2 should have been
-  // taken by the running registration, so the following method calls return 3.
-  EXPECT_EQ(3, context()->GetNewServiceWorkerHandleId());
-  EXPECT_EQ(3, context()->GetNewRegistrationHandleId());
+  // The new context should take over next handle ids.
+  EXPECT_EQ(1, context()->GetNewServiceWorkerHandleId());
+  EXPECT_EQ(1, context()->GetNewRegistrationHandleId());
 
   ASSERT_EQ(3u, notifications_.size());
   EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index e727135..398bbd0 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -235,6 +235,7 @@
     existing_handle->IncrementRefCount();
     return existing_handle;
   }
+
   std::unique_ptr<ServiceWorkerRegistrationHandle> new_handle(
       new ServiceWorkerRegistrationHandle(GetContext()->AsWeakPtr(),
                                           provider_host, registration));
@@ -963,13 +964,6 @@
                                                  std::move(info), this);
     GetContext()->AddProviderHost(std::move(provider_host));
   } else {
-    // Provider host for controller should be pre-created on StartWorker in
-    // ServiceWorkerVersion.
-    if (info.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
-      bad_message::ReceivedBadMessage(
-          this, bad_message::SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_CONTROLLER);
-      return;
-    }
     if (ServiceWorkerUtils::IsBrowserAssignedProviderId(info.provider_id)) {
       bad_message::ReceivedBadMessage(
           this, bad_message::SWDH_PROVIDER_CREATED_BAD_ID);
@@ -980,6 +974,88 @@
   }
 }
 
+void ServiceWorkerDispatcherHost::OnSetHostedVersionId(int provider_id,
+                                                       int64_t version_id,
+                                                       int embedded_worker_id) {
+  TRACE_EVENT0("ServiceWorker",
+               "ServiceWorkerDispatcherHost::OnSetHostedVersionId");
+  if (!GetContext())
+    return;
+  ServiceWorkerProviderHost* provider_host =
+      GetContext()->GetProviderHost(render_process_id_, provider_id);
+  if (!provider_host) {
+    bad_message::ReceivedBadMessage(
+        this, bad_message::SWDH_SET_HOSTED_VERSION_NO_HOST);
+    return;
+  }
+
+  // This provider host must be specialized for a controller.
+  if (provider_host->IsProviderForClient()) {
+    bad_message::ReceivedBadMessage(
+        this, bad_message::SWDH_SET_HOSTED_VERSION_INVALID_HOST);
+    return;
+  }
+
+  // A service worker context associated with this provider host was destroyed
+  // due to restarting the service worker system etc.
+  if (!provider_host->IsContextAlive())
+    return;
+
+  // We might not be STARTING if the stop sequence was entered (STOPPING) or
+  // ended up being detached (STOPPED).
+  ServiceWorkerVersion* version = GetContext()->GetLiveVersion(version_id);
+  if (!version || version->running_status() != EmbeddedWorkerStatus::STARTING)
+    return;
+
+  // If the version has a different embedded worker, assume the message is about
+  // a detached worker and ignore.
+  if (version->embedded_worker()->embedded_worker_id() != embedded_worker_id)
+    return;
+
+  // A process for the worker must be equal to a process for the provider host.
+  if (version->embedded_worker()->process_id() != provider_host->process_id()) {
+    // Temporary debugging for https://crbug.com/668633
+    base::debug::ScopedCrashKey scope_worker_pid(
+        "swdh_set_hosted_version_worker_pid",
+        base::IntToString(version->embedded_worker()->process_id()));
+    base::debug::ScopedCrashKey scope_provider_host_pid(
+        "swdh_set_hosted_version_host_pid",
+        base::IntToString(provider_host->process_id()));
+    if (version->embedded_worker()->process_id() !=
+        ChildProcessHost::kInvalidUniqueID) {
+      base::debug::ScopedCrashKey scope_is_new_process(
+          "swdh_set_hosted_version_is_new_process",
+          version->embedded_worker()->is_new_process() ? "true" : "false");
+    }
+    base::debug::ScopedCrashKey scope_worker_restart_count(
+        "swdh_set_hosted_version_restart_count",
+        base::IntToString(version->embedded_worker()->restart_count()));
+    bad_message::ReceivedBadMessage(
+        this, bad_message::SWDH_SET_HOSTED_VERSION_PROCESS_MISMATCH);
+    return;
+  }
+
+  provider_host->SetHostedVersion(version);
+
+  // Retrieve the registration associated with |version|. The registration
+  // must be alive because the version keeps it during starting worker.
+  ServiceWorkerRegistration* registration =
+      GetContext()->GetLiveRegistration(version->registration_id());
+  DCHECK(registration);
+
+  // Set the document URL to the script url in order to allow
+  // register/unregister/getRegistration on ServiceWorkerGlobalScope.
+  provider_host->SetDocumentUrl(version->script_url());
+
+  ServiceWorkerRegistrationObjectInfo info;
+  ServiceWorkerVersionAttributes attrs;
+  GetRegistrationObjectInfoAndVersionAttributes(provider_host->AsWeakPtr(),
+                                                registration, &info, &attrs);
+
+  Send(new ServiceWorkerMsg_AssociateRegistration(kDocumentMainThreadId,
+                                                  provider_id, info, attrs));
+}
+
 template <typename SourceInfo>
 void ServiceWorkerDispatcherHost::DispatchExtendableMessageEventInternal(
     scoped_refptr<ServiceWorkerVersion> worker,
@@ -1096,17 +1172,17 @@
 void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes(
     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
     ServiceWorkerRegistration* registration,
-    ServiceWorkerRegistrationObjectInfo* out_info,
-    ServiceWorkerVersionAttributes* out_attrs) {
+    ServiceWorkerRegistrationObjectInfo* info,
+    ServiceWorkerVersionAttributes* attrs) {
   ServiceWorkerRegistrationHandle* handle =
       GetOrCreateRegistrationHandle(provider_host, registration);
-  *out_info = handle->GetObjectInfo();
+  *info = handle->GetObjectInfo();
 
-  out_attrs->installing = provider_host->GetOrCreateServiceWorkerHandle(
+  attrs->installing = provider_host->GetOrCreateServiceWorkerHandle(
       registration->installing_version());
-  out_attrs->waiting = provider_host->GetOrCreateServiceWorkerHandle(
+  attrs->waiting = provider_host->GetOrCreateServiceWorkerHandle(
       registration->waiting_version());
-  out_attrs->active = provider_host->GetOrCreateServiceWorkerHandle(
+  attrs->active = provider_host->GetOrCreateServiceWorkerHandle(
       registration->active_version());
 }
 
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index 2d6be54..6670faa 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -44,8 +44,7 @@
 
 // This class is bound with mojom::ServiceWorkerDispatcherHost. All
 // InterfacePtrs on the same render process are bound to the same
-// content::ServiceWorkerDispatcherHost. This can be overridden only for
-// testing.
+// content::ServiceWorkerDispatcherHost.
 class CONTENT_EXPORT ServiceWorkerDispatcherHost
     : public BrowserMessageFilter,
       public BrowserAssociatedInterface<mojom::ServiceWorkerDispatcherHost>,
@@ -71,25 +70,13 @@
   // be destroyed.
   bool Send(IPC::Message* message) override;
 
-  // Virtual for testing.
-  virtual void RegisterServiceWorkerHandle(
-      std::unique_ptr<ServiceWorkerHandle> handle);
-  // Virtual for testing.
-  virtual void RegisterServiceWorkerRegistrationHandle(
+  void RegisterServiceWorkerHandle(std::unique_ptr<ServiceWorkerHandle> handle);
+  void RegisterServiceWorkerRegistrationHandle(
       std::unique_ptr<ServiceWorkerRegistrationHandle> handle);
 
   ServiceWorkerHandle* FindServiceWorkerHandle(int provider_id,
                                                int64_t version_id);
 
-  // Gets or creates the registration and version handles appropriate for
-  // representing |registration| inside of |provider_host|. Sets |out_info| and
-  // |out_attrs| accordingly for these handles.
-  void GetRegistrationObjectInfoAndVersionAttributes(
-      base::WeakPtr<ServiceWorkerProviderHost> provider_host,
-      ServiceWorkerRegistration* registration,
-      ServiceWorkerRegistrationObjectInfo* out_info,
-      ServiceWorkerVersionAttributes* out_attrs);
-
   // Returns the existing registration handle whose reference count is
   // incremented or a newly created one if it doesn't exist.
   ServiceWorkerRegistrationHandle* GetOrCreateRegistrationHandle(
@@ -108,14 +95,15 @@
                            ProviderCreatedAndDestroyed);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDispatcherHostTest,
                            CleanupOnRendererCrash);
-  FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest,
-                           RegisterWithoutLiveSWRegistration);
 
   using StatusCallback = base::Callback<void(ServiceWorkerStatusCode status)>;
   enum class ProviderStatus { OK, NO_CONTEXT, DEAD_HOST, NO_HOST, NO_URL };
 
   // mojom::ServiceWorkerDispatcherHost implementation
   void OnProviderCreated(ServiceWorkerProviderHostInfo info) override;
+  void OnSetHostedVersionId(int provider_id,
+                            int64_t version_id,
+                            int embedded_worker_id) override;
 
   // IPC Message handlers
   void OnRegisterServiceWorker(int thread_id,
@@ -204,6 +192,12 @@
       int provider_id,
       int64_t registration_handle_id);
 
+  void GetRegistrationObjectInfoAndVersionAttributes(
+      base::WeakPtr<ServiceWorkerProviderHost> provider_host,
+      ServiceWorkerRegistration* registration,
+      ServiceWorkerRegistrationObjectInfo* info,
+      ServiceWorkerVersionAttributes* attrs);
+
   // Callbacks from ServiceWorkerContextCore
   void RegistrationComplete(int thread_id,
                             int provider_id,
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index e97074f..0ebbc82 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -123,16 +123,14 @@
  public:
   FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr;
     instance_host_ptr.Bind(std::move(instance_host));
     instance_host_ptr->OnStopped();
@@ -198,6 +196,13 @@
     EXPECT_EQ(SERVICE_WORKER_OK, status);
   }
 
+  void SendSetHostedVersionId(int provider_id,
+                              int64_t version_id,
+                              int embedded_worker_id) {
+    dispatcher_host_->OnSetHostedVersionId(provider_id, version_id,
+                                           embedded_worker_id);
+  }
+
   void SendProviderCreated(ServiceWorkerProviderType type,
                            const GURL& pattern) {
     const int64_t kProviderId = 99;
@@ -212,19 +217,6 @@
         helper_->mock_render_process_id(), kProviderId);
   }
 
-  void PrepareProviderForServiceWorkerContext(ServiceWorkerVersion* version,
-                                              const GURL& pattern) {
-    std::unique_ptr<ServiceWorkerProviderHost> host =
-        CreateProviderHostForServiceWorkerContext(
-            helper_->mock_render_process_id(),
-            true /* is_parent_frame_secure */, version,
-            helper_->context()->AsWeakPtr(), &remote_endpoint_);
-    provider_host_ = host.get();
-    helper_->SimulateAddProcessToPattern(pattern,
-                                         helper_->mock_render_process_id());
-    context()->AddProviderHost(std::move(host));
-  }
-
   void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) {
     dispatcher_host_->OnMessageReceived(
         ServiceWorkerHostMsg_RegisterServiceWorker(
@@ -768,8 +760,8 @@
   GURL pattern = GURL("http://www.example.com/");
   GURL script_url = GURL("http://www.example.com/service_worker.js");
 
+  SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern);
   SetUpRegistration(pattern, script_url);
-  PrepareProviderForServiceWorkerContext(version_.get(), pattern);
 
   // Set the running hosted version so that we can retrieve a valid service
   // worker object information for the source attribute of the message event.
@@ -846,6 +838,62 @@
   EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
 }
 
+TEST_F(ServiceWorkerDispatcherHostTest, OnSetHostedVersionId) {
+  GURL pattern = GURL("http://www.example.com/");
+  GURL script_url = GURL("http://www.example.com/service_worker.js");
+
+  Initialize(base::WrapUnique(new FailToStartWorkerTestHelper));
+  SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern);
+  SetUpRegistration(pattern, script_url);
+
+  const int64_t kProviderId = 99;  // Dummy value
+  bool called;
+  ServiceWorkerStatusCode status;
+  // StartWorker puts the worker in STARTING state but it will have no
+  // process id yet.
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        base::Bind(&SaveStatusCallback, &called, &status));
+  EXPECT_NE(version_->embedded_worker()->process_id(),
+            provider_host_->process_id());
+  // SendSetHostedVersionId should reject because the provider host process id
+  // is different. It should call BadMessageReceived because it's not an
+  // expected error state.
+  SendSetHostedVersionId(kProviderId, version_->version_id(),
+                         version_->embedded_worker()->embedded_worker_id());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
+      ServiceWorkerMsg_AssociateRegistration::ID));
+  EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
+}
+
+TEST_F(ServiceWorkerDispatcherHostTest, OnSetHostedVersionId_DetachedWorker) {
+  GURL pattern = GURL("http://www.example.com/");
+  GURL script_url = GURL("http://www.example.com/service_worker.js");
+
+  Initialize(base::WrapUnique(new FailToStartWorkerTestHelper));
+  SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern);
+  SetUpRegistration(pattern, script_url);
+
+  const int64_t kProviderId = 99;  // Dummy value
+  bool called;
+  ServiceWorkerStatusCode status;
+  // StartWorker puts the worker in STARTING state.
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        base::Bind(&SaveStatusCallback, &called, &status));
+
+  // SendSetHostedVersionId should bail because the embedded worker is
+  // different. It shouldn't call BadMessageReceived because receiving a message
+  // for a detached worker is a legitimite possibility.
+  int bad_embedded_worker_id =
+      version_->embedded_worker()->embedded_worker_id() + 1;
+  SendSetHostedVersionId(kProviderId, version_->version_id(),
+                         bad_embedded_worker_id);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching(
+      ServiceWorkerMsg_AssociateRegistration::ID));
+  EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_);
+}
+
 TEST_F(ServiceWorkerDispatcherHostTest, ReceivedTimedOutRequestResponse) {
   GURL pattern = GURL("https://www.example.com/");
   GURL script_url = GURL("https://www.example.com/service_worker.js");
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc
index e603508..5938ee65 100644
--- a/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -20,17 +20,13 @@
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_disk_cache.h"
-#include "content/browser/service_worker/service_worker_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_handle.h"
 #include "content/browser/service_worker/service_worker_job_coordinator.h"
 #include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_registration_handle.h"
 #include "content/browser/service_worker/service_worker_registration_status.h"
 #include "content/browser/service_worker/service_worker_test_utils.h"
 #include "content/common/service_worker/embedded_worker_messages.h"
 #include "content/common/service_worker/service_worker_messages.h"
 #include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "ipc/ipc_test_sink.h"
 #include "net/base/io_buffer.h"
@@ -48,45 +44,6 @@
 
 namespace {
 
-// A dispatcher host that holds on to all registered ServiceWorkerHandles and
-// ServiceWorkerRegistrationHandles.
-class KeepHandlesDispatcherHost : public ServiceWorkerDispatcherHost {
- public:
-  KeepHandlesDispatcherHost(int render_process_id,
-                            ResourceContext* resource_context)
-      : ServiceWorkerDispatcherHost(render_process_id, resource_context) {}
-  void RegisterServiceWorkerHandle(
-      std::unique_ptr<ServiceWorkerHandle> handle) override {
-    handles_.push_back(std::move(handle));
-  }
-  void RegisterServiceWorkerRegistrationHandle(
-      std::unique_ptr<ServiceWorkerRegistrationHandle> handle) override {
-    registration_handles_.push_back(std::move(handle));
-  }
-
-  void RemoveHandles() {
-    handles_.clear();
-    registration_handles_.clear();
-  }
-
-  const std::vector<std::unique_ptr<ServiceWorkerHandle>>& handles() {
-    return handles_;
-  }
-
-  const std::vector<std::unique_ptr<ServiceWorkerRegistrationHandle>>&
-  registration_handles() {
-    return registration_handles_;
-  }
-
- private:
-  ~KeepHandlesDispatcherHost() override {}
-
-  std::vector<std::unique_ptr<ServiceWorkerHandle>> handles_;
-  std::vector<std::unique_ptr<ServiceWorkerRegistrationHandle>>
-      registration_handles_;
-  DISALLOW_COPY_AND_ASSIGN(KeepHandlesDispatcherHost);
-};
-
 void SaveRegistrationCallback(
     ServiceWorkerStatusCode expected_status,
     bool* called,
@@ -400,35 +357,17 @@
 TEST_F(ServiceWorkerJobTest, Unregister) {
   GURL pattern("http://www.example.com/");
 
-  // During registration, handles will be created for hosting the worker's
-  // context. KeepHandlesDispatcherHost will store the handles.
-  scoped_refptr<KeepHandlesDispatcherHost> dispatcher_host =
-      base::MakeRefCounted<KeepHandlesDispatcherHost>(
-          helper_->mock_render_process_id(),
-          helper_->browser_context()->GetResourceContext());
-  helper_->RegisterDispatcherHost(helper_->mock_render_process_id(),
-                                  dispatcher_host);
-  dispatcher_host->Init(helper_->context_wrapper());
-
   scoped_refptr<ServiceWorkerRegistration> registration =
       RunRegisterJob(pattern, GURL("http://www.example.com/service_worker.js"));
 
-  EXPECT_EQ(1UL, dispatcher_host->registration_handles().size());
-  EXPECT_EQ(3UL, dispatcher_host->handles().size());
-
   RunUnregisterJob(pattern);
 
-  // Remove the handles. The only reference to the registration object should be
-  // |registration|.
-  dispatcher_host->RemoveHandles();
-  EXPECT_EQ(0UL, dispatcher_host->registration_handles().size());
-  EXPECT_EQ(0UL, dispatcher_host->handles().size());
   ASSERT_TRUE(registration->HasOneRef());
 
   registration = FindRegistrationForPattern(pattern,
                                             SERVICE_WORKER_ERROR_NOT_FOUND);
 
-  ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(nullptr), registration);
+  ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(NULL), registration);
 }
 
 TEST_F(ServiceWorkerJobTest, Unregister_NothingRegistered) {
@@ -466,28 +405,12 @@
 // Make sure that when registering a duplicate pattern+script_url
 // combination, that the same registration is used.
 TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
-  // During registration, handles will be created for hosting the worker's
-  // context. KeepHandlesDispatcherHost will store the handles.
-  scoped_refptr<KeepHandlesDispatcherHost> dispatcher_host =
-      new KeepHandlesDispatcherHost(
-          helper_->mock_render_process_id(),
-          helper_->browser_context()->GetResourceContext());
-  helper_->RegisterDispatcherHost(helper_->mock_render_process_id(),
-                                  dispatcher_host);
-  dispatcher_host->Init(helper_->context_wrapper());
-
   GURL pattern("http://www.example.com/");
   GURL script_url("http://www.example.com/service_worker.js");
 
   scoped_refptr<ServiceWorkerRegistration> old_registration =
       RunRegisterJob(pattern, script_url);
 
-  // Ensure that the registration's handle doesn't have the reference.
-  EXPECT_EQ(1UL, dispatcher_host->registration_handles().size());
-  dispatcher_host->RemoveHandles();
-  EXPECT_EQ(0UL, dispatcher_host->registration_handles().size());
-  ASSERT_TRUE(old_registration->HasOneRef());
-
   scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern =
       FindRegistrationForPattern(pattern);
 
@@ -510,16 +433,14 @@
  public:
   FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr;
     instance_host_ptr.Bind(std::move(instance_host));
     instance_host_ptr->OnStopped();
@@ -976,16 +897,14 @@
   }
 
   // EmbeddedWorkerTestHelper overrides
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t version_id,
-      const GURL& scope,
-      const GURL& script,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t version_id,
+                     const GURL& scope,
+                     const GURL& script,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     const std::string kMockScriptBody = "mock_script";
     const uint64_t kMockScriptSize = 19284;
     ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
@@ -1040,14 +959,15 @@
 
     EmbeddedWorkerTestHelper::OnStartWorker(
         embedded_worker_id, version_id, scope, script, pause_after_download,
-        std::move(request), std::move(instance_host), std::move(provider_info));
+        std::move(request), std::move(instance_host));
   }
 
   void OnResumeAfterDownload(int embedded_worker_id) override {
     if (!force_start_worker_failure_) {
       EmbeddedWorkerTestHelper::OnResumeAfterDownload(embedded_worker_id);
     } else {
-      SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
+      SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id,
+                                  GetNextProviderId());
       SimulateWorkerScriptEvaluated(embedded_worker_id, false);
     }
   }
@@ -1095,16 +1015,14 @@
   EvictIncumbentVersionHelper() {}
   ~EvictIncumbentVersionHelper() override {}
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t version_id,
-      const GURL& scope,
-      const GURL& script,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t version_id,
+                     const GURL& scope,
+                     const GURL& script,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
     ServiceWorkerRegistration* registration =
         context()->GetLiveRegistration(version->registration_id());
@@ -1118,7 +1036,7 @@
     }
     UpdateJobTestHelper::OnStartWorker(
         embedded_worker_id, version_id, scope, script, pause_after_download,
-        std::move(request), std::move(instance_host), std::move(provider_info));
+        std::move(request), std::move(instance_host));
   }
 
   void OnRegistrationFailed(ServiceWorkerRegistration* registration) override {
@@ -1791,18 +1709,15 @@
   }
 
  protected:
-  void StartWorker(
-      const EmbeddedWorkerStartParams& params,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void StartWorker(const EmbeddedWorkerStartParams& params,
+                   mojom::ServiceWorkerEventDispatcherRequest request,
+                   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                       instance_host) override {
     ASSERT_TRUE(next_pause_after_download_.has_value());
     EXPECT_EQ(next_pause_after_download_.value(), params.pause_after_download);
     num_of_startworker_++;
     EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
-        params, std::move(request), std::move(instance_host),
-        std::move(provider_info));
+        params, std::move(request), std::move(instance_host));
   }
 
  private:
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index 5de525ed..34be8dd 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -36,13 +36,10 @@
 
 namespace {
 
-// Provider host for navigation with PlzNavigate or when service worker's
-// context is created on the browser side. This function provides the next
-// ServiceWorkerProviderHost ID for them, starts at -2 and keeps going down.
-int NextBrowserProvidedProviderId() {
-  static int g_next_browser_provided_provider_id = -2;
-  return g_next_browser_provided_provider_id--;
-}
+// PlzNavigate
+// Next ServiceWorkerProviderHost ID for navigations, starts at -2 and keeps
+// going down.
+int g_next_navigation_provider_id = -2;
 
 // A request handler derivative used to handle navigation requests when
 // skip_service_worker flag is set. It tracks the document URL and sets the url
@@ -62,9 +59,10 @@
   ~ServiceWorkerURLTrackingRequestHandler() override {}
 
   // Called via custom URLRequestJobFactory.
-  net::URLRequestJob* MaybeCreateJob(net::URLRequest* request,
-                                     net::NetworkDelegate*,
-                                     ResourceContext*) override {
+  net::URLRequestJob* MaybeCreateJob(
+      net::URLRequest* request,
+      net::NetworkDelegate* /* network_delegate */,
+      ResourceContext* /* resource_context */) override {
     // |provider_host_| may have been deleted when the request is resumed.
     if (!provider_host_)
       return nullptr;
@@ -116,31 +114,19 @@
     bool are_ancestors_secure,
     const WebContentsGetter& web_contents_getter) {
   CHECK(IsBrowserSideNavigationEnabled());
+  // Generate a new browser-assigned id for the host.
+  int provider_id = g_next_navigation_provider_id--;
   auto host = base::WrapUnique(new ServiceWorkerProviderHost(
       ChildProcessHost::kInvalidUniqueID,
-      ServiceWorkerProviderHostInfo(
-          NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
-          SERVICE_WORKER_PROVIDER_FOR_WINDOW, are_ancestors_secure),
+      ServiceWorkerProviderHostInfo(provider_id, MSG_ROUTING_NONE,
+                                    SERVICE_WORKER_PROVIDER_FOR_WINDOW,
+                                    are_ancestors_secure),
       context, nullptr));
   host->web_contents_getter_ = web_contents_getter;
   return host;
 }
 
 // static
-std::unique_ptr<ServiceWorkerProviderHost>
-ServiceWorkerProviderHost::PreCreateForController(
-    base::WeakPtr<ServiceWorkerContextCore> context) {
-  auto host = base::WrapUnique(new ServiceWorkerProviderHost(
-      ChildProcessHost::kInvalidUniqueID,
-      ServiceWorkerProviderHostInfo(NextBrowserProvidedProviderId(),
-                                    MSG_ROUTING_NONE,
-                                    SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
-                                    true /* is_parent_frame_secure */),
-      std::move(context), nullptr));
-  return host;
-}
-
-// static
 std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create(
     int process_id,
     ServiceWorkerProviderHostInfo info,
@@ -191,27 +177,20 @@
       binding_(this) {
   DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, info_.type);
 
+  // PlzNavigate
+  CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID ||
+        IsBrowserSideNavigationEnabled());
 
   if (info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) {
-    // Actual |render_process_id| will be set after choosing a process for the
-    // controller, and |render_thread id| will be set when the service worker
-    // context gets started.
-    DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id);
+    // Actual thread id is set when the service worker context gets started.
     render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
-  } else {
-    // PlzNavigate
-    DCHECK(render_process_id != ChildProcessHost::kInvalidUniqueID ||
-           IsBrowserSideNavigationEnabled());
   }
-
   context_->RegisterProviderHostByClientID(client_uuid_, this);
 
-  // |client_| and |binding_| will be bound on CompleteNavigationInitialized
-  // (PlzNavigate) or on CompleteStartWorkerPreparation (providers for
-  // controller).
-  if (!info_.client_ptr_info.is_valid() && !info_.host_request.is_pending()) {
-    DCHECK(IsBrowserSideNavigationEnabled() ||
-           info_.type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER);
+  // PlzNavigate
+  // |provider_| and |binding_| will be bound on CompleteNavigationInitialized.
+  if (IsBrowserSideNavigationEnabled()) {
+    DCHECK(!info.client_ptr_info.is_valid() && !info.host_request.is_pending());
     return;
   }
 
@@ -345,6 +324,14 @@
       version ? version->used_features() : std::set<uint32_t>()));
 }
 
+void ServiceWorkerProviderHost::SetHostedVersion(
+    ServiceWorkerVersion* version) {
+  DCHECK(!IsProviderForClient());
+  DCHECK_EQ(EmbeddedWorkerStatus::STARTING, version->running_status());
+  DCHECK_EQ(render_process_id_, version->embedded_worker()->process_id());
+  running_hosted_version_ = version;
+}
+
 bool ServiceWorkerProviderHost::IsProviderForClient() const {
   switch (info_.type) {
     case SERVICE_WORKER_PROVIDER_FOR_WINDOW:
@@ -672,54 +659,6 @@
   NotifyControllerToAssociatedProvider();
 }
 
-mojom::ServiceWorkerProviderInfoForStartWorkerPtr
-ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
-    int process_id,
-    scoped_refptr<ServiceWorkerVersion> hosted_version) {
-  DCHECK(context_);
-  DCHECK_EQ(kInvalidEmbeddedWorkerThreadId, render_thread_id_);
-  DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
-  DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, provider_type());
-  DCHECK(!running_hosted_version_);
-
-  DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
-
-  running_hosted_version_ = std::move(hosted_version);
-
-  ServiceWorkerDispatcherHost* dispatcher_host =
-      context_->GetDispatcherHost(process_id);
-  DCHECK(dispatcher_host);
-  render_process_id_ = process_id;
-  dispatcher_host_ = dispatcher_host;
-
-  // Retrieve the registration associated with |version|. The registration
-  // must be alive because the version keeps it during starting worker.
-  ServiceWorkerRegistration* registration = context_->GetLiveRegistration(
-      running_hosted_version()->registration_id());
-  DCHECK(registration);
-  ServiceWorkerRegistrationObjectInfo info;
-  ServiceWorkerVersionAttributes attrs;
-  dispatcher_host->GetRegistrationObjectInfoAndVersionAttributes(
-      AsWeakPtr(), registration, &info, &attrs);
-
-  // Initialize provider_info.
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
-      mojom::ServiceWorkerProviderInfoForStartWorker::New();
-  provider_info->provider_id = provider_id();
-  provider_info->attributes = std::move(attrs);
-  provider_info->registration = std::move(info);
-  provider_info->client_request = mojo::MakeRequest(&provider_);
-  binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info));
-  binding_.set_connection_error_handler(
-      base::Bind(&RemoveProviderHost, context_, process_id, provider_id()));
-
-  // Set the document URL to the script url in order to allow
-  // register/unregister/getRegistration on ServiceWorkerGlobalScope.
-  SetDocumentUrl(running_hosted_version()->script_url());
-
-  return provider_info;
-}
-
 void ServiceWorkerProviderHost::SendUpdateFoundMessage(
     int registration_handle_id) {
   if (!dispatcher_host_)
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index b5de3f2..f2ed389 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -58,23 +58,17 @@
 // For providers hosting a running service worker, this class will observe
 // resource loads made directly by the service worker.
 //
-// A ServiceWorkerProviderHost is created in the following situations:
-// 1) When it's for a document or worker (i.e., a service
-// worker client), the provider host is created when
-// ServiceWorkerNetworkProvider is created on the renderer process. Mojo's
-// connection from ServiceWorkerNetworkProvider is established on the creation
-// time.
-// 2) When it's for a running service worker, the provider host is created on
-// the browser process before launching the service worker's thread. Mojo's
-// connection to the renderer is established with the StartWorker message.
-// 3) When PlzNavigate is turned on, an instance is pre-created on the browser
+// A ServiceWorkerProviderHost instance is created when a
+// ServiceWorkerNetworkProvider is created on the renderer process, which
+// happens 1) when a document or worker (i.e., a service worker client) is
+// created, or 2) during service worker startup. Mojo's connection from
+// ServiceWorkerNetworkProvider is established on the creation time, and the
+// instance is destroyed on disconnection from the renderer side.
+// If PlzNavigate is turned on, an instance is pre-created on the browser
 // before ServiceWorkerNetworkProvider is created on the renderer because
 // navigation is initiated on the browser side. In that case, establishment of
 // Mojo's connection will be deferred until ServiceWorkerNetworkProvider is
 // created on the renderer.
-// Destruction of the ServiceWorkerProviderHost instance happens on
-// disconnection of the Mojo's pipe from the renderer side regardless of what
-// the provider is for.
 class CONTENT_EXPORT ServiceWorkerProviderHost
     : public NON_EXPORTED_BASE(ServiceWorkerRegistration::Listener),
       public base::SupportsWeakPtr<ServiceWorkerProviderHost>,
@@ -97,12 +91,6 @@
       bool are_ancestors_secure,
       const WebContentsGetter& web_contents_getter);
 
-  // Creates a ServiceWorkerProviderHost for hosting a running service worker.
-  // Information about this provider host is passed down to the service worker
-  // via StartWorker message.
-  static std::unique_ptr<ServiceWorkerProviderHost> PreCreateForController(
-      base::WeakPtr<ServiceWorkerContextCore> context);
-
   // Used to create a ServiceWorkerProviderHost when the renderer-side provider
   // is created. This ProviderHost will be created for the process specified by
   // |process_id|.
@@ -212,6 +200,8 @@
   // Clears the associated registration and stop listening to it.
   void DisassociateRegistration();
 
+  void SetHostedVersion(ServiceWorkerVersion* version);
+
   // Returns a handler for a request, the handler may return NULL if
   // the request doesn't require special handling.
   std::unique_ptr<ServiceWorkerRequestHandler> CreateRequestHandler(
@@ -280,16 +270,6 @@
       ServiceWorkerProviderHostInfo info,
       ServiceWorkerDispatcherHost* dispatcher_host);
 
-  // Completes initialization of provider hosts for controllers and returns the
-  // value to create ServiceWorkerNetworkProvider on the renderer which will be
-  // connected to this instance.
-  // This instance will keep the reference to |hosted_version|, so please be
-  // careful not to create a reference cycle.
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr
-  CompleteStartWorkerPreparation(
-      int process_id,
-      scoped_refptr<ServiceWorkerVersion> hosted_version);
-
   // Sends event messages to the renderer. Events for the worker are queued up
   // until the worker thread id is known via SetReadyToSendMessagesToWorker().
   void SendUpdateFoundMessage(
@@ -325,12 +305,6 @@
   void BindWorkerFetchContext(
       mojom::ServiceWorkerWorkerClientAssociatedPtrInfo client_ptr_info);
 
- protected:
-  ServiceWorkerProviderHost(int process_id,
-                            ServiceWorkerProviderHostInfo info,
-                            base::WeakPtr<ServiceWorkerContextCore> context,
-                            ServiceWorkerDispatcherHost* dispatcher_host);
-
  private:
   friend class ForeignFetchRequestHandlerTest;
   friend class LinkHeaderServiceWorkerTest;
@@ -361,6 +335,11 @@
     ~OneShotGetReadyCallback();
   };
 
+  ServiceWorkerProviderHost(int process_id,
+                            ServiceWorkerProviderHostInfo info,
+                            base::WeakPtr<ServiceWorkerContextCore> context,
+                            ServiceWorkerDispatcherHost* dispatcher_host);
+
   // ServiceWorkerRegistration::Listener overrides.
   void OnVersionAttributesChanged(
       ServiceWorkerRegistration* registration,
diff --git a/content/browser/service_worker/service_worker_registration.h b/content/browser/service_worker/service_worker_registration.h
index 71c6130..e0f107a 100644
--- a/content/browser/service_worker/service_worker_registration.h
+++ b/content/browser/service_worker/service_worker_registration.h
@@ -35,7 +35,7 @@
  public:
   typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
 
-  class CONTENT_EXPORT Listener {
+  class Listener {
    public:
     virtual void OnVersionAttributesChanged(
         ServiceWorkerRegistration* registration,
diff --git a/content/browser/service_worker/service_worker_registration_handle.h b/content/browser/service_worker/service_worker_registration_handle.h
index 1384604..e06b112 100644
--- a/content/browser/service_worker/service_worker_registration_handle.h
+++ b/content/browser/service_worker/service_worker_registration_handle.h
@@ -12,7 +12,6 @@
 #include "base/memory/weak_ptr.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/content_export.h"
 #include "content/common/service_worker/service_worker_types.h"
 
 namespace content {
@@ -31,10 +30,10 @@
 //
 // Has a reference to the corresponding ServiceWorkerRegistration in order to
 // ensure that the registration is alive while this handle is around.
-class CONTENT_EXPORT ServiceWorkerRegistrationHandle
+class ServiceWorkerRegistrationHandle
     : public ServiceWorkerRegistration::Listener {
  public:
-  ServiceWorkerRegistrationHandle(
+  CONTENT_EXPORT ServiceWorkerRegistrationHandle(
       base::WeakPtr<ServiceWorkerContextCore> context,
       base::WeakPtr<ServiceWorkerProviderHost> provider_host,
       ServiceWorkerRegistration* registration);
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index 7d943cd..444135ee 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -260,8 +260,6 @@
         helper_->mock_render_process_id(), 1 /* dummy provider_id */,
         true /* is_parent_frame_secure */, context()->AsWeakPtr(),
         &remote_endpoint_);
-    DCHECK(remote_endpoint_.client_request()->is_pending());
-    DCHECK(remote_endpoint_.host_ptr()->is_bound());
     version_1->AddControllee(host_.get());
 
     // Give the active version an in-flight request.
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index 7d99416..4c8f7390 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -7,8 +7,6 @@
 #include <utility>
 
 #include "content/browser/service_worker/service_worker_provider_host.h"
-#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "content/public/common/child_process_host.h"
 
 namespace content {
 
@@ -28,12 +26,6 @@
   info->host_request = mojo::MakeIsolatedRequest(&host_ptr_);
 }
 
-void ServiceWorkerRemoteProviderEndpoint::BindWithProviderInfo(
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr info) {
-  client_request_ = std::move(info->client_request);
-  host_ptr_.Bind(std::move(info->host_ptr_info));
-}
-
 std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
     int process_id,
     int provider_id,
@@ -51,19 +43,16 @@
 std::unique_ptr<ServiceWorkerProviderHost>
 CreateProviderHostForServiceWorkerContext(
     int process_id,
+    int provider_id,
     bool is_parent_frame_secure,
-    ServiceWorkerVersion* hosted_version,
     base::WeakPtr<ServiceWorkerContextCore> context,
     ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
-  ServiceWorkerProviderHostInfo info(
-      kInvalidServiceWorkerProviderId, MSG_ROUTING_NONE,
-      SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, is_parent_frame_secure);
-  std::unique_ptr<ServiceWorkerProviderHost> host =
-      ServiceWorkerProviderHost::PreCreateForController(std::move(context));
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
-      host->CompleteStartWorkerPreparation(process_id, hosted_version);
-  output_endpoint->BindWithProviderInfo(std::move(provider_info));
-  return host;
+  ServiceWorkerProviderHostInfo info(provider_id, MSG_ROUTING_NONE,
+                                     SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
+                                     is_parent_frame_secure);
+  output_endpoint->BindWithProviderHostInfo(&info);
+  return ServiceWorkerProviderHost::Create(process_id, std::move(info),
+                                           std::move(context), nullptr);
 }
 
 std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostWithDispatcherHost(
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h
index dc7217c4..2c9a086 100644
--- a/content/browser/service_worker/service_worker_test_utils.h
+++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -11,7 +11,7 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/memory/weak_ptr.h"
-#include "content/common/service_worker/service_worker_provider.mojom.h"
+#include "content/common/service_worker/service_worker_provider_interfaces.mojom.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -21,7 +21,6 @@
 class ServiceWorkerContextCore;
 class ServiceWorkerDispatcherHost;
 class ServiceWorkerProviderHost;
-class ServiceWorkerVersion;
 struct ServiceWorkerProviderHostInfo;
 
 template <typename Arg>
@@ -59,8 +58,6 @@
   ~ServiceWorkerRemoteProviderEndpoint();
 
   void BindWithProviderHostInfo(ServiceWorkerProviderHostInfo* info);
-  void BindWithProviderInfo(
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr info);
 
   mojom::ServiceWorkerProviderHostAssociatedPtr* host_ptr() {
     return &host_ptr_;
@@ -91,8 +88,8 @@
 std::unique_ptr<ServiceWorkerProviderHost>
 CreateProviderHostForServiceWorkerContext(
     int process_id,
+    int provider_id,
     bool is_parent_frame_secure,
-    ServiceWorkerVersion* hosted_version,
     base::WeakPtr<ServiceWorkerContextCore> context,
     ServiceWorkerRemoteProviderEndpoint* output_endpoint);
 
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index b6489eb0..54ab731 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -439,7 +439,7 @@
     EmbeddedWorkerTestHelper::OnStartWorker(
         embedded_worker_id_, service_worker_version_id_, scope_, script_url_,
         pause_after_download_, std::move(start_worker_request_),
-        std::move(start_worker_instance_host_), std::move(provider_info_));
+        std::move(start_worker_instance_host_));
   }
 
   void Respond() {
@@ -458,16 +458,14 @@
   }
 
  protected:
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     embedded_worker_id_ = embedded_worker_id;
     service_worker_version_id_ = service_worker_version_id;
     scope_ = scope;
@@ -475,7 +473,6 @@
     pause_after_download_ = pause_after_download;
     start_worker_request_ = std::move(request);
     start_worker_instance_host_ = std::move(instance_host);
-    provider_info_ = std::move(provider_info);
   }
 
   void OnFetchEvent(
@@ -500,7 +497,6 @@
   mojom::ServiceWorkerEventDispatcherRequest start_worker_request_;
   mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
       start_worker_instance_host_;
-  mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info_;
   int embedded_worker_id_ = 0;
   int fetch_event_id_ = 0;
   mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index c7fac32..b47f556 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -201,21 +201,6 @@
   }
 }
 
-mojom::ServiceWorkerProviderInfoForStartWorkerPtr
-CompleteProviderHostPreparation(
-    ServiceWorkerVersion* version,
-    std::unique_ptr<ServiceWorkerProviderHost> provider_host,
-    base::WeakPtr<ServiceWorkerContextCore> context,
-    int process_id) {
-  // Caller should ensure |context| is alive when completing StartWorker
-  // preparation.
-  DCHECK(context);
-  auto info =
-      provider_host->CompleteStartWorkerPreparation(process_id, version);
-  context->AddProviderHost(std::move(provider_host));
-  return info;
-}
-
 }  // namespace
 
 constexpr base::TimeDelta ServiceWorkerVersion::kTimeoutTimerDelay;
@@ -855,9 +840,6 @@
 
 void ServiceWorkerVersion::OnThreadStarted() {
   DCHECK_EQ(EmbeddedWorkerStatus::STARTING, running_status());
-  DCHECK(provider_host_);
-  provider_host_->SetReadyToSendMessagesToWorker(
-      embedded_worker()->thread_id());
   // Activate ping/pong now that JavaScript execution will start.
   ping_controller_->Activate();
 }
@@ -1476,10 +1458,6 @@
 
   StartTimeoutTimer();
 
-  std::unique_ptr<ServiceWorkerProviderHost> pending_provider_host =
-      ServiceWorkerProviderHost::PreCreateForController(context());
-  provider_host_ = pending_provider_host->AsWeakPtr();
-
   auto params = base::MakeUnique<EmbeddedWorkerStartParams>();
   params->service_worker_version_id = version_id_;
   params->scope = scope_;
@@ -1488,12 +1466,7 @@
   params->pause_after_download = pause_after_download_;
 
   embedded_worker_->Start(
-      std::move(params),
-      // Unretained is used here because the callback will be owned by
-      // |embedded_worker_| whose owner is |this|.
-      base::BindOnce(&CompleteProviderHostPreparation, base::Unretained(this),
-                     base::Passed(&pending_provider_host), context()),
-      mojo::MakeRequest(&event_dispatcher_),
+      std::move(params), mojo::MakeRequest(&event_dispatcher_),
       base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
                  weak_factory_.GetWeakPtr()));
   event_dispatcher_.set_connection_error_handler(base::Bind(
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 5ed49bf..e53d2169 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -298,13 +298,6 @@
     return controllee_map_;
   }
 
-  // The provider host hosting this version. Only valid while the version is
-  // running.
-  ServiceWorkerProviderHost* provider_host() {
-    DCHECK(provider_host_);
-    return provider_host_.get();
-  }
-
   base::WeakPtr<ServiceWorkerContextCore> context() const { return context_; }
 
   // Adds and removes |request_job| as a dependent job not to stop the
@@ -718,11 +711,6 @@
 
   std::set<const ServiceWorkerURLRequestJob*> streaming_url_request_jobs_;
 
-  // Keeps track of the provider hosting this running service worker for this
-  // version. |provider_host_| is always valid as long as this version is
-  // running.
-  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
-
   std::map<std::string, ServiceWorkerProviderHost*> controllee_map_;
   // Will be null while shutting down.
   base::WeakPtr<ServiceWorkerContextCore> context_;
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 8315638..925ba94 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -270,16 +270,14 @@
 
   enum class StartMode { STALL, FAIL, SUCCEED };
 
-  void OnStartWorker(
-      int embedded_worker_id,
-      int64_t service_worker_version_id,
-      const GURL& scope,
-      const GURL& script_url,
-      bool pause_after_download,
-      mojom::ServiceWorkerEventDispatcherRequest request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info)
-      override {
+  void OnStartWorker(int embedded_worker_id,
+                     int64_t service_worker_version_id,
+                     const GURL& scope,
+                     const GURL& script_url,
+                     bool pause_after_download,
+                     mojom::ServiceWorkerEventDispatcherRequest request,
+                     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
+                         instance_host) override {
     switch (mode_) {
       case StartMode::STALL:
         // Prepare for OnStopWorker().
@@ -298,8 +296,7 @@
       case StartMode::SUCCEED:
         MessageReceiver::OnStartWorker(
             embedded_worker_id, service_worker_version_id, scope, script_url,
-            pause_after_download, std::move(request), std::move(instance_host),
-            std::move(provider_info));
+            pause_after_download, std::move(request), std::move(instance_host));
         break;
     }
     current_mock_instance_index_++;
@@ -707,11 +704,6 @@
   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, listener.last_status);
 
-  // Destruct |version_| by releasing all references, including the provider
-  // host's.
-  helper_->context()->RemoveProviderHost(
-      version_->provider_host()->process_id(),
-      version_->provider_host()->provider_id());
   version_ = nullptr;
   EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, listener.last_status);
 }
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
index 1c5cd4d9..317ade5 100644
--- a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -288,14 +288,16 @@
 
   base::WeakPtr<ServiceWorkerProviderHost> CreateHostForVersion(
       int process_id,
+      int provider_id,
       const scoped_refptr<ServiceWorkerVersion>& version) {
     std::unique_ptr<ServiceWorkerProviderHost> host =
         CreateProviderHostForServiceWorkerContext(
-            process_id, true /* is_parent_frame_secure */, version.get(),
+            process_id, provider_id, true /* is_parent_frame_secure */,
             context()->AsWeakPtr(), &remote_endpoint_);
-    base::WeakPtr<ServiceWorkerProviderHost> host_weakptr = host->AsWeakPtr();
+    base::WeakPtr<ServiceWorkerProviderHost> provider_host = host->AsWeakPtr();
     context()->AddProviderHost(std::move(host));
-    return host_weakptr;
+    provider_host->running_hosted_version_ = version;
+    return provider_host;
   }
 
   void SetUpScriptRequest(int process_id, int provider_id) {
@@ -325,9 +327,11 @@
         scoped_refptr<ResourceRequestBodyImpl>());
   }
 
+  int NextProviderId() { return next_provider_id_++; }
   int NextVersionId() { return next_version_id_++; }
 
   void SetUp() override {
+    int provider_id = NextProviderId();
     helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
 
     // A new unstored registration/version.
@@ -336,8 +340,8 @@
     version_ =
         new ServiceWorkerVersion(registration_.get(), script_url_,
                                  NextVersionId(), context()->AsWeakPtr());
-    base::WeakPtr<ServiceWorkerProviderHost> host =
-        CreateHostForVersion(helper_->mock_render_process_id(), version_);
+    base::WeakPtr<ServiceWorkerProviderHost> host = CreateHostForVersion(
+        helper_->mock_render_process_id(), provider_id, version_);
     ASSERT_TRUE(host);
     SetUpScriptRequest(helper_->mock_render_process_id(), host->provider_id());
 
@@ -387,13 +391,14 @@
   // to the script |response|. Returns the new version.
   scoped_refptr<ServiceWorkerVersion> UpdateScript(
       const std::string& response) {
+    int provider_id = NextProviderId();
     scoped_refptr<ServiceWorkerVersion> new_version =
         new ServiceWorkerVersion(registration_.get(), script_url_,
                                  NextVersionId(), context()->AsWeakPtr());
     new_version->set_pause_after_download(true);
-    base::WeakPtr<ServiceWorkerProviderHost> host =
-        CreateHostForVersion(helper_->mock_render_process_id(), new_version);
-    EXPECT_TRUE(host);
+    base::WeakPtr<ServiceWorkerProviderHost> host = CreateHostForVersion(
+        helper_->mock_render_process_id(), provider_id, new_version);
+
     SetUpScriptRequest(helper_->mock_render_process_id(), host->provider_id());
     mock_protocol_handler_->SetCreateJobCallback(
         base::Bind(&CreateResponseJob, response));
@@ -430,6 +435,7 @@
   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
   scoped_refptr<ServiceWorkerRegistration> registration_;
   scoped_refptr<ServiceWorkerVersion> version_;
+  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
   std::unique_ptr<net::URLRequestContext> url_request_context_;
   std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
   std::unique_ptr<net::URLRequest> request_;
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
index ef7b8bd..57b608b 100644
--- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
+++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -27,6 +27,7 @@
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "media/audio/audio_manager.h"
+#include "media/audio/fake_audio_input_stream.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/perf/perf_test.h"
 
@@ -46,6 +47,8 @@
     "getUserMediaAndAnalyseAndStop";
 static const char kGetUserMediaAndExpectFailure[] =
     "getUserMediaAndExpectFailure";
+static const char kGetUserMediaForAudioMutingTest[] =
+    "getUserMediaForAudioMutingTest";
 static const char kRenderSameTrackMediastreamAndStop[] =
     "renderSameTrackMediastreamAndStop";
 static const char kRenderClonedMediastreamAndStop[] =
@@ -1463,4 +1466,53 @@
       MediaStreamManager::GenerateStreamTestCallback());
 }
 
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetAudioStreamAndCheckMutingInitiallyUnmuted) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  // Expect stream to initially not be muted
+  media::FakeAudioInputStream::SetGlobalMutedState(false);
+  ExecuteJavascriptAndWaitForOk(
+      base::StringPrintf("%s(false);", kGetUserMediaForAudioMutingTest));
+
+  // Mute
+  media::FakeAudioInputStream::SetGlobalMutedState(true);
+  EXPECT_EQ("onmute: muted=true, readyState=live",
+            ExecuteJavascriptAndReturnResult(
+                "failTestAfterTimeout('Got no mute event', 1500);"));
+  // Unmute
+  media::FakeAudioInputStream::SetGlobalMutedState(false);
+  EXPECT_EQ("onunmute: muted=false, readyState=live",
+            ExecuteJavascriptAndReturnResult(
+                "failTestAfterTimeout('Got no unmute event', 1500);"));
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetAudioStreamAndCheckMutingInitiallyMuted) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  // Expect stream to initially be muted
+  media::FakeAudioInputStream::SetGlobalMutedState(true);
+  ExecuteJavascriptAndWaitForOk(
+      base::StringPrintf("%s(true);", kGetUserMediaForAudioMutingTest));
+
+  // Unmute
+  media::FakeAudioInputStream::SetGlobalMutedState(false);
+  EXPECT_EQ("onunmute: muted=false, readyState=live",
+            ExecuteJavascriptAndReturnResult(
+                "failTestAfterTimeout('Got no unmute event', 1500);"));
+
+  // Mute
+  media::FakeAudioInputStream::SetGlobalMutedState(true);
+  EXPECT_EQ("onmute: muted=true, readyState=live",
+            ExecuteJavascriptAndReturnResult(
+                "failTestAfterTimeout('Got no mute event', 1500);"));
+}
+
 }  // namespace content
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h
index 83619d3dd7..5c6cabe 100644
--- a/content/child/service_worker/service_worker_dispatcher.h
+++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -163,11 +163,6 @@
       const ServiceWorkerRegistrationObjectInfo& info,
       const ServiceWorkerVersionAttributes& attrs);
 
-  void OnAssociateRegistration(int thread_id,
-                               int provider_id,
-                               const ServiceWorkerRegistrationObjectInfo& info,
-                               const ServiceWorkerVersionAttributes& attrs);
-
   static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
       ThreadSafeSender* thread_safe_sender,
       base::SingleThreadTaskRunner* main_thread_task_runner);
@@ -215,6 +210,10 @@
   // WorkerThread::Observer implementation.
   void WillStopCurrentWorkerThread() override;
 
+  void OnAssociateRegistration(int thread_id,
+                               int provider_id,
+                               const ServiceWorkerRegistrationObjectInfo& info,
+                               const ServiceWorkerVersionAttributes& attrs);
   void OnDisassociateRegistration(int thread_id,
                                   int provider_id);
   void OnRegistered(int thread_id,
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc
index 19c50777ed..364d0dc 100644
--- a/content/child/service_worker/service_worker_network_provider.cc
+++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -7,7 +7,6 @@
 #include "base/atomic_sequence_num.h"
 #include "content/child/child_thread_impl.h"
 #include "content/child/request_extra_data.h"
-#include "content/child/service_worker/service_worker_dispatcher.h"
 #include "content/child/service_worker/service_worker_handle_reference.h"
 #include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/common/navigation_params.h"
@@ -208,25 +207,6 @@
                                    GetNextProviderId(),
                                    is_parent_frame_secure) {}
 
-ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr info)
-    : provider_id_(info->provider_id) {
-  context_ = new ServiceWorkerProviderContext(
-      provider_id_, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
-      std::move(info->client_request),
-      ChildThreadImpl::current()->thread_safe_sender());
-
-  ServiceWorkerDispatcher* dispatcher =
-      ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-          ChildThreadImpl::current()->thread_safe_sender(),
-          base::ThreadTaskRunnerHandle::Get().get());
-  // TODO(shimazu): Set registration/attributes directly to |context_|.
-  dispatcher->OnAssociateRegistration(-1 /* unused thread_id */,
-                                      info->provider_id, info->registration,
-                                      info->attributes);
-  provider_host_.Bind(std::move(info->host_ptr_info));
-}
-
 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider()
     : provider_id_(kInvalidServiceWorkerProviderId) {}
 
@@ -238,6 +218,16 @@
   provider_host_.reset();
 }
 
+void ServiceWorkerNetworkProvider::SetServiceWorkerVersionId(
+    int64_t version_id,
+    int embedded_worker_id) {
+  DCHECK_NE(kInvalidServiceWorkerProviderId, provider_id_);
+  if (!ChildThreadImpl::current())
+    return;  // May be null in some tests.
+  dispatcher_host_->OnSetHostedVersionId(provider_id(), version_id,
+                                         embedded_worker_id);
+}
+
 bool ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const {
   if (ServiceWorkerUtils::IsServicificationEnabled()) {
     // Interception for subresource loading is not working (yet)
diff --git a/content/child/service_worker/service_worker_network_provider.h b/content/child/service_worker/service_worker_network_provider.h
index 1ca07d96..113d260 100644
--- a/content/child/service_worker/service_worker_network_provider.h
+++ b/content/child/service_worker/service_worker_network_provider.h
@@ -15,7 +15,6 @@
 #include "base/supports_user_data.h"
 #include "content/common/content_export.h"
 #include "content/common/service_worker/service_worker.mojom.h"
-#include "content/common/service_worker/service_worker_provider.mojom.h"
 
 namespace blink {
 class WebLocalFrame;
@@ -58,13 +57,9 @@
                                ServiceWorkerProviderType type,
                                int browser_provider_id,
                                bool is_parent_frame_secure);
-  // This is for service worker clients.
   ServiceWorkerNetworkProvider(int route_id,
                                ServiceWorkerProviderType type,
                                bool is_parent_frame_secure);
-  // This is for controllers.
-  explicit ServiceWorkerNetworkProvider(
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr info);
 
   ServiceWorkerNetworkProvider();
   ~ServiceWorkerNetworkProvider();
@@ -72,6 +67,11 @@
   int provider_id() const { return provider_id_; }
   ServiceWorkerProviderContext* context() const { return context_.get(); }
 
+  // This method is called for a provider that's associated with a
+  // running service worker script. The version_id indicates which
+  // ServiceWorkerVersion should be used.
+  void SetServiceWorkerVersionId(int64_t version_id, int embedded_worker_id);
+
   bool IsControlledByServiceWorker() const;
 
  private:
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom
index 928cba2..48ec1576 100644
--- a/content/common/service_worker/embedded_worker.mojom
+++ b/content/common/service_worker/embedded_worker.mojom
@@ -5,7 +5,6 @@
 module content.mojom;
 
 import "content/common/service_worker/service_worker_event_dispatcher.mojom";
-import "content/common/service_worker/service_worker_provider.mojom";
 import "mojo/common/string16.mojom";
 import "services/service_manager/public/interfaces/interface_provider.mojom";
 import "third_party/WebKit/public/web/console_message.mojom";
@@ -19,8 +18,7 @@
 interface EmbeddedWorkerInstanceClient {
   StartWorker(EmbeddedWorkerStartParams params,
               ServiceWorkerEventDispatcher& dispatcher_request,
-              associated EmbeddedWorkerInstanceHost instance_host,
-              ServiceWorkerProviderInfoForStartWorker provider_info);
+              associated EmbeddedWorkerInstanceHost instance_host);
   // The response is sent back via EmbeddedWorkerInstanceHost.OnStopped().
   StopWorker();
   ResumeAfterDownload();
@@ -39,9 +37,12 @@
   // Indicates that the worker has failed to load the script.
   OnScriptLoadFailed();
   // Indicates that the worker thread has started. |thread_id| is the actual
-  // platform thread id on which the worker runs.
+  // platform thread id on which the worker runs, while |provider_id| is the id
+  // of the ServiceWorkerNetworkProvider instance, which is unique in one
+  // renderer process, and the browser process uses this id to maintain a
+  // counterpart ServiceWorkerProviderHost instance.
   // This is called after OnScriptLoaded.
-  OnThreadStarted(int32 thread_id);
+  OnThreadStarted(int32 thread_id, int32 provider_id);
   // Indicates that the worker has evaluated the script. |success| means
   // evaluating the script completed and no uncaught exception occurred.
   // This is called after OnThreadStarted.
diff --git a/content/common/service_worker/service_worker.mojom b/content/common/service_worker/service_worker.mojom
index b9834324..7e8f5c8 100644
--- a/content/common/service_worker/service_worker.mojom
+++ b/content/common/service_worker/service_worker.mojom
@@ -16,4 +16,12 @@
   // ServiceWorkerProviderHost will be tied to the
   // mojom::ServiceWorkerProviderHost interface.
   OnProviderCreated(ServiceWorkerProviderHostInfo provider_info);
+
+  // Informs the browser that a service worker is starting up. |provider_id|
+  // identifies the ServiceWorkerProviderHost hosting the service
+  // worker. |version_id| identifies the ServiceWorkerVersion and
+  // |embedded_worker_id| identifies the EmbeddedWorkerInstance.  
+  OnSetHostedVersionId(int32 provider_id,
+                       int64 version_id,
+                       int32 embedded_worker_id);
 };
\ No newline at end of file
diff --git a/content/common/service_worker/service_worker_provider.mojom b/content/common/service_worker/service_worker_provider.mojom
index b01b1cf2..4016e42 100644
--- a/content/common/service_worker/service_worker_provider.mojom
+++ b/content/common/service_worker/service_worker_provider.mojom
@@ -7,20 +7,6 @@
 import "content/common/service_worker/service_worker_provider_interfaces.mojom";
 import "content/common/service_worker/service_worker_types.mojom";
 
-// A container object carried from the browser to the renderer process.
-// This contains the params for the constructor of ServiceWorkerNetworkProvider
-// used for starting a service worker.
-struct ServiceWorkerProviderInfoForStartWorker {
-  int32 provider_id;
-  // |registration| and |attributes| are information about the service worker's
-  // registration used to populate ServiceWorkerGlobalScope#registration.
-  ServiceWorkerRegistrationObjectInfo registration;
-  ServiceWorkerVersionAttributes attributes;
-
-  associated ServiceWorkerProviderHost host_ptr_info;
-  associated ServiceWorkerProvider& client_request;
-};
-
 // A container object carried from the renderer to the browser process.
 // This contains the parameters to specify the provider on the browser side.
 // See also comments in
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h
index c8a2e81c..a3f10c41 100644
--- a/content/common/service_worker/service_worker_types.h
+++ b/content/common/service_worker/service_worker_types.h
@@ -228,7 +228,7 @@
   int64_t registration_id;
 };
 
-struct CONTENT_EXPORT ServiceWorkerVersionAttributes {
+struct ServiceWorkerVersionAttributes {
   ServiceWorkerObjectInfo installing;
   ServiceWorkerObjectInfo waiting;
   ServiceWorkerObjectInfo active;
diff --git a/content/common/service_worker/service_worker_types.mojom b/content/common/service_worker/service_worker_types.mojom
index 9aa4bf0..1094171 100644
--- a/content/common/service_worker/service_worker_types.mojom
+++ b/content/common/service_worker/service_worker_types.mojom
@@ -17,15 +17,4 @@
 
   SERVICE_WORKER_PROVIDER_TYPE_LAST =
       SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
-};
-
-// Container for delivering the information about the ServiceWorkerRegistration.
-// Defined in service_worker_types.h.
-[Native]
-struct ServiceWorkerRegistrationObjectInfo;
-
-// Container for delivering the information about the installing, waiting and
-// active ServiceWorkers.
-// Defined in service_worker_types.h.
-[Native]
-struct ServiceWorkerVersionAttributes;
+};
\ No newline at end of file
diff --git a/content/common/service_worker/service_worker_types.typemap b/content/common/service_worker/service_worker_types.typemap
index e1122fb..be057a4 100644
--- a/content/common/service_worker/service_worker_types.typemap
+++ b/content/common/service_worker/service_worker_types.typemap
@@ -7,15 +7,9 @@
   "//content/common/service_worker/service_worker_client_info.h",
   "//content/common/service_worker/service_worker_types.h",
 ]
-traits_headers = [
-  "//content/common/service_worker/service_worker_messages.h",
-  "//content/common/service_worker/service_worker_types_struct_traits.h",
-]
+traits_headers =
+    [ "//content/common/service_worker/service_worker_types_struct_traits.h" ]
 sources = [
   "//content/common/service_worker/service_worker_types_struct_traits.cc",
 ]
-type_mappings = [
-  "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType",
-  "content.mojom.ServiceWorkerRegistrationObjectInfo=::content::ServiceWorkerRegistrationObjectInfo",
-  "content.mojom.ServiceWorkerVersionAttributes=::content::ServiceWorkerVersionAttributes",
-]
+type_mappings = [ "content.mojom.ServiceWorkerProviderType=::content::ServiceWorkerProviderType" ]
diff --git a/content/public/test/test_browser_thread_bundle_unittest.cc b/content/public/test/test_browser_thread_bundle_unittest.cc
index 1b239d258..85d9244 100644
--- a/content/public/test/test_browser_thread_bundle_unittest.cc
+++ b/content/public/test/test_browser_thread_bundle_unittest.cc
@@ -27,9 +27,12 @@
 }
 
 TEST(TestBrowserThreadBundleTest, MultipleTestBrowserThreadBundle) {
-  TestBrowserThreadBundle test_browser_thread_bundle;
-  EXPECT_DEATH({ TestBrowserThreadBundle other_test_browser_thread_bundle; },
-               "");
+  EXPECT_DEATH(
+      {
+        TestBrowserThreadBundle test_browser_thread_bundle;
+        TestBrowserThreadBundle other_test_browser_thread_bundle;
+      },
+      "");
 }
 
 }  // namespace content
diff --git a/content/renderer/media/media_stream_audio_source.cc b/content/renderer/media/media_stream_audio_source.cc
index 19ea853..649ea15f 100644
--- a/content/renderer/media/media_stream_audio_source.cc
+++ b/content/renderer/media/media_stream_audio_source.cc
@@ -148,9 +148,10 @@
 }
 
 void MediaStreamAudioSource::SetMutedState(bool muted_state) {
-  // TODO(ossu): Propagate this muted state into blink.
-  DVLOG(3) << "MediaStreamAudioSource::SetMutedState state=" << muted_state
-           << " (not implemented)";
+  DVLOG(3) << "MediaStreamAudioSource::SetMutedState state=" << muted_state;
+  task_runner_->PostTask(
+      FROM_HERE, base::Bind(&MediaStreamSource::SetSourceMuted, GetWeakPtr(),
+                            muted_state));
 }
 
 }  // namespace content
diff --git a/content/renderer/media/media_stream_source.cc b/content/renderer/media/media_stream_source.cc
index 3334bfd..890cc69 100644
--- a/content/renderer/media/media_stream_source.cc
+++ b/content/renderer/media/media_stream_source.cc
@@ -26,6 +26,16 @@
   Owner().SetReadyState(blink::WebMediaStreamSource::kReadyStateEnded);
 }
 
+void MediaStreamSource::SetSourceMuted(bool is_muted) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  // Although this change is valid only if the ready state isn't already Ended,
+  // there's code further along (like in blink::MediaStreamTrack) which filters
+  // that out alredy.
+  Owner().SetReadyState(is_muted
+                            ? blink::WebMediaStreamSource::kReadyStateMuted
+                            : blink::WebMediaStreamSource::kReadyStateLive);
+}
+
 void MediaStreamSource::SetDeviceInfo(const StreamDeviceInfo& device_info) {
   DCHECK(thread_checker_.CalledOnValidThread());
   device_info_ = device_info;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 901eb22..a937fc2 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6314,6 +6314,14 @@
 
   blink::WebURLRequest& request = info.url_request;
 
+  // Set RequestorOrigin and FirstPartyForCookies
+  WebDocument frame_document = frame_->GetDocument();
+  if (request.GetFrameType() == blink::WebURLRequest::kFrameTypeTopLevel)
+    request.SetFirstPartyForCookies(request.Url());
+  else
+    request.SetFirstPartyForCookies(frame_document.FirstPartyForCookies());
+  request.SetRequestorOrigin(frame_document.GetSecurityOrigin());
+
   // Note: At this stage, the goal is to apply all the modifications the
   // renderer wants to make to the request, and then send it to the browser, so
   // that the actual network request can be started. Ideally, all such
@@ -6326,14 +6334,6 @@
   // else in blink.
   WillSendRequest(request);
 
-  // Set RequestorOrigin and FirstPartyForCookies.
-  WebDocument frame_document = frame_->GetDocument();
-  if (request.GetFrameType() == blink::WebURLRequest::kFrameTypeTopLevel)
-    request.SetFirstPartyForCookies(request.Url());
-  else
-    request.SetFirstPartyForCookies(frame_document.FirstPartyForCookies());
-  request.SetRequestorOrigin(frame_document.GetSecurityOrigin());
-
   // Update the transition type of the request for client side redirects.
   if (!info.url_request.GetExtraData())
     info.url_request.SetExtraData(new RequestExtraData());
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
index b3c94bd..cf4ab1b 100644
--- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
+++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -47,19 +47,18 @@
 void EmbeddedWorkerInstanceClientImpl::StartWorker(
     const EmbeddedWorkerStartParams& params,
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
-    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
+    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host) {
   DCHECK(ChildThreadImpl::current());
   DCHECK(!wrapper_);
   TRACE_EVENT0("ServiceWorker",
                "EmbeddedWorkerInstanceClientImpl::StartWorker");
 
   wrapper_ = StartWorkerContext(
-      params, base::MakeUnique<ServiceWorkerContextClient>(
-                  params.embedded_worker_id, params.service_worker_version_id,
-                  params.scope, params.script_url,
-                  std::move(dispatcher_request), std::move(instance_host),
-                  std::move(provider_info), std::move(temporal_self_)));
+      params,
+      base::MakeUnique<ServiceWorkerContextClient>(
+          params.embedded_worker_id, params.service_worker_version_id,
+          params.scope, params.script_url, std::move(dispatcher_request),
+          std::move(instance_host), std::move(temporal_self_)));
 }
 
 void EmbeddedWorkerInstanceClientImpl::StopWorker() {
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.h b/content/renderer/service_worker/embedded_worker_instance_client_impl.h
index b8ff4fc7..fbef235 100644
--- a/content/renderer/service_worker/embedded_worker_instance_client_impl.h
+++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.h
@@ -71,8 +71,8 @@
   void StartWorker(
       const EmbeddedWorkerStartParams& params,
       mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
-      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) override;
+      mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host)
+      override;
   void StopWorker() override;
   void ResumeAfterDownload() override;
   void AddMessageToConsole(blink::WebConsoleMessage::Level level,
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index a1e97f3..7332acf3 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -554,7 +554,6 @@
     const GURL& script_url,
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
     mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-    mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
     std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client)
     : embedded_worker_id_(embedded_worker_id),
       service_worker_version_id_(service_worker_version_id),
@@ -576,11 +575,6 @@
       "ServiceWorkerContextClient::StartingWorkerContext",
       this,
       "PrepareWorker");
-  // Create a content::ServiceWorkerNetworkProvider for this data source so
-  // we can observe its requests.
-  pending_network_provider_ =
-      base::MakeUnique<ServiceWorkerNetworkProvider>(std::move(provider_info));
-  provider_context_ = pending_network_provider_->context();
 }
 
 ServiceWorkerContextClient::~ServiceWorkerContextClient() {}
@@ -722,7 +716,9 @@
 
   SetRegistrationInServiceWorkerGlobalScope(registration_info, version_attrs);
 
-  (*instance_host_)->OnThreadStarted(WorkerThread::GetCurrentId());
+  (*instance_host_)
+      ->OnThreadStarted(WorkerThread::GetCurrentId(),
+                        provider_context_->provider_id());
 
   TRACE_EVENT_ASYNC_STEP_INTO0(
       "ServiceWorker",
@@ -1100,9 +1096,23 @@
 std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
 ServiceWorkerContextClient::CreateServiceWorkerNetworkProvider() {
   DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+
+  // Create a content::ServiceWorkerNetworkProvider for this data source so
+  // we can observe its requests.
+  std::unique_ptr<ServiceWorkerNetworkProvider> provider =
+      base::MakeUnique<ServiceWorkerNetworkProvider>(
+          MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_CONTROLLER,
+          true /* is_parent_frame_secure */);
+  provider_context_ = provider->context();
+  network_provider_id_ = provider->provider_id();
+
+  // Tell the network provider about which version to load.
+  provider->SetServiceWorkerVersionId(service_worker_version_id_,
+                                      embedded_worker_id_);
+
   // Blink is responsible for deleting the returned object.
   return base::MakeUnique<WebServiceWorkerNetworkProviderImpl>(
-      std::move(pending_network_provider_));
+      std::move(provider));
 }
 
 std::unique_ptr<blink::WebWorkerFetchContext>
@@ -1118,7 +1128,7 @@
   // Blink is responsible for deleting the returned object.
   return base::MakeUnique<ServiceWorkerFetchContextImpl>(
       script_url_, worker_url_loader_factory_provider.PassInterface(),
-      provider_context_->provider_id());
+      network_provider_id_);
 }
 
 std::unique_ptr<blink::WebServiceWorkerProvider>
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index 9a1cd347..2d39dcba 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -22,7 +22,6 @@
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/embedded_worker.mojom.h"
 #include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
-#include "content/common/service_worker/service_worker_provider.mojom.h"
 #include "content/common/service_worker/service_worker_status_code.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "ipc/ipc_listener.h"
@@ -58,8 +57,8 @@
 struct PlatformNotificationData;
 struct PushEventPayload;
 struct ServiceWorkerClientInfo;
-class ServiceWorkerNetworkProvider;
 class ServiceWorkerProviderContext;
+class ServiceWorkerContextClient;
 class ThreadSafeSender;
 class EmbeddedWorkerInstanceClientImpl;
 class WebWorkerFetchContext;
@@ -88,7 +87,6 @@
       const GURL& script_url,
       mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
       mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
-      mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
       std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client);
   ~ServiceWorkerContextClient() override;
 
@@ -344,6 +342,7 @@
   const int64_t service_worker_version_id_;
   const GURL service_worker_scope_;
   const GURL script_url_;
+  int network_provider_id_ = kInvalidServiceWorkerProviderId;
   scoped_refptr<ThreadSafeSender> sender_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
   scoped_refptr<base::TaskRunner> worker_task_runner_;
@@ -360,10 +359,6 @@
   scoped_refptr<mojom::ThreadSafeEmbeddedWorkerInstanceHostAssociatedPtr>
       instance_host_;
 
-  // This is passed to ServiceWorkerNetworkProvider when
-  // createServiceWorkerNetworkProvider is called.
-  std::unique_ptr<ServiceWorkerNetworkProvider> pending_network_provider_;
-
   // Renderer-side object corresponding to WebEmbeddedWorkerInstance.
   // This is valid from the ctor to workerContextDestroyed.
   std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client_;
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 2a0443ee..eceffc1d 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -15,10 +15,22 @@
   ]
 }
 
+generate_jni_registration("content_shell_jni_registration") {
+  testonly = true
+  target = ":content_shell_apk"
+  output = "$root_gen_dir/content/shell/android/${target_name}.h"
+  exception_files = [
+    "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+  ]
+}
+
 shared_library("libcontent_shell_content_view") {
   testonly = true
   deps = [
     ":content_shell_jni_headers",
+    ":content_shell_jni_registration",
     "//build/config:exe_and_shlib_deps",
     "//components/crash/content/browser",
     "//content/shell:content_shell_lib",
@@ -26,6 +38,17 @@
     "//media",
     "//skia",
   ]
+
+  # Explicit dependency required for JNI registration to be able to
+  # find the native side functions.
+  if (is_component_build) {
+    deps += [
+      "//device/gamepad",
+      "//device/generic_sensor",
+      "//device/sensors",
+      "//media/midi",
+    ]
+  }
   sources = [
     "shell_library_loader.cc",
   ]
@@ -242,6 +265,7 @@
 
     deps = [
       ":linker_test_jni_headers",
+      ":linker_test_jni_registration",
       "//build/config:exe_and_shlib_deps",
       "//content/shell:content_shell_lib",
 
@@ -250,6 +274,17 @@
       "//skia",
       "//third_party/re2",
     ]
+
+    # Explicit dependency required for JNI registration to be able to
+    # find the native side functions.
+    if (is_component_build) {
+      deps += [
+        "//device/gamepad",
+        "//device/generic_sensor",
+        "//device/sensors",
+        "//media/midi",
+      ]
+    }
   }
 
   generate_jni("linker_test_jni_headers") {
@@ -259,6 +294,18 @@
       "linker_test_apk/src/org/chromium/chromium_linker_test_apk/LinkerTests.java",
     ]
   }
+
+  generate_jni_registration("linker_test_jni_registration") {
+    testonly = true
+    target = ":chromium_linker_test_apk__apk"
+    output =
+        "$root_gen_dir/content/shell/android/linker_test_apk/${target_name}.h"
+    exception_files = [
+      "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+      "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+    ]
+  }
 }
 
 android_library("content_shell_browsertests_java") {
diff --git a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
index 19f9c47..310bb2a 100644
--- a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
+++ b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
@@ -9,6 +9,7 @@
 #include "content/public/app/content_main.h"
 #include "content/public/browser/android/compositor.h"
 #include "content/shell/android/linker_test_apk/chromium_linker_test_linker_tests.h"
+#include "content/shell/android/linker_test_apk/linker_test_jni_registration.h"
 #include "content/shell/android/shell_jni_registrar.h"
 #include "content/shell/app/shell_main_delegate.h"
 
@@ -40,6 +41,11 @@
 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+  if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+    return -1;
+  }
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
       !NativeInit()) {
     return -1;
diff --git a/content/shell/android/shell_library_loader.cc b/content/shell/android/shell_library_loader.cc
index dc88bd67..8cd2e99 100644
--- a/content/shell/android/shell_library_loader.cc
+++ b/content/shell/android/shell_library_loader.cc
@@ -8,6 +8,7 @@
 #include "content/public/app/content_jni_onload.h"
 #include "content/public/app/content_main.h"
 #include "content/public/browser/android/compositor.h"
+#include "content/shell/android/content_shell_jni_registration.h"
 #include "content/shell/android/shell_jni_registrar.h"
 #include "content/shell/app/shell_main_delegate.h"
 
@@ -33,6 +34,12 @@
 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+  if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+    return -1;
+  }
+
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
       !NativeInit()) {
     return -1;
diff --git a/content/test/data/media/getusermedia.html b/content/test/data/media/getusermedia.html
index 49b2bece..e39912f 100644
--- a/content/test/data/media/getusermedia.html
+++ b/content/test/data/media/getusermedia.html
@@ -63,6 +63,33 @@
         function(error) { sendValueToTest(error.name); });
   }
 
+  // Requests getusermedia and sets it up to test audio muting callbacks.
+  function getUserMediaForAudioMutingTest(initial_muted_state) {
+    console.log('Calling getUserMediaForAudioMutingTest.');
+    navigator.webkitGetUserMedia(
+        {audio: true},
+        function (stream) {
+          var track = stream.getAudioTracks()[0];
+          track.onmute = function(event) {
+            cancelTestTimeout();
+            sendValueToTest("onmute: muted="+ track.muted.toString() +
+                            ", readyState=" + track.readyState);
+          }
+          track.onunmute = function(event) {
+            cancelTestTimeout();
+            sendValueToTest("onunmute: muted="+ track.muted.toString() +
+                              ", readyState=" + track.readyState);
+          }
+          if (track.muted == initial_muted_state) {
+            reportTestSuccess();
+          } else {
+            failTest("Expected track.muted to be: " + initial_muted_state +
+                     ", was: " + track.muted);
+          }
+        },
+        failedCallback);
+  }
+
   function renderClonedMediastreamAndStop(constraints, waitTimeInSeconds) {
     console.log('Calling renderClonedMediastreamAndStop.');
     navigator.webkitGetUserMedia(
diff --git a/content/test/data/media/webrtc_test_utilities.js b/content/test/data/media/webrtc_test_utilities.js
index aa11a975..2d0c4758 100644
--- a/content/test/data/media/webrtc_test_utilities.js
+++ b/content/test/data/media/webrtc_test_utilities.js
@@ -18,6 +18,8 @@
 
 var gAllEventsOccured = function () {};
 
+var gPendingTimeout;
+
 // Use this function to set a function that will be called once all expected
 // events has occurred.
 function setAllEventsOccuredHandler(handler) {
@@ -41,6 +43,20 @@
   window.domAutomationController.send(error.stack);
 }
 
+// Fail a test on the C++ side after a timeout. Will cancel any pending timeout.
+function failTestAfterTimeout(reason, timeout_ms) {
+  cancelTestTimeout();
+  gPendingTimeout = setTimeout(function() {
+    failTest(reason);
+  }, timeout_ms);
+}
+
+// Cancels the current test timeout.
+function cancelTestTimeout() {
+  clearTimeout(gPendingTimeout);
+  gPendingTimeout = null;
+}
+
 // Called if getUserMedia fails.
 function printGetUserMediaError(error) {
   var message = 'getUserMedia request unexpectedly failed:';
@@ -262,4 +278,3 @@
     failTest(description);
   }
 }
-
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
index 29bef61..1eeeec3f 100644
--- a/crypto/nss_util.cc
+++ b/crypto/nss_util.cc
@@ -12,46 +12,35 @@
 #include <prtime.h>
 #include <secmod.h>
 
+#include <map>
 #include <memory>
 #include <utility>
-
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "crypto/nss_util_internal.h"
-
-#if defined(OS_OPENBSD)
-#include <sys/mount.h>
-#include <sys/param.h>
-#endif
-
-#if defined(OS_CHROMEOS)
-#include <dlfcn.h>
-#endif
-
-#include <map>
 #include <vector>
 
 #include "base/base_paths.h"
 #include "base/bind.h"
-#include "base/cpu.h"
 #include "base/debug/alias.h"
 #include "base/debug/stack_trace.h"
-#include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/lazy_instance.h"
+#include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "base/native_library.h"
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/thread_checker.h"
 #include "base/threading/thread_restrictions.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/threading/worker_pool.h"
 #include "build/build_config.h"
 #include "crypto/nss_crypto_module_delegate.h"
+#include "crypto/nss_util_internal.h"
+
+#if defined(OS_CHROMEOS)
+#include <dlfcn.h>
+#endif
 
 namespace crypto {
 
@@ -135,37 +124,6 @@
   return nullptr;
 }
 
-// NSS creates a local cache of the sqlite database if it detects that the
-// filesystem the database is on is much slower than the local disk.  The
-// detection doesn't work with the latest versions of sqlite, such as 3.6.22
-// (NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=578561).  So we set
-// the NSS environment variable NSS_SDB_USE_CACHE to "yes" to override NSS's
-// detection when database_dir is on NFS.  See http://crbug.com/48585.
-//
-// Because this function sets an environment variable it must be run before we
-// go multi-threaded.
-void UseLocalCacheOfNSSDatabaseIfNFS(const base::FilePath& database_dir) {
-  bool db_on_nfs = false;
-#if defined(OS_LINUX)
-  base::FileSystemType fs_type = base::FILE_SYSTEM_UNKNOWN;
-  if (base::GetFileSystemType(database_dir, &fs_type))
-    db_on_nfs = (fs_type == base::FILE_SYSTEM_NFS);
-#elif defined(OS_OPENBSD)
-  struct statfs buf;
-  if (statfs(database_dir.value().c_str(), &buf) == 0)
-    db_on_nfs = (strcmp(buf.f_fstypename, MOUNT_NFS) == 0);
-#else
-  NOTIMPLEMENTED();
-#endif
-
-  if (db_on_nfs) {
-    std::unique_ptr<base::Environment> env(base::Environment::Create());
-    static const char kUseCacheEnvVar[] = "NSS_SDB_USE_CACHE";
-    if (!env->HasVar(kUseCacheEnvVar))
-      env->SetVar(kUseCacheEnvVar, "yes");
-  }
-}
-
 // A singleton to initialize/deinitialize NSPR.
 // Separate from the NSS singleton because we initialize NSPR on the UI thread.
 // Now that we're leaking the singleton, we could merge back with the NSS
@@ -685,11 +643,6 @@
     SECStatus status = SECFailure;
     base::FilePath database_dir = GetInitialConfigDirectory();
     if (!database_dir.empty()) {
-      // This duplicates the work which should have been done in
-      // EarlySetupForNSSInit. However, this function is idempotent so
-      // there's no harm done.
-      UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
-
       // Initialize with a persistent database (likely, ~/.pki/nssdb).
       // Use "sql:" which can be shared by multiple processes safely.
       std::string nss_config_dir =
@@ -843,12 +796,6 @@
   return ScopedPK11Slot(db_slot);
 }
 
-void EarlySetupForNSSInit() {
-  base::FilePath database_dir = GetInitialConfigDirectory();
-  if (!database_dir.empty())
-    UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
-}
-
 void EnsureNSPRInit() {
   g_nspr_singleton.Get();
 }
diff --git a/crypto/nss_util.h b/crypto/nss_util.h
index 5c34fc8..edf79a1 100644
--- a/crypto/nss_util.h
+++ b/crypto/nss_util.h
@@ -23,11 +23,6 @@
 // initialization functions.
 namespace crypto {
 
-// EarlySetupForNSSInit performs lightweight setup which must occur before the
-// process goes multithreaded. This does not initialise NSS. For test, see
-// EnsureNSSInit.
-CRYPTO_EXPORT void EarlySetupForNSSInit();
-
 // Initialize NRPR if it isn't already initialized.  This function is
 // thread-safe, and NSPR will only ever be initialized once.
 CRYPTO_EXPORT void EnsureNSPRInit();
diff --git a/extensions/browser/api/vpn_provider/OWNERS b/extensions/browser/api/vpn_provider/OWNERS
index c83fa211..a913a05 100644
--- a/extensions/browser/api/vpn_provider/OWNERS
+++ b/extensions/browser/api/vpn_provider/OWNERS
@@ -1,3 +1,2 @@
-kaliamoorthi@chromium.org
 bartfab@chromium.org
 emaxx@chromium.org
diff --git a/extensions/shell/browser/api/vpn_provider/OWNERS b/extensions/shell/browser/api/vpn_provider/OWNERS
index c83fa211..a913a05 100644
--- a/extensions/shell/browser/api/vpn_provider/OWNERS
+++ b/extensions/shell/browser/api/vpn_provider/OWNERS
@@ -1,3 +1,2 @@
-kaliamoorthi@chromium.org
 bartfab@chromium.org
 emaxx@chromium.org
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 30ddfcf..57026c97 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -602,7 +602,6 @@
     "//net/tools/testserver/",
     "//third_party/pyftpdlib/",
     "//third_party/pywebsocket/",
-    "//third_party/skia/",
     "//third_party/tlslite/",
     "test/data/",
   ]
diff --git a/headless/public/util/generic_url_request_job.cc b/headless/public/util/generic_url_request_job.cc
index 406b2343..84344322 100644
--- a/headless/public/util/generic_url_request_job.cc
+++ b/headless/public/util/generic_url_request_job.cc
@@ -258,6 +258,13 @@
   }
 }
 
+bool GenericURLRequestJob::IsAsync() const {
+  // In some tests |request_resource_info_| is null.
+  if (request_resource_info_)
+    return request_resource_info_->IsAsync();
+  return true;
+}
+
 std::string GenericURLRequestJob::GetPostData() const {
   if (!request_->has_upload())
     return "";
diff --git a/headless/public/util/generic_url_request_job.h b/headless/public/util/generic_url_request_job.h
index b97f153..434de84 100644
--- a/headless/public/util/generic_url_request_job.h
+++ b/headless/public/util/generic_url_request_job.h
@@ -75,6 +75,9 @@
 
   virtual ResourceType GetResourceType() const = 0;
 
+  // Whether or not an asynchronous IPC was used to load this resource.
+  virtual bool IsAsync() const = 0;
+
  protected:
   Request() {}
   virtual ~Request() {}
@@ -188,6 +191,7 @@
   std::string GetDevToolsAgentHostId() const override;
   std::string GetPostData() const override;
   ResourceType GetResourceType() const override;
+  bool IsAsync() const override;
 
   // PendingRequest implementation:
   const Request* GetRequest() const override;
diff --git a/ios/PRESUBMIT.py b/ios/PRESUBMIT.py
new file mode 100644
index 0000000..9fc3321
--- /dev/null
+++ b/ios/PRESUBMIT.py
@@ -0,0 +1,43 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Presubmit script for ios.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+TODO_PATTERN = r'TO[D]O\(([^\)]*)\)'
+CRBUG_PATTERN = r'crbug\.com/\d+$'
+
+def _CheckBugInToDo(input_api, output_api):
+  """ Checks whether TODOs in ios code are identified by a bug number."""
+  todo_regex = input_api.re.compile(TODO_PATTERN)
+  crbug_regex = input_api.re.compile(CRBUG_PATTERN)
+
+  errors = []
+  for f in input_api.AffectedFiles():
+    for line_num, line in f.ChangedContents():
+      todo_match = todo_regex.search(line)
+      if not todo_match:
+        continue
+      crbug_match = crbug_regex.match(todo_match.group(1))
+      if not crbug_match:
+        errors.append('%s:%s' % (f.LocalPath(), line_num))
+  if not errors:
+    return []
+
+  plural_suffix = '' if len(errors) == 1 else 's'
+  error_message = '\n'.join([
+      'Found TO''DO%(plural)s without bug number%(plural)s (expected format is '
+      '\"TO''DO(crbug.com/######)\":' % {'plural': plural_suffix}
+  ] + errors) + '\n'
+
+  return [output_api.PresubmitError(error_message)]
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  results = []
+  results.extend(_CheckBugInToDo(input_api, output_api))
+  return results
diff --git a/ios/PRESUBMIT_test.py b/ios/PRESUBMIT_test.py
new file mode 100644
index 0000000..e50ff3d
--- /dev/null
+++ b/ios/PRESUBMIT_test.py
@@ -0,0 +1,41 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import sys
+import unittest
+
+import PRESUBMIT
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import PRESUBMIT_test_mocks
+
+
+class CheckTODOFormatTest(unittest.TestCase):
+  """Test the _CheckBugInToDo presubmit check."""
+
+  def testTODOs(self):
+    bad_lines = ['TO''DO(ldap): fix this',
+                 'TO''DO(ladp): see crbug.com/8675309',
+                 'TO''DO(8675309): fix this',
+                 'TO''DO(http://crbug.com/8675309): fix this',
+                 'TO''DO( crbug.com/8675309): fix this',
+                 'TO''DO(crbug/8675309): fix this',
+                 'TO''DO(crbug.com): fix this']
+    good_lines = ['TO''DO(crbug.com/8675309): fix this',
+                  'TO''DO(crbug.com/8675309): fix this (please)']
+    mock_input = PRESUBMIT_test_mocks.MockInputApi()
+    mock_input.files = [PRESUBMIT_test_mocks.MockFile(
+        'ios/path/foo_controller.mm', bad_lines + good_lines)]
+    mock_output = PRESUBMIT_test_mocks.MockOutputApi()
+    errors = PRESUBMIT._CheckBugInToDo(mock_input, mock_output)
+    self.assertEqual(len(errors), 1)
+    self.assertEqual('error', errors[0].type)
+    self.assertTrue('without bug numbers' in errors[0].message)
+    error_lines = errors[0].message.split('\n')
+    self.assertEqual(len(error_lines), len(bad_lines) + 2)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 998a290..bf79379 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1480,9 +1480,6 @@
       <message name="IDS_IOS_TOOLS_MENU_SHARE" desc="The iOS menu item for sharing the current URL [Length: 15em] [iOS only]">
         Share...
       </message>
-      <message name="IDS_IOS_TOOLS_MENU_SUGGESTIONS" desc="The iOS menu item for displaying the Suggestions UI [Length: 15em] [iOS only]">
-        Suggestions
-      </message>
       <message name="IDS_IOS_TRANSLATE_SETTING" desc="Title for the view and option in Settings for Translate. [Length: 25em] [iOS only]">
         Google Translate
       </message>
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
index 49ac9b68..a590981 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -31,6 +31,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_commands.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h"
 #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h"
 #import "ios/chrome/browser/ui/ntp/google_landing_mediator.h"
@@ -48,10 +49,10 @@
 #error "This file requires ARC support."
 #endif
 
-@interface ContentSuggestionsCoordinator ()<ContentSuggestionsCommands>
+@interface ContentSuggestionsCoordinator ()<ContentSuggestionsCommands,
+                                            ContentSuggestionsHeaderCommands>
 
 @property(nonatomic, strong) AlertCoordinator* alertCoordinator;
-@property(nonatomic, strong) UINavigationController* navigationController;
 @property(nonatomic, strong)
     ContentSuggestionsViewController* suggestionsViewController;
 @property(nonatomic, strong)
@@ -78,7 +79,6 @@
 
 @synthesize alertCoordinator = _alertCoordinator;
 @synthesize browserState = _browserState;
-@synthesize navigationController = _navigationController;
 @synthesize suggestionsViewController = _suggestionsViewController;
 @synthesize URLLoader = _URLLoader;
 @synthesize visible = _visible;
@@ -127,28 +127,11 @@
   self.suggestionsViewController = [[ContentSuggestionsViewController alloc]
       initWithStyle:CollectionViewControllerStyleDefault
          dataSource:self.contentSuggestionsMediator];
-
+  self.suggestionsViewController.headerCommandHandler = self;
   self.suggestionsViewController.suggestionCommandHandler = self;
-  _navigationController = [[UINavigationController alloc]
-      initWithRootViewController:self.suggestionsViewController];
-
-  self.suggestionsViewController.navigationItem.leftBarButtonItem =
-      [[UIBarButtonItem alloc]
-          initWithTitle:l10n_util::GetNSString(IDS_IOS_SUGGESTIONS_DONE)
-                  style:UIBarButtonItemStylePlain
-                 target:self
-                 action:@selector(stop)];
-
-  [self.baseViewController presentViewController:_navigationController
-                                        animated:YES
-                                      completion:nil];
 }
 
 - (void)stop {
-  [[self.navigationController presentingViewController]
-      dismissViewControllerAnimated:YES
-                         completion:nil];
-  self.navigationController = nil;
   self.contentSuggestionsMediator = nil;
   self.alertCoordinator = nil;
   self.headerController = nil;
@@ -204,7 +187,7 @@
   ContentSuggestionsItem* articleItem =
       base::mac::ObjCCastStrict<ContentSuggestionsItem>(item);
   self.alertCoordinator = [[ActionSheetCoordinator alloc]
-      initWithBaseViewController:self.navigationController
+      initWithBaseViewController:self.suggestionsViewController
                            title:nil
                          message:nil
                             rect:CGRectMake(touchLocation.x, touchLocation.y, 0,
@@ -283,7 +266,7 @@
   ContentSuggestionsMostVisitedItem* mostVisitedItem =
       base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedItem>(item);
   self.alertCoordinator = [[ActionSheetCoordinator alloc]
-      initWithBaseViewController:self.navigationController
+      initWithBaseViewController:self.suggestionsViewController
                            title:nil
                          message:nil
                             rect:CGRectMake(touchLocation.x, touchLocation.y, 0,
@@ -374,6 +357,8 @@
   NOTREACHED();
 }
 
+#pragma mark - ContentSuggestionsHeaderCommands
+
 - (void)updateFakeOmniboxForScrollView:(UIScrollView*)scrollView {
   [self.delegate updateNtpBarShadowForPanelController:self];
 
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm
index 2f6bc477..137feb8 100644
--- a/ios/chrome/browser/payments/payment_request.mm
+++ b/ios/chrome/browser/payments/payment_request.mm
@@ -4,6 +4,8 @@
 
 #include "ios/chrome/browser/payments/payment_request.h"
 
+#include <algorithm>
+
 #include "base/containers/adapters.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -12,10 +14,12 @@
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/region_data_loader_impl.h"
+#include "components/autofill/core/browser/validation.h"
 #include "components/payments/core/currency_formatter.h"
 #include "components/payments/core/payment_request_data_util.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/autofill/validation_rules_storage_factory.h"
+#import "ios/chrome/browser/payments/payment_request_util.h"
 #include "ios/web/public/payments/payment_request.h"
 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
@@ -73,9 +77,17 @@
     selected_contact_profile_ = contact_profiles_[0];
   }
 
-  // Select the highest ranking credit card.
-  if (!credit_cards_.empty())
-    selected_credit_card_ = credit_cards_[0];
+  // TODO(crbug.com/702063): Change this code to prioritize credit cards by use
+  // count and other means.
+  auto first_complete_credit_card = std::find_if(
+      credit_cards_.begin(), credit_cards_.end(),
+      [this](const autofill::CreditCard* credit_card) {
+        DCHECK(credit_card);
+        return payment_request_util::IsCreditCardCompleteForPayment(
+            *credit_card, billing_profiles());
+      });
+  if (first_complete_credit_card != credit_cards_.end())
+    selected_credit_card_ = *first_complete_credit_card;
 }
 
 PaymentRequest::~PaymentRequest() {}
@@ -186,7 +198,19 @@
 }
 
 bool PaymentRequest::CanMakePayment() const {
-  return !credit_cards_.empty();
+  for (const autofill::CreditCard* credit_card : credit_cards_) {
+    DCHECK(credit_card);
+    autofill::CreditCardCompletionStatus status =
+        autofill::GetCompletionStatusForCard(
+            *credit_card, GetApplicationContext()->GetApplicationLocale(),
+            billing_profiles());
+    // A card only has to have a cardholder name and a number for the purposes
+    // of CanMakePayment. An expired card or one without a billing address is
+    // valid for this purpose.
+    return !(status & autofill::CREDIT_CARD_NO_CARDHOLDER ||
+             status & autofill::CREDIT_CARD_NO_NUMBER);
+  }
+  return false;
 }
 
 void PaymentRequest::PopulateCreditCardCache() {
diff --git a/ios/chrome/browser/payments/payment_request_unittest.mm b/ios/chrome/browser/payments/payment_request_unittest.mm
index 2ae1798..0ce80550 100644
--- a/ios/chrome/browser/payments/payment_request_unittest.mm
+++ b/ios/chrome/browser/payments/payment_request_unittest.mm
@@ -12,6 +12,7 @@
 #include "components/payments/core/currency_formatter.h"
 #include "components/payments/core/payment_method_data.h"
 #include "ios/chrome/browser/application_context.h"
+#include "ios/chrome/browser/payments/payment_request_test_util.h"
 #include "ios/web/public/payments/payment_request.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -442,3 +443,78 @@
   EXPECT_EQ(address1.guid(),
             payment_request.selected_contact_profile()->guid());
 }
+
+// Test that loading payment methods when none are available works as expected.
+TEST_F(PaymentRequestTest, SelectedPaymentMethod_NoPaymentMethods) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  web::PaymentRequest web_payment_request =
+      payment_request_test_util::CreateTestWebPaymentRequest();
+
+  // No payment methods are selected because none are available!
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(nullptr, payment_request.selected_credit_card());
+}
+
+// Test that loading expired credit cards works as expected.
+TEST_F(PaymentRequestTest, SelectedPaymentMethod_ExpiredCard) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
+  personal_data_manager.AddTestingProfile(&billing_address);
+  autofill::CreditCard credit_card = autofill::test::GetCreditCard();
+  personal_data_manager.AddTestingCreditCard(&credit_card);
+  credit_card.SetExpirationYear(2016);  // Expired.
+  credit_card.set_billing_address_id(billing_address.guid());
+
+  web::PaymentRequest web_payment_request =
+      payment_request_test_util::CreateTestWebPaymentRequest();
+
+  // credit_card is selected because expired cards are valid for payment.
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(credit_card.guid(), payment_request.selected_credit_card()->guid());
+}
+
+// Test that loading complete payment methods works as expected.
+TEST_F(PaymentRequestTest, SelectedPaymentMethod_Complete) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
+  personal_data_manager.AddTestingProfile(&billing_address);
+  autofill::CreditCard credit_card = autofill::test::GetCreditCard();
+  credit_card.set_use_count(5U);
+  personal_data_manager.AddTestingCreditCard(&credit_card);
+  credit_card.set_billing_address_id(billing_address.guid());
+  autofill::CreditCard credit_card2 = autofill::test::GetCreditCard2();
+  credit_card2.set_use_count(15U);
+  personal_data_manager.AddTestingCreditCard(&credit_card2);
+  credit_card2.set_billing_address_id(billing_address.guid());
+
+  web::PaymentRequest web_payment_request =
+      payment_request_test_util::CreateTestWebPaymentRequest();
+
+  // credit_card2 is selected because it has the most use count (Frecency
+  // model).
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(credit_card2.guid(),
+            payment_request.selected_credit_card()->guid());
+}
+
+// Test that loading incomplete payment methods works as expected.
+TEST_F(PaymentRequestTest, SelectedPaymentMethod_Incomplete) {
+  autofill::TestPersonalDataManager personal_data_manager;
+  autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
+  personal_data_manager.AddTestingProfile(&billing_address);
+  autofill::CreditCard credit_card = autofill::test::GetCreditCard();
+  credit_card.set_use_count(5U);
+  personal_data_manager.AddTestingCreditCard(&credit_card);
+  credit_card.set_billing_address_id(billing_address.guid());
+  autofill::CreditCard credit_card2 = autofill::test::GetCreditCard2();
+  credit_card2.set_use_count(15U);
+  personal_data_manager.AddTestingCreditCard(&credit_card2);
+
+  web::PaymentRequest web_payment_request =
+      payment_request_test_util::CreateTestWebPaymentRequest();
+
+  // Even though credit_card2 has more use counts, credit_card is selected
+  // because it is complete.
+  PaymentRequest payment_request(web_payment_request, &personal_data_manager);
+  EXPECT_EQ(credit_card.guid(), payment_request.selected_credit_card()->guid());
+}
diff --git a/ios/chrome/browser/payments/payment_request_util.h b/ios/chrome/browser/payments/payment_request_util.h
index 88fd9ee0..3bbb6d6 100644
--- a/ios/chrome/browser/payments/payment_request_util.h
+++ b/ios/chrome/browser/payments/payment_request_util.h
@@ -7,11 +7,14 @@
 
 #import <Foundation/Foundation.h>
 
+#include <vector>
+
 #include "base/strings/string16.h"
 #include "components/payments/core/payment_options_provider.h"
 
 namespace autofill {
 class AutofillProfile;
+class CreditCard;
 }  // namespace autofill
 
 class PaymentRequest;
@@ -49,6 +52,18 @@
     PaymentRequest& payment_request,
     const autofill::AutofillProfile& profile);
 
+// Returns whether the credit card is complete to be used as a payment method
+// without further editing.
+BOOL IsCreditCardCompleteForPayment(
+    const autofill::CreditCard& credit_card,
+    const std::vector<autofill::AutofillProfile*>& billing_profiles);
+
+// Helper function to create a notification label for what's missing from a
+// credit card. Returns nil if the resulting label is empty.
+NSString* GetPaymentMethodNotificationLabelFromCreditCard(
+    const autofill::CreditCard& credit_card,
+    const std::vector<autofill::AutofillProfile*>& billing_profiles);
+
 // Returns the title for the shipping section of the payment summary view given
 // the shipping type specified in |payment_request|.
 NSString* GetShippingSectionTitle(payments::PaymentShippingType shipping_type);
diff --git a/ios/chrome/browser/payments/payment_request_util.mm b/ios/chrome/browser/payments/payment_request_util.mm
index 3b643adf..0759516 100644
--- a/ios/chrome/browser/payments/payment_request_util.mm
+++ b/ios/chrome/browser/payments/payment_request_util.mm
@@ -9,8 +9,10 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/validation.h"
 #include "components/payments/core/payment_request_data_util.h"
 #include "components/payments/core/strings_util.h"
 #include "components/strings/grit/components_strings.h"
@@ -71,6 +73,26 @@
   return !label.empty() ? base::SysUTF16ToNSString(label) : nil;
 }
 
+BOOL IsCreditCardCompleteForPayment(
+    const autofill::CreditCard& credit_card,
+    const std::vector<autofill::AutofillProfile*>& billing_profiles) {
+  // EXPIRED cards are considered valid for payment. The user will be prompted
+  // to enter the new expiration at the CVC step.
+  return autofill::GetCompletionStatusForCard(
+             credit_card, GetApplicationContext()->GetApplicationLocale(),
+             billing_profiles) <= autofill::CREDIT_CARD_EXPIRED;
+}
+
+NSString* GetPaymentMethodNotificationLabelFromCreditCard(
+    const autofill::CreditCard& credit_card,
+    const std::vector<autofill::AutofillProfile*>& billing_profiles) {
+  base::string16 label = autofill::GetCompletionMessageForCard(
+      autofill::GetCompletionStatusForCard(
+          credit_card, GetApplicationContext()->GetApplicationLocale(),
+          billing_profiles));
+  return !label.empty() ? base::SysUTF16ToNSString(label) : nil;
+}
+
 NSString* GetShippingSectionTitle(payments::PaymentShippingType shipping_type) {
   switch (shipping_type) {
     case payments::PaymentShippingType::SHIPPING:
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 955677b..ea57dee5 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -49,7 +49,6 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/chrome_url_util.h"
-#import "ios/chrome/browser/content_suggestions/content_suggestions_coordinator.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
@@ -439,9 +438,6 @@
   // Used to display the Reading List.
   ReadingListCoordinator* _readingListCoordinator;
 
-  // Used to display the Suggestions.
-  ContentSuggestionsCoordinator* _contentSuggestionsCoordinator;
-
   // Used to display the Find In Page UI. Nil if not visible.
   FindBarControllerIOS* _findBarController;
 
@@ -1346,7 +1342,6 @@
     self.typingShield = nil;
     if (_voiceSearchController)
       _voiceSearchController->SetDelegate(nil);
-    _contentSuggestionsCoordinator = nil;
     _qrScannerViewController = nil;
     _readingListCoordinator = nil;
     _toolbarController = nil;
@@ -4196,11 +4191,6 @@
     case IDC_SHOW_QR_SCANNER:
       [self showQRScanner];
       break;
-    case IDC_SHOW_SUGGESTIONS:
-      if (experimental_flags::IsSuggestionsUIEnabled()) {
-        [self showSuggestionsUI];
-      }
-      break;
     default:
       // Unknown commands get sent up the responder chain.
       [super chromeExecuteCommand:sender];
@@ -4283,8 +4273,6 @@
   [_contextMenuCoordinator stop];
   [self dismissRateThisAppDialog];
 
-  [_contentSuggestionsCoordinator stop];
-
   if (self.presentedViewController) {
     // Dismisses any other modal controllers that may be present, e.g. Recent
     // Tabs.
@@ -4451,18 +4439,6 @@
                    completion:nil];
 }
 
-- (void)showSuggestionsUI {
-  if (!_contentSuggestionsCoordinator) {
-    _contentSuggestionsCoordinator =
-        [[ContentSuggestionsCoordinator alloc] initWithBaseViewController:self];
-    [_contentSuggestionsCoordinator setURLLoader:self];
-  }
-  _contentSuggestionsCoordinator.dispatcher = _dispatcher;
-  _contentSuggestionsCoordinator.webStateList = [_model webStateList];
-  [_contentSuggestionsCoordinator setBrowserState:_browserState];
-  [_contentSuggestionsCoordinator start];
-}
-
 - (void)showNTPPanel:(NewTabPage::PanelIdentifier)panel {
   DCHECK(self.visible || self.dismissingModal);
   GURL url(kChromeUINewTabURL);
diff --git a/ios/chrome/browser/ui/commands/ios_command_ids.h b/ios/chrome/browser/ui/commands/ios_command_ids.h
index 751932e6..a2925a3 100644
--- a/ios/chrome/browser/ui/commands/ios_command_ids.h
+++ b/ios/chrome/browser/ui/commands/ios_command_ids.h
@@ -75,7 +75,6 @@
 #define IDC_SHOW_CLEAR_BROWSING_DATA_SETTINGS          40951
 #define IDC_SHOW_SYNC_PASSPHRASE_SETTINGS              40952
 #define IDC_SHOW_QR_SCANNER                            40953
-#define IDC_SHOW_SUGGESTIONS                           40955
 #define IDC_SHOW_AUTOFILL_SETTINGS                     40956
 // clang-format on
 
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 44f79970..2f4d3c5 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -9,6 +9,7 @@
     "content_suggestions_commands.h",
     "content_suggestions_data_sink.h",
     "content_suggestions_data_source.h",
+    "content_suggestions_header_commands.h",
     "content_suggestions_image_fetcher.h",
     "content_suggestions_layout.h",
     "content_suggestions_layout.mm",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
index b4ad979..73a45824 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
@@ -30,8 +30,6 @@
 - (void)dismissContextMenu;
 // Handles the actions following a tap on the promo.
 - (void)handlePromoTapped;
-// Updates the fake omnibox to adapt to the current scrolling.
-- (void)updateFakeOmniboxForScrollView:(nonnull UIScrollView*)scrollView;
 
 @end
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_commands.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_commands.h
new file mode 100644
index 0000000..1bc22752
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_commands.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_HEADER_COMMANDS_H_
+#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_HEADER_COMMANDS_H_
+
+// Commands protocol allowing the ContentSuggestionsViewController to send
+// commands related to the header, containing the fake omnibox and the logo.
+@protocol ContentSuggestionsHeaderCommands
+
+// Updates the fake omnibox to adapt to the current scrolling.
+- (void)updateFakeOmniboxForScrollView:(nonnull UIScrollView*)scrollView;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_HEADER_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
index c8efaea..28e14b0 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -12,6 +12,7 @@
 @class ContentSuggestionsSectionInformation;
 @protocol ContentSuggestionsCommands;
 @protocol ContentSuggestionsDataSource;
+@protocol ContentSuggestionsHeaderCommands;
 @protocol SuggestedContent;
 
 // CollectionViewController to display the suggestions items.
@@ -28,6 +29,9 @@
 // Handler for the commands sent by the ContentSuggestionsViewController.
 @property(nonatomic, weak) id<ContentSuggestionsCommands>
     suggestionCommandHandler;
+// Handler for the commands sent by the ContentSuggestionsViewController.
+@property(nonatomic, weak) id<ContentSuggestionsHeaderCommands>
+    headerCommandHandler;
 // Override from superclass to have a more specific type.
 @property(nonatomic, readonly)
     CollectionViewModel<CollectionViewItem<SuggestedContent>*>*
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 9d205307..067626d 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_commands.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 
@@ -43,6 +44,7 @@
 @implementation ContentSuggestionsViewController
 
 @synthesize suggestionCommandHandler = _suggestionCommandHandler;
+@synthesize headerCommandHandler = _headerCommandHandler;
 @synthesize collectionUpdater = _collectionUpdater;
 @synthesize cardStyleMargin = _cardStyleMargin;
 @dynamic collectionViewModel;
@@ -365,7 +367,7 @@
 
 - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
   [super scrollViewDidScroll:scrollView];
-  [self.suggestionCommandHandler updateFakeOmniboxForScrollView:scrollView];
+  [self.headerCommandHandler updateFakeOmniboxForScrollView:scrollView];
 }
 
 #pragma mark - Private
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm
index b3a1508..89f7e4a 100644
--- a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator.mm
@@ -4,9 +4,13 @@
 
 #import "ios/chrome/browser/ui/payments/payment_method_selection_coordinator.h"
 
+#include <vector>
+
+#include "base/logging.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/payments/payment_request.h"
+#import "ios/chrome/browser/ui/payments/cells/payment_method_item.h"
 #include "ios/chrome/browser/ui/payments/payment_method_selection_mediator.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -79,12 +83,20 @@
 - (void)paymentRequestSelectorViewController:
             (PaymentRequestSelectorViewController*)controller
                         didSelectItemAtIndex:(NSUInteger)index {
-  // Update the data source with the selection.
-  self.mediator.selectedItemIndex = index;
-
   DCHECK(index < self.paymentRequest->credit_cards().size());
-  [self delayedNotifyDelegateOfSelection:self.paymentRequest
-                                             ->credit_cards()[index]];
+  autofill::CreditCard* creditCard = self.paymentRequest->credit_cards()[index];
+
+  // Proceed with item selection only if the item has all required info, or
+  // else bring up the credit card editor.
+  CollectionViewItem<PaymentsIsSelectable>* selectedItem =
+      self.mediator.selectableItems[index];
+  if (selectedItem.complete) {
+    // Update the data source with the selection.
+    self.mediator.selectedItemIndex = index;
+    [self delayedNotifyDelegateOfSelection:creditCard];
+  } else {
+    [self startCreditCardEditCoordinatorWithCreditCard:creditCard];
+  }
 }
 
 - (void)paymentRequestSelectorViewControllerDidFinish:
@@ -119,6 +131,16 @@
   // Update the data source with the new data.
   [self.mediator loadItems];
 
+  if (![self.viewController isEditing]) {
+    // Update the data source with the selection.
+    const std::vector<autofill::CreditCard*>& creditCards =
+        self.paymentRequest->credit_cards();
+    auto position =
+        std::find(creditCards.begin(), creditCards.end(), creditCard);
+    DCHECK(position != creditCards.end());
+    self.mediator.selectedItemIndex = position - creditCards.begin();
+  }
+
   [self.viewController loadModel];
   [self.viewController.collectionView reloadData];
 
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm
index dec60fa1..c0802c8 100644
--- a/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_method_selection_coordinator_unittest.mm
@@ -7,6 +7,7 @@
 #include "base/mac/foundation_util.h"
 #include "base/memory/ptr_util.h"
 #include "base/test/ios/wait_util.h"
+#include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
@@ -27,16 +28,23 @@
     : public PlatformTest {
  protected:
   PaymentRequestPaymentMethodSelectionCoordinatorTest()
-      : credit_card1_(autofill::test::GetCreditCard()),
+      : autofill_profile_(autofill::test::GetFullProfile()),
+        credit_card1_(autofill::test::GetCreditCard()),
         credit_card2_(autofill::test::GetCreditCard2()) {
-    // Add testing credit cards to autofill::TestPersonalDataManager.
+    // Add testing credit cards to autofill::TestPersonalDataManager. Make the
+    // less frequently used one incomplete.
+    credit_card1_.set_use_count(10U);
+    personal_data_manager_.AddTestingProfile(&autofill_profile_);
+    credit_card1_.set_billing_address_id(autofill_profile_.guid());
     personal_data_manager_.AddTestingCreditCard(&credit_card1_);
+    credit_card2_.set_use_count(5U);
     personal_data_manager_.AddTestingCreditCard(&credit_card2_);
     payment_request_ = base::MakeUnique<PaymentRequest>(
         payment_request_test_util::CreateTestWebPaymentRequest(),
         &personal_data_manager_);
   }
 
+  autofill::AutofillProfile autofill_profile_;
   autofill::CreditCard credit_card1_;
   autofill::CreditCard credit_card2_;
   autofill::TestPersonalDataManager personal_data_manager_;
@@ -76,7 +84,7 @@
 
 // Tests that calling the view controller delegate method which notifies the
 // coordinator about selection of a payment method invokes the corresponding
-// coordinator delegate method.
+// coordinator delegate method, only if the payment method is complete.
 TEST_F(PaymentRequestPaymentMethodSelectionCoordinatorTest,
        DidSelectPaymentMethod) {
   UIViewController* base_view_controller = [[UIViewController alloc] init];
@@ -92,9 +100,12 @@
   // Mock the coordinator delegate.
   id delegate = [OCMockObject
       mockForProtocol:@protocol(PaymentMethodSelectionCoordinatorDelegate)];
-  autofill::CreditCard* credit_card = payment_request_->credit_cards()[1];
-  [[delegate expect] paymentMethodSelectionCoordinator:coordinator
-                                didSelectPaymentMethod:credit_card];
+  [[delegate expect]
+      paymentMethodSelectionCoordinator:coordinator
+                 didSelectPaymentMethod:payment_request_->credit_cards()[0]];
+  [[delegate reject]
+      paymentMethodSelectionCoordinator:coordinator
+                 didSelectPaymentMethod:payment_request_->credit_cards()[1]];
   [coordinator setDelegate:delegate];
 
   EXPECT_EQ(1u, navigation_controller.viewControllers.count);
@@ -104,13 +115,16 @@
   base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSecondsD(1.0));
   EXPECT_EQ(2u, navigation_controller.viewControllers.count);
 
-  // Call the controller delegate method.
+  // Call the controller delegate method for both selectable items.
   PaymentRequestSelectorViewController* view_controller =
       base::mac::ObjCCastStrict<PaymentRequestSelectorViewController>(
           navigation_controller.visibleViewController);
   [coordinator paymentRequestSelectorViewController:view_controller
+                               didSelectItemAtIndex:0];
+  // Wait for the coordinator delegate to be notified.
+  base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5));
+  [coordinator paymentRequestSelectorViewController:view_controller
                                didSelectItemAtIndex:1];
-
   // Wait for the coordinator delegate to be notified.
   base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.5));
 
diff --git a/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm b/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm
index 53f748aa..064fc62 100644
--- a/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm
+++ b/ios/chrome/browser/ui/payments/payment_method_selection_mediator.mm
@@ -92,6 +92,11 @@
         base::SysUTF16ToNSString(paymentMethod->NetworkAndLastFourDigits());
     item.methodDetail = base::SysUTF16ToNSString(
         paymentMethod->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL));
+    item.notification =
+        payment_request_util::GetPaymentMethodNotificationLabelFromCreditCard(
+            *paymentMethod, _paymentRequest->billing_profiles());
+    item.complete = payment_request_util::IsCreditCardCompleteForPayment(
+        *paymentMethod, _paymentRequest->billing_profiles());
 
     autofill::AutofillProfile* billingAddress =
         autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
index b0ca87fb..87624db 100644
--- a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
@@ -12,6 +12,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/payments/payment_request.h"
+#include "ios/chrome/browser/payments/payment_request_util.h"
 #include "ios/chrome/browser/ui/payments/full_card_requester.h"
 #include "ios/chrome/browser/ui/payments/payment_request_mediator.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -426,6 +427,8 @@
             (PaymentMethodSelectionCoordinator*)coordinator
                    didSelectPaymentMethod:(autofill::CreditCard*)creditCard {
   DCHECK(creditCard);
+  DCHECK(payment_request_util::IsCreditCardCompleteForPayment(
+      *creditCard, _paymentRequest->billing_profiles()));
   _paymentRequest->set_selected_credit_card(creditCard);
   [_viewController updatePaymentMethodSection];
 
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm
index 005f6e6..2ae43be 100644
--- a/ios/chrome/browser/ui/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -660,20 +660,14 @@
   _pendingPaymentResponse.creditCard = card;
   _pendingPaymentResponse.verificationCode = verificationCode;
 
-  // TODO(crbug.com/714768): Make sure the billing address is set and valid
-  // before getting here. Once the bug is addressed, there will be no need to
-  // copy the address, *billing_address_ptr can be used to get the basic card
-  // response.
-  if (!card.billing_address_id().empty()) {
-    autofill::AutofillProfile* billingAddressPtr =
-        autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
-            card.billing_address_id(), _paymentRequest->billing_profiles());
-    if (billingAddressPtr) {
-      _pendingPaymentResponse.billingAddress = *billingAddressPtr;
-      _addressNormalizationManager->StartNormalizingAddress(
-          &_pendingPaymentResponse.billingAddress);
-    }
-  }
+  DCHECK(!card.billing_address_id().empty());
+  autofill::AutofillProfile* billingAddress =
+      autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
+          card.billing_address_id(), _paymentRequest->billing_profiles());
+  DCHECK(billingAddress);
+  _pendingPaymentResponse.billingAddress = *billingAddress;
+  _addressNormalizationManager->StartNormalizingAddress(
+      &_pendingPaymentResponse.billingAddress);
 
   if (_paymentRequest->request_shipping()) {
     // TODO(crbug.com/602666): User should get here only if they have selected
diff --git a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
index 18ba0099..e40dee0 100644
--- a/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_mediator_unittest.mm
@@ -53,6 +53,7 @@
         credit_card_(autofill::test::GetCreditCard()) {
     // Add testing profile and credit card to autofill::TestPersonalDataManager.
     personal_data_manager_.AddTestingProfile(&autofill_profile_);
+    credit_card_.set_billing_address_id(autofill_profile_.guid());
     personal_data_manager_.AddTestingCreditCard(&credit_card_);
 
     payment_request_ = base::MakeUnique<TestPaymentRequest>(
@@ -82,8 +83,13 @@
 
 // Tests whether payment can be completed when expected.
 TEST_F(PaymentRequestMediatorTest, TestCanPay) {
-  // Payment cannot be completed if there is no selected credit card.
+  EXPECT_TRUE(payment_request_->selected_credit_card());
+  EXPECT_TRUE(payment_request_->selected_shipping_profile());
+  EXPECT_TRUE(payment_request_->selected_shipping_option());
+  EXPECT_TRUE(payment_request_->selected_contact_profile());
   EXPECT_TRUE([GetPaymentRequestMediator() canPay]);
+
+  // Payment cannot be completed if there is no selected credit card.
   autofill::CreditCard* selected_credit_card =
       payment_request_->selected_credit_card();
   payment_request_->set_selected_credit_card(nullptr);
diff --git a/ios/chrome/browser/ui/toolbar/new_keyboard_accessory_view.mm b/ios/chrome/browser/ui/toolbar/new_keyboard_accessory_view.mm
index 7aa8597d..b4f1006 100644
--- a/ios/chrome/browser/ui/toolbar/new_keyboard_accessory_view.mm
+++ b/ios/chrome/browser/ui/toolbar/new_keyboard_accessory_view.mm
@@ -9,7 +9,6 @@
 #include "base/mac/foundation_util.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
-#import "ios/chrome/browser/ui/fancy_ui/colored_button.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -61,11 +60,10 @@
   if (!self.subviews.count)
     return;
 
-  const CGFloat kButtonMinWidth = 36.0;
+  const CGFloat kButtonMinWidth = 34.0;
   const CGFloat kButtonHeight = 34.0;
   const CGFloat kBetweenShortcutButtonSpacing = 5.0;
   const CGFloat kBetweenSearchButtonSpacing = 12.0;
-  const CGFloat kMarginFromBottom = 2.0;
   const CGFloat kHorizontalMargin = 12.0;
 
   // Create and add stackview filled with the shortcut buttons.
@@ -97,8 +95,8 @@
                    action:@selector(keyboardAccessoryCameraSearchTouchUpInside)
          forControlEvents:UIControlEventTouchUpInside];
 
-  // Create a stackview containing containing the buttons for voice search
-  // and camera search.
+  // Create and add a stackview containing containing the buttons for voice
+  // search and camera search.
   UIStackView* searchStackView = [[UIStackView alloc] init];
   searchStackView.translatesAutoresizingMaskIntoConstraints = NO;
   searchStackView.spacing = kBetweenSearchButtonSpacing;
@@ -110,44 +108,32 @@
   NSArray* constraints = @[
     @"H:|-horizontalMargin-[searchStackView]-(>=0)-[shortcutStackView]",
     @"[shortcutStackView]-horizontalMargin-|",
-    @"V:[searchStackView]-bottomMargin-|",
-    @"V:[shortcutStackView]-bottomMargin-|"
   ];
   NSDictionary* viewsDictionary = @{
     @"searchStackView" : searchStackView,
     @"shortcutStackView" : shortcutStackView,
   };
   NSDictionary* metrics = @{
-    @"bottomMargin" : @(kMarginFromBottom),
-    @"horizontalMargin" : @(kHorizontalMargin)
+    @"horizontalMargin" : @(kHorizontalMargin),
   };
   ApplyVisualConstraintsWithMetrics(constraints, viewsDictionary, metrics);
+  AddSameCenterYConstraint(searchStackView, self);
+  AddSameCenterYConstraint(shortcutStackView, self);
 }
 
 - (UIView*)shortcutButtonWithTitle:(NSString*)title {
-  const CGFloat kCornerRadius = 5.0;
-  const CGFloat kAlphaStateNormal = 0.3;
-  const CGFloat kAlphaStateHighlighted = 0.6;
   const CGFloat kHorizontalEdgeInset = 8;
-  const CGFloat kButtonTitleFontSize = 20.0;
-  const UIColor* kButtonBackgroundColor =
-      [UIColor colorWithRed:0.507 green:0.534 blue:0.57 alpha:1.0];
+  const CGFloat kButtonTitleFontSize = 16.0;
+  UIColor* kTitleColorStateNormal = [UIColor colorWithWhite:0.0 alpha:1.0];
+  UIColor* kTitleColorStateHighlighted = [UIColor colorWithWhite:0.0 alpha:0.3];
 
-  ColoredButton* button = [ColoredButton buttonWithType:UIButtonTypeCustom];
-
-  UIColor* stateNormalBackgroundColor =
-      [kButtonBackgroundColor colorWithAlphaComponent:kAlphaStateNormal];
-  UIColor* stateHighlightedBackgroundColor =
-      [kButtonBackgroundColor colorWithAlphaComponent:kAlphaStateHighlighted];
-
-  [button setBackgroundColor:stateNormalBackgroundColor
-                    forState:UIControlStateNormal];
-  [button setBackgroundColor:stateHighlightedBackgroundColor
-                    forState:UIControlStateHighlighted];
+  UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
+  [button setTitleColor:kTitleColorStateNormal forState:UIControlStateNormal];
+  [button setTitleColor:kTitleColorStateHighlighted
+               forState:UIControlStateHighlighted];
 
   [button setTitle:title forState:UIControlStateNormal];
   [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
-  button.layer.cornerRadius = kCornerRadius;
   button.contentEdgeInsets =
       UIEdgeInsetsMake(0, kHorizontalEdgeInset, 0, kHorizontalEdgeInset);
   button.clipsToBounds = YES;
@@ -163,10 +149,18 @@
 }
 
 - (UIButton*)iconButton:(NSString*)iconName {
+  const CGFloat kButtonShadowOpacity = 0.35;
+  const CGFloat kButtonShadowRadius = 1.0;
+  const CGFloat kButtonShadowVerticalOffset = 1.0;
+
   UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
   [button setTranslatesAutoresizingMaskIntoConstraints:NO];
   UIImage* icon = [UIImage imageNamed:iconName];
   [button setImage:icon forState:UIControlStateNormal];
+  button.layer.shadowColor = [UIColor blackColor].CGColor;
+  button.layer.shadowOffset = CGSizeMake(0, kButtonShadowVerticalOffset);
+  button.layer.shadowOpacity = kButtonShadowOpacity;
+  button.layer.shadowRadius = kButtonShadowRadius;
   return button;
 }
 
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner.png
index aefaff8..5f22b88 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner.png
Binary files differ
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@2x.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@2x.png
index f38ea03..c1ce84f 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@2x.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@3x.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@3x.png
index 95f4ba13..1c990fbb 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@3x.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_qr_scanner@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search.png
index 8ff74610b..b70692a1 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search.png
Binary files differ
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@2x.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@2x.png
index 000eed9..0601f2bb 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@2x.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@3x.png b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@3x.png
index aa36476..7b51edb 100644
--- a/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@3x.png
+++ b/ios/chrome/browser/ui/toolbar/resources/keyboard_accessory_voice_search@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.h b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.h
index 5e93f34..318b8bf 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.h
@@ -35,8 +35,6 @@
 extern NSString* const kToolsMenuSettingsId;
 // Help item accessibility Identifier.
 extern NSString* const kToolsMenuHelpId;
-// Suggestions item accessibility Identifier.
-extern NSString* const kToolsMenuSuggestionsId;
 // Request mobile item accessibility Identifier.
 extern NSString* const kToolsMenuRequestMobileId;
 
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
index 59908cf..aa2d2264 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
@@ -23,5 +23,4 @@
 NSString* const kToolsMenuRequestDesktopId = @"kToolsMenuRequestDesktopId";
 NSString* const kToolsMenuSettingsId = @"kToolsMenuSettingsId";
 NSString* const kToolsMenuHelpId = @"kToolsMenuHelpId";
-NSString* const kToolsMenuSuggestionsId = @"kToolsMenuSuggestionsId";
 NSString* const kToolsMenuRequestMobileId = @"kToolsMenuRequestMobileId";
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
index f4d45676..b31fbfa 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
@@ -46,9 +46,6 @@
   { IDS_IOS_TOOLS_MENU_READING_LIST,      kToolsMenuReadingListId,
     IDC_SHOW_READING_LIST,                ToolbarTypeWebAll,
     0,                                    [ReadingListMenuViewItem class] },
-  { IDS_IOS_TOOLS_MENU_SUGGESTIONS,       kToolsMenuSuggestionsId,
-    IDC_SHOW_SUGGESTIONS,                 ToolbarTypeWebAll,
-    0,                                    nil },
   { IDS_IOS_TOOLS_MENU_RECENT_TABS,       kToolsMenuOtherDevicesId,
     IDC_SHOW_OTHER_DEVICES,               ToolbarTypeWebAll,
     kVisibleNotIncognitoOnly,             nil },
@@ -96,8 +93,6 @@
       return IsIPadIdiom();
     case IDS_IOS_TOOLS_MENU_READER_MODE:
       return experimental_flags::IsReaderModeEnabled();
-    case IDS_IOS_TOOLS_MENU_SUGGESTIONS:
-      return experimental_flags::IsSuggestionsUIEnabled();
     case IDS_IOS_OPTIONS_REPORT_AN_ISSUE:
       return ios::GetChromeBrowserProvider()
           ->GetUserFeedbackProvider()
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
index 53c4fc6..5c3905e 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
@@ -31,7 +31,6 @@
 extern NSString* const kToolsMenuRequestDesktopId;
 extern NSString* const kToolsMenuSettingsId;
 extern NSString* const kToolsMenuHelpId;
-extern NSString* const kToolsMenuSuggestionsId;
 extern NSString* const kToolsMenuReadingListId;
 extern NSString* const kToolsMenuRequestMobileId;
 
diff --git a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
index 8cc88f5..96928dc 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
@@ -227,9 +227,6 @@
     case IDC_SHOW_READING_LIST:
       base::RecordAction(UserMetricsAction("MobileMenuReadingList"));
       break;
-    case IDC_SHOW_SUGGESTIONS:
-      // TODO(crbug.com/682174): Move it out of the tool menu or add metrics.
-      break;
     default:
       NOTREACHED();
       break;
diff --git a/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm b/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
index 1d7d1ad..9f91434 100644
--- a/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
+++ b/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
@@ -32,9 +32,6 @@
   { IDS_IOS_TOOLS_MENU_READING_LIST,          kToolsMenuReadingListId,
     ToolbarTypeNone,                          ItemVisibleAlways,
     nil },
-  { IDS_IOS_TOOLS_MENU_SUGGESTIONS,           kToolsMenuSuggestionsId,
-    ToolbarTypeNone,                          ItemVisibleAlways,
-    nil },
   { IDS_IOS_TOOLS_MENU_RECENT_TABS,           kToolsMenuOtherDevicesId,
     ToolbarTypeNone,                          ItemVisibleNotIncognitoOnly,
     nil },
diff --git a/ios/showcase/common/protocol_alerter.h b/ios/showcase/common/protocol_alerter.h
index 4eb6afc..52208b1 100644
--- a/ios/showcase/common/protocol_alerter.h
+++ b/ios/showcase/common/protocol_alerter.h
@@ -20,6 +20,9 @@
 // The view controller (if any) that will be used to present alerts.
 @property(nonatomic, weak) UIViewController* baseViewController;
 
+// Removes the logging for the method corresponding to |sel|.
+- (void)ignoreSelector:(SEL)sel;
+
 @end
 
 #endif  // IOS_SHOWCASE_COMMON_PROTOCOL_ALERTER_H_
diff --git a/ios/showcase/common/protocol_alerter.mm b/ios/showcase/common/protocol_alerter.mm
index 759b76ff..bb61e43 100644
--- a/ios/showcase/common/protocol_alerter.mm
+++ b/ios/showcase/common/protocol_alerter.mm
@@ -26,6 +26,8 @@
 
 @interface ProtocolAlerter () {
   NSSet<Protocol*>* _protocols;
+  // Selectors for which no logging should be done.
+  NSMutableSet<NSValue*>* _ignoredSelectors;
 }
 @end
 
@@ -39,9 +41,14 @@
   // NSProxy isn't a subclass of NSObject, and has no superclass, so
   // there's no [super init] to call.
   _protocols = [[NSSet<Protocol*> alloc] initWithArray:protocols];
+  _ignoredSelectors = [NSMutableSet set];
   return self;
 }
 
+- (void)ignoreSelector:(SEL)sel {
+  [_ignoredSelectors addObject:[NSValue valueWithPointer:sel]];
+}
+
 #pragma mark - NSProxy
 
 - (NSMethodSignature*)methodSignatureForSelector:(SEL)sel {
@@ -68,6 +75,10 @@
 }
 
 - (void)forwardInvocation:(NSInvocation*)invocation {
+  if ([_ignoredSelectors
+          containsObject:[NSValue valueWithPointer:invocation.selector]]) {
+    return;
+  }
   // Instead of actually doing anything the protocol method would normally
   // do, instead just generate a title and description and display an alert or
   // log a message.
diff --git a/ios/showcase/content_suggestions/sc_content_suggestions_egtest.mm b/ios/showcase/content_suggestions/sc_content_suggestions_egtest.mm
index 4ed0b536..08a30c1 100644
--- a/ios/showcase/content_suggestions/sc_content_suggestions_egtest.mm
+++ b/ios/showcase/content_suggestions/sc_content_suggestions_egtest.mm
@@ -67,8 +67,6 @@
 
 // Tests launching ContentSuggestionsViewController.
 - (void)testLaunch {
-  EARL_GREY_TEST_DISABLED(@"Disabled until it is possible to hide some alerts");
-
   showcase_utils::Open(@"ContentSuggestionsViewController");
   [CellWithMatcher(chrome_test_util::ButtonWithAccessibilityLabelId(
       IDS_IOS_CONTENT_SUGGESTIONS_FOOTER_TITLE))
@@ -81,8 +79,6 @@
 
 // Tests the opening of a suggestion item by tapping on it.
 - (void)testOpenItem {
-  EARL_GREY_TEST_DISABLED(@"Disabled until it is possible to hide some alerts");
-
   showcase_utils::Open(@"ContentSuggestionsViewController");
   [CellWithID([SCContentSuggestionsDataSource titleFirstSuggestion])
       performAction:grey_tap()];
@@ -103,8 +99,6 @@
 
 // Tests dismissing an item with swipe-to-dismiss.
 - (void)testSwipeToDismiss {
-  EARL_GREY_TEST_DISABLED(@"Disabled until it is possible to hide some alerts");
-
   showcase_utils::Open(@"ContentSuggestionsViewController");
 
   [CellWithID([SCContentSuggestionsDataSource titleFirstSuggestion])
@@ -130,8 +124,6 @@
 
 // Tests that long pressing an item starts a context menu.
 - (void)testLongPressItem {
-  EARL_GREY_TEST_DISABLED(@"Disabled until it is possible to hide some alerts");
-
   showcase_utils::Open(@"ContentSuggestionsViewController");
   [CellWithID([SCContentSuggestionsDataSource titleFirstSuggestion])
       performAction:grey_longPress()];
@@ -150,8 +142,6 @@
 
 // Tests that swipe-to-dismiss on empty item does nothing.
 - (void)testNoSwipeToDismissEmptyItem {
-  EARL_GREY_TEST_DISABLED(@"Disabled until it is possible to hide some alerts");
-
   showcase_utils::Open(@"ContentSuggestionsViewController");
   [CellWithID([SCContentSuggestionsDataSource titleReadingListItem])
       performAction:grey_swipeFastInDirection(kGREYDirectionLeft)];
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index f4ecd5c..c1140d1 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -24,7 +24,8 @@
 // But the number is expected to be big enough for now.
 constexpr Sample kMaxUmaDevices = 31;
 
-// Used to count events for usage histogram.
+// Used to count events for usage histogram. The item order should not be
+// changed, and new items should be just appended.
 enum class Usage {
   CREATED,
   CREATED_ON_UNSUPPORTED_PLATFORMS,
@@ -38,9 +39,20 @@
   MAX = OUTPUT_PORT_ADDED,
 };
 
+// Used to count events for transaction usage histogram. The item order should
+// not be changed, and new items should be just appended.
+enum class SendReceiveUsage {
+  NO_USE,
+  SENT,
+  RECEIVED,
+  SENT_AND_RECEIVED,
+
+  // New items should be inserted here, and |MAX| should point the last item.
+  MAX = SENT_AND_RECEIVED,
+};
+
 void ReportUsage(Usage usage) {
-  UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage",
-                            static_cast<Sample>(usage),
+  UMA_HISTOGRAM_ENUMERATION("Media.Midi.Usage", usage,
                             static_cast<Sample>(Usage::MAX) + 1);
 }
 
@@ -50,6 +62,8 @@
     : initialization_state_(InitializationState::NOT_STARTED),
       finalized_(false),
       result_(Result::NOT_INITIALIZED),
+      data_sent_(false),
+      data_received_(false),
       service_(service) {
   ReportUsage(Usage::CREATED);
 }
@@ -70,9 +84,8 @@
 #endif
 
 void MidiManager::Shutdown() {
-  UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown",
-                            static_cast<int>(result_),
-                            static_cast<int>(Result::MAX) + 1);
+  UMA_HISTOGRAM_ENUMERATION("Media.Midi.ResultOnShutdown", result_,
+                            static_cast<Sample>(Result::MAX) + 1);
   bool shutdown_synchronously = false;
   {
     base::AutoLock auto_lock(lock_);
@@ -165,6 +178,7 @@
 
 void MidiManager::AccumulateMidiBytesSent(MidiManagerClient* client, size_t n) {
   base::AutoLock auto_lock(lock_);
+  data_sent_ = true;
   if (clients_.find(client) == clients_.end())
     return;
 
@@ -239,6 +253,7 @@
                                   size_t length,
                                   double timestamp) {
   base::AutoLock auto_lock(lock_);
+  data_received_ = true;
 
   for (auto* client : clients_)
     client->ReceiveMidiData(port_index, data, length, timestamp);
@@ -247,11 +262,9 @@
 void MidiManager::CompleteInitializationInternal(Result result) {
   TRACE_EVENT0("midi", "MidiManager::CompleteInitialization");
   ReportUsage(Usage::INITIALIZED);
-  UMA_HISTOGRAM_ENUMERATION("Media.Midi.InputPorts",
-                            static_cast<Sample>(input_ports_.size()),
+  UMA_HISTOGRAM_ENUMERATION("Media.Midi.InputPorts", input_ports_.size(),
                             kMaxUmaDevices + 1);
-  UMA_HISTOGRAM_ENUMERATION("Media.Midi.OutputPorts",
-                            static_cast<Sample>(output_ports_.size()),
+  UMA_HISTOGRAM_ENUMERATION("Media.Midi.OutputPorts", output_ports_.size(),
                             kMaxUmaDevices + 1);
 
   base::AutoLock auto_lock(lock_);
@@ -287,6 +300,14 @@
   // Detach all clients so that they do not call MidiManager methods any more.
   for (auto* client : clients_)
     client->Detach();
+
+  UMA_HISTOGRAM_ENUMERATION(
+      "Media.Midi.SendReceiveUsage",
+      data_sent_ ? (data_received_ ? SendReceiveUsage::SENT_AND_RECEIVED
+                                   : SendReceiveUsage::SENT)
+                 : (data_received_ ? SendReceiveUsage::RECEIVED
+                                   : SendReceiveUsage::NO_USE),
+      static_cast<Sample>(SendReceiveUsage::MAX) + 1);
 }
 
 }  // namespace midi
diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h
index cea56b0..8a1c63f 100644
--- a/media/midi/midi_manager.h
+++ b/media/midi/midi_manager.h
@@ -219,9 +219,13 @@
   MidiPortInfoList input_ports_;
   MidiPortInfoList output_ports_;
 
+  // Tracks if actual data transmission happens.
+  bool data_sent_;
+  bool data_received_;
+
   // Protects access to |clients_|, |pending_clients_|,
   // |session_thread_runner_|, |initialization_state_|, |finalize_|, |result_|,
-  // |input_ports_| and |output_ports_|.
+  // |input_ports_|, |output_ports_|, |data_sent_| and |data_received_|.
   base::Lock lock_;
 
   // MidiService outlives MidiManager.
diff --git a/mojo/android/BUILD.gn b/mojo/android/BUILD.gn
index 525e7fc..179eb6f 100644
--- a/mojo/android/BUILD.gn
+++ b/mojo/android/BUILD.gn
@@ -140,6 +140,8 @@
     "//mojo/public/cpp/test_support:test_utils",
   ]
   defines = [ "UNIT_TEST" ]
+  configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+  configs += [ "//build/config/android:hide_all_but_jni" ]
 }
 
 instrumentation_test_apk("mojo_test_apk") {
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index f855f47..8ef6f7c 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -109,6 +109,9 @@
     ":java_test_native_support",
     "//net:test_support",
   ]
+
+  configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+  configs += [ "//build/config/android:hide_all_but_jni" ]
 }
 
 android_apk("net_test_support_apk") {
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 8a12c36..e96f88a 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -3291,13 +3291,13 @@
   bool selection_changed = false;
   for (const auto& old_selection : old_selections_) {
     if (!old_selection.IsEmpty()) {
-      engine_->client_->Invalidate(old_selection);
+      Invalidate(old_selection);
       selection_changed = true;
     }
   }
   for (const auto& new_selection : new_selections) {
     if (!new_selection.IsEmpty()) {
-      engine_->client_->Invalidate(new_selection);
+      Invalidate(new_selection);
       selection_changed = true;
     }
   }
@@ -3321,6 +3321,13 @@
   return rects;
 }
 
+void PDFiumEngine::SelectionChangeInvalidator::Invalidate(
+    const pp::Rect& selection) {
+  pp::Rect expanded_selection = selection;
+  expanded_selection.Inset(-1, -1);
+  engine_->client_->Invalidate(expanded_selection);
+}
+
 PDFiumEngine::MouseDownState::MouseDownState(
     const PDFiumPage::Area& area,
     const PDFiumPage::LinkTarget& target)
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h
index 449efdf8..5b46fc0 100644
--- a/pdf/pdfium/pdfium_engine.h
+++ b/pdf/pdfium/pdfium_engine.h
@@ -139,6 +139,10 @@
     // coordinates.
     std::vector<pp::Rect> GetVisibleSelections() const;
 
+    // Invalidates |selection|, but with |selection| slightly expanded to
+    // compensate for any rounding errors.
+    void Invalidate(const pp::Rect& selection);
+
     PDFiumEngine* const engine_;
     // The origin at the time this object was constructed.
     const pp::Point previous_origin_;
diff --git a/remoting/android/BUILD.gn b/remoting/android/BUILD.gn
index 248c1ea0..07cbe53 100644
--- a/remoting/android/BUILD.gn
+++ b/remoting/android/BUILD.gn
@@ -20,6 +20,16 @@
   jni_package = "remoting"
 }
 
+generate_jni_registration("remoting_jni_registration") {
+  target = ":remoting_apk"
+  output = "$root_gen_dir/remoting/client/${target_name}.h"
+  exception_files = [
+    "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+    "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+  ]
+}
+
 _raw_resources_base_dir = "$target_gen_dir/credits_resources_raw/res"
 
 # The target is named this way, instead of "..._raw_resources", specifically
diff --git a/remoting/client/jni/BUILD.gn b/remoting/client/jni/BUILD.gn
index f0f8082..6f10926 100644
--- a/remoting/client/jni/BUILD.gn
+++ b/remoting/client/jni/BUILD.gn
@@ -19,6 +19,7 @@
 shared_library("remoting_client_jni") {
   deps = [
     "//remoting/android:jni_headers",
+    "//remoting/android:remoting_jni_registration",
     "//remoting/base",
     "//remoting/client",
     "//remoting/client/display",
diff --git a/remoting/client/jni/remoting_jni_onload.cc b/remoting/client/jni/remoting_jni_onload.cc
index 9db79a8..dd1a283d 100644
--- a/remoting/client/jni/remoting_jni_onload.cc
+++ b/remoting/client/jni/remoting_jni_onload.cc
@@ -11,6 +11,7 @@
 #include "base/macros.h"
 #include "net/android/net_jni_registrar.h"
 #include "remoting/client/jni/remoting_jni_registrar.h"
+#include "remoting/client/remoting_jni_registration.h"
 #include "ui/gfx/android/gfx_jni_registrar.h"
 
 namespace {
@@ -32,6 +33,12 @@
 JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
   base::android::InitVM(vm);
   JNIEnv* env = base::android::AttachCurrentThread();
+  if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+    return -1;
+  }
+
+  // TODO(agrieve): Delete this block, this is a no-op now.
+  // https://crbug.com/683256.
   if (!RegisterJNI(env) || !base::android::OnJNIOnLoadInit()) {
     return -1;
   }
diff --git a/services/identity/identity_manager.cc b/services/identity/identity_manager.cc
index 37a452c..7321998b 100644
--- a/services/identity/identity_manager.cc
+++ b/services/identity/identity_manager.cc
@@ -82,13 +82,17 @@
   // directly returns the authenticated GAIA ID. We can of course get it from
   // the AccountInfo but once we have the ACcountInfo we ... have the
   // AccountInfo.
-  std::move(callback).Run(signin_manager_->GetAuthenticatedAccountInfo());
+  AccountInfo account_info = signin_manager_->GetAuthenticatedAccountInfo();
+  AccountState account_state = GetStateOfAccount(account_info);
+  std::move(callback).Run(account_info, account_state);
 }
 
 void IdentityManager::GetAccountInfoFromGaiaId(
     const std::string& gaia_id,
     GetAccountInfoFromGaiaIdCallback callback) {
-  std::move(callback).Run(account_tracker_->FindAccountInfoByGaiaId(gaia_id));
+  AccountInfo account_info = account_tracker_->FindAccountInfoByGaiaId(gaia_id);
+  AccountState account_state = GetStateOfAccount(account_info);
+  std::move(callback).Run(account_info, account_state);
 }
 
 void IdentityManager::GetAccessToken(const std::string& account_id,
@@ -108,4 +112,12 @@
   access_token_requests_.erase(request);
 }
 
+AccountState IdentityManager::GetStateOfAccount(
+    const AccountInfo& account_info) {
+  AccountState account_state;
+  account_state.has_refresh_token =
+      token_service_->RefreshTokenIsAvailable(account_info.account_id);
+  return account_state;
+}
+
 }  // namespace identity
diff --git a/services/identity/identity_manager.h b/services/identity/identity_manager.h
index 1c767c01..9e371d4 100644
--- a/services/identity/identity_manager.h
+++ b/services/identity/identity_manager.h
@@ -7,6 +7,7 @@
 
 #include "components/signin/core/browser/account_info.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/cpp/scope_set.h"
 #include "services/identity/public/interfaces/identity_manager.mojom.h"
 
@@ -75,6 +76,9 @@
   // Deletes |request|.
   void AccessTokenRequestCompleted(AccessTokenRequest* request);
 
+  // Gets the current state of the account represented by |account_info|.
+  AccountState GetStateOfAccount(const AccountInfo& account_info);
+
   AccountTrackerService* account_tracker_;
   SigninManagerBase* signin_manager_;
   ProfileOAuth2TokenService* token_service_;
diff --git a/services/identity/identity_manager_unittest.cc b/services/identity/identity_manager_unittest.cc
index 493a0b6..61afcdd 100644
--- a/services/identity/identity_manager_unittest.cc
+++ b/services/identity/identity_manager_unittest.cc
@@ -11,6 +11,7 @@
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/identity/identity_service.h"
+#include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/cpp/scope_set.h"
 #include "services/identity/public/interfaces/constants.mojom.h"
 #include "services/identity/public/interfaces/identity_manager.mojom.h"
@@ -90,15 +91,19 @@
 
   void OnReceivedPrimaryAccountInfo(
       base::Closure quit_closure,
-      const base::Optional<AccountInfo>& account_info) {
+      const base::Optional<AccountInfo>& account_info,
+      const AccountState& account_state) {
     primary_account_info_ = account_info;
+    primary_account_state_ = account_state;
     quit_closure.Run();
   }
 
   void OnReceivedAccountInfoFromGaiaId(
       base::Closure quit_closure,
-      const base::Optional<AccountInfo>& account_info) {
+      const base::Optional<AccountInfo>& account_info,
+      const AccountState& account_state) {
     account_info_from_gaia_id_ = account_info;
+    account_state_from_gaia_id_ = account_state;
     quit_closure.Run();
   }
 
@@ -126,7 +131,9 @@
 
   mojom::IdentityManagerPtr identity_manager_;
   base::Optional<AccountInfo> primary_account_info_;
+  AccountState primary_account_state_;
   base::Optional<AccountInfo> account_info_from_gaia_id_;
+  AccountState account_state_from_gaia_id_;
   base::Optional<std::string> access_token_;
   GoogleServiceAuthError access_token_error_;
 
@@ -154,8 +161,9 @@
   EXPECT_FALSE(primary_account_info_);
 }
 
-// Check that the primary account info has expected values if signed in.
-TEST_F(IdentityManagerTest, GetPrimaryAccountInfoSignedIn) {
+// Check that the primary account info has expected values if signed in without
+// a refresh token available.
+TEST_F(IdentityManagerTest, GetPrimaryAccountInfoSignedInNoRefreshToken) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   base::RunLoop run_loop;
   identity_manager_->GetPrimaryAccountInfo(
@@ -163,8 +171,30 @@
                  base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(primary_account_info_);
+  EXPECT_EQ(signin_manager()->GetAuthenticatedAccountId(),
+            primary_account_info_->account_id);
   EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia);
   EXPECT_EQ(kTestEmail, primary_account_info_->email);
+  EXPECT_FALSE(primary_account_state_.has_refresh_token);
+}
+
+// Check that the primary account info has expected values if signed in with a
+// refresh token available.
+TEST_F(IdentityManagerTest, GetPrimaryAccountInfoSignedInRefreshToken) {
+  signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
+  token_service()->UpdateCredentials(
+      signin_manager()->GetAuthenticatedAccountId(), kTestRefreshToken);
+  base::RunLoop run_loop;
+  identity_manager_->GetPrimaryAccountInfo(
+      base::Bind(&IdentityManagerTest::OnReceivedPrimaryAccountInfo,
+                 base::Unretained(this), run_loop.QuitClosure()));
+  run_loop.Run();
+  EXPECT_TRUE(primary_account_info_);
+  EXPECT_EQ(signin_manager()->GetAuthenticatedAccountId(),
+            primary_account_info_->account_id);
+  EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia);
+  EXPECT_EQ(kTestEmail, primary_account_info_->email);
+  EXPECT_TRUE(primary_account_state_.has_refresh_token);
 }
 
 // Check that the account info for a given GAIA ID is null if that GAIA ID is
@@ -180,9 +210,10 @@
 }
 
 // Check that the account info for a given GAIA ID has expected values if that
-// GAIA ID is known.
-TEST_F(IdentityManagerTest, GetAccountInfoForKnownGaiaId) {
-  account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
+// GAIA ID is known and there is no refresh token available for it.
+TEST_F(IdentityManagerTest, GetAccountInfoForKnownGaiaIdNoRefreshToken) {
+  std::string account_id =
+      account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
   base::RunLoop run_loop;
   identity_manager_->GetAccountInfoFromGaiaId(
       kTestGaiaId,
@@ -190,8 +221,29 @@
                  base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(account_info_from_gaia_id_);
+  EXPECT_EQ(account_id, account_info_from_gaia_id_->account_id);
   EXPECT_EQ(kTestGaiaId, account_info_from_gaia_id_->gaia);
   EXPECT_EQ(kTestEmail, account_info_from_gaia_id_->email);
+  EXPECT_FALSE(account_state_from_gaia_id_.has_refresh_token);
+}
+
+// Check that the account info for a given GAIA ID has expected values if that
+// GAIA ID is known and has a refresh token available.
+TEST_F(IdentityManagerTest, GetAccountInfoForKnownGaiaIdRefreshToken) {
+  std::string account_id =
+      account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
+  token_service()->UpdateCredentials(account_id, kTestRefreshToken);
+  base::RunLoop run_loop;
+  identity_manager_->GetAccountInfoFromGaiaId(
+      kTestGaiaId,
+      base::Bind(&IdentityManagerTest::OnReceivedAccountInfoFromGaiaId,
+                 base::Unretained(this), run_loop.QuitClosure()));
+  run_loop.Run();
+  EXPECT_TRUE(account_info_from_gaia_id_);
+  EXPECT_EQ(account_id, account_info_from_gaia_id_->account_id);
+  EXPECT_EQ(kTestGaiaId, account_info_from_gaia_id_->gaia);
+  EXPECT_EQ(kTestEmail, account_info_from_gaia_id_->email);
+  EXPECT_TRUE(account_state_from_gaia_id_.has_refresh_token);
 }
 
 // Check that the expected error is received if requesting an access token when
@@ -212,12 +264,13 @@
 // token when signed in.
 TEST_F(IdentityManagerTest, GetAccessTokenSignedIn) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
-  token_service()->UpdateCredentials(kTestGaiaId, kTestRefreshToken);
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+  token_service()->UpdateCredentials(account_id, kTestRefreshToken);
   token_service()->set_auto_post_fetch_response_on_message_loop(true);
   base::RunLoop run_loop;
 
   identity_manager_->GetAccessToken(
-      kTestGaiaId, ScopeSet(), "dummy_consumer",
+      account_id, ScopeSet(), "dummy_consumer",
       base::Bind(&IdentityManagerTest::OnReceivedAccessToken,
                  base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn
index 07ad0e4..0c02281 100644
--- a/services/identity/public/cpp/BUILD.gn
+++ b/services/identity/public/cpp/BUILD.gn
@@ -8,6 +8,8 @@
   output_name = "identity_cpp_types"
 
   sources = [
+    "account_state.cc",
+    "account_state.h",
     "scope_set.h",
   ]
 }
diff --git a/services/identity/public/cpp/account_state.cc b/services/identity/public/cpp/account_state.cc
new file mode 100644
index 0000000..81b3aec3
--- /dev/null
+++ b/services/identity/public/cpp/account_state.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/identity/public/cpp/account_state.h"
+
+namespace identity {
+
+AccountState::AccountState() : has_refresh_token(false) {}
+
+AccountState::AccountState(const AccountState& other) = default;
+AccountState::~AccountState() {}
+
+}  // namespace identity
diff --git a/services/identity/public/cpp/account_state.h b/services/identity/public/cpp/account_state.h
new file mode 100644
index 0000000..2485537
--- /dev/null
+++ b/services/identity/public/cpp/account_state.h
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_H_
+#define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_H_
+
+namespace identity {
+
+// C++ typemap of the Mojo struct giving information about the state of a
+// specific account. See account_state.mojom for documentation.
+struct AccountState {
+  AccountState();
+  AccountState(const AccountState& other);
+  ~AccountState();
+
+  bool has_refresh_token;
+};
+
+}  // namespace identity
+
+#endif  // SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_H_
diff --git a/services/identity/public/cpp/account_state.typemap b/services/identity/public/cpp/account_state.typemap
new file mode 100644
index 0000000..69c2539
--- /dev/null
+++ b/services/identity/public/cpp/account_state.typemap
@@ -0,0 +1,13 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//services/identity/public/interfaces/account_state.mojom"
+public_headers = [ "//services/identity/public/cpp/account_state.h" ]
+traits_headers =
+    [ "//services/identity/public/cpp/account_state_struct_traits.h" ]
+sources = [
+  "//services/identity/public/cpp/account_state_struct_traits.cc",
+]
+
+type_mappings = [ "identity.mojom.AccountState=identity::AccountState" ]
diff --git a/services/identity/public/cpp/account_state_struct_traits.cc b/services/identity/public/cpp/account_state_struct_traits.cc
new file mode 100644
index 0000000..2e8cee9
--- /dev/null
+++ b/services/identity/public/cpp/account_state_struct_traits.cc
@@ -0,0 +1,19 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/identity/public/cpp/account_state_struct_traits.h"
+
+namespace mojo {
+
+// static
+bool StructTraits<
+    identity::mojom::AccountState::DataView,
+    identity::AccountState>::Read(identity::mojom::AccountState::DataView data,
+                                  identity::AccountState* out) {
+  out->has_refresh_token = data.has_refresh_token();
+
+  return true;
+}
+
+}  // namespace mojo
diff --git a/services/identity/public/cpp/account_state_struct_traits.h b/services/identity/public/cpp/account_state_struct_traits.h
new file mode 100644
index 0000000..b6f258ca
--- /dev/null
+++ b/services/identity/public/cpp/account_state_struct_traits.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_STRUCT_TRAITS_H_
+#define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_STRUCT_TRAITS_H_
+
+#include "services/identity/public/cpp/account_state.h"
+#include "services/identity/public/interfaces/account_state.mojom.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<identity::mojom::AccountState::DataView,
+                    identity::AccountState> {
+  static bool has_refresh_token(const identity::AccountState& r) {
+    return r.has_refresh_token;
+  }
+
+  static bool Read(identity::mojom::AccountState::DataView data,
+                   identity::AccountState* out);
+};
+
+}  // namespace mojo
+
+#endif  // SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNT_STATE_STRUCT_TRAITS_H_
diff --git a/services/identity/public/cpp/typemaps.gni b/services/identity/public/cpp/typemaps.gni
index 006444b3..45059196 100644
--- a/services/identity/public/cpp/typemaps.gni
+++ b/services/identity/public/cpp/typemaps.gni
@@ -1,5 +1,6 @@
 typemaps = [
   "//services/identity/public/cpp/account_info.typemap",
+  "//services/identity/public/cpp/account_state.typemap",
   "//services/identity/public/cpp/google_service_auth_error.typemap",
   "//services/identity/public/cpp/scope_set.typemap",
 ]
diff --git a/services/identity/public/interfaces/BUILD.gn b/services/identity/public/interfaces/BUILD.gn
index a13d64e..dca69ec1e 100644
--- a/services/identity/public/interfaces/BUILD.gn
+++ b/services/identity/public/interfaces/BUILD.gn
@@ -7,6 +7,7 @@
 mojom("interfaces") {
   sources = [
     "account_info.mojom",
+    "account_state.mojom",
     "google_service_auth_error.mojom",
     "identity_manager.mojom",
     "scope_set.mojom",
diff --git a/services/identity/public/interfaces/account_state.mojom b/services/identity/public/interfaces/account_state.mojom
new file mode 100644
index 0000000..3ef655a
--- /dev/null
+++ b/services/identity/public/interfaces/account_state.mojom
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module identity.mojom;
+
+// Information about the state that a specific Google account is in at a given
+// moment. Note that unlike the long-lived information in AccountInfo, the
+// information in AccountState is essentially a snapshot.
+struct AccountState {
+  // Whether the account has a refresh token available.
+  bool has_refresh_token;
+};
diff --git a/services/identity/public/interfaces/identity_manager.mojom b/services/identity/public/interfaces/identity_manager.mojom
index c7a7ca4..8683460 100644
--- a/services/identity/public/interfaces/identity_manager.mojom
+++ b/services/identity/public/interfaces/identity_manager.mojom
@@ -6,6 +6,7 @@
 
 import "mojo/common/time.mojom";
 import "services/identity/public/interfaces/account_info.mojom";
+import "services/identity/public/interfaces/account_state.mojom";
 import "services/identity/public/interfaces/google_service_auth_error.mojom";
 import "services/identity/public/interfaces/scope_set.mojom";
 
@@ -13,12 +14,17 @@
 interface IdentityManager {
   // Returns the AccountInfo for the Google account that serves as the user's
   // primary account, or null if the user has no primary account (e.g., if they
-  // are not signed in).
-  GetPrimaryAccountInfo() => (AccountInfo? account_info);
+  // are not signed in). |account_state| gives the current state of the account
+  // (relevant only if |account_info| is non-null).
+  GetPrimaryAccountInfo() => (AccountInfo? account_info,
+                              AccountState account_state);
 
   // Returns the AccountInfo for the user's Google account corresponding to
   // |gaia_id|, or null if the user has such corresponding account.
-  GetAccountInfoFromGaiaId(string gaia_id) => (AccountInfo? account_info);
+  // |account_state| gives the current state of the account (relevant only if
+  // |account_info| is non-null).
+  GetAccountInfoFromGaiaId(string gaia_id) => (AccountInfo? account_info,
+                                               AccountState account_state);
 
   // Returns an access token with the requested scopes for the given
   // |account_id|, or null if it is not possible to obtain such a token (e.g.,
diff --git a/testing/test.gni b/testing/test.gni
index 36e0d91..64619b3 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -63,7 +63,7 @@
         # the default shared_library configs rather than executable configs.
         configs -= [
           "//build/config:shared_library_config",
-          "//build/config/android:hide_all_but_jni_onload",
+          "//build/config/android:hide_all_but_jni",
         ]
         configs += [ "//build/config:executable_config" ]
 
@@ -321,6 +321,8 @@
 set_defaults("test") {
   if (is_android) {
     configs = default_shared_library_configs
+    configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+    configs += [ "//build/config/android:hide_all_but_jni" ]
   } else {
     configs = default_executable_configs
   }
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 0120e10..5984e54 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2902,6 +2902,8 @@
 # Rebaselining a newly-passing test fixed by v8
 crbug.com/v8/6504 fast/js/mozilla/strict/B.1.2.html [ NeedsManualRebaseline ]
 
+crbug.com/v8/6529 inspector/console/console-dir.html [ NeedsManualRebaseline ]
+
 # These tests are failing on Mac-10.12 when using an Intel GPU.
 crbug.com/736177 [ Mac ] css2.1/t1202-counter-04-b.html [ Failure Pass ]
 crbug.com/736177 [ Mac ] css2.1/t1202-counters-04-b.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-constructor-expected.txt
index 9cc74ec4..31edfdf6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-constructor-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-constructor-expected.txt
@@ -3,7 +3,7 @@
 PASS URLSearchParams constructor, no arguments 
 FAIL URLSearchParams constructor, DOMException.prototype as argument Illegal invocation
 PASS URLSearchParams constructor, empty string as argument 
-FAIL URLSearchParams constructor, {} as argument assert_equals: expected "" but got "%5Bobject+Object%5D="
+PASS URLSearchParams constructor, {} as argument 
 PASS URLSearchParams constructor, string. 
 PASS URLSearchParams constructor, object. 
 PASS Parse + 
@@ -17,10 +17,10 @@
 PASS Parse 💩 
 PASS Parse %f0%9f%92%a9 
 PASS Constructor with sequence of sequences of strings 
-FAIL Construct with object with + assert_array_equals: property 0, expected "+" but got "[object Object]"
-FAIL Construct with object with two keys assert_array_equals: property 0, expected "c" but got "[object Object]"
+PASS Construct with object with + 
+PASS Construct with object with two keys 
 PASS Construct with array with two keys 
-FAIL Construct with object with NULL, non-ASCII, and surrogate keys assert_array_equals: property 0, expected "a\0b" but got "[object Object]"
-FAIL Custom [Symbol.iterator] assert_equals: expected (string) "b" but got (object) null
+PASS Construct with object with NULL, non-ASCII, and surrogate keys 
+PASS Custom [Symbol.iterator] 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-sort-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-sort-expected.txt
deleted file mode 100644
index 9066ba7..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/url/urlsearchparams-sort-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL Parse and sort: z=b&a=b&z=a&a=a params.sort is not a function
-FAIL URL parse and sort: z=b&a=b&z=a&a=a url.searchParams.sort is not a function
-FAIL Parse and sort: �=x&&�=a params.sort is not a function
-FAIL URL parse and sort: �=x&&�=a url.searchParams.sort is not a function
-FAIL Parse and sort: ffi&🌈 params.sort is not a function
-FAIL URL parse and sort: ffi&🌈 url.searchParams.sort is not a function
-FAIL Parse and sort: é&e�&é params.sort is not a function
-FAIL URL parse and sort: é&e�&é url.searchParams.sort is not a function
-FAIL Parse and sort: z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g params.sort is not a function
-FAIL URL parse and sort: z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g url.searchParams.sort is not a function
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
index 5ced91c5..f262947 100644
--- a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
@@ -55,8 +55,6 @@
     var params = new URLSearchParams('');
     assert_not_equals(params, null, 'constructor returned non-null value.');
     assert_equals(params.__proto__, URLSearchParams.prototype, 'expected URLSearchParams.prototype as prototype.');
-    params = new URLSearchParams({});
-    assert_equals(params + '', '%5Bobject+Object%5D=');
 }, 'URLSearchParams constructor, empty.');
 
 test(function() {
@@ -91,7 +89,7 @@
     assert_false(params.has('e'));
     params.append('g', 'h');
     assert_false(seed.has('g'));
-}, 'URLSearchParams constructor, object.');
+}, 'sequence initializer, object coerced to iterable');
 
 test(function() {
     var params = new URLSearchParams('a=b+c');
@@ -180,6 +178,18 @@
       "Sequence elements must be pairs");
 }, 'sequence initializer');
 
+test(function() {
+    let params = new URLSearchParams({});
+    assert_true(params !== null, 'Empty record');
+    assert_equals(params.toString(), '');
+
+    params = new URLSearchParams({1: 2, 'a': 'b'});
+    assert_equals(params.toString(), '1=2&a=b');
+
+    params = new URLSearchParams({false: true, 0: 'foo'});
+    assert_equals(params.toString(), '0=foo&false=true');
+}, 'record initializer');
+
 </script>
 </head>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt
index 7dbe40a5..decd735c 100644
--- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-expected.txt
@@ -6,7 +6,7 @@
 PASS getUserMedia succeeded.
 PASS track.readyState is "live"
 PASS Track onmute callback succeeded.
-PASS track.readyState is "muted"
+PASS track.readyState is "live"
 PASS track.muted is true
 PASS Track onunmute callback succeeded.
 PASS track.readyState is "live"
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html
index d7c0f66..28a4e1a4 100644
--- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack.html
@@ -49,7 +49,7 @@
 function onTrackMute() {
     testPassed('Track onmute callback succeeded.');
 
-    shouldBeEqualToString('track.readyState', 'muted');
+    shouldBeEqualToString('track.readyState', 'live');
     shouldBeTrue('track.muted');
 
     track.enabled = true;
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 32469023..6afbb05 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1079,6 +1079,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface WebGL2RenderingContext
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 8fbf1b8d..7e6e3036 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -855,6 +855,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index ddee30a..dd3bb68 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -814,6 +814,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
index 1541881..3156177 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -6106,6 +6106,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface USB : EventTarget
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index ed48080..fdd5392 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -814,6 +814,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
index 2a1c321..0d020233 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -6035,6 +6035,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface USB : EventTarget
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index a4e2cf4..c5bc0ba6 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1070,6 +1070,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface WebGL2RenderingContext
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 904cfe4..3a9a596 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -980,6 +980,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebGL2RenderingContext
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
index a01da38..13cb460 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -6932,6 +6932,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface USB : EventTarget
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-shared-worker-expected.txt
index 0d32b6a01..b272baa 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -980,6 +980,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebGL2RenderingContext
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 8cbddb99..7bc1dcf 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -856,6 +856,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index b5886b3..fe36be44 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -815,6 +815,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index 34730a3b0..e248bd6 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -815,6 +815,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebSocket : EventTarget
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 8fadf5a..2278f6b 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -988,6 +988,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebGL2RenderingContext
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 6d3ba1b..70e7b975 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -6940,6 +6940,7 @@
     method has
     method keys
     method set
+    method sort
     method toString
     method values
 interface USB : EventTarget
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 5b37c04..d0b071d 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -988,6 +988,7 @@
 [Worker]     method has
 [Worker]     method keys
 [Worker]     method set
+[Worker]     method sort
 [Worker]     method toString
 [Worker]     method values
 [Worker] interface WebGL2RenderingContext
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index c272330..4d57a5e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -73,8 +73,8 @@
   "$bindings_core_v8_output_dir/StringOrFloat.h",
   "$bindings_core_v8_output_dir/StringOrUnrestrictedDoubleSequence.cpp",
   "$bindings_core_v8_output_dir/StringOrUnrestrictedDoubleSequence.h",
-  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.cpp",
-  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h",
+  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString.cpp",
+  "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString.h",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrKeyframeAnimationOptions.cpp",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrKeyframeAnimationOptions.h",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrKeyframeEffectOptions.cpp",
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
index e6ce11d5..af4ee3b 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
@@ -4,6 +4,7 @@
 
 #include "core/dom/URLSearchParams.h"
 
+#include <algorithm>
 #include <utility>
 #include "core/dom/DOMURL.h"
 #include "platform/network/FormDataEncoder.h"
@@ -38,6 +39,11 @@
   size_t current_;
 };
 
+bool CompareParams(const std::pair<String, String>& a,
+                   const std::pair<String, String>& b) {
+  return WTF::CodePointCompareLessThan(a.first, b.first);
+}
+
 }  // namespace
 
 URLSearchParams* URLSearchParams::Create(const URLSearchParamsInit& init,
@@ -48,11 +54,10 @@
       return new URLSearchParams(query_string.Substring(1));
     return new URLSearchParams(query_string);
   }
-  // TODO(sof): copy constructor no longer in the spec,
-  // consider removing.
-  if (init.isURLSearchParams())
-    return new URLSearchParams(init.getAsURLSearchParams());
-
+  if (init.isUSVStringUSVStringRecord()) {
+    return URLSearchParams::Create(init.getAsUSVStringUSVStringRecord(),
+                                   exception_state);
+  }
   if (init.isUSVStringSequenceSequence()) {
     return URLSearchParams::Create(init.getAsUSVStringSequenceSequence(),
                                    exception_state);
@@ -87,9 +92,16 @@
     SetInput(query_string);
 }
 
-URLSearchParams::URLSearchParams(URLSearchParams* search_params) {
-  DCHECK(search_params);
-  params_ = search_params->params_;
+URLSearchParams* URLSearchParams::Create(
+    const Vector<std::pair<String, String>>& init,
+    ExceptionState& exception_state) {
+  URLSearchParams* instance = new URLSearchParams(String());
+  if (init.IsEmpty())
+    return instance;
+  for (const auto& item : init)
+    instance->AppendWithoutUpdate(item.first, item.second);
+  instance->RunUpdateSteps();
+  return instance;
 }
 
 URLSearchParams::~URLSearchParams() {}
@@ -222,6 +234,11 @@
     RunUpdateSteps();
 }
 
+void URLSearchParams::sort() {
+  std::stable_sort(params_.begin(), params_.end(), CompareParams);
+  RunUpdateSteps();
+}
+
 void URLSearchParams::EncodeAsFormData(Vector<char>& encoded_data) const {
   for (const auto& param : params_)
     FormDataEncoder::AddKeyValuePairAsFormData(
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.h b/third_party/WebKit/Source/core/dom/URLSearchParams.h
index 8ff91cd..6279ad2d 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.h
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.h
@@ -8,7 +8,7 @@
 #include <base/gtest_prod_util.h>
 #include <utility>
 #include "bindings/core/v8/Iterable.h"
-#include "bindings/core/v8/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h"
+#include "bindings/core/v8/USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 #include "platform/network/EncodedFormData.h"
@@ -20,7 +20,7 @@
 class ExceptionState;
 class DOMURL;
 
-typedef USVStringSequenceSequenceOrUSVStringOrURLSearchParams
+typedef USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString
     URLSearchParamsInit;
 
 class CORE_EXPORT URLSearchParams final
@@ -31,6 +31,8 @@
 
  public:
   static URLSearchParams* Create(const URLSearchParamsInit&, ExceptionState&);
+  static URLSearchParams* Create(const Vector<std::pair<String, String>>&,
+                                 ExceptionState&);
   static URLSearchParams* Create(const Vector<Vector<String>>&,
                                  ExceptionState&);
 
@@ -49,6 +51,7 @@
   Vector<String> getAll(const String&) const;
   bool has(const String&) const;
   void set(const String& name, const String& value);
+  void sort();
   void SetInput(const String&);
 
   // Internal helpers
@@ -65,7 +68,6 @@
   FRIEND_TEST_ALL_PREFIXES(URLSearchParamsTest, EncodedFormData);
 
   explicit URLSearchParams(const String&, DOMURL* = nullptr);
-  explicit URLSearchParams(URLSearchParams*);
 
   void RunUpdateSteps();
   IterationSource* StartIteration(ScriptState*, ExceptionState&) override;
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.idl b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
index 810b4dc..c9148aa 100644
--- a/third_party/WebKit/Source/core/dom/URLSearchParams.idl
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
@@ -5,7 +5,7 @@
 // https://url.spec.whatwg.org/#interface-urlsearchparams
 
 [
-    Constructor(optional (sequence<sequence<USVString>> or USVString or URLSearchParams) init = ""),
+    Constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""),
     Exposed=(Window,Worker),
     RaisesException=Constructor
 ] interface URLSearchParams {
@@ -16,6 +16,8 @@
     boolean has(USVString name);
     void set(USVString name, USVString value);
 
+    void sort();
+
     iterable<USVString, USVString>;
     stringifier;
 };
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
index 3fabee9..225bed4 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -99,9 +99,6 @@
 
   ThreadableLoaderOptions options;
   options.fetch_request_mode = WebURLRequest::kFetchRequestModeSameOrigin;
-  // FIXME: Is there a directive to which this load should be subject?
-  options.content_security_policy_enforcement =
-      kDoNotEnforceContentSecurityPolicy;
 
   ResourceLoaderOptions resource_loader_options;
   // Use special initiator to hide the request from the inspector.
diff --git a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
index 0c15738f..6ce5ab71 100644
--- a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
@@ -191,12 +191,14 @@
 
   // To be meaningful enough to indicate user intention, a keyboard event needs
   // - not to be a modifier event
+  // - not to be a browser shortcut
   // https://crbug.com/709765
   bool is_modifier =
       Platform::Current()->IsDomKeyForModifier(initial_key_event.dom_key);
+  bool is_browser_shortcut = initial_key_event.is_browser_shortcut;
 
   std::unique_ptr<UserGestureIndicator> gesture_indicator;
-  if (!is_modifier) {
+  if (!is_modifier && !is_browser_shortcut) {
     gesture_indicator.reset(new UserGestureIndicator(
         UserGestureToken::Create(frame_->GetDocument())));
   }
diff --git a/third_party/WebKit/Source/core/layout/GridLayoutUtils.cpp b/third_party/WebKit/Source/core/layout/GridLayoutUtils.cpp
index f8528d6..34a9c2c 100644
--- a/third_party/WebKit/Source/core/layout/GridLayoutUtils.cpp
+++ b/third_party/WebKit/Source/core/layout/GridLayoutUtils.cpp
@@ -49,4 +49,18 @@
              : child.MarginLogicalHeight();
 }
 
+bool GridLayoutUtils::IsOrthogonalChild(const LayoutGrid& grid,
+                                        const LayoutBox& child) {
+  return child.IsHorizontalWritingMode() != grid.IsHorizontalWritingMode();
+}
+
+GridTrackSizingDirection GridLayoutUtils::FlowAwareDirectionForChild(
+    const LayoutGrid& grid,
+    const LayoutBox& child,
+    GridTrackSizingDirection direction) {
+  return !IsOrthogonalChild(grid, child)
+             ? direction
+             : (direction == kForColumns ? kForRows : kForColumns);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/GridLayoutUtils.h b/third_party/WebKit/Source/core/layout/GridLayoutUtils.h
index c6995c4..221f2d5 100644
--- a/third_party/WebKit/Source/core/layout/GridLayoutUtils.h
+++ b/third_party/WebKit/Source/core/layout/GridLayoutUtils.h
@@ -16,6 +16,11 @@
                                                const LayoutBox&);
   static LayoutUnit MarginLogicalHeightForChild(const LayoutGrid&,
                                                 const LayoutBox&);
+  static bool IsOrthogonalChild(const LayoutGrid&, const LayoutBox&);
+  static GridTrackSizingDirection FlowAwareDirectionForChild(
+      const LayoutGrid&,
+      const LayoutBox&,
+      GridTrackSizingDirection);
 };
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
index 574307c..cdf80e5 100644
--- a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
+++ b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
@@ -147,9 +147,12 @@
 
 bool GridTrackSizingAlgorithmStrategy::
     ShouldClearOverrideContainingBlockContentSizeForChild(
+        const LayoutGrid& grid,
         const LayoutBox& child,
         GridTrackSizingDirection direction) {
-  if (direction == kForColumns) {
+  GridTrackSizingDirection child_inline_direction =
+      GridLayoutUtils::FlowAwareDirectionForChild(grid, child, kForColumns);
+  if (direction == child_inline_direction) {
     return child.HasRelativeLogicalWidth() ||
            child.StyleRef().LogicalWidth().IsIntrinsicOrAuto();
   }
@@ -168,20 +171,9 @@
     child.SetOverrideContainingBlockContentLogicalHeight(size);
 }
 
-GridTrackSizingDirection
-GridTrackSizingAlgorithmStrategy::FlowAwareDirectionForChild(
-    const LayoutGrid* layout_grid,
-    const LayoutBox& child,
-    GridTrackSizingDirection direction) {
-  return child.IsHorizontalWritingMode() ==
-                 layout_grid->IsHorizontalWritingMode()
-             ? direction
-             : (direction == kForColumns ? kForRows : kForColumns);
-}
-
 LayoutUnit GridTrackSizingAlgorithm::AssumedRowsSizeForOrthogonalChild(
     const LayoutBox& child) const {
-  DCHECK(layout_grid_->IsOrthogonalChild(child));
+  DCHECK(GridLayoutUtils::IsOrthogonalChild(*layout_grid_, child));
   const GridSpan& span = grid_.GridItemSpan(child, kForRows);
   LayoutUnit grid_area_size;
   bool grid_area_is_indefinite = false;
@@ -246,12 +238,14 @@
 LayoutUnit GridTrackSizingAlgorithmStrategy::LogicalHeightForChild(
     LayoutBox& child) const {
   GridTrackSizingDirection child_block_direction =
-      FlowAwareDirectionForChild(GetLayoutGrid(), child, kForRows);
-
-  // If |child| has a relative logical height, we shouldn't let it override its
-  // intrinsic height, which is what we are interested in here. Thus we need to
-  // set the block-axis override size to -1 (no possible resolution).
-  if (ShouldClearOverrideContainingBlockContentSizeForChild(child, kForRows)) {
+      GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child,
+                                                  kForRows);
+  // If |child| has a relative block-axis size, we shouldn't let it override its
+  // intrinsic size, which is what we are interested in here. Thus we
+  // need to set the block-axis OverrideContainingBlock size to -1 (no possible
+  // resolution).
+  if (ShouldClearOverrideContainingBlockContentSizeForChild(
+          *GetLayoutGrid(), child, child_block_direction)) {
     SetOverrideContainingBlockContentSizeForChild(child, child_block_direction,
                                                   LayoutUnit(-1));
     child.SetNeedsLayout(LayoutInvalidationReason::kGridChanged, kMarkOnlyThis);
@@ -269,13 +263,15 @@
 LayoutUnit GridTrackSizingAlgorithmStrategy::MinContentForChild(
     LayoutBox& child) const {
   GridTrackSizingDirection child_inline_direction =
-      FlowAwareDirectionForChild(GetLayoutGrid(), child, kForColumns);
+      GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child,
+                                                  kForColumns);
   if (Direction() == child_inline_direction) {
-    // If |child| has a relative logical width, we shouldn't let it override its
-    // intrinsic width, which is what we are interested in here. Thus we need to
-    // set the inline-axis override size to -1 (no possible resolution).
-    if (ShouldClearOverrideContainingBlockContentSizeForChild(child,
-                                                              kForColumns)) {
+    // If |child| has a relative inline-axis size, we shouldn't let it override
+    // its intrinsic size, which is what we are interested in here.
+    // Thus we need to set the inline-axis OverrideContainingBlock size to -1
+    // (no possible resolution).
+    if (ShouldClearOverrideContainingBlockContentSizeForChild(
+            *GetLayoutGrid(), child, child_inline_direction)) {
       SetOverrideContainingBlockContentSizeForChild(
           child, child_inline_direction, LayoutUnit(-1));
     }
@@ -288,7 +284,7 @@
   }
 
   if (Direction() == kForColumns && !AvailableSpace()) {
-    DCHECK(GetLayoutGrid()->IsOrthogonalChild(child));
+    DCHECK(GridLayoutUtils::IsOrthogonalChild(*GetLayoutGrid(), child));
     if (auto baseline_extent = ExtentForBaselineAlignment(child))
       return baseline_extent.value();
   }
@@ -303,13 +299,15 @@
 LayoutUnit GridTrackSizingAlgorithmStrategy::MaxContentForChild(
     LayoutBox& child) const {
   GridTrackSizingDirection child_inline_direction =
-      FlowAwareDirectionForChild(GetLayoutGrid(), child, kForColumns);
+      GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child,
+                                                  kForColumns);
   if (Direction() == child_inline_direction) {
-    // If |child| has a relative logical width, we shouldn't let it override its
-    // intrinsic width, which is what we are interested in here. Thus we need to
-    // set the inline-axis override size to -1 (no possible resolution).
-    if (ShouldClearOverrideContainingBlockContentSizeForChild(child,
-                                                              kForColumns)) {
+    // If |child| has a relative inline-axis size, we shouldn't let it override
+    // its intrinsic size, which is what we are interested in here.
+    // Thus we need to set the inline-axis OverrideContainingBlock size to -1
+    // (no possible resolution).
+    if (ShouldClearOverrideContainingBlockContentSizeForChild(
+            *GetLayoutGrid(), child, child_inline_direction)) {
       SetOverrideContainingBlockContentSizeForChild(
           child, child_inline_direction, LayoutUnit(-1));
     }
@@ -330,7 +328,8 @@
 LayoutUnit GridTrackSizingAlgorithmStrategy::MinSizeForChild(
     LayoutBox& child) const {
   GridTrackSizingDirection child_inline_direction =
-      FlowAwareDirectionForChild(GetLayoutGrid(), child, kForColumns);
+      GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child,
+                                                  kForColumns);
   bool is_row_axis = Direction() == child_inline_direction;
   const Length& child_size = is_row_axis ? child.StyleRef().LogicalWidth()
                                          : child.StyleRef().LogicalHeight();
@@ -390,8 +389,9 @@
 GridTrackSizingAlgorithmStrategy::ExtentForBaselineAlignment(
     LayoutBox& child) const {
   auto grid = algorithm_.layout_grid_;
-  GridAxis baseline_axis =
-      grid->IsOrthogonalChild(child) ? kGridRowAxis : kGridColumnAxis;
+  GridAxis baseline_axis = GridLayoutUtils::IsOrthogonalChild(*grid, child)
+                               ? kGridRowAxis
+                               : kGridColumnAxis;
   if (!grid->IsBaselineAlignmentForChild(child, baseline_axis) ||
       !grid->IsBaselineContextComputed(baseline_axis))
     return WTF::nullopt;
diff --git a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
index d09d5381..a63e98c 100644
--- a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
+++ b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
@@ -282,6 +282,7 @@
       const LayoutBox& child,
       GridTrackSizingDirection);
   static bool ShouldClearOverrideContainingBlockContentSizeForChild(
+      const LayoutGrid&,
       const LayoutBox& child,
       GridTrackSizingDirection);
   static void SetOverrideContainingBlockContentSizeForChild(
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 89f7578..a79c04d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -1408,8 +1408,8 @@
   return rare_data_->override_logical_content_height_;
 }
 
-// TODO (lajava) Now that we have implemented these functions based on physical
-// direction, we'd rather remove the logical ones.
+// TODO (lajava) Shouldn't we implement these functions based on physical
+// direction ?.
 LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalWidth() const {
   DCHECK(HasOverrideContainingBlockLogicalWidth());
   return rare_data_->override_containing_block_content_logical_width_;
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index c7b7b09..a0f84eb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -582,10 +582,6 @@
              : child.OverrideContainingBlockContentLogicalHeight();
 }
 
-bool LayoutGrid::IsOrthogonalChild(const LayoutBox& child) const {
-  return child.IsHorizontalWritingMode() != IsHorizontalWritingMode();
-}
-
 // Unfortunately there are still many layout methods that return -1 for
 // non-resolvable sizes. We prefer to represent them with WTF::nullopt.
 static Optional<LayoutUnit> ConvertLayoutUnitToOptional(LayoutUnit size) {
@@ -798,7 +794,8 @@
       continue;
 
     has_any_orthogonal_grid_item =
-        has_any_orthogonal_grid_item || IsOrthogonalChild(*child);
+        has_any_orthogonal_grid_item ||
+        GridLayoutUtils::IsOrthogonalChild(*this, *child);
     grid.SetGridItemPaintOrder(*child, child_index++);
 
     GridArea area = grid.GridItemArea(*child);
@@ -1319,7 +1316,8 @@
 
     LayoutPositionedObject(child, relayout_children, info);
 
-    bool is_orthogonal_child = IsOrthogonalChild(*child);
+    bool is_orthogonal_child =
+        GridLayoutUtils::IsOrthogonalChild(*this, *child);
     LayoutUnit logical_left =
         child->LogicalLeft() +
         (is_orthogonal_child ? row_offset : column_offset);
@@ -1577,19 +1575,11 @@
       SelfAlignmentNormalBehavior(&child), style);
 }
 
-GridTrackSizingDirection LayoutGrid::FlowAwareDirectionForChild(
-    const LayoutBox& child,
-    GridTrackSizingDirection direction) const {
-  return !IsOrthogonalChild(child)
-             ? direction
-             : (direction == kForColumns ? kForRows : kForColumns);
-}
-
 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to
 // LayoutBox.
 void LayoutGrid::ApplyStretchAlignmentToChildIfNeeded(LayoutBox& child) {
   GridTrackSizingDirection child_block_direction =
-      FlowAwareDirectionForChild(child, kForRows);
+      GridLayoutUtils::FlowAwareDirectionForChild(*this, child, kForRows);
   bool block_flow_is_column_axis = child_block_direction == kForRows;
   bool allowed_to_stretch_child_block_size =
       block_flow_is_column_axis ? AllowedToStretchChildAlongColumnAxis(child)
@@ -1751,7 +1741,7 @@
   if (!baseline_child)
     return -1;
 
-  int baseline = IsOrthogonalChild(*baseline_child)
+  int baseline = GridLayoutUtils::IsOrthogonalChild(*this, *baseline_child)
                      ? -1
                      : baseline_child->FirstLineBoxBaseline();
   // We take border-box's bottom if no valid baseline.
@@ -1787,8 +1777,9 @@
 
 bool LayoutGrid::IsParallelToBlockAxisForChild(const LayoutBox& child,
                                                GridAxis axis) const {
-  return axis == kGridColumnAxis ? !IsOrthogonalChild(child)
-                                 : IsOrthogonalChild(child);
+  return axis == kGridColumnAxis
+             ? !GridLayoutUtils::IsOrthogonalChild(*this, child)
+             : GridLayoutUtils::IsOrthogonalChild(*this, child);
 }
 
 bool LayoutGrid::IsDescentBaselineForChild(const LayoutBox& child,
@@ -1987,7 +1978,7 @@
       // Aligns the alignment subject to be flush with the edge of the alignment
       // container corresponding to the alignment subject's 'start' side in the
       // column axis.
-      if (IsOrthogonalChild(child)) {
+      if (GridLayoutUtils::IsOrthogonalChild(*this, child)) {
         // If orthogonal writing-modes, self-start will be based on the child's
         // inline-axis direction (inline-start), because it's the one parallel
         // to the column axis.
@@ -2004,7 +1995,7 @@
       // Aligns the alignment subject to be flush with the edge of the alignment
       // container corresponding to the alignment subject's 'end' side in the
       // column axis.
-      if (IsOrthogonalChild(child)) {
+      if (GridLayoutUtils::IsOrthogonalChild(*this, child)) {
         // If orthogonal writing-modes, self-end will be based on the child's
         // inline-axis direction, (inline-end) because it's the one parallel to
         // the column axis.
@@ -2066,7 +2057,7 @@
       // Aligns the alignment subject to be flush with the edge of the alignment
       // container corresponding to the alignment subject's 'start' side in the
       // row axis.
-      if (IsOrthogonalChild(child)) {
+      if (GridLayoutUtils::IsOrthogonalChild(*this, child)) {
         // If orthogonal writing-modes, self-start will be based on the child's
         // block-axis direction, because it's the one parallel to the row axis.
         if (child.StyleRef().IsFlippedBlocksWritingMode())
@@ -2082,7 +2073,7 @@
       // Aligns the alignment subject to be flush with the edge of the alignment
       // container corresponding to the alignment subject's 'end' side in the
       // row axis.
-      if (IsOrthogonalChild(child)) {
+      if (GridLayoutUtils::IsOrthogonalChild(*this, child)) {
         // If orthogonal writing-modes, self-end will be based on the child's
         // block-axis direction, because it's the one parallel to the row axis.
         if (child.StyleRef().IsFlippedBlocksWritingMode())
@@ -2156,7 +2147,7 @@
         end_of_row -= offset_between_rows_;
       }
       LayoutUnit column_axis_child_size =
-          IsOrthogonalChild(child)
+          GridLayoutUtils::IsOrthogonalChild(*this, child)
               ? child.LogicalWidth() + child.MarginLogicalWidth()
               : child.LogicalHeight() + child.MarginLogicalHeight();
       OverflowAlignment overflow = AlignSelfForChild(child).Overflow();
@@ -2198,7 +2189,7 @@
         end_of_column -= offset_between_columns_;
       }
       LayoutUnit row_axis_child_size =
-          IsOrthogonalChild(child)
+          GridLayoutUtils::IsOrthogonalChild(*this, child)
               ? child.LogicalHeight() + child.MarginLogicalHeight()
               : child.LogicalWidth() + child.MarginLogicalWidth();
       OverflowAlignment overflow = JustifySelfForChild(child).Overflow();
@@ -2355,13 +2346,15 @@
 LayoutPoint LayoutGrid::FindChildLogicalPosition(const LayoutBox& child) const {
   LayoutUnit column_axis_offset = ColumnAxisOffsetForChild(child);
   LayoutUnit row_axis_offset = RowAxisOffsetForChild(child);
+  bool is_orthogonal_child = GridLayoutUtils::IsOrthogonalChild(*this, child);
   // We stored m_columnPosition's data ignoring the direction, hence we might
   // need now to translate positions from RTL to LTR, as it's more convenient
   // for painting.
-  if (!Style()->IsLeftToRightDirection())
-    row_axis_offset = TranslateRTLCoordinate(row_axis_offset) -
-                      (IsOrthogonalChild(child) ? child.LogicalHeight()
-                                                : child.LogicalWidth());
+  if (!Style()->IsLeftToRightDirection()) {
+    row_axis_offset =
+        TranslateRTLCoordinate(row_axis_offset) -
+        (is_orthogonal_child ? child.LogicalHeight() : child.LogicalWidth());
+  }
 
   // "In the positioning phase [...] calculations are performed according to the
   // writing mode of the containing block of the box establishing the orthogonal
@@ -2369,8 +2362,8 @@
   // 'setLogicalPosition' in order to set the child's logical position, which
   // will only take into account the child's writing-mode.
   LayoutPoint child_location(row_axis_offset, column_axis_offset);
-  return IsOrthogonalChild(child) ? child_location.TransposedPoint()
-                                  : child_location;
+  return is_orthogonal_child ? child_location.TransposedPoint()
+                             : child_location;
 }
 
 LayoutPoint LayoutGrid::GridAreaLogicalPosition(const GridArea& area) const {
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index f662f7b..3d4fc29 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -1196,7 +1196,8 @@
     data->ForEachSegment([this](const char* segment, size_t segment_size,
                                 size_t segment_offset) -> bool {
       HandleReceivedData(segment, segment_size);
-      return true;
+      // The client may cancel this loader in handleReceivedData().
+      return client_;
     });
   }
 
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoader.h b/third_party/WebKit/Source/core/loader/ThreadableLoader.h
index 912b02af..fda5562 100644
--- a/third_party/WebKit/Source/core/loader/ThreadableLoader.h
+++ b/third_party/WebKit/Source/core/loader/ThreadableLoader.h
@@ -48,17 +48,11 @@
 
 enum PreflightPolicy { kConsiderPreflight, kPreventPreflight };
 
-enum ContentSecurityPolicyEnforcement {
-  kEnforceContentSecurityPolicy,
-  kDoNotEnforceContentSecurityPolicy,
-};
-
 struct ThreadableLoaderOptions {
   DISALLOW_NEW();
   ThreadableLoaderOptions()
       : preflight_policy(kConsiderPreflight),
         fetch_request_mode(WebURLRequest::kFetchRequestModeSameOrigin),
-        content_security_policy_enforcement(kEnforceContentSecurityPolicy),
         timeout_milliseconds(0) {}
 
   // When adding members, CrossThreadThreadableLoaderOptionsData should
@@ -68,7 +62,6 @@
   PreflightPolicy preflight_policy;
 
   WebURLRequest::FetchRequestMode fetch_request_mode;
-  ContentSecurityPolicyEnforcement content_security_policy_enforcement;
   unsigned long timeout_milliseconds;
 };
 
@@ -79,23 +72,18 @@
       const ThreadableLoaderOptions& options)
       : preflight_policy(options.preflight_policy),
         fetch_request_mode(options.fetch_request_mode),
-        content_security_policy_enforcement(
-            options.content_security_policy_enforcement),
         timeout_milliseconds(options.timeout_milliseconds) {}
 
   operator ThreadableLoaderOptions() const {
     ThreadableLoaderOptions options;
     options.preflight_policy = preflight_policy;
     options.fetch_request_mode = fetch_request_mode;
-    options.content_security_policy_enforcement =
-        content_security_policy_enforcement;
     options.timeout_milliseconds = timeout_milliseconds;
     return options;
   }
 
   PreflightPolicy preflight_policy;
   WebURLRequest::FetchRequestMode fetch_request_mode;
-  ContentSecurityPolicyEnforcement content_security_policy_enforcement;
   unsigned long timeout_milliseconds;
 };
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
index 53423ca..a671a98 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
@@ -81,9 +81,6 @@
 
   ThreadableLoaderOptions options;
   options.fetch_request_mode = WebURLRequest::kFetchRequestModeNoCORS;
-  // FIXME: Should we add EnforceScriptSrcDirective here?
-  options.content_security_policy_enforcement =
-      kDoNotEnforceContentSecurityPolicy;
 
   ResourceLoaderOptions resource_loader_options;
 
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index 354559b9..de191f87 100644
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -1011,10 +1011,6 @@
   options.fetch_request_mode =
       upload_events ? WebURLRequest::kFetchRequestModeCORSWithForcedPreflight
                     : WebURLRequest::kFetchRequestModeCORS;
-  options.content_security_policy_enforcement =
-      ContentSecurityPolicy::ShouldBypassMainWorld(&execution_context)
-          ? kDoNotEnforceContentSecurityPolicy
-          : kEnforceContentSecurityPolicy;
   options.timeout_milliseconds = timeout_milliseconds_;
 
   ResourceLoaderOptions resource_loader_options;
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
index 266eff9..3241677 100644
--- a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
+++ b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
@@ -155,10 +155,6 @@
   ThreadableLoaderOptions options;
   options.preflight_policy = kPreventPreflight;
   options.fetch_request_mode = WebURLRequest::kFetchRequestModeCORS;
-  options.content_security_policy_enforcement =
-      ContentSecurityPolicy::ShouldBypassMainWorld(&execution_context)
-          ? kDoNotEnforceContentSecurityPolicy
-          : kEnforceContentSecurityPolicy;
 
   ResourceLoaderOptions resource_loader_options;
   resource_loader_options.data_buffering_policy = kDoNotBufferData;
diff --git a/third_party/WebKit/Source/modules/fetch/BlobBytesConsumer.cpp b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumer.cpp
index ac72334f..2726dfc 100644
--- a/third_party/WebKit/Source/modules/fetch/BlobBytesConsumer.cpp
+++ b/third_party/WebKit/Source/modules/fetch/BlobBytesConsumer.cpp
@@ -282,8 +282,6 @@
 ThreadableLoader* BlobBytesConsumer::CreateLoader() {
   ThreadableLoaderOptions options;
   options.fetch_request_mode = WebURLRequest::kFetchRequestModeSameOrigin;
-  options.content_security_policy_enforcement =
-      kDoNotEnforceContentSecurityPolicy;
 
   ResourceLoaderOptions resource_loader_options;
   resource_loader_options.data_buffering_policy = kDoNotBufferData;
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
index f438b19..11d3831 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -773,10 +773,6 @@
   resource_loader_options.security_origin = request_->Origin().Get();
 
   ThreadableLoaderOptions threadable_loader_options;
-  threadable_loader_options.content_security_policy_enforcement =
-      ContentSecurityPolicy::ShouldBypassMainWorld(execution_context_)
-          ? kDoNotEnforceContentSecurityPolicy
-          : kEnforceContentSecurityPolicy;
   switch (request_->Mode()) {
     case WebURLRequest::kFetchRequestModeSameOrigin:
     case WebURLRequest::kFetchRequestModeNoCORS:
@@ -830,10 +826,6 @@
   resource_loader_options.security_origin = request_->Origin().Get();
 
   ThreadableLoaderOptions threadable_loader_options;
-  threadable_loader_options.content_security_policy_enforcement =
-      ContentSecurityPolicy::ShouldBypassMainWorld(execution_context_)
-          ? kDoNotEnforceContentSecurityPolicy
-          : kEnforceContentSecurityPolicy;
   threadable_loader_options.fetch_request_mode =
       WebURLRequest::kFetchRequestModeNoCORS;
 
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp
index b6da2392..58e16b2d 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrack.cpp
@@ -64,7 +64,7 @@
 MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
                                    MediaStreamComponent* component)
     : ContextLifecycleObserver(context),
-      ready_state_(MediaStreamSource::kReadyStateLive),
+      ready_state_(component->Source()->GetReadyState()),
       is_iterating_registered_media_streams_(false),
       stopped_(false),
       component_(component),
@@ -72,6 +72,10 @@
       constraints_() {
   component_->Source()->AddObserver(this);
 
+  // If the source is already non-live at this point, the observer won't have
+  // been called. Update the muted state manually.
+  component_->SetMuted(ready_state_ == MediaStreamSource::kReadyStateMuted);
+
   if (component_->Source() &&
       component_->Source()->GetType() == MediaStreamSource::kTypeVideo) {
     // ImageCapture::create() only throws if |this| track is not of video type.
@@ -183,11 +187,12 @@
   if (Ended())
     return "ended";
 
+  // Although muted is tracked as a ReadyState, only "live" and "ended" are
+  // visible externally.
   switch (ready_state_) {
     case MediaStreamSource::kReadyStateLive:
-      return "live";
     case MediaStreamSource::kReadyStateMuted:
-      return "muted";
+      return "live";
     case MediaStreamSource::kReadyStateEnded:
       return "ended";
   }
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIInput.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIInput.cpp
index 0514d072..4a498d80 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIInput.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIInput.cpp
@@ -30,6 +30,8 @@
 
 #include "modules/webmidi/MIDIInput.h"
 
+#include "core/dom/Document.h"
+#include "core/frame/UseCounter.h"
 #include "modules/webmidi/MIDIAccess.h"
 #include "modules/webmidi/MIDIMessageEvent.h"
 #include "platform/heap/Handle.h"
@@ -98,6 +100,9 @@
     return;
   DOMUint8Array* array = DOMUint8Array::Create(data, length);
   DispatchEvent(MIDIMessageEvent::Create(time_stamp, array));
+
+  UseCounter::Count(*ToDocument(GetExecutionContext()),
+                    WebFeature::kMIDIMessageEvent);
 }
 
 DEFINE_TRACE(MIDIInput) {
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIOutput.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIOutput.cpp
index e287267..8df9e5cf 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIOutput.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIOutput.cpp
@@ -31,9 +31,11 @@
 #include "modules/webmidi/MIDIOutput.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalDOMWindow.h"
+#include "core/frame/UseCounter.h"
 #include "core/timing/DOMWindowPerformance.h"
 #include "core/timing/Performance.h"
 #include "media/midi/midi_service.mojom-blink.h"
@@ -229,6 +231,9 @@
   if (timestamp == 0.0)
     timestamp = Now(GetExecutionContext());
 
+  UseCounter::Count(*ToDocument(GetExecutionContext()),
+                    WebFeature::kMIDIOutputSend);
+
   // Implicit open. It does nothing if the port is already opened.
   // This should be performed even if |array| is invalid.
   open();
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp
index bffc632..525fb136 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIPort.cpp
@@ -32,6 +32,8 @@
 
 #include "bindings/core/v8/ScriptPromise.h"
 #include "core/dom/DOMException.h"
+#include "core/dom/Document.h"
+#include "core/frame/UseCounter.h"
 #include "modules/webmidi/MIDIAccess.h"
 #include "modules/webmidi/MIDIConnectionEvent.h"
 
@@ -172,6 +174,8 @@
 }
 
 void MIDIPort::open() {
+  UseCounter::Count(*ToDocument(GetExecutionContext()),
+                    WebFeature::kMIDIPortOpen);
   switch (state_) {
     case PortState::DISCONNECTED:
       SetStates(state_, kConnectionStatePending);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index fecc6263..4c7dbb6 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -357,7 +357,7 @@
     },
     {
       name: "DeviceRAMHeader",
-      status: "test",
+      status: "experimental",
     },
     {
       name: "DisplayList2dCanvas",
diff --git a/third_party/WebKit/Source/platform/loader/BUILD.gn b/third_party/WebKit/Source/platform/loader/BUILD.gn
index 3ac6a5f..46aa3fa2 100644
--- a/third_party/WebKit/Source/platform/loader/BUILD.gn
+++ b/third_party/WebKit/Source/platform/loader/BUILD.gn
@@ -22,6 +22,8 @@
     "LinkHeader.cpp",
     "LinkHeader.h",
     "fetch/AccessControlStatus.h",
+    "fetch/BufferingDataPipeWriter.cpp",
+    "fetch/BufferingDataPipeWriter.h",
     "fetch/CachedMetadata.cpp",
     "fetch/CachedMetadata.h",
     "fetch/CachedMetadataHandler.h",
@@ -92,6 +94,7 @@
   deps = [
     ":make_platform_loader_generated_fetch_initiator_type_names",
     "//components/link_header_util:link_header_util",
+    "//mojo/public/cpp/system:system",
     "//storage/public/interfaces:interfaces_blink__generator",
   ]
 
@@ -113,6 +116,7 @@
   # Source files for blink_platform_unittests.
   sources = [
     "LinkHeaderTest.cpp",
+    "fetch/BufferingDataPipeWriterTest.cpp",
     "fetch/ClientHintsPreferencesTest.cpp",
     "fetch/CrossOriginAccessControlTest.cpp",
     "fetch/FetchUtilsTest.cpp",
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
new file mode 100644
index 0000000..ec9a960
--- /dev/null
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
@@ -0,0 +1,111 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/loader/fetch/BufferingDataPipeWriter.h"
+
+#include "base/single_thread_task_runner.h"
+
+namespace blink {
+
+namespace {
+
+const auto kNone = MOJO_WRITE_DATA_FLAG_NONE;
+
+}  // namespace
+
+BufferingDataPipeWriter::BufferingDataPipeWriter(
+    mojo::ScopedDataPipeProducerHandle handle,
+    WebTaskRunner* runner)
+    : handle_(std::move(handle)),
+      watcher_(BLINK_FROM_HERE,
+               mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+               runner->ToSingleThreadTaskRunner()) {
+  watcher_.Watch(
+      handle_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+      MOJO_WATCH_CONDITION_SATISFIED,
+      base::Bind(&BufferingDataPipeWriter::OnWritable, base::Unretained(this)));
+}
+
+bool BufferingDataPipeWriter::Write(const char* buffer, uint32_t num_bytes) {
+  DCHECK(!finished_);
+  if (!handle_.is_valid())
+    return false;
+
+  if (buffer_.empty()) {
+    while (num_bytes > 0) {
+      uint32_t size = num_bytes;
+      MojoResult result =
+          mojo::WriteDataRaw(handle_.get(), buffer, &size, kNone);
+      if (result == MOJO_RESULT_SHOULD_WAIT)
+        break;
+      if (result != MOJO_RESULT_OK) {
+        Clear();
+        return false;
+      }
+      num_bytes -= size;
+      buffer += size;
+    }
+  }
+  if (num_bytes == 0)
+    return true;
+
+  buffer_.push_back(Vector<char>());
+  buffer_.back().Append(buffer, num_bytes);
+  if (!waiting_) {
+    waiting_ = true;
+    watcher_.ArmOrNotify();
+  }
+  return true;
+}
+
+void BufferingDataPipeWriter::Finish() {
+  finished_ = true;
+  ClearIfNeeded();
+}
+
+void BufferingDataPipeWriter::OnWritable(MojoResult) {
+  if (!handle_.is_valid())
+    return;
+  waiting_ = false;
+  while (!buffer_.empty()) {
+    WTF::Vector<char>& front = buffer_.front();
+
+    uint32_t size = front.size() - front_written_size_;
+
+    MojoResult result = mojo::WriteDataRaw(
+        handle_.get(), front.data() + front_written_size_, &size, kNone);
+    if (result == MOJO_RESULT_SHOULD_WAIT) {
+      waiting_ = true;
+      watcher_.ArmOrNotify();
+      return;
+    }
+    if (result != MOJO_RESULT_OK) {
+      Clear();
+      return;
+    }
+    front_written_size_ += size;
+
+    if (front_written_size_ == front.size()) {
+      front_written_size_ = 0;
+      buffer_.TakeFirst();
+    }
+  }
+  ClearIfNeeded();
+}
+
+void BufferingDataPipeWriter::Clear() {
+  handle_.reset();
+  watcher_.Cancel();
+  buffer_.clear();
+}
+
+void BufferingDataPipeWriter::ClearIfNeeded() {
+  if (!finished_)
+    return;
+
+  if (buffer_.empty())
+    Clear();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h
new file mode 100644
index 0000000..baf6792
--- /dev/null
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BufferingDataPipeWriter_h
+#define BufferingDataPipeWriter_h
+
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "platform/PlatformExport.h"
+#include "platform/WebTaskRunner.h"
+#include "platform/wtf/Deque.h"
+#include "platform/wtf/Vector.h"
+
+namespace blink {
+
+// A writer to a mojo data pipe which has a buffer to store contents. As a
+// result, it is possible for a caller to miss write failures.
+class PLATFORM_EXPORT BufferingDataPipeWriter {
+ public:
+  BufferingDataPipeWriter(mojo::ScopedDataPipeProducerHandle, WebTaskRunner*);
+
+  // Writes buffer[0:num_bytes] to the data pipe. Returns true if there is no
+  // error.
+  bool Write(const char* buffer, uint32_t num_bytes);
+
+  // Finishes writing. After calling this function, Write must not be called.
+  void Finish();
+
+ private:
+  void OnWritable(MojoResult);
+  void ClearIfNeeded();
+  void Clear();
+
+  mojo::ScopedDataPipeProducerHandle handle_;
+  mojo::SimpleWatcher watcher_;
+  Deque<Vector<char>> buffer_;
+  size_t front_written_size_ = 0;
+  bool waiting_ = false;
+  bool finished_ = false;
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp
new file mode 100644
index 0000000..f83ab92
--- /dev/null
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp
@@ -0,0 +1,79 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/loader/fetch/BufferingDataPipeWriter.h"
+
+#include <memory>
+#include <random>
+
+#include "platform/testing/TestingPlatformSupport.h"
+#include "platform/wtf/PtrUtil.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+namespace {
+
+TEST(BufferingDataPipeWriterTest, WriteMany) {
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
+  constexpr int kCapacity = 4096;
+
+  std::minstd_rand engine(99);
+
+  mojo::ScopedDataPipeProducerHandle producer;
+  mojo::ScopedDataPipeConsumerHandle consumer;
+  MojoCreateDataPipeOptions options;
+  options.struct_size = sizeof(MojoCreateDataPipeOptions);
+  options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
+  options.element_num_bytes = 1;
+  options.capacity_num_bytes = kCapacity;
+
+  MojoResult result = mojo::CreateDataPipe(&options, &producer, &consumer);
+  ASSERT_EQ(MOJO_RESULT_OK, result);
+
+  constexpr size_t total = kCapacity * 3;
+  constexpr size_t writing_chunk_size = 5;
+  constexpr size_t reading_chunk_size = 7;
+  Vector<char> input, output;
+
+  for (size_t i = 0; i < total; ++i)
+    input.push_back(static_cast<char>(engine() % 26 + 'A'));
+
+  auto writer = WTF::MakeUnique<BufferingDataPipeWriter>(
+      std::move(producer), platform->CurrentThread()->GetWebTaskRunner());
+
+  for (size_t i = 0; i < total;) {
+    // We use a temporary buffer to check that the buffer is copied immediately.
+    char temp[writing_chunk_size] = {};
+    size_t size = std::min(total - i, writing_chunk_size);
+
+    std::copy(input.data() + i, input.data() + i + size, temp);
+    ASSERT_TRUE(writer->Write(temp, size));
+
+    i += size;
+  }
+
+  writer->Finish();
+
+  while (true) {
+    constexpr auto kNone = MOJO_READ_DATA_FLAG_NONE;
+    char buffer[reading_chunk_size] = {};
+    uint32_t size = reading_chunk_size;
+    result = mojo::ReadDataRaw(consumer.get(), buffer, &size, kNone);
+
+    if (result == MOJO_RESULT_SHOULD_WAIT) {
+      platform->RunUntilIdle();
+      continue;
+    }
+    if (result == MOJO_RESULT_FAILED_PRECONDITION)
+      break;
+
+    ASSERT_EQ(MOJO_RESULT_OK, result);
+    output.Append(buffer, size);
+  }
+  EXPECT_EQ(output, input);
+}
+
+}  // namespace
+}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
index 446beb2..f8b5533 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
@@ -148,10 +148,10 @@
     client->ResponseReceived(this, GetResponse(), nullptr);
   if (!HasClient(c))
     return;
-  if (Data()) {
-    Data()->ForEachSegment([this, &client](const char* segment,
-                                           size_t segment_size,
-                                           size_t segment_offset) -> bool {
+  if (RefPtr<SharedBuffer> data = Data()) {
+    data->ForEachSegment([this, &client](const char* segment,
+                                         size_t segment_size,
+                                         size_t segment_offset) -> bool {
       client->DataReceived(this, segment, segment_size);
 
       // Stop pushing data if the client removed itself.
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
index 542a75f..37ec1fb 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -169,6 +169,8 @@
   DCHECK(GetMainThreadOnly().was_shutdown);
 }
 
+#define TASK_DURATION_METRIC_NAME "RendererScheduler.TaskDurationPerQueueType2"
+
 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
     RendererSchedulerImpl* renderer_scheduler_impl,
     const scoped_refptr<TaskQueue>& compositor_task_runner,
@@ -221,22 +223,19 @@
       background_status_changed_at(now),
       rail_mode_observer(nullptr),
       wake_up_budget_pool(nullptr),
-      task_duration_reporter("RendererScheduler.TaskDurationPerQueueType2"),
-      foreground_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType2.Foreground"),
-      background_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType2.Background"),
-      background_first_minute_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType2.Background.FirstMinute"),
+      task_duration_reporter(TASK_DURATION_METRIC_NAME),
+      foreground_task_duration_reporter(TASK_DURATION_METRIC_NAME
+                                        ".Foreground"),
+      background_task_duration_reporter(TASK_DURATION_METRIC_NAME
+                                        ".Background"),
+      background_first_minute_task_duration_reporter(TASK_DURATION_METRIC_NAME
+                                                     ".Background.FirstMinute"),
       background_after_first_minute_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType2.Background."
-          "AfterFirstMinute"),
-      hidden_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType2.Hidden"),
-      visible_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType.Visible"),
-      hidden_music_task_duration_reporter(
-          "RendererScheduler.TaskDurationPerQueueType.HiddenMusic") {
+          TASK_DURATION_METRIC_NAME ".Background.AfterFirstMinute"),
+      hidden_task_duration_reporter(TASK_DURATION_METRIC_NAME ".Hidden"),
+      visible_task_duration_reporter(TASK_DURATION_METRIC_NAME ".Visible"),
+      hidden_music_task_duration_reporter(TASK_DURATION_METRIC_NAME
+                                          ".HiddenMusic") {
   foreground_main_thread_load_tracker.Resume(now);
 }
 
diff --git a/third_party/WebKit/public/platform/WebFeature.h b/third_party/WebKit/public/platform/WebFeature.h
index 1fc23fd1..33495d7 100644
--- a/third_party/WebKit/public/platform/WebFeature.h
+++ b/third_party/WebKit/public/platform/WebFeature.h
@@ -1561,6 +1561,9 @@
   kDocumentDomainSetWithDefaultPort = 2026,
   kFeaturePolicyHeader = 2027,
   kFeaturePolicyAllowAttribute = 2028,
+  kMIDIPortOpen = 2029,
+  kMIDIOutputSend = 2030,
+  kMIDIMessageEvent = 2031,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/boringssl/err_data.c b/third_party/boringssl/err_data.c
index d476d95..44c1882c 100644
--- a/third_party/boringssl/err_data.c
+++ b/third_party/boringssl/err_data.c
@@ -184,43 +184,43 @@
     0x28340c5e,
     0x283480ac,
     0x283500ea,
-    0x2c322c00,
+    0x2c322c26,
     0x2c329283,
-    0x2c332c0e,
-    0x2c33ac20,
-    0x2c342c34,
-    0x2c34ac46,
-    0x2c352c61,
-    0x2c35ac73,
-    0x2c362c86,
+    0x2c332c34,
+    0x2c33ac46,
+    0x2c342c5a,
+    0x2c34ac6c,
+    0x2c352c87,
+    0x2c35ac99,
+    0x2c362cac,
     0x2c36832d,
-    0x2c372c93,
-    0x2c37aca5,
-    0x2c382cca,
-    0x2c38ace1,
-    0x2c392cef,
-    0x2c39acff,
-    0x2c3a2d11,
-    0x2c3aad25,
-    0x2c3b2d36,
-    0x2c3bad55,
+    0x2c372cb9,
+    0x2c37accb,
+    0x2c382cf0,
+    0x2c38ad07,
+    0x2c392d15,
+    0x2c39ad25,
+    0x2c3a2d37,
+    0x2c3aad4b,
+    0x2c3b2d5c,
+    0x2c3bad7b,
     0x2c3c1295,
     0x2c3c92ab,
-    0x2c3d2d69,
+    0x2c3d2d8f,
     0x2c3d92c4,
-    0x2c3e2d86,
-    0x2c3ead94,
-    0x2c3f2dac,
-    0x2c3fadc4,
-    0x2c402dd1,
+    0x2c3e2dac,
+    0x2c3eadba,
+    0x2c3f2dd2,
+    0x2c3fadea,
+    0x2c402df7,
     0x2c409196,
-    0x2c412de2,
-    0x2c41adf5,
+    0x2c412e08,
+    0x2c41ae1b,
     0x2c42116f,
-    0x2c42ae06,
+    0x2c42ae2c,
     0x2c430720,
-    0x2c43ad47,
-    0x2c442cb8,
+    0x2c43ad6d,
+    0x2c442cde,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -353,219 +353,220 @@
     0x3c410d13,
     0x3c418d52,
     0x3c420e4f,
-    0x4032187e,
-    0x40329894,
-    0x403318c2,
-    0x403398cc,
-    0x403418e3,
-    0x40349901,
-    0x40351911,
-    0x40359923,
-    0x40361930,
-    0x4036993c,
-    0x40371951,
-    0x40379963,
-    0x4038196e,
-    0x40389980,
+    0x403218a4,
+    0x403298ba,
+    0x403318e8,
+    0x403398f2,
+    0x40341909,
+    0x40349927,
+    0x40351937,
+    0x40359949,
+    0x40361956,
+    0x40369962,
+    0x40371977,
+    0x40379989,
+    0x40381994,
+    0x403899a6,
     0x40390eed,
-    0x40399990,
-    0x403a19a3,
-    0x403a99c4,
-    0x403b19d5,
-    0x403b99e5,
+    0x403999b6,
+    0x403a19c9,
+    0x403a99ea,
+    0x403b19fb,
+    0x403b9a0b,
     0x403c0064,
     0x403c8083,
-    0x403d1a69,
-    0x403d9a7f,
-    0x403e1a8e,
-    0x403e9ac6,
-    0x403f1ae0,
-    0x403f9aee,
-    0x40401b03,
-    0x40409b30,
-    0x40411b4d,
-    0x40419b68,
-    0x40421b81,
-    0x40429b94,
-    0x40431ba8,
-    0x40439bc0,
-    0x40441bd7,
+    0x403d1a8f,
+    0x403d9aa5,
+    0x403e1ab4,
+    0x403e9aec,
+    0x403f1b06,
+    0x403f9b14,
+    0x40401b29,
+    0x40409b56,
+    0x40411b73,
+    0x40419b8e,
+    0x40421ba7,
+    0x40429bba,
+    0x40431bce,
+    0x40439be6,
+    0x40441bfd,
     0x404480ac,
-    0x40451bec,
-    0x40459bfe,
-    0x40461c22,
-    0x40469c42,
-    0x40471c50,
-    0x40479c77,
-    0x40481cb4,
-    0x40489ccd,
-    0x40491ce4,
-    0x40499cfe,
-    0x404a1d15,
-    0x404a9d33,
-    0x404b1d4b,
-    0x404b9d62,
-    0x404c1d78,
-    0x404c9d8a,
-    0x404d1dab,
-    0x404d9dcd,
-    0x404e1de1,
-    0x404e9dee,
-    0x404f1e1b,
-    0x404f9e44,
-    0x40501e7f,
-    0x40509e93,
-    0x40511eae,
-    0x40521ebe,
-    0x40529ee2,
-    0x40531efa,
-    0x40539f0d,
-    0x40541f22,
-    0x40549f45,
-    0x40551f53,
-    0x40559f70,
-    0x40561f7d,
-    0x40569f96,
-    0x40571fae,
-    0x40579fc1,
-    0x40581fd6,
-    0x40589ffd,
-    0x4059202c,
-    0x4059a059,
-    0x405a206d,
-    0x405aa07d,
-    0x405b2095,
-    0x405ba0a6,
-    0x405c20b9,
-    0x405ca0f8,
-    0x405d2105,
-    0x405da11c,
-    0x405e215a,
+    0x40451c12,
+    0x40459c24,
+    0x40461c48,
+    0x40469c68,
+    0x40471c76,
+    0x40479c9d,
+    0x40481cda,
+    0x40489cf3,
+    0x40491d0a,
+    0x40499d24,
+    0x404a1d3b,
+    0x404a9d59,
+    0x404b1d71,
+    0x404b9d88,
+    0x404c1d9e,
+    0x404c9db0,
+    0x404d1dd1,
+    0x404d9df3,
+    0x404e1e07,
+    0x404e9e14,
+    0x404f1e41,
+    0x404f9e6a,
+    0x40501ea5,
+    0x40509eb9,
+    0x40511ed4,
+    0x40521ee4,
+    0x40529f08,
+    0x40531f20,
+    0x40539f33,
+    0x40541f48,
+    0x40549f6b,
+    0x40551f79,
+    0x40559f96,
+    0x40561fa3,
+    0x40569fbc,
+    0x40571fd4,
+    0x40579fe7,
+    0x40581ffc,
+    0x4058a023,
+    0x40592052,
+    0x4059a07f,
+    0x405a2093,
+    0x405aa0a3,
+    0x405b20bb,
+    0x405ba0cc,
+    0x405c20df,
+    0x405ca11e,
+    0x405d212b,
+    0x405da142,
+    0x405e2180,
     0x405e8ab1,
-    0x405f217b,
-    0x405fa188,
-    0x40602196,
-    0x4060a1b8,
-    0x406121fc,
-    0x4061a234,
-    0x4062224b,
-    0x4062a25c,
-    0x4063226d,
-    0x4063a282,
-    0x40642299,
-    0x4064a2c5,
-    0x406522e0,
-    0x4065a2f7,
-    0x4066230f,
-    0x4066a339,
-    0x40672364,
-    0x4067a385,
-    0x406823ac,
-    0x4068a3cd,
-    0x406923ff,
-    0x4069a42d,
-    0x406a244e,
-    0x406aa46e,
-    0x406b25f6,
-    0x406ba619,
-    0x406c262f,
-    0x406ca8aa,
-    0x406d28d9,
-    0x406da901,
-    0x406e292f,
-    0x406ea963,
-    0x406f2982,
-    0x406fa997,
-    0x407029aa,
-    0x4070a9c7,
+    0x405f21a1,
+    0x405fa1ae,
+    0x406021bc,
+    0x4060a1de,
+    0x40612222,
+    0x4061a25a,
+    0x40622271,
+    0x4062a282,
+    0x40632293,
+    0x4063a2a8,
+    0x406422bf,
+    0x4064a2eb,
+    0x40652306,
+    0x4065a31d,
+    0x40662335,
+    0x4066a35f,
+    0x4067238a,
+    0x4067a3ab,
+    0x406823d2,
+    0x4068a3f3,
+    0x40692425,
+    0x4069a453,
+    0x406a2474,
+    0x406aa494,
+    0x406b261c,
+    0x406ba63f,
+    0x406c2655,
+    0x406ca8d0,
+    0x406d28ff,
+    0x406da927,
+    0x406e2955,
+    0x406ea9a2,
+    0x406f29c1,
+    0x406fa9d6,
+    0x407029e9,
+    0x4070aa06,
     0x40710800,
-    0x4071a9d9,
-    0x407229ec,
-    0x4072aa05,
-    0x40732a1d,
+    0x4071aa18,
+    0x40722a2b,
+    0x4072aa44,
+    0x40732a5c,
     0x40739482,
-    0x40742a31,
-    0x4074aa4b,
-    0x40752a5c,
-    0x4075aa70,
-    0x40762a7e,
+    0x40742a70,
+    0x4074aa8a,
+    0x40752a9b,
+    0x4075aaaf,
+    0x40762abd,
     0x40769259,
-    0x40772aa3,
-    0x4077aac5,
-    0x40782ae0,
-    0x4078ab19,
-    0x40792b30,
-    0x4079ab46,
-    0x407a2b52,
-    0x407aab65,
-    0x407b2b7a,
-    0x407bab8c,
-    0x407c2bbd,
-    0x407cabc6,
-    0x407d23e8,
-    0x407d9e54,
-    0x407e2af5,
-    0x407ea00d,
-    0x407f1c64,
-    0x407f9a0b,
-    0x40801e2b,
-    0x40809c8c,
-    0x40811ed0,
-    0x40819e05,
-    0x4082291a,
-    0x408299f1,
-    0x40831fe8,
-    0x4083a2aa,
-    0x40841ca0,
-    0x4084a045,
-    0x408520ca,
-    0x4085a1e0,
-    0x4086213c,
-    0x40869e6e,
-    0x40872947,
-    0x4087a211,
-    0x40881a52,
-    0x4088a398,
-    0x40891aa1,
-    0x40899a2e,
-    0x408a264f,
+    0x40772ae2,
+    0x4077ab04,
+    0x40782b1f,
+    0x4078ab58,
+    0x40792b6f,
+    0x4079ab85,
+    0x407a2b91,
+    0x407aaba4,
+    0x407b2bb9,
+    0x407babcb,
+    0x407c2bfc,
+    0x407cac05,
+    0x407d240e,
+    0x407d9e7a,
+    0x407e2b34,
+    0x407ea033,
+    0x407f1c8a,
+    0x407f9a31,
+    0x40801e51,
+    0x40809cb2,
+    0x40811ef6,
+    0x40819e2b,
+    0x40822940,
+    0x40829a17,
+    0x4083200e,
+    0x4083a2d0,
+    0x40841cc6,
+    0x4084a06b,
+    0x408520f0,
+    0x4085a206,
+    0x40862162,
+    0x40869e94,
+    0x40872986,
+    0x4087a237,
+    0x40881a78,
+    0x4088a3be,
+    0x40891ac7,
+    0x40899a54,
+    0x408a2675,
     0x408a9862,
-    0x408b2ba1,
-    0x408b9b17,
-    0x408c20da,
-    0x41f42521,
-    0x41f925b3,
-    0x41fe24a6,
-    0x41fea69b,
-    0x41ff278c,
-    0x4203253a,
-    0x4208255c,
-    0x4208a598,
-    0x4209248a,
-    0x4209a5d2,
-    0x420a24e1,
-    0x420aa4c1,
-    0x420b2501,
-    0x420ba57a,
-    0x420c27a8,
-    0x420ca668,
-    0x420d2682,
-    0x420da6b9,
-    0x421226d3,
-    0x4217276f,
-    0x4217a715,
-    0x421c2737,
-    0x421f26f2,
-    0x422127bf,
-    0x42262752,
-    0x422b288e,
-    0x422ba83c,
-    0x422c2876,
-    0x422ca7fb,
-    0x422d27da,
-    0x422da85b,
-    0x422e2821,
-    0x422eabe7,
+    0x408b2be0,
+    0x408b9b3d,
+    0x408c2100,
+    0x408c987e,
+    0x41f42547,
+    0x41f925d9,
+    0x41fe24cc,
+    0x41fea6c1,
+    0x41ff27b2,
+    0x42032560,
+    0x42082582,
+    0x4208a5be,
+    0x420924b0,
+    0x4209a5f8,
+    0x420a2507,
+    0x420aa4e7,
+    0x420b2527,
+    0x420ba5a0,
+    0x420c27ce,
+    0x420ca68e,
+    0x420d26a8,
+    0x420da6df,
+    0x421226f9,
+    0x42172795,
+    0x4217a73b,
+    0x421c275d,
+    0x421f2718,
+    0x422127e5,
+    0x42262778,
+    0x422b28b4,
+    0x422ba862,
+    0x422c289c,
+    0x422ca821,
+    0x422d2800,
+    0x422da881,
+    0x422e2847,
+    0x422ea96d,
     0x4432072b,
     0x4432873a,
     0x44330746,
@@ -618,69 +619,69 @@
     0x4c4014a7,
     0x4c4092d5,
     0x4c4114cb,
-    0x50322e18,
-    0x5032ae27,
-    0x50332e32,
-    0x5033ae42,
-    0x50342e5b,
-    0x5034ae75,
-    0x50352e83,
-    0x5035ae99,
-    0x50362eab,
-    0x5036aec1,
-    0x50372eda,
-    0x5037aeed,
-    0x50382f05,
-    0x5038af16,
-    0x50392f2b,
-    0x5039af3f,
-    0x503a2f5f,
-    0x503aaf75,
-    0x503b2f8d,
-    0x503baf9f,
-    0x503c2fbb,
-    0x503cafd2,
-    0x503d2feb,
-    0x503db001,
-    0x503e300e,
-    0x503eb024,
-    0x503f3036,
+    0x50322e3e,
+    0x5032ae4d,
+    0x50332e58,
+    0x5033ae68,
+    0x50342e81,
+    0x5034ae9b,
+    0x50352ea9,
+    0x5035aebf,
+    0x50362ed1,
+    0x5036aee7,
+    0x50372f00,
+    0x5037af13,
+    0x50382f2b,
+    0x5038af3c,
+    0x50392f51,
+    0x5039af65,
+    0x503a2f85,
+    0x503aaf9b,
+    0x503b2fb3,
+    0x503bafc5,
+    0x503c2fe1,
+    0x503caff8,
+    0x503d3011,
+    0x503db027,
+    0x503e3034,
+    0x503eb04a,
+    0x503f305c,
     0x503f8382,
-    0x50403049,
-    0x5040b059,
-    0x50413073,
-    0x5041b082,
-    0x5042309c,
-    0x5042b0b9,
-    0x504330c9,
-    0x5043b0d9,
-    0x504430e8,
+    0x5040306f,
+    0x5040b07f,
+    0x50413099,
+    0x5041b0a8,
+    0x504230c2,
+    0x5042b0df,
+    0x504330ef,
+    0x5043b0ff,
+    0x5044310e,
     0x5044843f,
-    0x504530fc,
-    0x5045b11a,
-    0x5046312d,
-    0x5046b143,
-    0x50473155,
-    0x5047b16a,
-    0x50483190,
-    0x5048b19e,
-    0x504931b1,
-    0x5049b1c6,
-    0x504a31dc,
-    0x504ab1ec,
-    0x504b320c,
-    0x504bb21f,
-    0x504c3242,
-    0x504cb270,
-    0x504d3282,
-    0x504db29f,
-    0x504e32ba,
-    0x504eb2d6,
-    0x504f32e8,
-    0x504fb2ff,
-    0x5050330e,
+    0x50453122,
+    0x5045b140,
+    0x50463153,
+    0x5046b169,
+    0x5047317b,
+    0x5047b190,
+    0x504831b6,
+    0x5048b1c4,
+    0x504931d7,
+    0x5049b1ec,
+    0x504a3202,
+    0x504ab212,
+    0x504b3232,
+    0x504bb245,
+    0x504c3268,
+    0x504cb296,
+    0x504d32a8,
+    0x504db2c5,
+    0x504e32e0,
+    0x504eb2fc,
+    0x504f330e,
+    0x504fb325,
+    0x50503334,
     0x505086ef,
-    0x50513321,
+    0x50513347,
     0x58320f2b,
     0x68320eed,
     0x68328c6a,
@@ -1043,6 +1044,7 @@
     "VALUE_MISSING\0"
     "WRONG_SIGNATURE_LENGTH\0"
     "ALPN_MISMATCH_ON_EARLY_DATA\0"
+    "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\0"
     "APP_DATA_IN_HANDSHAKE\0"
     "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\0"
     "BAD_ALERT\0"
@@ -1217,6 +1219,7 @@
     "TOO_MANY_EMPTY_FRAGMENTS\0"
     "TOO_MANY_KEY_UPDATES\0"
     "TOO_MANY_WARNING_ALERTS\0"
+    "TOO_MUCH_READ_EARLY_DATA\0"
     "TOO_MUCH_SKIPPED_EARLY_DATA\0"
     "UNABLE_TO_FIND_ECDH_PARAMETERS\0"
     "UNEXPECTED_EXTENSION\0"
@@ -1246,7 +1249,6 @@
     "WRONG_VERSION_ON_EARLY_DATA\0"
     "X509_LIB\0"
     "X509_VERIFICATION_SETUP_PROBLEMS\0"
-    "TOO_MUCH_READ_EARLY_DATA\0"
     "AKID_MISMATCH\0"
     "BAD_X509_FILETYPE\0"
     "BASE64_DECODE_ERROR\0"
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 927af53a..afd63ffe 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -15539,6 +15539,9 @@
   <int value="2026" label="DocumentDomainSetWithDefaultPort"/>
   <int value="2027" label="FeaturePolicyHeader"/>
   <int value="2028" label="FeaturePolicyAllowAttribute"/>
+  <int value="2029" label="MIDIPortOpen"/>
+  <int value="2030" label="MIDIOutputSend"/>
+  <int value="2031" label="MIDIMessageEvent"/>
 </enum>
 
 <enum name="FeedbackSource">
@@ -22021,7 +22024,7 @@
 from previous Chrome versions.
 -->
 
-  <summary>Chrome flags that lead to Chrome restart on Chrome OS.</summary>
+  <summary>Chrome flags that lead to chrome restart on ChromeOS.</summary>
   <int value="-2146613579" label="V8Future:disabled"/>
   <int value="-2143961262" label="D3DVsync:disabled"/>
   <int value="-2143328006"
@@ -22070,7 +22073,6 @@
   <int value="-2035126988" label="enabled-new-style-notification"/>
   <int value="-2033225430" label="NTPMostLikelyFaviconsFromServer:disabled"/>
   <int value="-2029912304" label="StaleWhileRevalidate2:enabled"/>
-  <int value="-2028232016" label="spurious-power-button-lid-angle-change"/>
   <int value="-2025367104" label="enable-material-design-ntp"/>
   <int value="-2020721975" label="smart-virtual-keyboard"/>
   <int value="-2020024440" label="scroll-end-effect"/>
@@ -22134,7 +22136,6 @@
   <int value="-1872867546" label="EnumerateAudioDevices:disabled"/>
   <int value="-1870961970" label="enable-filemanager-mtp"/>
   <int value="-1869845022" label="force-show-update-menu-item"/>
-  <int value="-1868978829" label="spurious-power-button-accel-count"/>
   <int value="-1867382602" label="WebRTC-H264WithOpenH264FFmpeg:enabled"/>
   <int value="-1867342522" label="MaterialDesignHistory:enabled"/>
   <int value="-1861814223" label="MidiManagerDynamicInstantiation:enabled"/>
@@ -22991,7 +22992,6 @@
   <int value="1211284676" label="V8NoTurbo:enabled"/>
   <int value="1214455758" label="VideoRotateToFullscreen:disabled"/>
   <int value="1215531732" label="OmniboxUIExperiments:disabled"/>
-  <int value="1217907443" label="spurious-power-button-keyboard-accel"/>
   <int value="1219628795" label="PrintScaling:disabled"/>
   <int value="1219826373" label="ServiceWorkerNavigationPreload:enabled"/>
   <int value="1220171692" label="SpeculativeLaunchServiceWorker:enabled"/>
@@ -23007,7 +23007,6 @@
   <int value="1250071868" label="disable-timezone-tracking-option"/>
   <int value="1253698118" label="ash-disable-stable-overview-order"/>
   <int value="1257980502" label="disable-accelerated-video-decode"/>
-  <int value="1260186484" label="spurious-power-button-screen-accel"/>
   <int value="1268470658" label="disable-android-password-link"/>
   <int value="1269940659" label="EnumerateAudioDevices:enabled"/>
   <int value="1269952439" label="AndroidAIAFetching:disabled"/>
@@ -23121,7 +23120,6 @@
   <int value="1658644418" label="disable-app-list-voice-search"/>
   <int value="1661925474" label="silent-debugger-extension-api"/>
   <int value="1664401033" label="ColorCorrectRendering:enabled"/>
-  <int value="1665349789" label="spurious-power-button-window"/>
   <int value="1668611601" label="enable-encrypted-media"/>
   <int value="1673427566" label="ChromeHomeExpandButton:disabled"/>
   <int value="1689123607" label="enable-app-link"/>
@@ -24840,6 +24838,13 @@
   <int value="3" label="Generic initialization error"/>
 </enum>
 
+<enum name="MidiSendReceiveUsage">
+  <int value="0" label="No transaction"/>
+  <int value="1" label="Sent"/>
+  <int value="2" label="Received"/>
+  <int value="3" label="Sent and received"/>
+</enum>
+
 <enum name="MidiUsage">
   <int value="0" label="Instantiated"/>
   <int value="1" label="Instantiated on unsupported platforms"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 1da648b..8adc0209 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -29564,6 +29564,16 @@
   <summary>The final status of MidiManager on browser shutdown.</summary>
 </histogram>
 
+<histogram name="Media.Midi.SendReceiveUsage" enum="MidiSendReceiveUsage">
+  <owner>toyoshim@chromium.org</owner>
+  <summary>
+    Reports whether any data was sent or received by a MidiManager. Recorded
+    once per MidiManager instantiation, upon destruction. MidiManager is
+    instantiated when the first Web MIDI client starts a session, and destroyed
+    when the last client ends the session.
+  </summary>
+</histogram>
+
 <histogram name="Media.Midi.SysExMessageSizeUpTo1MB" units="bytes">
   <owner>toyoshim@chromium.org</owner>
   <summary>Reports sysex message size.</summary>
diff --git a/tools/perf/page_sets/webrtc_cases.py b/tools/perf/page_sets/webrtc_cases.py
index 582dc53..9f2a3ef8 100644
--- a/tools/perf/page_sets/webrtc_cases.py
+++ b/tools/perf/page_sets/webrtc_cases.py
@@ -51,12 +51,12 @@
 
 
 class DataChannel(WebrtcPage):
-  """Why: Transfer as much data as possible through a data channel in 20s."""
+  """Why: Transfer as much data as possible through a data channel in 15s."""
 
   def __init__(self, page_set, tags):
     super(DataChannel, self).__init__(
         url='file://webrtc_cases/datatransfer.html',
-        name='30s_datachannel_transfer',
+        name='15s_datachannel_transfer',
         page_set=page_set, tags=tags)
 
   def RunPageInteractions(self, action_runner):
@@ -64,7 +64,7 @@
     # cpu + memory anyway rather than how much data we manage to transfer.
     action_runner.ExecuteJavaScript('megsToSend.value = 512;')
     action_runner.ClickElement('button[id="sendTheData"]')
-    action_runner.Wait(30)
+    action_runner.Wait(15)
 
 
 class AudioCall(WebrtcPage):
@@ -152,7 +152,3 @@
     self.DisableStory('audio_call_isac/1600_10s',
                       [story.expectations.ALL],
                       'crbug.com/468732')
-
-    self.DisableStory('30s_datachannel_transfer',
-                      [story.expectations.ALL_DESKTOP],
-                      'crbug.com/726811')
diff --git a/tools/roll_swiftshader.py b/tools/roll_swiftshader.py
index 8e23b82e..78e2844 100755
--- a/tools/roll_swiftshader.py
+++ b/tools/roll_swiftshader.py
@@ -23,7 +23,8 @@
   },
   {
     "mastername": "master.tryserver.chromium.linux",
-    "buildernames": ["linux_optional_gpu_tests_rel"]
+    "buildernames": ["linux_optional_gpu_tests_rel",
+                     "linux_chromium_cfi_rel_ng"]
   },
   {
     "mastername": "master.tryserver.chromium.android",
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
index cc452512..fb9c3b6 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -172,18 +172,29 @@
                          const base::FilePath& build_path,
                          const base::CommandLine::StringVector& path_filters,
                          const bool full_run) {
-  base::CommandLine cmdline(source_path.Append(FILE_PATH_LITERAL("tools"))
-                                .Append(FILE_PATH_LITERAL("clang"))
-                                .Append(FILE_PATH_LITERAL("scripts"))
-                                .Append(FILE_PATH_LITERAL("run_tool.py")));
-  cmdline.AppendSwitch("generate-compdb");
-  cmdline.AppendSwitch("tool=traffic_annotation_extractor");
-  cmdline.AppendArg(
-      base::StringPrintf("-p=%s", build_path.MaybeAsASCII().c_str()));
+  base::FilePath options_filepath;
+  if (!base::CreateTemporaryFile(&options_filepath)) {
+    LOG(ERROR) << "Could not create temporary options file.";
+    return std::string();
+  }
+  FILE* options_file = base::OpenFile(options_filepath, "wt");
+  if (!options_file) {
+    LOG(ERROR) << "Could not create temporary options file.";
+    return std::string();
+  }
+  fprintf(options_file,
+          "--generate-compdb --tool=traffic_annotation_extractor -p=%s ",
+          build_path.MaybeAsASCII().c_str());
 
   if (full_run) {
-    for (const auto& path : path_filters)
-      cmdline.AppendArgNative(path);
+    for (const auto& file_path : path_filters)
+      fprintf(options_file, "%s ",
+#if defined(OS_WIN)
+              base::WideToUTF8(file_path).c_str()
+#else
+              file_path.c_str()
+#endif
+                  );
   } else {
     TrafficAnnotationFileFilter filter;
     std::vector<std::string> file_paths;
@@ -202,18 +213,35 @@
       filter.GetRelevantFiles(source_path, "", &file_paths);
     }
 
-    if (!file_paths.size())
-      return "";
+    if (!file_paths.size()) {
+      base::CloseFile(options_file);
+      base::DeleteFile(options_filepath, false);
+      return std::string();
+    }
     for (const auto& file_path : file_paths)
-      cmdline.AppendArg(file_path);
+      fprintf(options_file, "%s ", file_path.c_str());
   }
+  base::CloseFile(options_file);
+
+  base::CommandLine cmdline(source_path.Append(FILE_PATH_LITERAL("tools"))
+                                .Append(FILE_PATH_LITERAL("clang"))
+                                .Append(FILE_PATH_LITERAL("scripts"))
+                                .Append(FILE_PATH_LITERAL("run_tool.py")));
 
 #if defined(OS_WIN)
   cmdline.PrependWrapper(L"python");
 #endif
 
+  cmdline.AppendArg(base::StringPrintf(
+      "--options-file=%s", options_filepath.MaybeAsASCII().c_str()));
+
   std::string results;
-  return base::GetAppOutput(cmdline, &results) ? results : "";
+  if (!base::GetAppOutput(cmdline, &results))
+    results = std::string();
+
+  base::DeleteFile(options_filepath, false);
+
+  return results;
 }
 
 bool ParseClangToolRawOutput(const std::string& clang_output,