diff --git a/DEPS b/DEPS
index a16d2bc2..0dcbf8ce 100644
--- a/DEPS
+++ b/DEPS
@@ -74,7 +74,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': 'be4ffab4e208ec47b4298621b9c9e8456f31717e',
+  'skia_revision': 'edc4f3e604b907d910aae0215787060d0d07ec28',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -98,7 +98,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'f8f22c7ac7f3d4b922f40f67e910114e55b187b0',
+  'pdfium_revision': '8ccdf196e41f5b769e50c95a11f741f568587d6c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc
index 6d7d964..04701bc 100644
--- a/ash/system/network/network_list.cc
+++ b/ash/system/network/network_list.cc
@@ -298,11 +298,18 @@
   }
 
   // chromeos::NetworkStateHandlerObserver
-  // Update state if the Cellular or Tether device state may have changed, or if
-  // the list of Cellular or Tether networks may have changed.
+
+  // Called when the available devices changes.
   void DeviceListChanged() override { UpdateState(); }
+
+  // Called when the state of a device changes (e.g. the enabled state).
+  void DevicePropertiesUpdated(const chromeos::DeviceState* device) override {
+    UpdateState();
+  }
+
   void NetworkListChanged() override { UpdateState(); }
 
+ private:
   void UpdateState() {
     NetworkStateHandler::TechnologyState cellular_state =
         network_state_handler_->GetTechnologyState(
@@ -400,7 +407,6 @@
     SetSubtitle(subtitle);
   }
 
- private:
   // When Tether is disabled because Bluetooth is off, then enabling Bluetooth
   // will enable Tether. If enabling Bluetooth takes longer than some timeout
   // period, it is assumed that there was an error. In that case, Tether will
diff --git a/ash/system/network/tray_network_state_observer.cc b/ash/system/network/tray_network_state_observer.cc
index f2ea186..044de08 100644
--- a/ash/system/network/tray_network_state_observer.cc
+++ b/ash/system/network/tray_network_state_observer.cc
@@ -78,6 +78,11 @@
   SignalUpdate(false /* notify_a11y */);
 }
 
+void TrayNetworkStateObserver::DevicePropertiesUpdated(
+    const chromeos::DeviceState* device) {
+  SignalUpdate(false /* notify_a11y */);
+}
+
 void TrayNetworkStateObserver::SignalUpdate(bool notify_a11y) {
   if (timer_.IsRunning())
     return;
diff --git a/ash/system/network/tray_network_state_observer.h b/ash/system/network/tray_network_state_observer.h
index ead056d81..1991281 100644
--- a/ash/system/network/tray_network_state_observer.h
+++ b/ash/system/network/tray_network_state_observer.h
@@ -34,6 +34,7 @@
   void NetworkConnectionStateChanged(
       const chromeos::NetworkState* network) override;
   void NetworkPropertiesUpdated(const chromeos::NetworkState* network) override;
+  void DevicePropertiesUpdated(const chromeos::DeviceState* device) override;
 
  private:
   void SignalUpdate(bool notify_a11y);
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc
index 37a018a..b62698f 100644
--- a/cc/paint/image_transfer_cache_entry.cc
+++ b/cc/paint/image_transfer_cache_entry.cc
@@ -34,10 +34,6 @@
 }
 ClientImageTransferCacheEntry::~ClientImageTransferCacheEntry() = default;
 
-TransferCacheEntryType ClientImageTransferCacheEntry::Type() const {
-  return TransferCacheEntryType::kImage;
-}
-
 size_t ClientImageTransferCacheEntry::SerializedSize() const {
   return size_;
 }
@@ -63,10 +59,6 @@
 ServiceImageTransferCacheEntry::ServiceImageTransferCacheEntry() = default;
 ServiceImageTransferCacheEntry::~ServiceImageTransferCacheEntry() = default;
 
-TransferCacheEntryType ServiceImageTransferCacheEntry::Type() const {
-  return TransferCacheEntryType::kImage;
-}
-
 size_t ServiceImageTransferCacheEntry::CachedSize() const {
   return size_;
 }
diff --git a/cc/paint/image_transfer_cache_entry.h b/cc/paint/image_transfer_cache_entry.h
index bd3a5138..7af3fff 100644
--- a/cc/paint/image_transfer_cache_entry.h
+++ b/cc/paint/image_transfer_cache_entry.h
@@ -17,7 +17,7 @@
 // for transferring image data. On the client side, this is a CPU SkPixmap,
 // on the service side the image is uploaded and is a GPU SkImage.
 class CC_PAINT_EXPORT ClientImageTransferCacheEntry
-    : public ClientTransferCacheEntry {
+    : public ClientTransferCacheEntryBase<TransferCacheEntryType::kImage> {
  public:
   explicit ClientImageTransferCacheEntry(
       const SkPixmap* pixmap,
@@ -25,7 +25,6 @@
   ~ClientImageTransferCacheEntry() final;
 
   // ClientTransferCacheEntry implementation:
-  TransferCacheEntryType Type() const final;
   size_t SerializedSize() const final;
   bool Serialize(base::span<uint8_t> data) const final;
 
@@ -35,13 +34,12 @@
 };
 
 class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
-    : public ServiceTransferCacheEntry {
+    : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kImage> {
  public:
   ServiceImageTransferCacheEntry();
   ~ServiceImageTransferCacheEntry() final;
 
   // ServiceTransferCacheEntry implementation:
-  TransferCacheEntryType Type() const final;
   size_t CachedSize() const final;
   bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
 
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index c32b09e2..addbebe 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -20,6 +20,7 @@
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_export.h"
 #include "cc/paint/paint_flags.h"
+#include "cc/paint/transfer_cache_deserialize_helper.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkPicture.h"
 #include "third_party/skia/include/core/SkRect.h"
@@ -28,7 +29,6 @@
 
 // PaintOpBuffer is a reimplementation of SkLiteDL.
 // See: third_party/skia/src/core/SkLiteDL.h.
-
 namespace cc {
 
 class CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix {
@@ -128,7 +128,9 @@
     const PaintFlags* flags_to_serialize = nullptr;
   };
 
-  struct DeserializeOptions {};
+  struct DeserializeOptions {
+    TransferCacheDeserializeHelper* transfer_cache = nullptr;
+  };
 
   // Subclasses should provide a static Serialize() method called from here.
   // If the op can be serialized to |memory| in no more than |size| bytes,
diff --git a/cc/paint/raw_memory_transfer_cache_entry.cc b/cc/paint/raw_memory_transfer_cache_entry.cc
index 4702550b..31da6c9 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -14,10 +14,6 @@
 ClientRawMemoryTransferCacheEntry::~ClientRawMemoryTransferCacheEntry() =
     default;
 
-TransferCacheEntryType ClientRawMemoryTransferCacheEntry::Type() const {
-  return TransferCacheEntryType::kRawMemory;
-}
-
 size_t ClientRawMemoryTransferCacheEntry::SerializedSize() const {
   return data_.size();
 }
@@ -36,10 +32,6 @@
 ServiceRawMemoryTransferCacheEntry::~ServiceRawMemoryTransferCacheEntry() =
     default;
 
-TransferCacheEntryType ServiceRawMemoryTransferCacheEntry::Type() const {
-  return TransferCacheEntryType::kRawMemory;
-}
-
 size_t ServiceRawMemoryTransferCacheEntry::CachedSize() const {
   return data_.size();
 }
diff --git a/cc/paint/raw_memory_transfer_cache_entry.h b/cc/paint/raw_memory_transfer_cache_entry.h
index 71e4745..2e8aa978 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.h
+++ b/cc/paint/raw_memory_transfer_cache_entry.h
@@ -15,11 +15,10 @@
 // backed by raw memory, with no conversion during serialization or
 // deserialization.
 class CC_PAINT_EXPORT ClientRawMemoryTransferCacheEntry
-    : public ClientTransferCacheEntry {
+    : public ClientTransferCacheEntryBase<TransferCacheEntryType::kRawMemory> {
  public:
   explicit ClientRawMemoryTransferCacheEntry(std::vector<uint8_t> data);
   ~ClientRawMemoryTransferCacheEntry() final;
-  TransferCacheEntryType Type() const final;
   size_t SerializedSize() const final;
   bool Serialize(base::span<uint8_t> data) const final;
 
@@ -28,11 +27,10 @@
 };
 
 class CC_PAINT_EXPORT ServiceRawMemoryTransferCacheEntry
-    : public ServiceTransferCacheEntry {
+    : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kRawMemory> {
  public:
   ServiceRawMemoryTransferCacheEntry();
   ~ServiceRawMemoryTransferCacheEntry() final;
-  TransferCacheEntryType Type() const final;
   size_t CachedSize() const final;
   bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
   const std::vector<uint8_t>& data() { return data_; }
diff --git a/cc/paint/transfer_cache_deserialize_helper.h b/cc/paint/transfer_cache_deserialize_helper.h
new file mode 100644
index 0000000..4c90047b
--- /dev/null
+++ b/cc/paint/transfer_cache_deserialize_helper.h
@@ -0,0 +1,42 @@
+// Copyright (c) 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 CC_PAINT_TRANSFER_CACHE_DESERIALIZE_HELPER_H_
+#define CC_PAINT_TRANSFER_CACHE_DESERIALIZE_HELPER_H_
+
+#include <cstdint>
+
+#include "cc/paint/paint_export.h"
+#include "cc/paint/transfer_cache_entry.h"
+
+namespace cc {
+
+// Helper interface consumed by cc/paint during OOP raster deserialization.
+// Provides access to the transfer cache.
+// TODO(ericrk): We should use TransferCacheEntryId, not uint64_t here, but
+// we need to figure out layering. crbug.com/777622
+class CC_PAINT_EXPORT TransferCacheDeserializeHelper {
+ public:
+  virtual ~TransferCacheDeserializeHelper() {}
+
+  // Type safe access to an entry in the transfer cache. Returns null if the
+  // entry is missing or of the wrong type.
+  template <typename T>
+  T* GetEntryAs(uint64_t id) {
+    ServiceTransferCacheEntry* entry = GetEntryInternal(id);
+    if (entry == nullptr) {
+      return nullptr;
+    }
+    if (entry->Type() != T::kType)
+      return nullptr;
+    return static_cast<T*>(entry);
+  }
+
+ private:
+  virtual ServiceTransferCacheEntry* GetEntryInternal(uint64_t id) = 0;
+};
+
+};  // namespace cc
+
+#endif  // CC_PAINT_TRANSFER_CACHE_DESERIALIZE_HELPER_H_
diff --git a/cc/paint/transfer_cache_entry.h b/cc/paint/transfer_cache_entry.h
index ed09802..1d0e51b 100644
--- a/cc/paint/transfer_cache_entry.h
+++ b/cc/paint/transfer_cache_entry.h
@@ -18,8 +18,7 @@
 //  - Add a type name to the TransferCacheEntryType enum.
 //  - Implement a ClientTransferCacheEntry and ServiceTransferCacheEntry for
 //    your new type.
-//  - Update ServiceTransferCacheEntry::Create and ServiceTransferCacheEntry::
-//    DeduceType in transfer_cache_entry.cc.
+//  - Update ServiceTransferCacheEntry::Create in transfer_cache_entry.cc.
 enum class TransferCacheEntryType {
   kRawMemory,
   kImage,
@@ -76,6 +75,22 @@
   virtual bool Deserialize(GrContext* context, base::span<uint8_t> data) = 0;
 };
 
+// Helpers to simplify subclassing.
+template <class Base, TransferCacheEntryType EntryType>
+class TransferCacheEntryBase : public Base {
+ public:
+  static constexpr TransferCacheEntryType kType = EntryType;
+  TransferCacheEntryType Type() const final { return kType; }
+};
+
+template <TransferCacheEntryType EntryType>
+using ClientTransferCacheEntryBase =
+    TransferCacheEntryBase<ClientTransferCacheEntry, EntryType>;
+
+template <TransferCacheEntryType EntryType>
+using ServiceTransferCacheEntryBase =
+    TransferCacheEntryBase<ServiceTransferCacheEntry, EntryType>;
+
 };  // namespace cc
 
 #endif  // CC_PAINT_TRANSFER_CACHE_ENTRY_H_
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java
index 390c934..f9c1ec2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java
@@ -17,6 +17,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
@@ -127,6 +128,7 @@
     @MediumTest
     @Feature({"Navigation", "Main"})
     //@RetryOnFailure
+    @DisabledTest(message = "crbug.com/793534")
     public void testNavigate() throws Exception {
         String url = mTestServer.getURL("/chrome/test/data/android/navigate/simple.html");
         String result = typeInOmniboxAndNavigate(url, "Simple");
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index 58f96bb2..7caaf3c 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -388,7 +388,6 @@
   "//chrome/profiling:manifest",
   "//components/patch_service:manifest",
   "//chrome/services/file_util:manifest",
-  "//services/metrics:manifest",
   "//services/proxy_resolver:proxy_resolver_manifest",
   "//services/preferences:local_state_manifest",
 ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index cb295be..e53c448 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1748,7 +1748,6 @@
     "//services/data_decoder/public/cpp",
     "//services/device/public/cpp:device_features",
     "//services/identity:lib",
-    "//services/metrics",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network/public/interfaces",
     "//services/preferences/public/cpp",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 4ae3b24..bc6eedde 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -226,8 +226,6 @@
 #include "ppapi/features/features.h"
 #include "ppapi/host/ppapi_host.h"
 #include "printing/features/features.h"
-#include "services/metrics/metrics_mojo_service.h"
-#include "services/metrics/public/interfaces/constants.mojom.h"
 #include "services/preferences/public/cpp/in_process_service_factory.h"
 #include "services/preferences/public/interfaces/preferences.mojom.h"
 #include "services/proxy_resolver/public/interfaces/proxy_resolver.mojom.h"
@@ -3215,8 +3213,6 @@
         std::make_pair(prefs::mojom::kLocalStateServiceName, info));
   }
   service_manager::EmbeddedServiceInfo info;
-  info.factory = base::Bind(&metrics::CreateMetricsService);
-  services->emplace(metrics::mojom::kMetricsServiceName, info);
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
   {
     service_manager::EmbeddedServiceInfo info;
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc
index 7cbfce27..fbb9440e 100644
--- a/chrome/browser/chromeos/tether/tether_service.cc
+++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -19,6 +19,7 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/components/tether/tether_component_impl.h"
 #include "chromeos/components/tether/tether_host_fetcher_impl.h"
+#include "chromeos/network/device_state.h"
 #include "chromeos/network/network_connect.h"
 #include "chromeos/network/network_type_pattern.h"
 #include "components/cryptauth/cryptauth_enrollment_manager.h"
@@ -263,6 +264,18 @@
 }
 
 void TetherService::DeviceListChanged() {
+  UpdateEnabledState();
+}
+
+void TetherService::DevicePropertiesUpdated(
+    const chromeos::DeviceState* device) {
+  if (device->Matches(chromeos::NetworkTypePattern::Tether()) ||
+      device->Matches(chromeos::NetworkTypePattern::WiFi())) {
+    UpdateEnabledState();
+  }
+}
+
+void TetherService::UpdateEnabledState() {
   bool was_pref_enabled = IsEnabledbyPreference();
   chromeos::NetworkStateHandler::TechnologyState tether_technology_state =
       network_state_handler_->GetTechnologyState(
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h
index 795550e1..2c9700e1f 100644
--- a/chrome/browser/chromeos/tether/tether_service.h
+++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -83,6 +83,10 @@
 
   // chromeos::NetworkStateHandlerObserver:
   void DeviceListChanged() override;
+  void DevicePropertiesUpdated(const chromeos::DeviceState* device) override;
+
+  // Helper method called from NetworkStateHandlerObserver methods.
+  void UpdateEnabledState();
 
   // chromeos::tether::TetherComponent::Observer:
   void OnShutdownComplete() override;
diff --git a/chromeos/components/tether/wifi_hotspot_connector.cc b/chromeos/components/tether/wifi_hotspot_connector.cc
index a09d337..a564c2a3 100644
--- a/chromeos/components/tether/wifi_hotspot_connector.cc
+++ b/chromeos/components/tether/wifi_hotspot_connector.cc
@@ -9,10 +9,12 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/default_clock.h"
+#include "chromeos/network/device_state.h"
 #include "chromeos/network/network_connect.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_type_pattern.h"
 #include "chromeos/network/shill_property_util.h"
 #include "components/proximity_auth/logging/logging.h"
 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
@@ -85,9 +87,9 @@
 
   // If Wi-Fi is enabled, continue with creating the configuration of the
   // hotspot. Otherwise, request that Wi-Fi be enabled and wait; see
-  // DeviceListChanged().
+  // UpdateWaitingForWifi.
   if (network_state_handler_->IsTechnologyEnabled(NetworkTypePattern::WiFi())) {
-    // Ensure that a possible previous pending callback to DeviceListChanged()
+    // Ensure that a possible previous pending callback to UpdateWaitingForWifi
     // won't result in a second call to CreateWifiConfiguration().
     is_waiting_for_wifi_to_enable_ = false;
 
@@ -95,7 +97,7 @@
   } else if (!is_waiting_for_wifi_to_enable_) {
     is_waiting_for_wifi_to_enable_ = true;
 
-    // Once Wi-Fi is enabled, DeviceListChanged() will be called.
+    // Once Wi-Fi is enabled, UpdateWaitingForWifi will be called.
     network_state_handler_->SetTechnologyEnabled(
         NetworkTypePattern::WiFi(), true /*enabled */,
         base::Bind(&WifiHotspotConnector::OnEnableWifiError,
@@ -111,13 +113,7 @@
 }
 
 void WifiHotspotConnector::DeviceListChanged() {
-  if (is_waiting_for_wifi_to_enable_ &&
-      network_state_handler_->IsTechnologyEnabled(NetworkTypePattern::WiFi())) {
-    is_waiting_for_wifi_to_enable_ = false;
-
-    if (!ssid_.empty())
-      CreateWifiConfiguration();
-  }
+  UpdateWaitingForWifi();
 }
 
 void WifiHotspotConnector::NetworkPropertiesUpdated(
@@ -164,6 +160,22 @@
   }
 }
 
+void WifiHotspotConnector::DevicePropertiesUpdated(const DeviceState* device) {
+  if (device->Matches(NetworkTypePattern::WiFi()))
+    UpdateWaitingForWifi();
+}
+
+void WifiHotspotConnector::UpdateWaitingForWifi() {
+  if (!is_waiting_for_wifi_to_enable_ ||
+      !network_state_handler_->IsTechnologyEnabled(
+          NetworkTypePattern::WiFi())) {
+    return;
+  }
+  is_waiting_for_wifi_to_enable_ = false;
+  if (!ssid_.empty())
+    CreateWifiConfiguration();
+}
+
 void WifiHotspotConnector::CompleteActiveConnectionAttempt(bool success) {
   DCHECK(!callback_.is_null());
   DCHECK(!wifi_network_guid_.empty());
diff --git a/chromeos/components/tether/wifi_hotspot_connector.h b/chromeos/components/tether/wifi_hotspot_connector.h
index 4a9dfa8..dbf1cc8 100644
--- a/chromeos/components/tether/wifi_hotspot_connector.h
+++ b/chromeos/components/tether/wifi_hotspot_connector.h
@@ -50,12 +50,14 @@
   // NetworkStateHandlerObserver:
   void DeviceListChanged() override;
   void NetworkPropertiesUpdated(const NetworkState* network) override;
+  void DevicePropertiesUpdated(const DeviceState* device) override;
 
  private:
   friend class WifiHotspotConnectorTest;
 
   static const int64_t kConnectionTimeoutSeconds = 20;
 
+  void UpdateWaitingForWifi();
   void CompleteActiveConnectionAttempt(bool success);
   void CreateWifiConfiguration();
   base::DictionaryValue CreateWifiPropertyDictionary(
diff --git a/chromeos/dbus/shill_service_client.cc b/chromeos/dbus/shill_service_client.cc
index d41c003..69813364 100644
--- a/chromeos/dbus/shill_service_client.cc
+++ b/chromeos/dbus/shill_service_client.cc
@@ -230,7 +230,6 @@
       return it->second;
 
     // There is no helper for the profile, create it.
-    NET_LOG_DEBUG("AddShillClientHelper", service_path.value());
     dbus::ObjectProxy* object_proxy =
         bus_->GetObjectProxy(shill::kFlimflamServiceName, service_path);
     ShillClientHelper* helper = new ShillClientHelper(object_proxy);
@@ -257,7 +256,6 @@
                     shill::kFlimflamServicePath);
       return;
     }
-    NET_LOG_DEBUG("RemoveShillClientHelper", object_path.value());
     bus_->RemoveObjectProxy(shill::kFlimflamServiceName,
                             object_path, base::Bind(&base::DoNothing));
     helpers_.erase(object_path.value());
diff --git a/chromeos/network/network_device_handler_impl.cc b/chromeos/network/network_device_handler_impl.cc
index 4f3f9198..927e180 100644
--- a/chromeos/network/network_device_handler_impl.cc
+++ b/chromeos/network/network_device_handler_impl.cc
@@ -113,7 +113,7 @@
     const base::Value& value,
     const base::Closure& callback,
     const network_handler::ErrorCallback& error_callback) {
-  NET_LOG(USER) << "Device.SetProperty: " << property_name;
+  NET_LOG(USER) << "Device.SetProperty: " << property_name << " = " << value;
   DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
       dbus::ObjectPath(device_path),
       property_name,
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
index 68210a66..d71daf0b 100644
--- a/chromeos/network/network_state.cc
+++ b/chromeos/network/network_state.cc
@@ -207,8 +207,9 @@
 
 bool NetworkState::InitialPropertiesReceived(
     const base::DictionaryValue& properties) {
-  NET_LOG(EVENT) << "InitialPropertiesReceived: " << path() << ": " << name()
-                 << " State: " << connection_state_ << " Visible: " << visible_;
+  NET_LOG(EVENT) << "InitialPropertiesReceived: " << name() << " (" << path()
+                 << ") State: " << connection_state_
+                 << " Visible: " << visible_;
   if (!properties.HasKey(shill::kTypeProperty)) {
     NET_LOG(ERROR) << "NetworkState has no type: "
                    << shill_property_util::GetNetworkIdFromProperties(
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 924d930..128993b0 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -39,10 +39,18 @@
 bool ConnectionStateChanged(NetworkState* network,
                             const std::string& prev_connection_state,
                             bool prev_is_captive_portal) {
-  return ((network->connection_state() != prev_connection_state) &&
-          !((network->connection_state() == shill::kStateIdle) &&
-            prev_connection_state.empty())) ||
-         (network->is_captive_portal() != prev_is_captive_portal);
+  if (network->is_captive_portal() != prev_is_captive_portal)
+    return true;
+  std::string connection_state = network->connection_state();
+  // Treat 'idle' and 'discoonect' the same.
+  bool prev_idle = prev_connection_state.empty() ||
+                   prev_connection_state == shill::kStateIdle ||
+                   prev_connection_state == shill::kStateDisconnect;
+  bool cur_idle = connection_state == shill::kStateIdle ||
+                  connection_state == shill::kStateDisconnect;
+  if (prev_idle || cur_idle)
+    return prev_idle != cur_idle;
+  return connection_state != prev_connection_state;
 }
 
 std::string GetManagedStateLogType(const ManagedState* state) {
@@ -1136,7 +1144,6 @@
                                prev_is_captive_portal)) {
       OnNetworkConnectionStateChanged(network);
     }
-    NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network));
     NotifyNetworkPropertiesUpdated(network);
   }
 }
@@ -1211,7 +1218,6 @@
     return;
 
   LogPropertyUpdated(device, key, value);
-  NotifyDeviceListChanged();
   NotifyDevicePropertiesUpdated(device);
 
   if (key == shill::kScanningProperty && device->scanning() == false) {
@@ -1628,7 +1634,7 @@
 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
     const NetworkState* network) {
   SCOPED_NET_LOG_IF_SLOW();
-  NET_LOG_DEBUG("NOTIFY:NetworkPropertiesUpdated", GetLogName(network));
+  NET_LOG_EVENT("NOTIFY:NetworkPropertiesUpdated", GetLogName(network));
   notifying_network_observers_ = true;
   for (auto& observer : observers_)
     observer.NetworkPropertiesUpdated(network);
@@ -1638,21 +1644,21 @@
 void NetworkStateHandler::NotifyDevicePropertiesUpdated(
     const DeviceState* device) {
   SCOPED_NET_LOG_IF_SLOW();
-  NET_LOG_DEBUG("NOTIFY:DevicePropertiesUpdated", GetLogName(device));
+  NET_LOG_EVENT("NOTIFY:DevicePropertiesUpdated", GetLogName(device));
   for (auto& observer : observers_)
     observer.DevicePropertiesUpdated(device);
 }
 
 void NetworkStateHandler::NotifyScanRequested() {
   SCOPED_NET_LOG_IF_SLOW();
-  NET_LOG_DEBUG("NOTIFY:ScanRequested", "");
+  NET_LOG_EVENT("NOTIFY:ScanRequested", "");
   for (auto& observer : observers_)
     observer.ScanRequested();
 }
 
 void NetworkStateHandler::NotifyScanCompleted(const DeviceState* device) {
   SCOPED_NET_LOG_IF_SLOW();
-  NET_LOG_DEBUG("NOTIFY:ScanCompleted", GetLogName(device));
+  NET_LOG_EVENT("NOTIFY:ScanCompleted", GetLogName(device));
   for (auto& observer : observers_)
     observer.ScanCompleted(device);
 }
@@ -1670,8 +1676,8 @@
           ? device_event_log::LOG_LEVEL_ERROR
           : device_event_log::LOG_LEVEL_EVENT;
   DEVICE_LOG(::device_event_log::LOG_TYPE_NETWORK, log_level)
-      << type_str << "PropertyUpdated: " << state->name() << "." << key << " = "
-      << value;
+      << type_str << "PropertyUpdated: " << state->path() << " ("
+      << state->name() << ") " << key << " = " << value;
 }
 
 std::string NetworkStateHandler::GetTechnologyForType(
diff --git a/chromeos/network/network_state_handler_observer.h b/chromeos/network/network_state_handler_observer.h
index b70a4fc..ae1c365 100644
--- a/chromeos/network/network_state_handler_observer.h
+++ b/chromeos/network/network_state_handler_observer.h
@@ -26,7 +26,8 @@
   // The list of networks changed.
   virtual void NetworkListChanged();
 
-  // The list of devices changed, or a property changed (e.g. scanning).
+  // The list of devices changed. Use DevicePropertiesUpdated to be notified
+  // when a Device property changes.
   virtual void DeviceListChanged();
 
   // The default network changed (includes VPNs) or one of its properties
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index d6c40f9..5d989db 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -61,6 +61,7 @@
     // Deprecated.
     {::onc::eap::kServerCARef, &kStringSignature},
     {::onc::eap::kServerCARefs, &kStringListSignature},
+    {::onc::eap::kSubjectMatch, &kStringSignature},
     {::onc::eap::kTLSVersionMax, &kStringSignature},
     {::onc::eap::kUseProactiveKeyCaching, &kBoolSignature},
     {::onc::eap::kUseSystemCAs, &kBoolSignature},
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc
index 300c222..ff604e5 100644
--- a/chromeos/network/shill_property_handler.cc
+++ b/chromeos/network/shill_property_handler.cc
@@ -483,16 +483,14 @@
     const std::string& path,
     DBusMethodCallStatus call_status,
     const base::DictionaryValue& properties) {
-  NET_LOG(DEBUG) << "GetPropertiesCallback: "
-                 << ManagedState::TypeToString(type) << " For: " << path;
   pending_updates_[type].erase(path);
   if (call_status != DBUS_METHOD_CALL_SUCCESS) {
     // The shill service no longer exists.  This can happen when a network
     // has been removed.
-    NET_LOG(DEBUG) << "Failed to get properties for: " << path << ": "
-                   << call_status;
     return;
   }
+  NET_LOG(DEBUG) << "GetProperties received for "
+                 << ManagedState::TypeToString(type) << ": " << path;
   listener_->UpdateManagedStateProperties(type, path, properties);
 
   if (type == ManagedState::MANAGED_TYPE_NETWORK) {
diff --git a/chromeos/test/data/network/shill_l2tpipsec.json b/chromeos/test/data/network/shill_l2tpipsec.json
index 68e275cc..b06b437 100644
--- a/chromeos/test/data/network/shill_l2tpipsec.json
+++ b/chromeos/test/data/network/shill_l2tpipsec.json
@@ -4,6 +4,7 @@
   "Provider.Host": "some.host.org",
   "Provider.Type": "l2tpipsec",
   "L2TPIPsec.PSK": "some_preshared_key",
+  "L2TPIPsec.TunnelGroup": "my_group",
   "L2TPIPsec.User": "some username",
   "L2TPIPsec.XauthPassword": "some xauth password",
   "L2TPIPsec.XauthUser": "some xauth username",
diff --git a/chromeos/test/data/network/shill_output_l2tpipsec.json b/chromeos/test/data/network/shill_output_l2tpipsec.json
index e9f33ea7..4a56c0b 100644
--- a/chromeos/test/data/network/shill_output_l2tpipsec.json
+++ b/chromeos/test/data/network/shill_output_l2tpipsec.json
@@ -5,6 +5,7 @@
     "Host": "some.host.org",
     "L2TPIPsec.LCPEchoDisabled": true,
     "L2TPIPsec.PSK": "some_preshared_key",
+    "L2TPIPsec.TunnelGroup": "my_group",
     "L2TPIPsec.User": "some username",
     "L2TPIPsec.XauthPassword": "some xauth password",
     "L2TPIPsec.XauthUser": "some xauth username",
diff --git a/chromeos/test/data/network/shill_wifi_eap_tls.json b/chromeos/test/data/network/shill_wifi_eap_tls.json
index fc680a70..1be3b2b 100644
--- a/chromeos/test/data/network/shill_wifi_eap_tls.json
+++ b/chromeos/test/data/network/shill_wifi_eap_tls.json
@@ -4,6 +4,7 @@
    "EAP.Identity": "my_identity",
    "EAP.KeyID": "1:123456abcdef",
    "EAP.PIN": "111111",
+   "EAP.SubjectMatch": "my_subject",
    "EAP.TLSVersionMax": "1.2",
    "EAP.UseSystemCAs": true,
    "GUID": "{77db0089-0bc8-4358-929c-123xcv}",
diff --git a/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc b/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
index 84bbfc3..8fa5d50 100644
--- a/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
+++ b/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
@@ -6,6 +6,7 @@
     "Host": "some.host.org",
     "IPsec": {
       "AuthenticationType": "PSK",
+      "Group": "my_group",
       // This field is part of ONC (and is required). However, it does not
       // exist explicitly in the Shill dictionary. As there is no use-case yet
       // that requires reconstructing this field from a Shill dictionary, we
diff --git a/chromeos/test/data/network/translation_of_shill_wifi_eap_tls.onc b/chromeos/test/data/network/translation_of_shill_wifi_eap_tls.onc
index 0f01ad3..458bdb9 100644
--- a/chromeos/test/data/network/translation_of_shill_wifi_eap_tls.onc
+++ b/chromeos/test/data/network/translation_of_shill_wifi_eap_tls.onc
@@ -9,6 +9,7 @@
       "ClientCertPKCS11Id": "1:123456abcdef",
       "Outer": "EAP-TLS",
       "Identity": "my_identity",
+      "SubjectMatch": "my_subject",
       "TLSVersionMax": "1.2",
       "UseSystemCAs": true,
       "SaveCredentials": true
diff --git a/chromeos/test/data/network/valid_l2tpipsec.onc b/chromeos/test/data/network/valid_l2tpipsec.onc
index 498a217..541f83350 100644
--- a/chromeos/test/data/network/valid_l2tpipsec.onc
+++ b/chromeos/test/data/network/valid_l2tpipsec.onc
@@ -6,6 +6,7 @@
     "Host": "some.host.org",
     "IPsec": {
       "AuthenticationType": "PSK",
+      "Group": "my_group",
       "IKEVersion": 1,
       "PSK": "some_preshared_key",
       "SaveCredentials": true,
diff --git a/chromeos/test/data/network/wifi_eap_tls.onc b/chromeos/test/data/network/wifi_eap_tls.onc
index e5bc0f05..4d3f18a 100644
--- a/chromeos/test/data/network/wifi_eap_tls.onc
+++ b/chromeos/test/data/network/wifi_eap_tls.onc
@@ -11,6 +11,7 @@
       "ClientCertType": "PKCS11Id",
       "ClientCertPKCS11Id": "1:123456abcdef",
       "SaveCredentials": true,
+      "SubjectMatch": "my_subject",
       "TLSVersionMax": "1.2",
       "UseSystemCAs": true
     }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index be749242..e060267 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -124,6 +124,7 @@
     "//services/device/public/interfaces:generic_sensor",
     "//services/file:lib",
     "//services/file/public/interfaces",
+    "//services/metrics",
     "//services/metrics/public/cpp:metrics_cpp",
     "//services/network/public/cpp",
     "//services/network/public/interfaces",
diff --git a/content/browser/renderer_host/input/composited_scrolling_browsertest.cc b/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
index 6df2743a..1bfed52 100644
--- a/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
+++ b/content/browser/renderer_host/input/composited_scrolling_browsertest.cc
@@ -115,9 +115,9 @@
   int DoTouchScroll(const gfx::Point& point, const gfx::Vector2d& distance) {
     EXPECT_EQ(0, GetScrollTop());
 
-    int scrollHeight = ExecuteScriptAndExtractInt(
+    int scroll_height = ExecuteScriptAndExtractInt(
         "document.getElementById('scroller').scrollHeight");
-    EXPECT_EQ(1000, scrollHeight);
+    EXPECT_EQ(1000, scroll_height);
 
     SyntheticSmoothScrollGestureParams params;
     params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
@@ -159,11 +159,11 @@
 IN_PROC_BROWSER_TEST_F(CompositedScrollingBrowserTest,
                        MAYBE_Scroll3DTransformedScroller) {
   LoadURL();
-  int scrollDistance =
+  int scroll_distance =
       DoTouchScroll(gfx::Point(50, 150), gfx::Vector2d(0, 100));
   // The scroll distance is increased due to the rotation of the scroller.
   EXPECT_EQ(std::floor(100 / std::cos(gfx::DegToRad(30.f))) - 1,
-            scrollDistance);
+            scroll_distance);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index c16cb1a..1752b78 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -134,9 +134,9 @@
                      bool wait_until_scrolled) {
     EXPECT_EQ(0, GetScrollTop());
 
-    int scrollHeight = ExecuteScriptAndExtractInt(
-        "document.documentElement.scrollHeight");
-    EXPECT_EQ(10200, scrollHeight);
+    int scroll_height =
+        ExecuteScriptAndExtractInt("document.documentElement.scrollHeight");
+    EXPECT_EQ(10200, scroll_height);
 
     FrameWatcher frame_watcher(shell()->web_contents());
 
@@ -167,12 +167,12 @@
     }
 
     // Check the scroll offset
-    int scrollTop = GetScrollTop();
-    if (scrollTop == 0)
+    int scroll_top = GetScrollTop();
+    if (scroll_top == 0)
       return false;
 
     // Allow for 1px rounding inaccuracies for some screen sizes.
-    EXPECT_LT(distance.y() / 2, scrollTop);
+    EXPECT_LT(distance.y() / 2, scroll_top);
     return true;
   }
 
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index 033cfa0..bdaf373 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -50,6 +50,8 @@
 #include "services/data_decoder/public/interfaces/constants.mojom.h"
 #include "services/device/device_service.h"
 #include "services/device/public/interfaces/constants.mojom.h"
+#include "services/metrics/metrics_mojo_service.h"
+#include "services/metrics/public/interfaces/constants.mojom.h"
 #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
 #include "services/resource_coordinator/public/interfaces/service_constants.mojom.h"
 #include "services/resource_coordinator/resource_coordinator_service.h"
@@ -475,6 +477,13 @@
         resource_coordinator::mojom::kServiceName, resource_coordinator_info);
   }
 
+  {
+    service_manager::EmbeddedServiceInfo info;
+    info.factory = base::BindRepeating(&metrics::CreateMetricsService);
+    packaged_services_connection_->AddEmbeddedService(
+        metrics::mojom::kMetricsServiceName, info);
+  }
+
   ContentBrowserClient::StaticServiceMap services;
   GetContentClient()->browser()->RegisterInProcessServices(&services);
   for (const auto& entry : services) {
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn
index 28730e51..425c0bd 100644
--- a/content/public/app/BUILD.gn
+++ b/content/public/app/BUILD.gn
@@ -187,6 +187,7 @@
     "//media/mojo/services:media_manifest",
     "//services/data_decoder:manifest",
     "//services/device:manifest",
+    "//services/metrics:manifest",
     "//services/resource_coordinator:manifest",
     "//services/shape_detection:manifest",
     "//services/video_capture:manifest",
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index 9850f968..e317eae 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -776,6 +776,8 @@
 
 void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
     const viz::FrameSinkId& frame_sink_id) {
+  // RendererWindowTreeClient should only call this when mus is hosting viz.
+  DCHECK(switches::IsMusHostingViz());
   OnGuestReady(browser_plugin_instance_id_, frame_sink_id);
 }
 #endif
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc
index 596740f..9edcbe8 100644
--- a/content/renderer/mus/renderer_window_tree_client.cc
+++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -17,6 +17,7 @@
 #include "content/renderer/mus/mus_embedded_frame.h"
 #include "content/renderer/mus/mus_embedded_frame_delegate.h"
 #include "content/renderer/render_frame_proxy.h"
+#include "ui/base/ui_base_switches_util.h"
 
 namespace content {
 
@@ -215,6 +216,11 @@
 void RendererWindowTreeClient::OnFrameSinkIdAllocated(
     ui::Id window_id,
     const viz::FrameSinkId& frame_sink_id) {
+  // When mus is not hosting viz FrameSinkIds come from the browser, so we
+  // ignore them here.
+  if (!switches::IsMusHostingViz())
+    return;
+
   for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
     if (embedded_frame->window_id_ == window_id) {
       embedded_frame->delegate_->OnMusEmbeddedFrameSinkIdAllocated(
@@ -312,6 +318,7 @@
 void RendererWindowTreeClient::OnWindowSurfaceChanged(
     ui::Id window_id,
     const viz::SurfaceInfo& surface_info) {
+  DCHECK(switches::IsMusHostingViz());
   for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
     if (embedded_frame->window_id_ == window_id) {
       embedded_frame->delegate_->OnMusEmbeddedFrameSurfaceChanged(surface_info);
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 09eac0f..a8a14dda 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -708,6 +708,8 @@
 
 void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
     const viz::FrameSinkId& frame_sink_id) {
+  // RendererWindowTreeClient should only call this when mus is hosting viz.
+  DCHECK(switches::IsMusHostingViz());
   frame_sink_id_ = frame_sink_id;
   // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
   // changes.
diff --git a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
index a6ec942..9128a5e 100644
--- a/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
+++ b/extensions/browser/api/networking_private/networking_private_event_router_chromeos.cc
@@ -223,6 +223,9 @@
 
 void NetworkingPrivateEventRouterImpl::DevicePropertiesUpdated(
     const DeviceState* device) {
+  // networkingPrivate uses a single event for device changes.
+  DeviceListChanged();
+
   // DeviceState changes may affect Cellular networks.
   if (device->type() != shill::kTypeCellular)
     return;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 08d5d97..bdc1a84 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -20309,6 +20309,23 @@
   texture_manager()->SetLevelCleared(texture_ref, texture->target(), 0, true);
 }
 
+class TransferCacheDeserializeHelperImpl
+    : public cc::TransferCacheDeserializeHelper {
+ public:
+  explicit TransferCacheDeserializeHelperImpl(
+      ServiceTransferCache* transfer_cache)
+      : transfer_cache_(transfer_cache) {
+    DCHECK(transfer_cache_);
+  }
+  ~TransferCacheDeserializeHelperImpl() override = default;
+
+ private:
+  cc::ServiceTransferCacheEntry* GetEntryInternal(uint64_t id) override {
+    return transfer_cache_->GetEntry(TransferCacheEntryId::FromUnsafeValue(id));
+  }
+  ServiceTransferCache* transfer_cache_;
+};
+
 error::Error GLES2DecoderImpl::HandleRasterCHROMIUM(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
@@ -20330,6 +20347,8 @@
   SkMatrix original_ctm;
   cc::PlaybackParams playback_params(nullptr, original_ctm);
   cc::PaintOp::DeserializeOptions options;
+  TransferCacheDeserializeHelperImpl impl(GetContextGroup()->transfer_cache());
+  options.transfer_cache = &impl;
 
   int op_idx = 0;
   while (size > 4) {
diff --git a/services/metrics/manifest.json b/services/metrics/manifest.json
index a756a1c..2e08346 100644
--- a/services/metrics/manifest.json
+++ b/services/metrics/manifest.json
@@ -7,6 +7,9 @@
         "url_keyed_metrics": [
           "ukm::mojom::UkmRecorderInterface"
         ]
+      },
+      "requires": {
+        "service_manager": [ "service_manager:all_users" ]
       }
     }
   }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 04c9e217..e28fd0d 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -4280,8 +4280,7 @@
       },
       {
         "args": [
-          "--mus",
-          "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.mus.content_browsertests.filter"
+          "--mus"
         ],
         "name": "mus_content_browsertests",
         "override_isolate_target": "content_browsertests",
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn
index 28da71d..7c7b3e61 100644
--- a/testing/buildbot/filters/BUILD.gn
+++ b/testing/buildbot/filters/BUILD.gn
@@ -44,7 +44,6 @@
     "//testing/buildbot/filters/cast-linux.content_browsertests.filter",
     "//testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter",
     "//testing/buildbot/filters/site-per-process.content_browsertests.filter",
-    "//testing/buildbot/filters/mojo.fyi.mus.content_browsertests.filter",
     "//testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter",
     "//testing/buildbot/filters/mus.content_browsertests.filter",
     "//testing/buildbot/filters/viz.content_browsertests.filter",
diff --git a/testing/buildbot/filters/mojo.fyi.mus.content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.mus.content_browsertests.filter
deleted file mode 100644
index dd301af4..0000000
--- a/testing/buildbot/filters/mojo.fyi.mus.content_browsertests.filter
+++ /dev/null
@@ -1,124 +0,0 @@
-# TODO: reevaluate these once --mus no longer implies Viz. All of these
-# failures appear to be code relying on in process access to parts of Viz.
-# This is covered by http://crbug.com/775030. There are also a couple that rely
-# on capture, which again should work fine once --mus no longer implies Viz.
-
-# TODO: reenable, these use
-# BrowserMainLoop::GetInstance()->gpu_channel_establish_factory().
-# http://crbug.com/775030.
--BrowserGpuChannelHostFactoryTest.GrContextKeepsGpuChannelAlive
--GpuProcessHostBrowserTest.Shutdown
--SignalTest.BasicSignalQueryTest
--SignalTest.BasicSignalSyncTokenTest
--SignalTest.EmptySignalSyncTokenTest
--SignalTest.InvalidSignalQueryUnboundTest
--SignalTest.InvalidSignalSyncTokenTest
--SignalTest.SignalQueryUnboundTest
-
-# TODO: reenable, uses ImageTransportFactory, which is not created in mus (viz
-# actually). http://crbug.com/775030.
--ImageTransportFactoryTearDownBrowserTest.LoseOnTearDown
-
-# Uses MainThreadFrameObserver, http://crbug.com/775030.
--SitePerProcessMouseWheelBrowserTest.MainframeWheelEventsOnMainThread
--SitePerProcessMouseWheelBrowserTest.InputEventRouterWheelTargetTest
--SitePerProcessMouseWheelBrowserTest.SubframeWheelEventsOnMainThread
--SitePerProcessBrowserTest.CrossSiteIframeDisplayNone
--SitePerProcessBrowserTest.MainframeTouchEventRouting
--MainThreadEventQueueBrowserTest.MouseMove
--MainThreadEventQueueBrowserTest.TouchMove
--NonBlockingEventBrowserTest.MouseWheel
--NonBlockingEventBrowserTest.PassiveTouchStartBlockingTouchEnd
--NonBlockingEventBrowserTest.TouchStart
--PointerLockBrowserTest.PointerLockEventRouting
--PointerLockBrowserTest.PointerLockWheelEventRouting
--ScreenOrientationOOPIFBrowserTest.ScreenOrientation
-
-# TODO: reenable, uses WaitForChildFrameSurfaceReady(), http://crbug.com/775030.
--SitePerProcessBrowserTest.CancelWheelScrollBubblingOnWheelTargetDeletion
--SitePerProcessBrowserTest.ScrollBubblingFromNestedOOPIFTest
--SitePerProcessBrowserTest.ViewBoundsInNestedFrameTest
--SitePerProcessBrowserTest.GestureFlingStartEventsBubble
--SitePerProcessBrowserTest.ScrollBubblingFromOOPIFTest
--SitePerProcessBrowserTest.RootConsumesScrollDuringOverscrollGesture
--SitePerProcessBrowserTest.ScrollEventToOOPIF
--SitePerProcessBrowserTest.NestedSurfaceHitTestTest
--SitePerProcessBrowserTest.SurfaceHitTestPointerEventsNone
--SitePerProcessBrowserTest.CrossProcessMouseEnterAndLeaveTest
--SitePerProcessBrowserTest.CrossProcessMouseCapture
--SitePerProcessBrowserTest.CursorUpdateReceivedCrossSiteIframe
--SitePerProcessBrowserTest.SubframeTouchEventRouting
--SitePerProcessBrowserTest.InputEventRouterGestureTargetMapTest
--SitePerProcessBrowserTest.InputEventRouterGesturePreventDefaultTargetMapTest
--SitePerProcessBrowserTest.InputEventRouterTouchpadGestureTargetTest
--SitePerProcessBrowserTest.PopupMenuTest
--SitePerProcessGestureBrowserTest.MainframeGesturePinchGoesToMainFrame
--SitePerProcessGestureBrowserTest.SubframeGesturePinchGoesToMainFrame
--SitePerProcessBrowserTest.NavigateCrashedSubframeToSameSite
--SitePerProcessBrowserTest.SurfaceHitTestTest
--SitePerProcessHighDPIBrowserTest.SurfaceHitTestTest
-
-# TODO: reenable, uses RendererFrameNumber(), http://crbug.com/775030.
--SitePerProcessBrowserTest.CompositorFrameSwapped
--TouchSelectionForCrossProcessFramesTests/TouchSelectionControllerClientAuraSiteIsolationTest.BasicSelectionIsolatedIframe/0
--TouchSelectionForCrossProcessFramesTests/TouchSelectionControllerClientAuraSiteIsolationTest.BasicSelectionIsolatedIframe/1
-
-# TODO: reenable, uses SurfaceHitTestReadyNotifier::WaitForSurfaceReady(),
-# http://crbug.com/775030.
--SitePerProcessBrowserTest.CreateContextMenuTest
--SitePerProcessHighDPIBrowserTest.HighDPICreateContextMenuTest
-
-# TODO: reenable, uses
-# RenderWidgetHostViewChildFrame::RegisterFrameSwappedCallback(),
-# http://crbug.com/775030.
--SitePerProcessBrowserTest.HiddenOOPIFWillNotGenerateCompositorFrames
--SitePerProcessBrowserTest.HiddenOOPIFWillNotGenerateCompositorFramesAfterNavigation
-
-# TODO: reenable, uses FrameWatcher, http://crbug.com/775030.
--CompositedScrollingBrowserTest.Scroll3DTransformedScroller
--RenderWidgetHostViewBrowserTestBase.CompositorWorksWhenReusingRenderer
--ScrollLatencyBrowserTest.SmoothWheelScroll
--TouchActionBrowserTest.TouchActionNone
--WheelScrollLatchingBrowserTest.WheelEventTarget
--WheelScrollLatchingDisabledBrowserTest.WheelEventTarget
-
-# Stuck in DevToolsProtocolTest::WaitForResponse().
--CaptureScreenshotTest.CaptureScreenshot
--CaptureScreenshotTest.CaptureScreenshotJpeg
-
-# These get stuck waiting for an event, InputMsgWatcher::WaitForAck().
--MouseLatencyBrowserTest.CoalescedMouseMovesCorrectlyTerminated
--MouseLatencyBrowserTest.MouseDownAndUpRecordedWithoutSwap
-
-# These wait for mojom::kGpuServiceName to connect to browser, but that won't
-# happen with mus.
--PowerMonitorTest.TestGpuProcess
-
-# These all timeout, investigate why.
--GLAndSoftwareCompositing*
-
-# TODO: these hit a DCHECK on the waterfall. They hit DCHECK:
-# PaintLayerCompositor.cpp(94)] Check failed:
-# layout_view_.Layer()->IsAllowedToQueryCompositingState()
--SitePerProcessBrowserTest.ScrollElementIntoView
--FindRequestManagerTests/FindRequestManagerTest.NavigateFrame/1
-
-# TODO: these all need capture. http://crbug.com/754872
--SnapshotBrowserTest.AsyncMultiWindowTest
--SnapshotBrowserTest.SingleWindowTest
--SnapshotBrowserTest.SyncMultiWindowTest
--WebRtcCaptureFromElementBrowserTest.CaptureFromCanvas2DHandlesContextLoss
--WebRtcCaptureFromElementBrowserTest.CaptureFromOpaqueCanvas2DHandlesContextLoss
-
-
-# TODO: these all rely on RenderWidgetHostImpl::SubmitCompositorFrame(), which
-# isn't hit for mus.
--TouchSelectionControllerClientAuraScaleFactorTest.InsertionHandleCoordinates
--TouchSelectionControllerClientAuraScaleFactorTest.SelectionHandleCoordinates
--TouchSelectionControllerClientAuraTest.BasicInsertionFollowedByTapsOnHandle
--TouchSelectionControllerClientAuraTest.BasicSelection
--TouchSelectionControllerClientAuraTest.HiddenAfterOverscroll
--TouchSelectionControllerClientAuraTest.HiddenOnScroll
--TouchSelectionControllerClientAuraTest.QuickMenuHiddenOnTouch
--TouchSelectionForCrossProcessFramesTests/TouchSelectionControllerClientAuraSiteIsolationTest.BasicSelectionIsolatedScrollMainframe/0
--TouchSelectionForCrossProcessFramesTests/TouchSelectionControllerClientAuraSiteIsolationTest.BasicSelectionIsolatedScrollMainframe/1
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.html b/ui/webui/resources/cr_components/chromeos/network/network_config.html
index 7819a02..831a7e1 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_config.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_config.html
@@ -52,11 +52,11 @@
           value="{{configProperties_.VPN.Host}}">
       </network-config-input>
       <network-config-input label="[[i18n('OncName')]]"
-          value="{{configProperties_.Name}}">
+          value="{{configProperties_.Name}}" disabled="[[hasGuid_(guid)]]">
       </network-config-input>
       <network-config-select id="outer" label="[[i18n('OncVPN-Type')]]"
           value="{{vpnType_}}" items="[[vpnTypeItems_]]"
-          onc-prefix="VPN.Type">
+          onc-prefix="VPN.Type" disabled="[[hasGuid_(guid)]]">
       </network-config-select>
       <template is="dom-if" if="[[!showVpn_.OpenVPN]]">
         <network-config-input label="[[i18n('OncVPN-Username')]]"
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js
index 4fb1d5d5..f03c3606 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_config.js
+++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -358,20 +358,22 @@
       return;
     this.propertiesSent_ = true;
     this.error_ = '';
+
+    var propertiesToSet = this.getPropertiesToSet_();
     if (!this.guid || this.getSource_() == CrOnc.Source.NONE) {
       // New network configurations default to 'AutoConnect' unless prohibited
       // by policy.
       CrOnc.setTypeProperty(
-          this.configProperties_, 'AutoConnect',
+          propertiesToSet, 'AutoConnect',
           !(this.globalPolicy &&
             this.globalPolicy.AllowOnlyPolicyNetworksToConnect));
 
       // Create the configuration, then connect to it in the callback.
       this.networkingPrivate.createNetwork(
-          this.shareNetwork_, this.configProperties_,
+          this.shareNetwork_, propertiesToSet,
           this.createNetworkCallback_.bind(this));
     } else {
-      var propertiesToSet = this.getPropertiesToSet_();
+      propertiesToSet.GUID = this.guid;
       this.networkingPrivate.setProperties(
           this.guid, propertiesToSet, this.setPropertiesCallback_.bind(this));
     }
@@ -642,6 +644,7 @@
             L2TP: {Username: ''},
           };
         }
+        this.security_ = CrOnc.Security.NONE;
         break;
     }
     this.configProperties_ = configProperties;
@@ -886,17 +889,25 @@
    * @private
    */
   setSelectedCerts_: function(pem, certId) {
-    var serverCa = (!!pem && this.serverCaCerts_.find(function(cert) {
-                     return cert.pem == pem;
-                   })) ||
-        this.serverCaCerts_[0];
-    this.selectedServerCaHash_ = (serverCa && serverCa.hash) || '';
+    if (pem) {
+      var serverCa = this.serverCaCerts_.find(function(cert) {
+        return cert.pem == pem;
+      });
+      if (serverCa)
+        this.selectedServerCaHash_ = serverCa.hash;
+    }
+    if (!this.selectedServerCaHash_ && this.serverCaCerts_[0])
+      this.selectedServerCaHash_ = this.serverCaCerts_[0].hash;
 
-    var userCert = (!!certId && this.userCerts_.find(function(cert) {
-                     return cert.PKCS11Id == certId;
-                   })) ||
-        this.userCerts_[0];
-    this.selectedUserCertHash_ = (userCert && userCert.hash) || '';
+    if (certId) {
+      var userCert = this.userCerts_.find(function(cert) {
+        return cert.PKCS11Id == certId;
+      });
+      if (userCert)
+        this.selectedUserCertHash_ = userCert.hash;
+    }
+    if (!this.selectedUserCertHash_ && this.userCerts_[0])
+      this.selectedUserCertHash_ = this.userCerts_[0].hash;
   },
 
   /**
@@ -904,6 +915,9 @@
    * @private
    */
   getIsConfigured_: function() {
+    if (this.configProperties_.Type == CrOnc.Type.VPN)
+      return this.vpnIsConfigured_();
+
     if (this.type == CrOnc.Type.WI_FI) {
       if (!this.get('WiFi.SSID', this.configProperties_))
         return false;
@@ -915,8 +929,6 @@
     }
     if (this.security_ == CrOnc.Security.WPA_EAP)
       return this.eapIsConfigured_();
-    if (this.configProperties_.Type == CrOnc.Type.VPN)
-      return this.vpnIsConfigured_();
     return true;
   },
 
@@ -1059,7 +1071,6 @@
   /** @private */
   getPropertiesToSet_: function() {
     var propertiesToSet = Object.assign({}, this.configProperties_);
-    propertiesToSet.GUID = this.guid;
     var eap = this.getEap_(propertiesToSet);
     if (eap)
       this.setEapProperties_(eap);
@@ -1151,6 +1162,7 @@
     assert(vpn.IPsec);
     if (vpn.IPsec.AuthenticationType == CrOnc.IPsecAuthenticationType.CERT)
       vpn.IPsec.ClientCertPKCS11Id = this.getUserCertPkcs11Id_();
+    vpn.IPsec.IKEVersion = 1;
     vpn.IPsec.SaveCredentials = this.vpnSaveCredentials_;
     vpn.L2TP.SaveCredentials = this.vpnSaveCredentials_;
   },
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
index 821cb3c..b04b3732 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.html
@@ -10,8 +10,8 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="network_config_input.html">
 <link rel="import" href="network_shared_css.html">
 
 <dom-module id="network-siminfo">
@@ -33,14 +33,6 @@
         font-weight: 500;
       }
 
-      .pin {
-        min-width: 100px;
-      }
-
-      .puk {
-        min-width: 200px;
-      }
-
       .separator {
         -webkit-border-start: var(--cr-separator-line);
         -webkit-margin-end: var(--cr-section-padding);
@@ -98,11 +90,11 @@
         on-close="onEnterPinDialogClose_">
       <div slot="title">[[i18n('networkSimEnterPinTitle')]]</div>
       <div slot="body">
-        <paper-input id="enterPin" class="pin" no-label-float autofocus
+        <network-config-input id="enterPin" password autofocus
             label="[[i18n('networkSimEnterPin')]]">
           <iron-a11y-keys keys="enter" on-keys-pressed="sendEnterPin_">
           </iron-a11y-keys>
-        </paper-input>
+        </network-config-input>
         <div class="dialog-error">
           [[getErrorMsg_(error_, networkProperties)]]
         </div>
@@ -119,17 +111,17 @@
         on-close="onChangePinDialogClose_">
       <div slot="title">[[i18n('networkSimChangePinTitle')]]</div>
       <div slot="body">
-        <paper-input id="changePinOld" class="pin" no-label-float autofocus
+        <network-config-input id="changePinOld" password autofocus
             label="[[i18n('networkSimEnterOldPin')]]">
-        </paper-input>
-        <paper-input id="changePinNew1" class="pin" no-label-float
+        </network-config-input>
+        <network-config-input id="changePinNew1" password
             label="[[i18n('networkSimEnterNewPin')]]">
-        </paper-input>
-        <paper-input id="changePinNew2" class="pin" no-label-float
+        </network-config-input>
+        <network-config-input id="changePinNew2" password
             label="[[i18n('networkSimReEnterNewPin')]]">
           <iron-a11y-keys keys="enter" on-keys-pressed="sendChangePin_">
           </iron-a11y-keys>
-        </paper-input>
+        </network-config-input>
         <div class="dialog-error">
           [[getErrorMsg_(error_, networkProperties)]]
         </div>
@@ -146,11 +138,11 @@
         on-close="onUnlockPinDialogClose_">
       <div slot="title">[[i18n('networkSimLockedTitle')]]</div>
       <div slot="body">
-        <paper-input id="unlockPin" class="pin" no-label-float autofocus
+        <network-config-input id="unlockPin" password autofocus
             label="[[i18n('networkSimEnterPin')]]">
           <iron-a11y-keys keys="enter" on-keys-pressed="sendUnlockPin_">
           </iron-a11y-keys>
-        </paper-input>
+        </network-config-input>
         <div class="dialog-error">
           [[getErrorMsg_(error_, networkProperties)]]
         </div>
@@ -170,17 +162,17 @@
         <div>
           Enter the 8-digit PIN Unblocking Key provided by your carrier
         </div>
-        <paper-input id="unlockPuk" class="puk" no-label-float autofocus
+        <network-config-input id="unlockPuk" password autofocus
             label="[[i18n('networkSimEnterPuk')]]">
-        </paper-input>
-        <paper-input id="unlockPin1" class="pin" no-label-float
+        </network-config-input>
+        <network-config-input id="unlockPin1" password
             label="[[i18n('networkSimEnterNewPin')]]">
-        </paper-input>
-        <paper-input id="unlockPin2" class="pin" no-label-float
+        </network-config-input>
+        <network-config-input id="unlockPin2" password
             label="[[i18n('networkSimReEnterNewPin')]]">
           <iron-a11y-keys keys="enter" on-keys-pressed="sendUnlockPuk_">
           </iron-a11y-keys>
-        </paper-input>
+        </network-config-input>
         <div class="dialog-error">
           [[i18n('networkSimLockedWarning')]]
         </div>