diff --git a/DEPS b/DEPS
index bc855e6d..61c9656c 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   # 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': '304f9d4e0feb4665d88804c3a4c28b6397c377b0',
+  'skia_revision': 'ee93e7803ac23beaed838834948091b0062465aa',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '5e929b82e0be688c1569cb0788212ef865001852',
+  'catapult_revision': '37015fb470d81b7a96a091127590e6e461705059',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/chrome/browser/chromeos/login/screens/update_screen.cc b/chrome/browser/chromeos/login/screens/update_screen.cc
index 96a797e..e1be9461 100644
--- a/chrome/browser/chromeos/login/screens/update_screen.cc
+++ b/chrome/browser/chromeos/login/screens/update_screen.cc
@@ -197,6 +197,7 @@
         case UpdateEngineClient::UPDATE_STATUS_DOWNLOADING:
         case UpdateEngineClient::UPDATE_STATUS_FINALIZING:
         case UpdateEngineClient::UPDATE_STATUS_VERIFYING:
+        case UpdateEngineClient::UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE:
           DCHECK(!HasCriticalUpdate());
         // Noncritical update, just exit screen as if there is no update.
         // no break
@@ -330,6 +331,7 @@
       // else no break
     case UpdateEngineClient::UPDATE_STATUS_ERROR:
     case UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT:
+    case UpdateEngineClient::UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE:
       ExitUpdate(REASON_UPDATE_ENDED);
       break;
     default:
diff --git a/chrome/browser/extensions/api/system_private/system_private_api.cc b/chrome/browser/extensions/api/system_private/system_private_api.cc
index 997e83e..730d1de 100644
--- a/chrome/browser/extensions/api/system_private/system_private_api.cc
+++ b/chrome/browser/extensions/api/system_private/system_private_api.cc
@@ -126,6 +126,7 @@
       break;
     case chromeos::UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT:
     case chromeos::UpdateEngineClient::UPDATE_STATUS_ATTEMPTING_ROLLBACK:
+    case chromeos::UpdateEngineClient::UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE:
       state = kNotAvailableState;
       break;
   }
diff --git a/chromeos/dbus/fake_update_engine_client.cc b/chromeos/dbus/fake_update_engine_client.cc
index 9e89f1ed..e6df858 100644
--- a/chromeos/dbus/fake_update_engine_client.cc
+++ b/chromeos/dbus/fake_update_engine_client.cc
@@ -93,6 +93,11 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
 }
 
+void FakeUpdateEngineClient::SetUpdateOverCellularTarget(
+    const std::string& target_version,
+    int64_t target_size,
+    const SetUpdateOverCellularTargetCallback& callback) {}
+
 void FakeUpdateEngineClient::set_default_status(
     const UpdateEngineClient::Status& status) {
   default_status_ = status;
diff --git a/chromeos/dbus/fake_update_engine_client.h b/chromeos/dbus/fake_update_engine_client.h
index 2d9db4cc..e23c2b34 100644
--- a/chromeos/dbus/fake_update_engine_client.h
+++ b/chromeos/dbus/fake_update_engine_client.h
@@ -38,7 +38,10 @@
   void GetEolStatus(const GetEolStatusCallback& callback) override;
   void SetUpdateOverCellularPermission(bool allowed,
                                        const base::Closure& callback) override;
-
+  void SetUpdateOverCellularTarget(
+      const std::string& target_version,
+      int64_t target_size,
+      const SetUpdateOverCellularTargetCallback& callback) override;
   // Pushes UpdateEngineClient::Status in the queue to test changing status.
   // GetLastStatus() returns the status set by this method in FIFO order.
   // See set_default_status().
diff --git a/chromeos/dbus/update_engine_client.cc b/chromeos/dbus/update_engine_client.cc
index 5cfe3976..218cd4af 100644
--- a/chromeos/dbus/update_engine_client.cc
+++ b/chromeos/dbus/update_engine_client.cc
@@ -69,6 +69,8 @@
     return UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT;
   if (str == update_engine::kUpdateStatusAttemptingRollback)
     return UpdateEngineClient::UPDATE_STATUS_ATTEMPTING_ROLLBACK;
+  if (str == update_engine::kUpdateStatusNeedPermissionToUpdate)
+    return UpdateEngineClient::UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE;
   return UpdateEngineClient::UPDATE_STATUS_ERROR;
 }
 
@@ -245,6 +247,26 @@
                    weak_ptr_factory_.GetWeakPtr(), callback));
   }
 
+  void SetUpdateOverCellularTarget(
+      const std::string& target_version,
+      int64_t target_size,
+      const SetUpdateOverCellularTargetCallback& callback) override {
+    dbus::MethodCall method_call(update_engine::kUpdateEngineInterface,
+                                 update_engine::kSetUpdateOverCellularTarget);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(target_version);
+    writer.AppendInt64(target_size);
+
+    VLOG(1) << "Requesting UpdateEngine to allow updates over cellular "
+            << "to target version: \"" << target_version << "\" "
+            << "target_size: " << target_size;
+
+    return update_engine_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&UpdateEngineClientImpl::OnSetUpdateOverCellularTarget,
+                   weak_ptr_factory_.GetWeakPtr(), callback));
+  }
+
  protected:
   void Init(dbus::Bus* bus) override {
     update_engine_proxy_ = bus->GetObjectProxy(
@@ -432,25 +454,9 @@
   // Called when a response for SetUpdateOverCellularPermission() is received.
   void OnSetUpdateOverCellularPermission(const base::Closure& callback,
                                          dbus::Response* response) {
-    constexpr char kFailureMessage[] =
-        "Failed to set UpdateEngine to allow updates over cellular: ";
-
-    if (response) {
-      switch (response->GetMessageType()) {
-        case dbus::Message::MESSAGE_ERROR:
-          LOG(ERROR) << kFailureMessage
-                     << "DBus responded with error: " << response->ToString();
-          break;
-        case dbus::Message::MESSAGE_INVALID:
-          LOG(ERROR) << kFailureMessage
-                     << "Invalid response from DBus (cannot be parsed).";
-          break;
-        default:
-          VLOG(1) << "Successfully set UpdateEngine to allow update over cell.";
-          break;
-      }
-    } else {
-      LOG(ERROR) << kFailureMessage << "No response from DBus.";
+    if (!response) {
+      LOG(ERROR) << update_engine::kSetUpdateOverCellularPermission
+                 << " call failed";
     }
 
     // Callback should run anyway, regardless of whether DBus call to enable
@@ -458,6 +464,19 @@
     callback.Run();
   }
 
+  // Called when a response for SetUpdateOverCellularPermission() is received.
+  void OnSetUpdateOverCellularTarget(
+      const SetUpdateOverCellularTargetCallback& callback,
+      dbus::Response* response) {
+    if (!response) {
+      LOG(ERROR) << update_engine::kSetUpdateOverCellularTarget
+                 << " call failed";
+      callback.Run(false);
+      return;
+    }
+    callback.Run(true);
+  }
+
   // Called when a status update signal is received.
   void StatusUpdateReceived(dbus::Signal* signal) {
     VLOG(1) << "Status update signal received: " << signal->ToString();
@@ -563,6 +582,11 @@
     callback.Run();
   }
 
+  void SetUpdateOverCellularTarget(
+      const std::string& target_version,
+      int64_t target_size,
+      const SetUpdateOverCellularTargetCallback& callback) override {}
+
   std::string current_channel_;
   std::string target_channel_;
 };
@@ -619,6 +643,7 @@
       case UPDATE_STATUS_UPDATED_NEED_REBOOT:
       case UPDATE_STATUS_REPORTING_ERROR_EVENT:
       case UPDATE_STATUS_ATTEMPTING_ROLLBACK:
+      case UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE:
         return;
       case UPDATE_STATUS_CHECKING_FOR_UPDATE:
         next_status = UPDATE_STATUS_UPDATE_AVAILABLE;
diff --git a/chromeos/dbus/update_engine_client.h b/chromeos/dbus/update_engine_client.h
index 94c89ea..5206aa6 100644
--- a/chromeos/dbus/update_engine_client.h
+++ b/chromeos/dbus/update_engine_client.h
@@ -40,7 +40,8 @@
     UPDATE_STATUS_FINALIZING,
     UPDATE_STATUS_UPDATED_NEED_REBOOT,
     UPDATE_STATUS_REPORTING_ERROR_EVENT,
-    UPDATE_STATUS_ATTEMPTING_ROLLBACK
+    UPDATE_STATUS_ATTEMPTING_ROLLBACK,
+    UPDATE_STATUS_NEED_PERMISSION_TO_UPDATE,
   };
 
   // The status of the ongoing update attempt.
@@ -84,7 +85,7 @@
 
   // Called once RequestUpdateCheck() is complete. Takes one parameter:
   // - UpdateCheckResult: the result of the update check.
-  typedef base::Callback<void(UpdateCheckResult)> UpdateCheckCallback;
+  using UpdateCheckCallback = base::Callback<void(UpdateCheckResult)>;
 
   // Requests an update check and calls |callback| when completed.
   virtual void RequestUpdateCheck(const UpdateCheckCallback& callback) = 0;
@@ -97,7 +98,7 @@
 
   // Called once CanRollbackCheck() is complete. Takes one parameter:
   // - bool: the result of the rollback availability check.
-  typedef base::Callback<void(bool can_rollback)> RollbackCheckCallback;
+  using RollbackCheckCallback = base::Callback<void(bool can_rollback)>;
 
   // Checks if Rollback is available and calls |callback| when completed.
   virtual void CanRollbackCheck(
@@ -105,8 +106,8 @@
 
   // Called once GetChannel() is complete. Takes one parameter;
   // - string: the channel name like "beta-channel".
-  typedef base::Callback<void(const std::string& channel_name)>
-      GetChannelCallback;
+  using GetChannelCallback =
+      base::Callback<void(const std::string& channel_name)>;
 
   // Returns the last status the object received from the update engine.
   //
@@ -137,8 +138,8 @@
 
   // Called once GetEolStatus() is complete. Takes one parameter;
   // - EndOfLife Status: the end of life status of the device.
-  typedef base::Callback<void(update_engine::EndOfLifeStatus status)>
-      GetEolStatusCallback;
+  using GetEolStatusCallback =
+      base::Callback<void(update_engine::EndOfLifeStatus status)>;
 
   // Get EndOfLife status of the device and calls |callback| when completed.
   virtual void GetEolStatus(const GetEolStatusCallback& callback) = 0;
@@ -149,6 +150,27 @@
       bool allowed,
       const base::Closure& callback) = 0;
 
+  // Called once SetUpdateOverCellularTarget() is complete. Takes one parameter;
+  // - success: indicates whether the target is set successfully.
+  using SetUpdateOverCellularTargetCallback =
+      base::Callback<void(bool success)>;
+
+  // Sets the target in the preferences maintained by update engine which then
+  // performs update to this given target after RequestUpdateCheck() is invoked
+  // in the |callback|.
+  // - target_version: the Chrome OS version we want to update to.
+  // - target_size: the size of that Chrome OS version in bytes.
+  // These two parameters are a failsafe to prevent downloading an update user
+  // didn't agree to. They should be set using the version and size we received
+  // from update engine when it broadcasts NEED_PERMISSION_TO_UPDATE. They are
+  // used by update engine to double-check with update server in case there's a
+  // new update available or a delta update becomes a full update with larger
+  // size.
+  virtual void SetUpdateOverCellularTarget(
+      const std::string& target_version,
+      int64_t target_size,
+      const SetUpdateOverCellularTargetCallback& callback) = 0;
+
   // Returns an empty UpdateCheckCallback that does nothing.
   static UpdateCheckCallback EmptyUpdateCheckCallback();
 
diff --git a/components/payments/content/payment_response_helper.h b/components/payments/content/payment_response_helper.h
index d4711f63..b9cf024 100644
--- a/components/payments/content/payment_response_helper.h
+++ b/components/payments/content/payment_response_helper.h
@@ -16,8 +16,6 @@
 class PaymentRequestDelegate;
 class PaymentRequestSpec;
 
-// TODO(sebsg): Asynchronously normalize the billing and shipping addresses
-// before adding them to the PaymentResponse.
 // A helper class to facilitate the creation of the PaymentResponse.
 class PaymentResponseHelper : public PaymentInstrument::Delegate,
                               public AddressNormalizer::Delegate {
diff --git a/components/payments/content/payment_response_helper_unittest.cc b/components/payments/content/payment_response_helper_unittest.cc
index 331dd8b..6279886ca 100644
--- a/components/payments/content/payment_response_helper_unittest.cc
+++ b/components/payments/content/payment_response_helper_unittest.cc
@@ -109,7 +109,6 @@
   // Default options (no shipping, no contact info).
   RecreateSpecWithOptions(mojom::PaymentOptions::New());
 
-  // TODO(mathp): Currently synchronous, when async will need a RunLoop.
   // "visa" is specified directly in the supportedMethods so it is returned
   // as the method name.
   PaymentResponseHelper helper("en-US", spec(), test_instrument(),
@@ -147,7 +146,6 @@
                                     mojom::PaymentDetails::New(),
                                     std::move(method_data));
 
-  // TODO(mathp): Currently synchronous, when async will need a RunLoop.
   // "basic-card" is specified so it is returned as the method name.
   PaymentResponseHelper helper("en-US", spec(), test_instrument(),
                                test_payment_request_delegate(), test_address(),
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index ed241731..70861541 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -819,16 +819,34 @@
 
   base::TimeDelta time_saved;
   if (bytes_downloaded_with_parallel_streams > 0) {
+    int64_t bandwidth_with_parallel_streams = CalculateBandwidthBytesPerSecond(
+        bytes_downloaded_with_parallel_streams, time_with_parallel_streams);
     RecordBandwidthMetric(
         "Download.ParallelizableDownloadBandwidth."
         "WithParallelRequestsMultipleStreams",
-        CalculateBandwidthBytesPerSecond(bytes_downloaded_with_parallel_streams,
-                                         time_with_parallel_streams));
+        bandwidth_with_parallel_streams);
     if (bandwidth_without_parallel_streams > 0) {
       time_saved = base::TimeDelta::FromMilliseconds(
                        1000.0 * bytes_downloaded_with_parallel_streams /
                        bandwidth_without_parallel_streams) -
                    time_with_parallel_streams;
+      int bandwidth_ratio_percentage =
+          (100.0 * bandwidth_with_parallel_streams) /
+          bandwidth_without_parallel_streams;
+      UMA_HISTOGRAM_CUSTOM_COUNTS(
+          "Download.ParallelDownload.BandwidthRatioPercentage",
+          bandwidth_ratio_percentage, 0, 400, 101);
+      base::TimeDelta total_time =
+          time_with_parallel_streams + time_without_parallel_streams;
+      size_t total_size = bytes_downloaded_with_parallel_streams +
+                          bytes_downloaded_without_parallel_streams;
+      base::TimeDelta non_parallel_time = base::TimeDelta::FromSecondsD(
+          static_cast<double>(total_size) / bandwidth_without_parallel_streams);
+      int time_ratio_percentage =
+          100.0 * total_time.InSecondsF() / non_parallel_time.InSecondsF();
+      UMA_HISTOGRAM_CUSTOM_COUNTS(
+          "Download.ParallelDownload.TotalTimeRatioPercentage",
+          time_ratio_percentage, 0, 200, 101);
     }
   }
 
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index a2e47af..c8a6a73 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -35143,6 +35143,7 @@
   <int value="47" label="kErrorCodeFilesystemVerifierError"/>
   <int value="48" label="kErrorCodeUserCanceled"/>
   <int value="49" label="kErrorCodeNonCriticalUpdateInOOBE"/>
+  <int value="50" label="kErrorCodeOmahaUpdateIgnoredOverCellular"/>
 </enum>
 
 <enum name="UpdateEngineInstallDateProvisioningSource" type="int">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 6d5db71..4dc1b4a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -14213,6 +14213,14 @@
   </summary>
 </histogram>
 
+<histogram name="Download.ParallelDownload.BandwidthRatioPercentage" units="%">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    Records the ratio of parallel streams bandwidth to single stream bandwidth
+    in parallel download.
+  </summary>
+</histogram>
+
 <histogram name="Download.ParallelDownload.CreationEvent"
     enum="ParallelDownloadCreationEvent">
   <owner>xingliu@chromium.org</owner>
@@ -14234,6 +14242,15 @@
   </summary>
 </histogram>
 
+<histogram name="Download.ParallelDownload.TotalTimeRatioPercentage" units="%">
+  <owner>xingliu@chromium.org</owner>
+  <summary>
+    Records the ratio of the actual total time of the download to the total time
+    without parallel streams. The total time without parallel streams is
+    calculated as the size of the file divided by the single stream bandwidth.
+  </summary>
+</histogram>
+
 <histogram name="Download.ParallelDownloadAddStreamSuccess"
     enum="BooleanSuccess">
   <owner>xingliu@chromium.org</owner>