diff --git a/DEPS b/DEPS
index 2af7275..695987ec3 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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': 'fc61514c46eb8d3c3dfa2a154405d76af2ae873f',
+  'v8_revision': '05751f9b95cae7ce26bdcc6b426fa89cdca448f1',
   # 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.
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc
index f0f1a929..58bc5f6 100644
--- a/ash/system/network/network_list.cc
+++ b/ash/system/network/network_list.cc
@@ -70,7 +70,7 @@
   if (!policy_prohibites_unmanaged)
     return false;
   return !managed_configuration_handler->FindPolicyByGuidAndProfile(
-      network->guid(), network->profile_path());
+      network->guid(), network->profile_path(), nullptr /* onc_source */);
 }
 
 }  // namespace
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
index a9b751b..84e5146 100644
--- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
+++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
@@ -11,7 +11,7 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/sequenced_task_runner.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
 #include "chrome/browser/android/offline_pages/background_loader_offliner.h"
 #include "chrome/browser/android/offline_pages/background_scheduler_bridge.h"
 #include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h"
@@ -36,7 +36,6 @@
 #include "components/offline_pages/core/offline_page_item.h"
 #include "components/offline_pages/core/offline_page_model.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
 #include "jni/OfflinePageEvaluationBridge_jni.h"
 #include "jni/SavePageRequest_jni.h"
 
@@ -132,8 +131,7 @@
     std::unique_ptr<OfflinerPolicy> policy,
     std::unique_ptr<Offliner> offliner) {
   scoped_refptr<base::SequencedTaskRunner> background_task_runner =
-      content::BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
-          content::BrowserThread::GetBlockingPool()->GetSequenceToken());
+      base::CreateSequencedTaskRunnerWithTraits(base::TaskTraits().MayBlock());
   Profile* profile = Profile::FromBrowserContext(context);
   base::FilePath queue_store_path =
       profile->GetPath().Append(chrome::kOfflinePageRequestQueueDirname);
diff --git a/chrome/browser/chromeos/enrollment_dialog_view.cc b/chrome/browser/chromeos/enrollment_dialog_view.cc
index 33f3af5a..0fdf43cd 100644
--- a/chrome/browser/chromeos/enrollment_dialog_view.cc
+++ b/chrome/browser/chromeos/enrollment_dialog_view.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/grit/generated_resources.h"
+#include "chromeos/login/login_state.h"
 #include "chromeos/network/client_cert_util.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
 #include "chromeos/network/network_event_log.h"
@@ -251,6 +252,37 @@
   NET_LOG_USER("Enrollment Complete", network_id);
 }
 
+// Decides if the enrollment dialog is allowed in the current login state.
+bool EnrollmentDialogAllowed(Profile* profile) {
+  // Enrollment dialog is currently not supported on the sign-in profile.
+  // This also applies to lock screen,
+  if (ProfileHelper::IsSigninProfile(profile))
+    return false;
+
+  chromeos::LoginState::LoggedInUserType user_type =
+      LoginState::Get()->GetLoggedInUserType();
+  switch (user_type) {
+    case LoginState::LOGGED_IN_USER_NONE:
+      return false;
+    case LoginState::LOGGED_IN_USER_REGULAR:
+      return true;
+    case LoginState::LOGGED_IN_USER_OWNER:
+      return true;
+    case LoginState::LOGGED_IN_USER_GUEST:
+      return true;
+    case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
+      return false;
+    case LoginState::LOGGED_IN_USER_SUPERVISED:
+      return true;
+    case LoginState::LOGGED_IN_USER_KIOSK_APP:
+      return false;
+    case LoginState::LOGGED_IN_USER_ARC_KIOSK_APP:
+      return false;
+  }
+  NOTREACHED();
+  return false;
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -270,6 +302,8 @@
   Browser* browser = chrome::FindBrowserWithWindow(owning_window);
   Profile* profile =
       browser ? browser->profile() : ProfileManager::GetPrimaryUserProfile();
+  if (!EnrollmentDialogAllowed(profile))
+    return false;
   std::string username_hash = ProfileHelper::GetUserIdHashFromProfile(profile);
 
   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
@@ -278,14 +312,11 @@
           ->managed_network_configuration_handler()
           ->FindPolicyByGUID(username_hash, network_id, &onc_source);
 
-  // We skip certificate patterns for device policy ONC so that an unmanaged
-  // user can't get to the place where a cert is presented for them
-  // involuntarily.
-  if (!policy || onc_source == onc::ONC_SOURCE_DEVICE_POLICY)
+  if (!policy)
     return false;
 
   client_cert::ClientCertConfig cert_config;
-  OncToClientCertConfig(*policy, &cert_config);
+  OncToClientCertConfig(onc_source, *policy, &cert_config);
 
   if (cert_config.client_cert_type != onc::client_cert::kPattern)
     return false;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 06ecc1d9..91c4629 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -130,22 +130,15 @@
                       TestParameter(NOT_IN_GUEST_MODE, "imageOpenDownloads"),
                       TestParameter(NOT_IN_GUEST_MODE, "imageOpenDrive")));
 
-#if defined(DISABLE_SLOW_FILESAPP_TESTS) || defined(OFFICIAL_BUILD)
-#define MAYBE_CreateNewFolder DISABLED_CreateNewFolder
-#else
-#define MAYBE_CreateNewFolder CreateNewFolder
-#endif
+// Flaky: crbug.com/715963
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    MAYBE_CreateNewFolder,
+    DISABLED_CreateNewFolder,
     FileManagerBrowserTest,
-    ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
-                                    "createNewFolderAfterSelectFile"),
-                      TestParameter(IN_GUEST_MODE,
-                                    "createNewFolderDownloads"),
-                      TestParameter(NOT_IN_GUEST_MODE,
-                                    "createNewFolderDownloads"),
-                      TestParameter(NOT_IN_GUEST_MODE,
-                                    "createNewFolderDrive")));
+    ::testing::Values(
+        TestParameter(NOT_IN_GUEST_MODE, "createNewFolderAfterSelectFile"),
+        TestParameter(IN_GUEST_MODE, "createNewFolderDownloads"),
+        TestParameter(NOT_IN_GUEST_MODE, "createNewFolderDownloads"),
+        TestParameter(NOT_IN_GUEST_MODE, "createNewFolderDrive")));
 
 // Fails on official build. http://crbug.com/429294
 #if defined(DISABLE_SLOW_FILESAPP_TESTS) || defined(OFFICIAL_BUILD)
diff --git a/chrome/browser/policy/cloud/test_request_interceptor.cc b/chrome/browser/policy/cloud/test_request_interceptor.cc
index 40e42f5..ea725628 100644
--- a/chrome/browser/policy/cloud/test_request_interceptor.cc
+++ b/chrome/browser/policy/cloud/test_request_interceptor.cc
@@ -15,9 +15,8 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/sequenced_task_runner.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "content/public/browser/browser_thread.h"
 #include "net/base/net_errors.h"
 #include "net/base/upload_bytes_element_reader.h"
 #include "net/base/upload_data_stream.h"
@@ -64,12 +63,13 @@
                                     net::URLRequest* request,
                                     net::NetworkDelegate* network_delegate) {
   return new net::URLRequestMockHTTPJob(
-      request,
-      network_delegate,
-      file_path,
-      content::BrowserThread::GetBlockingPool()
-          ->GetTaskRunnerWithShutdownBehavior(
-              base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
+      request, network_delegate, file_path,
+      base::CreateTaskRunnerWithTraits(
+          base::TaskTraits()
+              .MayBlock()
+              .WithPriority(base::TaskPriority::BACKGROUND)
+              .WithShutdownBehavior(
+                  base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN)));
 }
 
 // Parses the upload data in |request| into |request_msg|, and validates the
diff --git a/chrome/browser/supervised_user/supervised_user_site_list.cc b/chrome/browser/supervised_user/supervised_user_site_list.cc
index 8b9253b2..9a7c7162 100644
--- a/chrome/browser/supervised_user/supervised_user_site_list.cc
+++ b/chrome/browser/supervised_user/supervised_user_site_list.cc
@@ -11,10 +11,8 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/values.h"
-#include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
 const int kLegacyWhitelistFormatVersion = 2;
@@ -91,14 +89,16 @@
                                   const base::FilePath& large_icon_path,
                                   const base::FilePath& path,
                                   const LoadedCallback& callback) {
-  base::PostTaskAndReplyWithResult(
-      content::BrowserThread::GetBlockingPool()
-          ->GetTaskRunnerWithShutdownBehavior(
-              base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
-          .get(),
-      FROM_HERE, base::Bind(&ReadFileOnBlockingThread, path),
-      base::Bind(&SupervisedUserSiteList::OnJsonLoaded, id, title,
-                 large_icon_path, path, base::TimeTicks::Now(), callback));
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      base::TaskTraits()
+          .MayBlock()
+          .WithPriority(base::TaskPriority::BACKGROUND)
+          .WithShutdownBehavior(
+              base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN),
+      base::BindOnce(&ReadFileOnBlockingThread, path),
+      base::BindOnce(&SupervisedUserSiteList::OnJsonLoaded, id, title,
+                     large_icon_path, path, base::TimeTicks::Now(), callback));
 }
 
 SupervisedUserSiteList::SupervisedUserSiteList(
diff --git a/chrome/common/extensions/api/notifications.idl b/chrome/common/extensions/api/notifications.idl
index d3cc1ac..1827388 100644
--- a/chrome/common/extensions/api/notifications.idl
+++ b/chrome/common/extensions/api/notifications.idl
@@ -10,9 +10,11 @@
     basic,
 
     // icon, title, message, expandedMessage, image, up to two buttons
+    [deprecated="The image is not visible for Mac OS X users."]
     image,
 
-    // icon, title, message, items, up to two buttons
+    // icon, title, message, items, up to two buttons. Users on Mac OS X only
+    // see the first item.
     list,
 
     // icon, title, message, progress, up to two buttons
@@ -44,6 +46,7 @@
 
   dictionary NotificationButton {
     DOMString title;
+    [deprecated="Button icons not visible for Mac OS X users."]
     DOMString? iconUrl;
     [nodoc] NotificationBitmap? iconBitmap;
   };
@@ -64,9 +67,10 @@
 
     // A URL to the app icon mask. URLs have the same restrictions as
     // $(ref:notifications.NotificationOptions.iconUrl iconUrl).
-    // 
+    //
     // The app icon mask should be in alpha channel, as only the alpha channel
     // of the image will be considered.
+    [deprecated="The app icon mask is not visible for Mac OS X users."]
     DOMString? appIconMaskUrl;
     [nodoc] NotificationBitmap? appIconMaskBitmap;
 
@@ -98,12 +102,14 @@
     [nodoc] DOMString? expandedMessage;
 
     // A URL to the image thumbnail for image-type notifications.
-    // URLs have the same restrictions as 
+    // URLs have the same restrictions as
     // $(ref:notifications.NotificationOptions.iconUrl iconUrl).
+    [deprecated="The image is not visible for Mac OS X users."]
     DOMString? imageUrl;
     [nodoc] NotificationBitmap? imageBitmap;
 
-    // Items for multi-item notifications.
+    // Items for multi-item notifications. Users on Mac OS X only see the first
+    // item.
     NotificationItem[]? items;
 
     // Current progress ranges from 0 to 100.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index fd7c3df..e69c13f 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -395,7 +395,6 @@
       "../browser/ui/views/accessibility/navigation_accessibility_uitest_win.cc",
       "../browser/ui/webui/options/language_dictionary_interactive_uitest.cc",
       "../browser/ui/webui/options/language_options_interactive_uitest.cc",
-      "//ui/base/clipboard/clipboard_android_unittest.cc",
       "//ui/base/clipboard/clipboard_unittest.cc",
       "base/always_on_top_window_killer_win.cc",
       "base/always_on_top_window_killer_win.h",
diff --git a/chromeos/cert_loader.cc b/chromeos/cert_loader.cc
index 4e4131ba..0b9a638 100644
--- a/chromeos/cert_loader.cc
+++ b/chromeos/cert_loader.cc
@@ -9,8 +9,9 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/threading/worker_pool.h"
 #include "crypto/nss_util.h"
 #include "crypto/scoped_nss_types.h"
@@ -20,7 +21,56 @@
 
 namespace chromeos {
 
-static CertLoader* g_cert_loader = NULL;
+namespace {
+
+// Checks if |certificate| is on the given |slot|.
+bool IsCertificateOnSlot(const net::X509Certificate* certificate,
+                         PK11SlotInfo* slot) {
+  crypto::ScopedPK11SlotList slots_for_cert(
+      PK11_GetAllSlotsForCert(certificate->os_cert_handle(), nullptr));
+  if (!slots_for_cert)
+    return false;
+
+  for (PK11SlotListElement* slot_element =
+           PK11_GetFirstSafe(slots_for_cert.get());
+       slot_element; slot_element = PK11_GetNextSafe(slots_for_cert.get(),
+                                                     slot_element, PR_FALSE)) {
+    if (slot_element->slot == slot) {
+      // All previously visited elements have been freed by PK11_GetNextSafe,
+      // but we're not calling that for the last one, so free it explicitly.
+      // The slots_for_cert list itself will be freed because ScopedPK11SlotList
+      // is a unique_ptr.
+      PK11_FreeSlotListElement(slots_for_cert.get(), slot_element);
+      return true;
+    }
+  }
+  return false;
+}
+
+// Goes through all certificates in |all_certs| and copies those certificates
+// which are on |system_slot| to a new list.
+std::unique_ptr<net::CertificateList> FilterSystemTokenCertificates(
+    const net::CertificateList* all_certs,
+    crypto::ScopedPK11Slot system_slot) {
+  VLOG(1) << "FilterSystemTokenCertificates";
+  std::unique_ptr<net::CertificateList> system_certs =
+      base::MakeUnique<net::CertificateList>();
+  if (!system_slot)
+    return system_certs;
+
+  // Extract certificates which are in the system token into the
+  // |system_certs_| sublist.
+  for (const auto& cert : *all_certs) {
+    if (IsCertificateOnSlot(cert.get(), system_slot.get())) {
+      system_certs->push_back(cert);
+    }
+  }
+  return system_certs;
+}
+
+}  // namespace
+
+static CertLoader* g_cert_loader = nullptr;
 static bool g_force_hardware_backed_for_test = false;
 
 // static
@@ -33,7 +83,7 @@
 void CertLoader::Shutdown() {
   CHECK(g_cert_loader);
   delete g_cert_loader;
-  g_cert_loader = NULL;
+  g_cert_loader = nullptr;
 }
 
 // static
@@ -51,10 +101,9 @@
     : certificates_loaded_(false),
       certificates_update_required_(false),
       certificates_update_running_(false),
-      database_(NULL),
-      cert_list_(new net::CertificateList),
-      weak_factory_(this) {
-}
+      database_(nullptr),
+      all_certs_(base::MakeUnique<net::CertificateList>()),
+      weak_factory_(this) {}
 
 CertLoader::~CertLoader() {
   net::CertDatabase::GetInstance()->RemoveObserver(this);
@@ -116,8 +165,8 @@
   DCHECK(slot_id);
 
   CERTCertificateStr* cert_handle = cert.os_cert_handle();
-  SECKEYPrivateKey *priv_key =
-      PK11_FindKeyByAnyCert(cert_handle, NULL /* wincx */);
+  SECKEYPrivateKey* priv_key =
+      PK11_FindKeyByAnyCert(cert_handle, nullptr /* wincx */);
   if (!priv_key)
     return std::string();
 
@@ -136,7 +185,7 @@
 }
 
 void CertLoader::LoadCertificates() {
-  CHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   VLOG(1) << "LoadCertificates: " << certificates_update_running_;
 
   if (certificates_update_running_) {
@@ -148,17 +197,38 @@
   certificates_update_required_ = false;
 
   database_->ListCerts(
-      base::Bind(&CertLoader::UpdateCertificates, weak_factory_.GetWeakPtr()));
+      base::Bind(&CertLoader::CertificatesLoaded, weak_factory_.GetWeakPtr()));
+}
+
+void CertLoader::CertificatesLoaded(
+    std::unique_ptr<net::CertificateList> all_certs) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  VLOG(1) << "CertificatesLoaded: " << all_certs->size();
+
+  crypto::ScopedPK11Slot system_slot = database_->GetSystemSlot();
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      base::TaskTraits()
+          .WithShutdownBehavior(
+              base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
+          .MayBlock(),
+      base::BindOnce(&FilterSystemTokenCertificates,
+                     base::Unretained(all_certs.get()), std::move(system_slot)),
+      base::BindOnce(&CertLoader::UpdateCertificates,
+                     weak_factory_.GetWeakPtr(), std::move(all_certs)));
 }
 
 void CertLoader::UpdateCertificates(
-    std::unique_ptr<net::CertificateList> cert_list) {
-  CHECK(thread_checker_.CalledOnValidThread());
+    std::unique_ptr<net::CertificateList> all_certs,
+    std::unique_ptr<net::CertificateList> system_certs) {
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(certificates_update_running_);
-  VLOG(1) << "UpdateCertificates: " << cert_list->size();
+  VLOG(1) << "UpdateCertificates: " << all_certs->size() << " ("
+          << system_certs->size() << " on system slot)";
 
   // Ignore any existing certificates.
-  cert_list_ = std::move(cert_list);
+  all_certs_ = std::move(all_certs);
+  system_certs_ = std::move(system_certs);
 
   bool initial_load = !certificates_loaded_;
   certificates_loaded_ = true;
@@ -171,7 +241,7 @@
 
 void CertLoader::NotifyCertificatesLoaded(bool initial_load) {
   for (auto& observer : observers_)
-    observer.OnCertificatesLoaded(*cert_list_, initial_load);
+    observer.OnCertificatesLoaded(*all_certs_, initial_load);
 }
 
 void CertLoader::OnCertDBChanged() {
diff --git a/chromeos/cert_loader.h b/chromeos/cert_loader.h
index 7243c6d..7faedbf7 100644
--- a/chromeos/cert_loader.h
+++ b/chromeos/cert_loader.h
@@ -35,10 +35,10 @@
  public:
   class Observer {
    public:
-    // Called when the certificates, passed for convenience as |cert_list|,
+    // Called when the certificates, passed for convenience as |all_certs|,
     // have completed loading. |initial_load| is true the first time this
     // is called.
-    virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
+    virtual void OnCertificatesLoaded(const net::CertificateList& all_certs,
                                       bool initial_load) = 0;
 
    protected:
@@ -83,8 +83,19 @@
 
   bool certificates_loaded() const { return certificates_loaded_; }
 
-  // This will be empty until certificates_loaded() is true.
-  const net::CertificateList& cert_list() const { return *cert_list_; }
+  // Returns all certificates. This will be empty until certificates_loaded() is
+  // true.
+  const net::CertificateList& all_certs() const {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return *all_certs_;
+  }
+
+  // Returns certificates from the system token. This will be empty until
+  // certificates_loaded() is true.
+  const net::CertificateList& system_certs() const {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return *system_certs_;
+  }
 
   // Called in tests if |IsCertificateHardwareBacked()| should always return
   // true.
@@ -98,8 +109,12 @@
   // progress, will start a reload once the current task is finished.
   void LoadCertificates();
 
+  // Called when the underlying NSS database finished loading certificates.
+  void CertificatesLoaded(std::unique_ptr<net::CertificateList> all_certs);
+
   // Called if a certificate load task is finished.
-  void UpdateCertificates(std::unique_ptr<net::CertificateList> cert_list);
+  void UpdateCertificates(std::unique_ptr<net::CertificateList> all_certs,
+                          std::unique_ptr<net::CertificateList> system_certs);
 
   void NotifyCertificatesLoaded(bool initial_load);
 
@@ -117,8 +132,12 @@
   // should be loaded.
   net::NSSCertDatabase* database_;
 
-  // Cached Certificates loaded from the database.
-  std::unique_ptr<net::CertificateList> cert_list_;
+  // Cached certificates loaded from the database.
+  std::unique_ptr<net::CertificateList> all_certs_;
+
+  // Cached certificates from system token. Currently this is a sublist of
+  // |all_certs_|.
+  std::unique_ptr<net::CertificateList> system_certs_;
 
   base::ThreadChecker thread_checker_;
 
diff --git a/chromeos/cert_loader_unittest.cc b/chromeos/cert_loader_unittest.cc
index 6056f76..405cf29d 100644
--- a/chromeos/cert_loader_unittest.cc
+++ b/chromeos/cert_loader_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_scheduler.h"
 #include "crypto/scoped_nss_types.h"
 #include "crypto/scoped_test_nss_db.h"
 #include "net/cert/nss_cert_database_chromeos.h"
@@ -45,7 +46,8 @@
                                 std::move(private_slot)) {}
   ~TestNSSCertDatabase() override {}
 
-  void NotifyOfCertAdded(const net::X509Certificate* cert) {
+  // Make this method visible in the public interface.
+  void NotifyObserversCertDBChanged() {
     NSSCertDatabaseChromeOS::NotifyObserversCertDBChanged();
   }
 };
@@ -54,7 +56,9 @@
                        public CertLoader::Observer {
  public:
   CertLoaderTest()
-      : cert_loader_(nullptr), certificates_loaded_events_count_(0U) {}
+      : cert_loader_(nullptr),
+        scoped_task_scheduler_(&message_loop_),
+        certificates_loaded_events_count_(0U) {}
 
   ~CertLoaderTest() override {}
 
@@ -80,6 +84,17 @@
     GetAndResetCertificatesLoadedEventsCount();
   }
 
+  // Starts the cert loader with a primary cert database which has access to the
+  // system token.
+  void StartCertLoaderWithPrimaryDBAndSystemToken() {
+    CreateCertDatabase(&primary_db_, &primary_certdb_);
+    AddSystemToken(primary_certdb_.get());
+    cert_loader_->StartWithNSSDB(primary_certdb_.get());
+
+    base::RunLoop().RunUntilIdle();
+    GetAndResetCertificatesLoadedEventsCount();
+  }
+
   // CertLoader::Observer:
   // The test keeps count of times the observer method was called.
   void OnCertificatesLoaded(const net::CertificateList& cert_list,
@@ -125,17 +140,27 @@
     ASSERT_TRUE(failed.empty());
   }
 
+  // Import a client cert and key into a PKCS11 slot. Then notify
+  // |database_to_notify| (which is presumably using that slot) that new
+  // certificates are available.
   scoped_refptr<net::X509Certificate> ImportClientCertAndKey(
-      TestNSSCertDatabase* database) {
+      TestNSSCertDatabase* database_to_notify,
+      PK11SlotInfo* slot_to_use) {
     // Import a client cert signed by that CA.
     scoped_refptr<net::X509Certificate> client_cert(
         net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
                                             "client_1.pem", "client_1.pk8",
-                                            database->GetPrivateSlot().get()));
-    database->NotifyOfCertAdded(client_cert.get());
+                                            slot_to_use));
+    database_to_notify->NotifyObserversCertDBChanged();
     return client_cert;
   }
 
+  // Import a client cert into |database|'s private slot.
+  scoped_refptr<net::X509Certificate> ImportClientCertAndKey(
+      TestNSSCertDatabase* database) {
+    return ImportClientCertAndKey(database, database->GetPrivateSlot().get());
+  }
+
   CertLoader* cert_loader_;
 
   // The user is primary as the one whose certificates CertLoader handles, it
@@ -144,9 +169,20 @@
   crypto::ScopedTestNSSDB primary_db_;
   std::unique_ptr<TestNSSCertDatabase> primary_certdb_;
 
+  // Additional NSS DB simulating the system token.
+  crypto::ScopedTestNSSDB system_db_;
+
   base::MessageLoop message_loop_;
 
  private:
+  // Adds the PKCS11 slot from |system_db_| to |certdb| as system slot.
+  void AddSystemToken(TestNSSCertDatabase* certdb) {
+    ASSERT_TRUE(system_db_.is_open());
+    certdb->SetSystemSlot(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(system_db_.slot())));
+  }
+
+  base::test::ScopedTaskScheduler scoped_task_scheduler_;
   size_t certificates_loaded_events_count_;
 };
 
@@ -161,7 +197,7 @@
 
   EXPECT_FALSE(cert_loader_->certificates_loaded());
   EXPECT_TRUE(cert_loader_->CertificatesLoading());
-  EXPECT_TRUE(cert_loader_->cert_list().empty());
+  EXPECT_TRUE(cert_loader_->all_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   base::RunLoop().RunUntilIdle();
@@ -171,7 +207,7 @@
   EXPECT_FALSE(cert_loader_->CertificatesLoading());
 
   // Default CA cert roots should get loaded.
-  EXPECT_FALSE(cert_loader_->cert_list().empty());
+  EXPECT_FALSE(cert_loader_->all_certs().empty());
 }
 
 TEST_F(CertLoaderTest, CertLoaderUpdatesCertListOnNewCert) {
@@ -183,7 +219,7 @@
   // Certs are loaded asynchronously, so the new cert should not yet be in the
   // cert list.
   EXPECT_FALSE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
+      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   base::RunLoop().RunUntilIdle();
@@ -191,7 +227,7 @@
 
   // The certificate list should be updated now, as the message loop's been run.
   EXPECT_TRUE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
+      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
 
   EXPECT_FALSE(cert_loader_->IsCertificateHardwareBacked(certs[0].get()));
 }
@@ -209,7 +245,7 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_FALSE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
+      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
 }
 
 TEST_F(CertLoaderTest, ClientLoaderUpdateOnNewClientCert) {
@@ -222,7 +258,24 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
-  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->cert_list()));
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+}
+
+TEST_F(CertLoaderTest, ClientLoaderUpdateOnNewClientCertInSystemToken) {
+  StartCertLoaderWithPrimaryDBAndSystemToken();
+
+  EXPECT_TRUE(cert_loader_->system_certs().empty());
+  scoped_refptr<net::X509Certificate> cert(ImportClientCertAndKey(
+      primary_certdb_.get(), primary_certdb_->GetSystemSlot().get()));
+
+  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
+
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_EQ(1U, cert_loader_->system_certs().size());
+  EXPECT_TRUE(
+      IsCertInCertificateList(cert.get(), cert_loader_->system_certs()));
 }
 
 TEST_F(CertLoaderTest, CertLoaderNoUpdateOnNewClientCertInSecondaryDb) {
@@ -237,7 +290,7 @@
 
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->cert_list()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
 }
 
 TEST_F(CertLoaderTest, UpdatedOnCertRemoval) {
@@ -249,7 +302,7 @@
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  ASSERT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->cert_list()));
+  ASSERT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
 
   primary_certdb_->DeleteCertAndKey(cert.get());
 
@@ -257,7 +310,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
-  ASSERT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->cert_list()));
+  ASSERT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
 }
 
 TEST_F(CertLoaderTest, UpdatedOnCACertTrustChange) {
@@ -269,7 +322,7 @@
   base::RunLoop().RunUntilIdle();
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
   ASSERT_TRUE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
+      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
 
   // The value that should have been set by |ImportCACert|.
   ASSERT_EQ(net::NSSCertDatabase::TRUST_DEFAULT,
diff --git a/chromeos/chromeos_paths.cc b/chromeos/chromeos_paths.cc
index 53177d2..e5c12b9 100644
--- a/chromeos/chromeos_paths.cc
+++ b/chromeos/chromeos_paths.cc
@@ -32,8 +32,8 @@
 const base::FilePath::CharType kMachineHardwareInfoFileName[] =
     FILE_PATH_LITERAL("/tmp/machine-info");
 
-const base::FilePath::CharType kVpdFileName[] =
-    FILE_PATH_LITERAL("/var/log/vpd_2.0.txt");
+const base::FilePath::CharType kVpdFileName[] = FILE_PATH_LITERAL(
+    "/mnt/stateful_partition/unencrypted/cache/vpd/filtered.txt");
 
 const base::FilePath::CharType kUptimeFileName[] =
     FILE_PATH_LITERAL("/proc/uptime");
diff --git a/chromeos/network/auto_connect_handler.cc b/chromeos/network/auto_connect_handler.cc
index 69d84a5..885068dc 100644
--- a/chromeos/network/auto_connect_handler.cc
+++ b/chromeos/network/auto_connect_handler.cc
@@ -241,7 +241,7 @@
     const bool network_is_policy_managed =
         !network->profile_path().empty() && !network->guid().empty() &&
         managed_configuration_handler_->FindPolicyByGuidAndProfile(
-            network->guid(), network->profile_path());
+            network->guid(), network->profile_path(), nullptr /* onc_source */);
     if (network_is_policy_managed)
       continue;
 
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index 788e5ee9..74cb136 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -13,6 +13,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/task_scheduler/post_task.h"
@@ -191,25 +192,35 @@
 // Searches for matches between |networks| and |certs| and writes matches to
 // |matches|. Because this calls NSS functions and is potentially slow, it must
 // be run on a worker thread.
-void FindCertificateMatches(const net::CertificateList& certs,
-                            std::vector<NetworkAndCertPattern>* networks,
-                            base::Time now,
-                            NetworkCertMatches* matches) {
-  std::vector<CertAndIssuer> client_certs(
-      CreateSortedCertAndIssuerList(certs, now));
+std::unique_ptr<NetworkCertMatches> FindCertificateMatches(
+    const net::CertificateList& all_certs,
+    const net::CertificateList& system_certs,
+    std::vector<NetworkAndCertPattern>* networks,
+    base::Time now) {
+  std::unique_ptr<NetworkCertMatches> matches =
+      base::MakeUnique<NetworkCertMatches>();
+
+  std::vector<CertAndIssuer> all_client_certs(
+      CreateSortedCertAndIssuerList(all_certs, now));
+  std::vector<CertAndIssuer> system_client_certs(
+      CreateSortedCertAndIssuerList(system_certs, now));
 
   for (std::vector<NetworkAndCertPattern>::const_iterator it =
            networks->begin();
        it != networks->end(); ++it) {
-    std::vector<CertAndIssuer>::iterator cert_it =
-        std::find_if(client_certs.begin(),
-                     client_certs.end(),
-                     MatchCertWithPattern(it->cert_config.pattern));
+    // Use only certs from the system token if the source of the client cert
+    // pattern is device policy.
+    std::vector<CertAndIssuer>* client_certs =
+        it->cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY
+            ? &system_client_certs
+            : &all_client_certs;
+    auto cert_it = std::find_if(client_certs->begin(), client_certs->end(),
+                                MatchCertWithPattern(it->cert_config.pattern));
     std::string pkcs11_id;
     int slot_id = -1;
     std::string identity;
 
-    if (cert_it == client_certs.end()) {
+    if (cert_it == client_certs->end()) {
       VLOG(1) << "Couldn't find a matching client cert for network "
               << it->service_path;
       // Leave |pkcs11_id| empty to indicate that no cert was found for this
@@ -256,6 +267,7 @@
         it->service_path, it->cert_config.location, pkcs11_id, slot_id,
         identity));
   }
+  return matches;
 }
 
 void LogError(const std::string& service_path,
@@ -325,15 +337,23 @@
 // static
 bool ClientCertResolver::ResolveCertificatePatternSync(
     const client_cert::ConfigType client_cert_type,
-    const CertificatePattern& pattern,
+    const client_cert::ClientCertConfig& client_cert_config,
     base::DictionaryValue* shill_properties) {
-  // Prepare and sort the list of known client certs.
-  std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(
-      CertLoader::Get()->cert_list(), base::Time::Now()));
+  // Prepare and sort the list of known client certs. Use only certs from the
+  // system token if the source of the client cert pattern is device policy.
+  std::vector<CertAndIssuer> client_certs;
+  if (client_cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
+    client_certs = CreateSortedCertAndIssuerList(
+        CertLoader::Get()->system_certs(), base::Time::Now());
+  } else {
+    client_certs = CreateSortedCertAndIssuerList(CertLoader::Get()->all_certs(),
+                                                 base::Time::Now());
+  }
 
   // Search for a certificate matching the pattern.
-  std::vector<CertAndIssuer>::iterator cert_it = std::find_if(
-      client_certs.begin(), client_certs.end(), MatchCertWithPattern(pattern));
+  std::vector<CertAndIssuer>::iterator cert_it =
+      std::find_if(client_certs.begin(), client_certs.end(),
+                   MatchCertWithPattern(client_cert_config.pattern));
 
   if (cert_it == client_certs.end()) {
     VLOG(1) << "Couldn't find a matching client cert";
@@ -452,9 +472,10 @@
     if (network->profile_path().empty())
       continue;
 
+    onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
     const base::DictionaryValue* policy =
         managed_network_config_handler_->FindPolicyByGuidAndProfile(
-            network->guid(), network->profile_path());
+            network->guid(), network->profile_path(), &onc_source);
 
     if (!policy) {
       VLOG(1) << "The policy for network " << network->path() << " with GUID "
@@ -466,7 +487,7 @@
 
     VLOG(2) << "Inspecting network " << network->path();
     client_cert::ClientCertConfig cert_config;
-    OncToClientCertConfig(*policy, &cert_config);
+    OncToClientCertConfig(onc_source, *policy, &cert_config);
 
     // Skip networks that don't have a ClientCertPattern.
     if (cert_config.client_cert_type != ::onc::client_cert::kPattern)
@@ -493,16 +514,17 @@
 
   VLOG(2) << "Start task for resolving client cert patterns.";
   resolve_task_running_ = true;
-  NetworkCertMatches* matches = new NetworkCertMatches;
-  base::PostTaskWithTraitsAndReply(
-      FROM_HERE, base::TaskTraits()
-                     .WithShutdownBehavior(
-                         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
-                     .MayBlock(),
-      base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(),
-                 base::Owned(networks_to_resolve.release()), Now(), matches),
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      base::TaskTraits()
+          .WithShutdownBehavior(
+              base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
+          .MayBlock(),
+      base::Bind(&FindCertificateMatches, CertLoader::Get()->all_certs(),
+                 CertLoader::Get()->system_certs(),
+                 base::Owned(networks_to_resolve.release()), Now()),
       base::Bind(&ClientCertResolver::ConfigureCertificates,
-                 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches)));
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void ClientCertResolver::ResolvePendingNetworks() {
@@ -523,7 +545,8 @@
   ResolveNetworks(networks_to_resolve);
 }
 
-void ClientCertResolver::ConfigureCertificates(NetworkCertMatches* matches) {
+void ClientCertResolver::ConfigureCertificates(
+    std::unique_ptr<NetworkCertMatches> matches) {
   for (NetworkCertMatches::const_iterator it = matches->begin();
        it != matches->end(); ++it) {
     VLOG(1) << "Configuring certificate of network " << it->service_path;
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h
index 63d6d89..669109c46 100644
--- a/chromeos/network/client_cert_resolver.h
+++ b/chromeos/network/client_cert_resolver.h
@@ -79,7 +79,7 @@
   // expiration.
   static bool ResolveCertificatePatternSync(
       const client_cert::ConfigType client_cert_type,
-      const CertificatePattern& pattern,
+      const client_cert::ClientCertConfig& client_cert_config,
       base::DictionaryValue* shill_properties);
 
  private:
@@ -105,7 +105,8 @@
 
   // |matches| contains networks for which a matching certificate was found.
   // Configures these networks.
-  void ConfigureCertificates(std::vector<NetworkAndMatchingCert>* matches);
+  void ConfigureCertificates(
+      std::unique_ptr<std::vector<NetworkAndMatchingCert>> matches);
 
   // Trigger a ResolveRequestCompleted event on all observers.
   void NotifyResolveRequestCompleted();
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 8caac7a..0657648 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -53,16 +53,12 @@
 class ClientCertResolverTest : public testing::Test,
                                public ClientCertResolver::Observer {
  public:
-  ClientCertResolverTest()
-      : network_properties_changed_count_(0),
-        service_test_(nullptr),
-        profile_test_(nullptr),
-        cert_loader_(nullptr),
-        scoped_task_scheduler_(&message_loop_) {}
+  ClientCertResolverTest() : scoped_task_scheduler_(&message_loop_) {}
   ~ClientCertResolverTest() override {}
 
   void SetUp() override {
     ASSERT_TRUE(test_nssdb_.is_open());
+    ASSERT_TRUE(test_system_nssdb_.is_open());
 
     // Use the same DB for public and private slot.
     test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
@@ -86,10 +82,12 @@
   }
 
   void TearDown() override {
-    client_cert_resolver_->RemoveObserver(this);
+    if (client_cert_resolver_)
+      client_cert_resolver_->RemoveObserver(this);
     client_cert_resolver_.reset();
     test_clock_.reset();
-    network_state_handler_->Shutdown();
+    if (network_state_handler_)
+      network_state_handler_->Shutdown();
     managed_config_handler_.reset();
     network_config_handler_.reset();
     network_profile_handler_.reset();
@@ -137,6 +135,16 @@
     ASSERT_TRUE(test_client_cert_.get());
   }
 
+  void SetupTestCertInSystemToken(const std::string& prefix) {
+    test_nsscertdb_->SetSystemSlot(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
+
+    test_client_cert_ = net::ImportClientCertAndKeyFromFile(
+        net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
+        test_system_nssdb_.slot());
+    ASSERT_TRUE(test_client_cert_.get());
+  }
+
   void SetupNetworkHandlers() {
     network_state_handler_ = NetworkStateHandler::InitializeForTest();
     network_profile_handler_.reset(new NetworkProfileHandler());
@@ -184,7 +192,7 @@
 
   // Sets up a policy with a certificate pattern that matches any client cert
   // with a certain Issuer CN. It will match the test client cert.
-  void SetupPolicyMatchingIssuerCN() {
+  void SetupPolicyMatchingIssuerCN(onc::ONCSource onc_source) {
     const char* kTestPolicy =
         "[ { \"GUID\": \"wifi_stub\","
         "    \"Name\": \"wifi_stub\","
@@ -213,15 +221,40 @@
     base::ListValue* policy = nullptr;
     ASSERT_TRUE(policy_value->GetAsList(&policy));
 
+    std::string user_hash =
+        onc_source == onc::ONC_SOURCE_USER_POLICY ? kUserHash : "";
     managed_config_handler_->SetPolicy(
-        onc::ONC_SOURCE_USER_POLICY, kUserHash, *policy,
+        onc_source, user_hash, *policy,
         base::DictionaryValue() /* no global network config */);
   }
 
+  void SetupCertificateConfigMatchingIssuerCN(
+      onc::ONCSource onc_source,
+      client_cert::ClientCertConfig* client_cert_config) {
+    const char* kTestOncPattern =
+        "{"
+        "  \"Issuer\": {"
+        "    \"CommonName\": \"B CA\""
+        "  }"
+        "}";
+    std::string error;
+    std::unique_ptr<base::Value> onc_pattern_value =
+        base::JSONReader::ReadAndReturnError(
+            kTestOncPattern, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);
+    ASSERT_TRUE(onc_pattern_value) << error;
+
+    base::DictionaryValue* onc_pattern_dict;
+    onc_pattern_value->GetAsDictionary(&onc_pattern_dict);
+
+    client_cert_config->onc_source = onc_source;
+    client_cert_config->pattern.ReadFromONCDictionary(*onc_pattern_dict);
+  }
+
   // Sets up a policy with a certificate pattern that matches any client cert
   // that is signed by the test CA cert (stored in |test_ca_cert_pem_|). In
   // particular it will match the test client cert.
-  void SetupPolicyMatchingIssuerPEM(const std::string& identity) {
+  void SetupPolicyMatchingIssuerPEM(onc::ONCSource onc_source,
+                                    const std::string& identity) {
     const char* kTestPolicyTemplate =
         "[ { \"GUID\": \"wifi_stub\","
         "    \"Name\": \"wifi_stub\","
@@ -251,10 +284,10 @@
     base::ListValue* policy = nullptr;
     ASSERT_TRUE(policy_value->GetAsList(&policy));
 
+    std::string user_hash =
+        onc_source == onc::ONC_SOURCE_USER_POLICY ? kUserHash : "";
     managed_config_handler_->SetPolicy(
-        onc::ONC_SOURCE_USER_POLICY,
-        kUserHash,
-        *policy,
+        onc_source, user_hash, *policy,
         base::DictionaryValue() /* no global network config */);
   }
 
@@ -273,10 +306,11 @@
     properties->GetStringWithoutPathExpansion(prop_name, prop_value);
   }
 
-  int network_properties_changed_count_;
+  int network_properties_changed_count_ = 0;
   std::string test_cert_id_;
   std::unique_ptr<base::SimpleTestClock> test_clock_;
   std::unique_ptr<ClientCertResolver> client_cert_resolver_;
+  CertLoader* cert_loader_ = nullptr;
 
  private:
   // ClientCertResolver::Observer:
@@ -285,9 +319,8 @@
       ++network_properties_changed_count_;
   }
 
-  ShillServiceClient::TestInterface* service_test_;
-  ShillProfileClient::TestInterface* profile_test_;
-  CertLoader* cert_loader_;
+  ShillServiceClient::TestInterface* service_test_ = nullptr;
+  ShillProfileClient::TestInterface* profile_test_ = nullptr;
   std::unique_ptr<NetworkStateHandler> network_state_handler_;
   std::unique_ptr<NetworkProfileHandler> network_profile_handler_;
   std::unique_ptr<NetworkConfigurationHandler> network_config_handler_;
@@ -298,6 +331,7 @@
   scoped_refptr<net::X509Certificate> test_client_cert_;
   std::string test_ca_cert_pem_;
   crypto::ScopedTestNSSDB test_nssdb_;
+  crypto::ScopedTestNSSDB test_system_nssdb_;
   std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
 
   DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest);
@@ -310,7 +344,7 @@
   base::RunLoop().RunUntilIdle();
   network_properties_changed_count_ = 0;
   SetupNetworkHandlers();
-  SetupPolicyMatchingIssuerPEM("");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
   base::RunLoop().RunUntilIdle();
 
   // Verify that no client certificate was configured.
@@ -327,7 +361,7 @@
   base::RunLoop().RunUntilIdle();
 
   SetupNetworkHandlers();
-  SetupPolicyMatchingIssuerCN();
+  SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
   base::RunLoop().RunUntilIdle();
 
   network_properties_changed_count_ = 0;
@@ -348,7 +382,7 @@
   base::RunLoop().RunUntilIdle();
 
   SetupNetworkHandlers();
-  SetupPolicyMatchingIssuerPEM("");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
   base::RunLoop().RunUntilIdle();
 
   network_properties_changed_count_ = 0;
@@ -373,7 +407,7 @@
 
   // Policy application will trigger the ClientCertResolver.
   network_properties_changed_count_ = 0;
-  SetupPolicyMatchingIssuerPEM("");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
   base::RunLoop().RunUntilIdle();
 
   // Verify that the resolver positively matched the pattern in the policy with
@@ -390,7 +424,7 @@
   base::RunLoop().RunUntilIdle();
 
   SetupNetworkHandlers();
-  SetupPolicyMatchingIssuerPEM("");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
   base::RunLoop().RunUntilIdle();
 
   StartCertLoader();
@@ -414,13 +448,130 @@
   EXPECT_EQ(std::string(), pkcs11_id);
 }
 
+TEST_F(ClientCertResolverTest, UserPolicyUsesSystemToken) {
+  SetupTestCertInSystemToken("client_1");
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+
+  SetupNetworkHandlers();
+  SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
+  base::RunLoop().RunUntilIdle();
+
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1U, cert_loader_->system_certs().size());
+
+  // Verify that the resolver positively matched the pattern in the policy with
+  // the test client cert and configured the network.
+  std::string pkcs11_id;
+  GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+}
+
+TEST_F(ClientCertResolverTest, UserPolicyUsesSystemTokenSync) {
+  SetupTestCertInSystemToken("client_1");
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+
+  client_cert::ClientCertConfig client_cert_config;
+  SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY,
+                                         &client_cert_config);
+
+  base::DictionaryValue shill_properties;
+  ClientCertResolver::ResolveCertificatePatternSync(
+      client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
+  std::string pkcs11_id;
+  shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
+                                                 &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+}
+
+TEST_F(ClientCertResolverTest, DevicePolicyUsesSystemToken) {
+  SetupTestCertInSystemToken("client_1");
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+
+  SetupNetworkHandlers();
+  SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_USER_POLICY);
+  base::RunLoop().RunUntilIdle();
+
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1U, cert_loader_->system_certs().size());
+
+  // Verify that the resolver positively matched the pattern in the policy with
+  // the test client cert and configured the network.
+  std::string pkcs11_id;
+  GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+}
+
+TEST_F(ClientCertResolverTest, DevicePolicyUsesSystemTokenSync) {
+  SetupTestCertInSystemToken("client_1");
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+
+  client_cert::ClientCertConfig client_cert_config;
+  SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY,
+                                         &client_cert_config);
+
+  base::DictionaryValue shill_properties;
+  ClientCertResolver::ResolveCertificatePatternSync(
+      client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
+  std::string pkcs11_id;
+  shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
+                                                 &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+}
+
+TEST_F(ClientCertResolverTest, DevicePolicyDoesNotUseUserToken) {
+  SetupTestCerts("client_1", false /* do not import the issuer */);
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+
+  SetupNetworkHandlers();
+  SetupPolicyMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY);
+  base::RunLoop().RunUntilIdle();
+
+  network_properties_changed_count_ = 0;
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0U, cert_loader_->system_certs().size());
+
+  // Verify that no client certificate was configured.
+  std::string pkcs11_id;
+  GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
+  EXPECT_EQ(std::string(), pkcs11_id);
+  EXPECT_EQ(1, network_properties_changed_count_);
+  EXPECT_FALSE(client_cert_resolver_->IsAnyResolveTaskRunning());
+}
+
+TEST_F(ClientCertResolverTest, DevicePolicyDoesNotUseUserTokenSync) {
+  SetupTestCerts("client_1", false /* do not import the issuer */);
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+
+  client_cert::ClientCertConfig client_cert_config;
+  SetupCertificateConfigMatchingIssuerCN(onc::ONC_SOURCE_DEVICE_POLICY,
+                                         &client_cert_config);
+
+  base::DictionaryValue shill_properties;
+  ClientCertResolver::ResolveCertificatePatternSync(
+      client_cert::CONFIG_TYPE_EAP, client_cert_config, &shill_properties);
+  std::string pkcs11_id;
+  shill_properties.GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
+                                                 &pkcs11_id);
+  EXPECT_EQ(std::string(), pkcs11_id);
+}
+
 TEST_F(ClientCertResolverTest, PopulateIdentityFromCert) {
   SetupTestCerts("client_3", true /* import issuer */);
   SetupWifi();
   base::RunLoop().RunUntilIdle();
 
   SetupNetworkHandlers();
-  SetupPolicyMatchingIssuerPEM("${CERT_SAN_EMAIL}");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY,
+                               "${CERT_SAN_EMAIL}");
   base::RunLoop().RunUntilIdle();
 
   network_properties_changed_count_ = 0;
@@ -437,7 +588,8 @@
   // Verify that after changing the ONC policy to request a variant of the
   // Microsoft Universal Principal Name field instead, the correct value is
   // substituted into the shill service entry.
-  SetupPolicyMatchingIssuerPEM("upn-${CERT_SAN_UPN}-suffix");
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY,
+                               "upn-${CERT_SAN_UPN}-suffix");
   base::RunLoop().RunUntilIdle();
 
   GetServiceProperty(shill::kEapIdentityProperty, &identity);
diff --git a/chromeos/network/client_cert_util.cc b/chromeos/network/client_cert_util.cc
index 361664f..735ee2ca 100644
--- a/chromeos/network/client_cert_util.cc
+++ b/chromeos/network/client_cert_util.cc
@@ -39,8 +39,11 @@
 }
 
 void GetClientCertTypeAndPattern(
+    onc::ONCSource onc_source,
     const base::DictionaryValue& dict_with_client_cert,
     ClientCertConfig* cert_config) {
+  cert_config->onc_source = onc_source;
+
   dict_with_client_cert.GetStringWithoutPathExpansion(
       ::onc::eap::kIdentity, &cert_config->policy_identity);
 
@@ -266,7 +269,8 @@
 
 ClientCertConfig::ClientCertConfig(const ClientCertConfig& other) = default;
 
-void OncToClientCertConfig(const base::DictionaryValue& network_config,
+void OncToClientCertConfig(::onc::ONCSource onc_source,
+                           const base::DictionaryValue& network_config,
                            ClientCertConfig* cert_config) {
   using namespace ::onc;
 
@@ -317,8 +321,10 @@
     cert_config->location = CONFIG_TYPE_EAP;
   }
 
-  if (dict_with_client_cert)
-    GetClientCertTypeAndPattern(*dict_with_client_cert, cert_config);
+  if (dict_with_client_cert) {
+    GetClientCertTypeAndPattern(onc_source, *dict_with_client_cert,
+                                cert_config);
+  }
 }
 
 bool IsCertificateConfigured(const ConfigType cert_config_type,
diff --git a/chromeos/network/client_cert_util.h b/chromeos/network/client_cert_util.h
index e687e06..baef5a09 100644
--- a/chromeos/network/client_cert_util.h
+++ b/chromeos/network/client_cert_util.h
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/network/certificate_pattern.h"
+#include "components/onc/onc_constants.h"
 
 namespace base {
 class DictionaryValue;
@@ -50,6 +51,9 @@
 
   // The value of kIdentity, to enable substitutions.
   std::string policy_identity;
+
+  // source of this ClientCertConfig.
+  ::onc::ONCSource onc_source;
 };
 
 // Returns true only if any fields set in this pattern match exactly with
@@ -99,6 +103,7 @@
 // Determines the type of the CertificatePattern configuration, i.e. is it a
 // pattern within an EAP, IPsec or OpenVPN configuration.
 CHROMEOS_EXPORT void OncToClientCertConfig(
+    ::onc::ONCSource onc_source,
     const base::DictionaryValue& network_config,
     ClientCertConfig* cert_config);
 
diff --git a/chromeos/network/managed_network_configuration_handler.h b/chromeos/network/managed_network_configuration_handler.h
index 448ac0f..a813efe2 100644
--- a/chromeos/network/managed_network_configuration_handler.h
+++ b/chromeos/network/managed_network_configuration_handler.h
@@ -156,10 +156,12 @@
       const std::string& userhash) const = 0;
 
   // Returns the policy with |guid| for profile |profile_path|. If such
-  // doesn't exist, returns NULL.
+  // doesn't exist, returns nullptr. Sets |onc_source| accordingly if it is not
+  // nullptr.
   virtual const base::DictionaryValue* FindPolicyByGuidAndProfile(
       const std::string& guid,
-      const std::string& profile_path) const = 0;
+      const std::string& profile_path,
+      ::onc::ONCSource* onc_source) const = 0;
 
  private:
   DISALLOW_ASSIGN(ManagedNetworkConfigurationHandler);
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc
index f9b80551..1fc9374 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.cc
+++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -730,7 +730,8 @@
 const base::DictionaryValue*
 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
     const std::string& guid,
-    const std::string& profile_path) const {
+    const std::string& profile_path,
+    ::onc::ONCSource* onc_source) const {
   const NetworkProfile* profile =
       network_profile_handler_->GetProfileForPath(profile_path);
   if (!profile) {
@@ -742,7 +743,13 @@
   if (!policies)
     return NULL;
 
-  return GetByGUID(policies->per_network_config, guid);
+  const base::DictionaryValue* policy =
+      GetByGUID(policies->per_network_config, guid);
+  if (policy && onc_source) {
+    *onc_source = (profile->userhash.empty() ? ::onc::ONC_SOURCE_DEVICE_POLICY
+                                             : ::onc::ONC_SOURCE_USER_POLICY);
+  }
+  return policy;
 }
 
 const ManagedNetworkConfigurationHandlerImpl::Policies*
diff --git a/chromeos/network/managed_network_configuration_handler_impl.h b/chromeos/network/managed_network_configuration_handler_impl.h
index 3a45d74..2aee0d3 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.h
+++ b/chromeos/network/managed_network_configuration_handler_impl.h
@@ -95,7 +95,8 @@
 
   const base::DictionaryValue* FindPolicyByGuidAndProfile(
       const std::string& guid,
-      const std::string& profile_path) const override;
+      const std::string& profile_path,
+      onc::ONCSource* onc_source) const override;
 
   // NetworkProfileObserver overrides
   void OnProfileAdded(const NetworkProfile& profile) override;
@@ -155,7 +156,11 @@
                       const std::string& service_path,
                       std::unique_ptr<base::DictionaryValue> shill_properties);
 
+  // Returns the Policies for the given |userhash|, or the device policies if
+  // |userhash| is empty.
   const Policies* GetPoliciesForUser(const std::string& userhash) const;
+  // Returns the Policies for the given network |profile|. These could be either
+  // user or device policies.
   const Policies* GetPoliciesForProfile(const NetworkProfile& profile) const;
 
   void OnPolicyAppliedToNetwork(const std::string& service_path,
diff --git a/chromeos/network/mock_managed_network_configuration_handler.h b/chromeos/network/mock_managed_network_configuration_handler.h
index e8938951..038509f6 100644
--- a/chromeos/network/mock_managed_network_configuration_handler.h
+++ b/chromeos/network/mock_managed_network_configuration_handler.h
@@ -70,10 +70,11 @@
                      const GuidToPolicyMap*(const std::string& userhash));
   MOCK_CONST_METHOD1(GetGlobalConfigFromPolicy,
                      const base::DictionaryValue*(const std::string& userhash));
-  MOCK_CONST_METHOD2(
+  MOCK_CONST_METHOD3(
       FindPolicyByGuidAndProfile,
       const base::DictionaryValue*(const std::string& guid,
-                                   const std::string& profile_path));
+                                   const std::string& profile_path,
+                                   ::onc::ONCSource* onc_source));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockManagedNetworkConfigurationHandler);
diff --git a/chromeos/network/network_cert_migrator.cc b/chromeos/network/network_cert_migrator.cc
index 20ea816d..332e38d 100644
--- a/chromeos/network/network_cert_migrator.cc
+++ b/chromeos/network/network_cert_migrator.cc
@@ -187,7 +187,7 @@
   // certificates.
   VLOG(2) << "Start certificate migration of network configurations.";
   scoped_refptr<MigrationTask> helper(new MigrationTask(
-      CertLoader::Get()->cert_list(), weak_ptr_factory_.GetWeakPtr()));
+      CertLoader::Get()->all_certs(), weak_ptr_factory_.GetWeakPtr()));
   NetworkStateHandler::NetworkStateList networks;
   network_state_handler_->GetNetworkListByType(
       NetworkTypePattern::Default(),
diff --git a/chromeos/network/network_cert_migrator_unittest.cc b/chromeos/network/network_cert_migrator_unittest.cc
index d57a4ae..cab86e62 100644
--- a/chromeos/network/network_cert_migrator_unittest.cc
+++ b/chromeos/network/network_cert_migrator_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/scoped_task_scheduler.h"
 #include "chromeos/cert_loader.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_profile_client.h"
@@ -39,7 +40,8 @@
 
 class NetworkCertMigratorTest : public testing::Test {
  public:
-  NetworkCertMigratorTest() : service_test_(nullptr) {}
+  NetworkCertMigratorTest()
+      : service_test_(nullptr), scoped_task_scheduler_(&message_loop_) {}
   ~NetworkCertMigratorTest() override {}
 
   void SetUp() override {
@@ -190,6 +192,7 @@
   base::MessageLoop message_loop_;
 
  private:
+  base::test::ScopedTaskScheduler scoped_task_scheduler_;
   std::unique_ptr<NetworkStateHandler> network_state_handler_;
   std::unique_ptr<NetworkCertMigrator> network_cert_migrator_;
   crypto::ScopedTestNSSDB test_nssdb_;
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc
index 2542fd4..69483bf 100644
--- a/chromeos/network/network_connection_handler.cc
+++ b/chromeos/network/network_connection_handler.cc
@@ -458,8 +458,10 @@
   std::string profile;
   service_properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
                                                    &profile);
-  const base::DictionaryValue* user_policy =
-      managed_configuration_handler_->FindPolicyByGuidAndProfile(guid, profile);
+  ::onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+  const base::DictionaryValue* policy =
+      managed_configuration_handler_->FindPolicyByGuidAndProfile(guid, profile,
+                                                                 &onc_source);
 
   if (IsNetworkProhibitedByPolicy(type, guid, profile)) {
     ErrorCallbackForPendingRequest(service_path, kErrorUnmanagedNetwork);
@@ -467,8 +469,10 @@
   }
 
   client_cert::ClientCertConfig cert_config_from_policy;
-  if (user_policy)
-    client_cert::OncToClientCertConfig(*user_policy, &cert_config_from_policy);
+  if (policy) {
+    client_cert::OncToClientCertConfig(onc_source, *policy,
+                                       &cert_config_from_policy);
+  }
 
   client_cert::ConfigType client_cert_type = client_cert::CONFIG_TYPE_NONE;
   if (type == shill::kTypeVPN) {
@@ -517,9 +521,7 @@
     if (cert_config_from_policy.client_cert_type ==
         onc::client_cert::kPattern) {
       if (!ClientCertResolver::ResolveCertificatePatternSync(
-              client_cert_type,
-              cert_config_from_policy.pattern,
-              &config_properties)) {
+              client_cert_type, cert_config_from_policy, &config_properties)) {
         ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired);
         return;
       }
@@ -594,7 +596,7 @@
     return false;
   }
   return !managed_configuration_handler_->FindPolicyByGuidAndProfile(
-      guid, profile_path);
+      guid, profile_path, nullptr /* onc_source */);
 }
 
 void NetworkConnectionHandler::QueueConnectRequest(
diff --git a/chromeos/network/network_connection_handler_unittest.cc b/chromeos/network/network_connection_handler_unittest.cc
index 30919f3..683d09d6 100644
--- a/chromeos/network/network_connection_handler_unittest.cc
+++ b/chromeos/network/network_connection_handler_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/scoped_task_scheduler.h"
 #include "chromeos/cert_loader.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/network/managed_network_configuration_handler_impl.h"
@@ -116,7 +117,7 @@
 
 class NetworkConnectionHandlerTest : public NetworkStateTest {
  public:
-  NetworkConnectionHandlerTest() {}
+  NetworkConnectionHandlerTest() : scoped_task_scheduler_(&message_loop_) {}
 
   ~NetworkConnectionHandlerTest() override {}
 
@@ -297,6 +298,8 @@
   std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_;
 
  private:
+  base::test::ScopedTaskScheduler scoped_task_scheduler_;
+
   DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
 };
 
diff --git a/chromeos/network/onc/onc_validator.cc b/chromeos/network/onc/onc_validator.cc
index f596bec..5842134e 100644
--- a/chromeos/network/onc/onc_validator.cc
+++ b/chromeos/network/onc/onc_validator.cc
@@ -301,9 +301,6 @@
   std::string cert_type;
   result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
 
-  if (IsCertPatternInDevicePolicy(cert_type))
-    return false;
-
   bool all_required_exist = true;
 
   if (cert_type == kPattern)
@@ -508,17 +505,6 @@
   return true;
 }
 
-bool Validator::IsCertPatternInDevicePolicy(const std::string& cert_type) {
-  if (cert_type == ::onc::client_cert::kPattern &&
-      onc_source_ == ::onc::ONC_SOURCE_DEVICE_POLICY) {
-    error_or_warning_found_ = true;
-    LOG(ERROR) << MessageHeader() << "Client certificate patterns are "
-               << "prohibited in ONC device policies.";
-    return true;
-  }
-  return false;
-}
-
 bool Validator::IsGlobalNetworkConfigInUserImport(
     const base::DictionaryValue& onc_object) {
   if (onc_source_ == ::onc::ONC_SOURCE_USER_IMPORT &&
diff --git a/chromeos/network/onc/onc_validator.h b/chromeos/network/onc/onc_validator.h
index 3109590f..0610a6bf 100644
--- a/chromeos/network/onc/onc_validator.h
+++ b/chromeos/network/onc/onc_validator.h
@@ -207,10 +207,6 @@
                                     const std::string& kGUID,
                                     std::set<std::string> *guids);
 
-  // Prohibit certificate patterns for device policy ONC so that an unmanaged
-  // user won't have a certificate presented for them involuntarily.
-  bool IsCertPatternInDevicePolicy(const std::string& cert_type);
-
   // Prohibit global network configuration in user ONC imports.
   bool IsGlobalNetworkConfigInUserImport(
       const base::DictionaryValue& onc_object);
diff --git a/chromeos/network/onc/onc_validator_unittest.cc b/chromeos/network/onc/onc_validator_unittest.cc
index 92b3c87..4102a0c 100644
--- a/chromeos/network/onc/onc_validator_unittest.cc
+++ b/chromeos/network/onc/onc_validator_unittest.cc
@@ -544,11 +544,6 @@
                                  &kNetworkConfigurationSignature,
                                  true),
                        ExpectBothNotValid("", "")),
-        std::make_pair(OncParams("network-with-client-cert-pattern",
-                                 &kNetworkConfigurationSignature,
-                                 true,
-                                 ::onc::ONC_SOURCE_DEVICE_POLICY),
-                       ExpectBothNotValid("", "")),
         std::make_pair(OncParams("openvpn-invalid-verify-x509-type",
                                  &kNetworkConfigurationSignature,
                                  false),
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc
index c7144df..adfd9c8 100644
--- a/chromeos/system/statistics_provider.cc
+++ b/chromeos/system/statistics_provider.cc
@@ -57,7 +57,8 @@
 
 // File to get ECHO coupon info from, and key/value delimiters of
 // the file.
-const char kEchoCouponFile[] = "/var/cache/echo/vpd_echo.txt";
+const char kEchoCouponFile[] =
+    "/mnt/stateful_partition/unencrypted/cache/vpd/echo/vpd_echo.txt";
 const char kEchoCouponEq[] = "=";
 const char kEchoCouponDelim[] = "\n";
 
diff --git a/chromeos/test/data/network/invalid_settings_with_repairs.json b/chromeos/test/data/network/invalid_settings_with_repairs.json
index df1abaf..c6e0e5c0 100644
--- a/chromeos/test/data/network/invalid_settings_with_repairs.json
+++ b/chromeos/test/data/network/invalid_settings_with_repairs.json
@@ -308,28 +308,6 @@
             "RoutingPrefix": 123
         } ],
     },
-    "network-with-client-cert-pattern": {
-        "GUID": "guid",
-        "Type": "WiFi",
-        "Name": "name",
-        "WiFi": {
-            "SSID": "ssid",
-            "Security": "WPA-EAP",
-            "EAP": {
-                "Outer": "EAP-TLS",
-                "Identity": "abc ${LOGIN_ID}@my.domain.com",
-                "ClientCertType": "Pattern",
-                "ClientCertPattern": {
-                    "IssuerCARef": [
-                        "{58ac1967-a0e7-49e9-be68-123abc}"
-                    ],
-                    "EnrollmentURI": [
-                        "chrome-extension://delkjfjibodjclmdijflfnimdmgdagfk/generate-cert.html"
-                    ]
-                }
-            }
-        }
-    },
     "ipsec-with-psk-and-cacert": {
       "AuthenticationType": "PSK",
       "IKEVersion": 1,
diff --git a/components/password_manager/core/browser/password_reuse_detector.cc b/components/password_manager/core/browser/password_reuse_detector.cc
index dd9b2a9..4ebe2d3 100644
--- a/components/password_manager/core/browser/password_reuse_detector.cc
+++ b/components/password_manager/core/browser/password_reuse_detector.cc
@@ -79,6 +79,11 @@
   }
 }
 
+void PasswordReuseDetector::SaveSyncPasswordHash(
+    const base::string16& password) {
+  // TODO(crbug.com/657041) Implement saving of sync password hash.
+}
+
 void PasswordReuseDetector::AddPassword(const autofill::PasswordForm& form) {
   if (form.password_value.size() < kMinPasswordLengthToCheck)
     return;
diff --git a/components/password_manager/core/browser/password_reuse_detector.h b/components/password_manager/core/browser/password_reuse_detector.h
index 967c941a..e9766c8 100644
--- a/components/password_manager/core/browser/password_reuse_detector.h
+++ b/components/password_manager/core/browser/password_reuse_detector.h
@@ -51,6 +51,9 @@
                   const std::string& domain,
                   PasswordReuseDetectorConsumer* consumer);
 
+  // Saves a hash of |password| for password reuse checking.
+  void SaveSyncPasswordHash(const base::string16& password);
+
  private:
   using passwords_iterator = std::map<base::string16,
                                       std::set<std::string>,
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index 3597674..ba13db6 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -317,6 +317,11 @@
   ScheduleTask(base::Bind(&PasswordStore::CheckReuseImpl, this,
                           base::Passed(&check_reuse_request), input, domain));
 }
+
+void PasswordStore::SaveSyncPasswordHash(const base::string16& password) {
+  ScheduleTask(
+      base::Bind(&PasswordStore::SaveSyncPasswordHashImpl, this, password));
+}
 #endif
 
 PasswordStore::~PasswordStore() {
@@ -399,6 +404,11 @@
   if (reuse_detector_)
     reuse_detector_->CheckReuse(input, domain, request.get());
 }
+
+void PasswordStore::SaveSyncPasswordHashImpl(const base::string16& password) {
+  if (reuse_detector_)
+    reuse_detector_->SaveSyncPasswordHash(password);
+}
 #endif
 
 void PasswordStore::Schedule(
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h
index 0a0b915..c578023 100644
--- a/components/password_manager/core/browser/password_store.h
+++ b/components/password_manager/core/browser/password_store.h
@@ -241,6 +241,9 @@
   virtual void CheckReuse(const base::string16& input,
                           const std::string& domain,
                           PasswordReuseDetectorConsumer* consumer);
+
+  // Saves a hash of |password| for password reuse checking.
+  void SaveSyncPasswordHash(const base::string16& password);
 #endif
 
  protected:
@@ -402,6 +405,9 @@
   void CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request,
                       const base::string16& input,
                       const std::string& domain);
+
+  // Synchronous implementation of SaveSyncPasswordHash().
+  void SaveSyncPasswordHashImpl(const base::string16& password);
 #endif
 
   // TaskRunner for tasks that run on the main thread (usually the UI thread).
diff --git a/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc b/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
index 1f142a1..882a839 100644
--- a/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
+++ b/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
@@ -109,7 +109,8 @@
   }
   const base::DictionaryValue* FindPolicyByGuidAndProfile(
       const std::string& guid,
-      const std::string& profile_path) const override {
+      const std::string& profile_path,
+      ::onc::ONCSource* onc_source) const override {
     NOTIMPLEMENTED();
     return nullptr;
   }
diff --git a/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc b/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc
index 0ec091e..03b27dd 100644
--- a/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc
+++ b/storage/browser/fileapi/file_system_dir_url_request_job_unittest.cc
@@ -22,6 +22,7 @@
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_request_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_test_util.h"
@@ -179,8 +180,9 @@
         url.GetOrigin().host(), file_system_context));
     empty_context_.set_job_factory(job_factory_.get());
 
-    request_ = empty_context_.CreateRequest(
-        url, net::DEFAULT_PRIORITY, delegate_.get());
+    request_ = empty_context_.CreateRequest(url, net::DEFAULT_PRIORITY,
+                                            delegate_.get(),
+                                            TRAFFIC_ANNOTATION_FOR_TESTS);
     request_->Start();
     ASSERT_TRUE(request_->is_pending());  // verify that we're starting async
     if (run_to_completion)
diff --git a/storage/browser/fileapi/file_system_url_request_job_unittest.cc b/storage/browser/fileapi/file_system_url_request_job_unittest.cc
index 75507a7..bdb9c59 100644
--- a/storage/browser/fileapi/file_system_url_request_job_unittest.cc
+++ b/storage/browser/fileapi/file_system_url_request_job_unittest.cc
@@ -28,6 +28,7 @@
 #include "net/base/request_priority.h"
 #include "net/http/http_byte_range.h"
 #include "net/http/http_request_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_test_util.h"
@@ -194,8 +195,9 @@
         url.GetOrigin().host(), file_system_context));
     empty_context_.set_job_factory(job_factory_.get());
 
-    request_ = empty_context_.CreateRequest(
-        url, net::DEFAULT_PRIORITY, delegate_.get());
+    request_ = empty_context_.CreateRequest(url, net::DEFAULT_PRIORITY,
+                                            delegate_.get(),
+                                            TRAFFIC_ANNOTATION_FOR_TESTS);
     if (headers)
       request_->SetExtraRequestHeaders(*headers);
 
diff --git a/storage/browser/fileapi/file_writer_delegate_unittest.cc b/storage/browser/fileapi/file_writer_delegate_unittest.cc
index 9733b4b..d0524f39 100644
--- a/storage/browser/fileapi/file_writer_delegate_unittest.cc
+++ b/storage/browser/fileapi/file_writer_delegate_unittest.cc
@@ -20,6 +20,7 @@
 #include "net/base/io_buffer.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_job.h"
@@ -148,8 +149,9 @@
                        int64_t allowed_growth) {
     file_writer_delegate_.reset(
         CreateWriterDelegate(test_file_path, offset, allowed_growth));
-    request_ = empty_context_.CreateRequest(
-        blob_url, net::DEFAULT_PRIORITY, file_writer_delegate_.get());
+    request_ = empty_context_.CreateRequest(blob_url, net::DEFAULT_PRIORITY,
+                                            file_writer_delegate_.get(),
+                                            TRAFFIC_ANNOTATION_FOR_TESTS);
   }
 
   // This should be alive until the very end of this instance.
@@ -379,8 +381,9 @@
   // Credate another FileWriterDelegate for concurrent write.
   file_writer_delegate2.reset(
       CreateWriterDelegate("test2", 0, std::numeric_limits<int64_t>::max()));
-  request2 = empty_context_.CreateRequest(
-      kBlobURL2, net::DEFAULT_PRIORITY, file_writer_delegate2.get());
+  request2 = empty_context_.CreateRequest(kBlobURL2, net::DEFAULT_PRIORITY,
+                                          file_writer_delegate2.get(),
+                                          TRAFFIC_ANNOTATION_FOR_TESTS);
 
   Result result, result2;
   ASSERT_EQ(0, usage());
diff --git a/third_party/WebKit/LayoutTests/external/wpt/WebIDL/current-realm-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/WebIDL/current-realm-expected.txt
index 9c345bc..6c26cec5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/WebIDL/current-realm-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/WebIDL/current-realm-expected.txt
@@ -27,7 +27,7 @@
 PASS cloneRange 
 PASS getContext 2d 
 PASS getContext webgl 
-FAIL createImageData assert_false: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 should not be from top-level Realm expected false got true
+FAIL createImageData Failed to execute 'createImageData' on 'CanvasRenderingContext2D': The provided value is not of type '(Uint8ClampedArray or Uint16Array or Float32Array)'
 FAIL getImageData assert_false: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 should not be from top-level Realm expected false got true
 PASS FontFace's load() 
 Harness: the test ran to completion.
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 4f0b0e4..552dddd 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
@@ -597,7 +597,6 @@
     getter height
     getter width
     method constructor
-    method createImageData
     method getColorSettings
 interface InstallEvent : ExtendableEvent
     method constructor
diff --git a/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/canvas-createPutGetImageData-colorManaged.html b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/canvas-createPutGetImageData-colorManaged.html
new file mode 100644
index 0000000..78494cb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/canvas-createPutGetImageData-colorManaged.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<body>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script>
+
+var xWidth = xHeight = 10;
+
+function checkImageData(canvasColorSettings, imageData) {
+  var imageDataColorSettings = imageData.getColorSettings();
+  //console.log(canvasColorSettings);
+  console.log(imageDataColorSettings);
+
+  assert_equals(canvasColorSettings.colorSpace, imageDataColorSettings.colorSpace);
+  if (canvasColorSettings.pixelFormat == "8-8-8-8") {
+    //console.log("8-8-8-8 -> ");
+    assert_equals("uint8", imageDataColorSettings.storageFormat);
+    assert_equals(imageData.data.length, 4 * xWidth * xHeight);
+  } else {
+    //console.log("float16 -> ");
+    assert_equals("float32", imageDataColorSettings.storageFormat);
+    assert_equals(imageData.dataUnion.length, 4 * xWidth * xHeight);
+  }
+}
+
+// Test createImageData when the canvas is color managed
+var helperImageData = new ImageData(xWidth, xHeight);
+function runTestCreateImageData(canvasColorSettings) {
+  var aCanvas = document.createElement("canvas");
+  aCanvas.width = xWidth;
+  aCanvas.height = xHeight;
+  var ctx = aCanvas.getContext('2d', canvasColorSettings);
+  var imageData = ctx.createImageData(xWidth, xHeight);
+  checkImageData(canvasColorSettings, imageData);
+
+  imageData = ctx.createImageData(helperImageData);
+  checkImageData(canvasColorSettings, imageData);
+}
+
+var testScenariosCreateImageData = [
+  ["Test color managed cretateImageData: {srgb, 8-8-8-8} -> {srgb, uint8}", {colorSpace: "srgb", pixelFormat: "8-8-8-8"}],
+  ["Test color managed cretateImageData: {srgb, float16} -> {srgb, float32}", {colorSpace: "srgb", pixelFormat: "float16"}], 
+  ["Test color managed cretateImageData: {rec2020, float16} -> {rec2020, float32}", {colorSpace: "rec2020", pixelFormat: "float16"}],
+  ["Test color managed cretateImageData: {p3, float16} -> {p3, float32}", {colorSpace: "p3", pixelFormat: "float16"}],
+];
+
+//generate_tests(runTestCreateImageData, testScenariosCreateImageData);
+
+// Test getImageData when the canvas is color managed
+function runTestGetImageData(canvasColorSettings) {
+  var aCanvas = document.createElement("canvas");
+  aCanvas.width = xWidth;
+  aCanvas.height = xHeight;
+  var ctx = aCanvas.getContext('2d', canvasColorSettings);
+  var imageData = ctx.getImageData(0, 0, xWidth, xHeight);
+  checkImageData(canvasColorSettings, imageData);
+}
+
+var testScenariosGetImageData = [
+//  ["Test color managed getImageData: {srgb, 8-8-8-8} -> {srgb, uint8}", {colorSpace: "srgb", pixelFormat: "8-8-8-8"}],
+  ["Test color managed getImageData: {srgb, float16} -> {srgb, float32}", {colorSpace: "srgb", pixelFormat: "float16"}], 
+//  ["Test color managed getImageData: {rec2020, float16} -> {rec2020, float32}", {colorSpace: "rec2020", pixelFormat: "float16"}],
+//  ["Test color managed getImageData: {p3, float16} -> {p3, float32}", {colorSpace: "p3", pixelFormat: "float16"}],
+];
+
+generate_tests(runTestGetImageData, testScenariosGetImageData);
+
+// Test putImageData when the canvas is color managed.
+// This test passes if differen possible calls do not crash. To avoid hard
+// coded expected results that need to get synced after related Skia updates,
+// the output correcteness is verified as a unit test. Please see:
+// CanvasRenderingContext2DTest::ColorManagedGetPutImageData
+
+var dataU8 = new Uint8ClampedArray(4 * xWidth * xHeight);
+var dataU16 = new Uint16Array(4 * xWidth * xHeight);
+var dataF32 = new Float32Array(4 * xWidth * xHeight);
+function prepareDataArrays() {
+  for (i = 0; i < 4 * xWidth * xHeight; i++) {
+    dataU8[i] = (i % 4 == 3) ? 255 : i % 256;
+    dataU16[i] = dataU8[i] * 257;
+    dataF32[i] = dataU8[i] / 255.0;
+  }
+}
+
+var testScenariosPutImageData = [];
+function prepareTestScenariosPutImageData() {
+  var colorSpaces = ["srgb", "p3", "rec2020"];
+  var imageDataStorageFormats = ["uint8", "uint16", "float32"];
+  var canvasPixelFormats = ["8-8-8-8", "float16"];
+
+  for (i = 0; i < colorSpaces.length; i++)
+    for (j = 0; j < imageDataStorageFormats.length; j++)
+      for (k = 0; k < colorSpaces.length; k++)
+        for (l = 0; l < canvasPixelFormats.length; l++) {
+          testTitle = "Test color managed putImageData: ".concat(
+            "{", colorSpaces[i], ", ", imageDataStorageFormats[j], "} -> {", colorSpaces[k],
+            ", ", canvasPixelFormats[l], "}");
+          imageDataColorSettings =
+            {colorSpace: colorSpaces[i], storageFormat: imageDataStorageFormats[j]};
+          canvasColorSettings =
+            {colorSpace: colorSpaces[k], pixelFormat: canvasPixelFormats[l]};
+          testScenariosPutImageData.push([testTitle, imageDataColorSettings, canvasColorSettings]);
+        }
+}
+
+function createAndPutImageData(data, imageDataColorSettings, canvasColorSettings) {
+  // create color managed canvas
+  var aCanvas = document.createElement("canvas");
+  aCanvas.width = xWidth;
+  aCanvas.height = xHeight;
+  var ctx = aCanvas.getContext('2d', canvasColorSettings);
+  // create color managed ImageData
+  var imageData = ctx.createImageData(data, xWidth, xHeight, imageDataColorSettings);
+  // put image data into canvas. test succeeds if this does not crash.
+  ctx.putImageData(imageData, 0, 0);
+}
+
+function runTestPutImageData(imageDataColorSettings, canvasColorSettings) {
+  createAndPutImageData(dataU8, imageDataColorSettings, canvasColorSettings);
+  createAndPutImageData(dataU16, imageDataColorSettings, canvasColorSettings);
+  createAndPutImageData(dataF32, imageDataColorSettings, canvasColorSettings);
+}
+
+prepareDataArrays();
+prepareTestScenariosPutImageData();
+//generate_tests(runTestPutImageData, testScenariosPutImageData);
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/imageData-colorSpace.html
similarity index 88%
rename from third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html
rename to third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/imageData-colorSpace.html
index 2d5d56d..549462cd 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html
+++ b/third_party/WebKit/LayoutTests/virtual/color_space/fast/canvas/color-space/imageData-colorSpace.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <body>
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
 <script>
 
 var dataU8 = new Uint8ClampedArray([255, 192, 128, 64]);
@@ -23,24 +23,25 @@
 }
 
 function runTest(colorSettings, expectedColorSettings) {
-  experimental = new ImageData(1,1);
+  var canvas = document.createElement("canvas");
+  var ctx = canvas.getContext("2d");
   
-  imageData = experimental.createImageData(1, 1, colorSettings);
+  imageData = ctx.createImageData(1, 1, colorSettings);
   checkDataTypeAgainstStorageFormat(imageData.dataUnion, colorSettings.storageFormat);
   assert_array_equals(imageData.dataUnion, [0, 0, 0, 0]);
   checkColorSettings(imageData.getColorSettings(), expectedColorSettings.colorSpace, expectedColorSettings.storageFormat);
 
-  imageData = experimental.createImageData(dataU8, 1, 1, colorSettings);
+  imageData = ctx.createImageData(dataU8, 1, 1, colorSettings);
   assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Uint8ClampedArray]");
   assert_array_equals(imageData.dataUnion, dataU8);
   checkColorSettings(imageData.getColorSettings(), expectedColorSettings.colorSpace, "uint8");
 
-  imageData = experimental.createImageData(dataU16, 1, 1, colorSettings);
+  imageData = ctx.createImageData(dataU16, 1, 1, colorSettings);
   assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Uint16Array]");
   assert_array_equals(imageData.dataUnion, dataU16);
   checkColorSettings(imageData.getColorSettings(), expectedColorSettings.colorSpace, "uint16");
 
-  imageData = experimental.createImageData(dataF32, 1, 1, colorSettings);
+  imageData = ctx.createImageData(dataF32, 1, 1, colorSettings);
   assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Float32Array]");
   assert_array_equals(imageData.dataUnion, dataF32);
   checkColorSettings(imageData.getColorSettings(), expectedColorSettings.colorSpace, "float32");
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 ec4f603..8280e05 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
@@ -596,7 +596,6 @@
     getter height
     getter width
     method constructor
-    method createImageData
     method getColorSettings
 interface InstallEvent : ExtendableEvent
     method constructor
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 0b22d590..b8097e42 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
@@ -620,7 +620,6 @@
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
-[Worker]     method createImageData
 [Worker]     method getColorSettings
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
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 653b94c..0e745ff 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
@@ -3799,7 +3799,6 @@
     getter height
     getter width
     method constructor
-    method createImageData
     method getColorSettings
 interface InputDeviceCapabilities
     attribute @@toStringTag
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 c661271f1..ffce2e4 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
@@ -615,7 +615,6 @@
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
-[Worker]     method createImageData
 [Worker]     method getColorSettings
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 4f0b0e4..552dddd 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -597,7 +597,6 @@
     getter height
     getter width
     method constructor
-    method createImageData
     method getColorSettings
 interface InstallEvent : ExtendableEvent
     method constructor
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 7f49c3b5..f5485e1f 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
@@ -620,7 +620,6 @@
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
-[Worker]     method createImageData
 [Worker]     method getColorSettings
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
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 a0a196f..7b8356f 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3799,7 +3799,6 @@
     getter height
     getter width
     method constructor
-    method createImageData
     method getColorSettings
 interface InputDeviceCapabilities
     attribute @@toStringTag
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 9709dba..ce13cfa 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
@@ -615,7 +615,6 @@
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
-[Worker]     method createImageData
 [Worker]     method getColorSettings
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
diff --git a/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
new file mode 100644
index 0000000..99491ef
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div id="holder">
+  </div>
+<script src="../resources/runner.js"></script>
+</script>
+<script>
+var holderElement = document.getElementById("holder");
+
+PerfTestRunner.measureTime({
+    description: "Measures performance of layout when adding many child elements.",
+
+    setup: function() {
+      while (holderElement.firstChild) {
+        holderElement.removeChild(holderElement.firstChild);
+      }
+    },
+
+    run: function() {
+        for (var i = 0; i < 50; ++i) {
+            var element = document.createElement("div");
+            element.title = 'dummy';
+            element.innerText = "FOO";
+            holderElement.appendChild(element);
+            PerfTestRunner.forceLayout();
+        }
+    },
+    warmUpCount: 3,
+    iterationCount: 10,
+    tracingCategories: 'blink',
+    traceEventsToMeasure: ['FrameView::layout', 'UpdateLayoutTree']
+});
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html b/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html
new file mode 100644
index 0000000..a55b247
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<body>
+<script src="../resources/runner.js"></script>
+<style>
+  span {
+    padding: 1px;
+  }
+  .changeColor {
+    background-color: green;
+  }
+</style>
+<script>
+// This test measures the lifecycle update performance of changing background
+// colors in large trees.
+
+function buildTree(parent, depth, arity, tagNameCallback, createElementCallback) {
+  for (var child = 0; child < arity; child++) {
+    var element = document.createElement(tagNameCallback(depth));
+    parent.appendChild(element);
+    createElementCallback(element, depth);
+    if (depth > 1)
+      buildTree(element, depth - 1, arity, tagNameCallback, createElementCallback);
+  }
+}
+
+// Build a tall tree that is skinny. A middle layer of
+// the tree should have the changeColor class.
+buildTree(document.body, 15, 2,
+  function(depth) {
+    // Use divs at upper levels to avoid too much layout time.
+    return depth > 9 ? 'div' : 'span';
+  },
+  function(element, depth) {
+    element.style.backgroundColor = 'green';
+    if (depth == 5)
+      element.setAttribute('class', 'changeColor');
+  }
+);
+
+// Build a short tree that is fat. A middle layer of
+// the tree should have the changeColor class.
+buildTree(document.body, 6, 7,
+  function(depth) {
+    // Use divs at upper levels to avoid too much layout time.
+    return depth > 4 ? 'div' : 'span';
+  },
+  function(element, depth) {
+    element.style.backgroundColor = 'orange';
+    if (depth == 3)
+      element.setAttribute('class', 'changeColor');
+  }
+);
+
+var runCount = 0;
+var elementsToChange = document.getElementsByClassName('changeColor');
+var colors = [
+ "rgb(128, 18, 237)",
+ "rgb(191, 1, 191)",
+ "rgb(237, 18, 128)",
+ "rgb(255, 64, 64)",
+ "rgb(237, 127, 18)",
+ "rgb(191, 191, 1)",
+ "rgb(128, 237, 18)",
+ "rgb(64, 255, 64)",
+ "rgb(18, 237, 127)",
+ "rgb(1, 191, 191)",
+ "rgb(18, 128, 237)",
+ "rgb(64, 64, 255)"
+];
+
+PerfTestRunner.measureFrameTime({
+  run: function() {
+    runCount++;
+    var newColor = colors[runCount % colors.length];
+    for (var index = 0; index < elementsToChange.length; index++)
+      elementsToChange[index].style.backgroundColor = newColor;
+  },
+   warmUpCount: 3,
+   iterationCount: 10,
+   tracingCategories: 'blink',
+   traceEventsToMeasure: ['FrameView::prePaint', 'FrameView::paintTree']
+});
+</script>
+</body>
diff --git a/third_party/WebKit/PerformanceTests/resources/runner.js b/third_party/WebKit/PerformanceTests/resources/runner.js
index 22a5e8e..7ce98b7 100644
--- a/third_party/WebKit/PerformanceTests/resources/runner.js
+++ b/third_party/WebKit/PerformanceTests/resources/runner.js
@@ -157,8 +157,16 @@
         PerfTestRunner.log("Running " + iterationCount + " times");
         if (test.doNotIgnoreInitialRun)
             completedIterations++;
-        if (runner)
+
+        if (runner && test.tracingCategories && window.testRunner &&
+            window.testRunner.supportTracing) {
+            window.testRunner.traceEventsToMeasure = test.traceEventsToMeasure;
+            window.testRunner.startTracing(test.tracingCategories, function() {
+                scheduleNextRun(scheduler, runner);
+            });
+        } else if (runner) {
             scheduleNextRun(scheduler, runner);
+        }
     }
 
     function scheduleNextRun(scheduler, runner) {
@@ -225,8 +233,17 @@
             logInDocument("Got an exception while finalizing the test with name=" + exception.name + ", message=" + exception.message);
         }
 
-        if (window.testRunner)
-            testRunner.notifyDone();
+        if (window.testRunner) {
+            if (currentTest.traceEventsToMeasure &&
+                testRunner.supportTracing) {
+                testRunner.stopTracingAndMeasure(
+                    currentTest.traceEventsToMeasure, function() {
+                        testRunner.notifyDone();
+                    });
+            } else {
+                testRunner.notifyDone();
+            }
+        }
     }
 
     PerfTestRunner.prepareToMeasureValuesAsync = function (test) {
@@ -248,6 +265,25 @@
             finish();
     }
 
+    function addRunTestStartMarker() {
+      if (!window.testRunner || !window.testRunner.supportTracing)
+          return;
+      if (completedIterations < 0)
+          console.time('blink_perf.runTest.warmup');
+      else
+          console.time('blink_perf.runTest');
+    }
+
+    function addRunTestEndMarker() {
+      if (!window.testRunner || !window.testRunner.supportTracing)
+          return;
+      if (completedIterations < 0)
+          console.timeEnd('blink_perf.runTest.warmup');
+      else
+          console.timeEnd('blink_perf.runTest');
+    }
+
+
     PerfTestRunner.measureFrameTime = function (test) {
         PerfTestRunner.unit = "ms";
         PerfTestRunner.bufferedLog = true;
@@ -261,9 +297,12 @@
 
     var lastFrameTime = -1;
     function measureFrameTimeOnce() {
+        if (lastFrameTime != -1)
+          addRunTestEndMarker();
         var now = PerfTestRunner.now();
         var result = lastFrameTime == -1 ? -1 : now - lastFrameTime;
         lastFrameTime = now;
+        addRunTestStartMarker();
 
         var returnValue = currentTest.run();
         if (returnValue - 0 === returnValue) {
@@ -290,7 +329,9 @@
         PerfTestRunner.gc();
 
         var start = PerfTestRunner.now();
+        addRunTestStartMarker();
         var returnValue = currentTest.run();
+        addRunTestEndMarker();
         var end = PerfTestRunner.now();
 
         if (returnValue - 0 === returnValue) {
diff --git a/third_party/WebKit/Source/core/dom/TaskRunnerHelper.cpp b/third_party/WebKit/Source/core/dom/TaskRunnerHelper.cpp
index 631c5de..30c377d 100644
--- a/third_party/WebKit/Source/core/dom/TaskRunnerHelper.cpp
+++ b/third_party/WebKit/Source/core/dom/TaskRunnerHelper.cpp
@@ -31,24 +31,24 @@
     // TODO(nhiroki): Throttle them again after we're convinced that it's safe
     // or provide a mechanism that web pages can opt-out it if throttling is not
     // desirable.
+    case TaskType::kDOMManipulation:
     case TaskType::kDatabaseAccess:
+    case TaskType::kFileReading:
+    case TaskType::kHistoryTraversal:
+    case TaskType::kPerformanceTimeline:
+    case TaskType::kPostedMessage:
+    case TaskType::kRemoteEvent:
+    case TaskType::kSensor:
+    case TaskType::kUnshippedPortMessage:
+    case TaskType::kWebSocket:
       return frame ? frame->FrameScheduler()->SuspendableTaskRunner()
                    : Platform::Current()->CurrentThread()->GetWebTaskRunner();
-    case TaskType::kDOMManipulation:
     case TaskType::kUserInteraction:
-    case TaskType::kHistoryTraversal:
     case TaskType::kEmbed:
     case TaskType::kMediaElementEvent:
     case TaskType::kCanvasBlobSerialization:
-    case TaskType::kRemoteEvent:
-    case TaskType::kWebSocket:
     case TaskType::kMicrotask:
-    case TaskType::kPostedMessage:
-    case TaskType::kUnshippedPortMessage:
-    case TaskType::kFileReading:
     case TaskType::kPresentation:
-    case TaskType::kSensor:
-    case TaskType::kPerformanceTimeline:
     case TaskType::kWebGL:
     case TaskType::kUnspecedTimer:
     case TaskType::kMiscPlatformAPI:
diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/ImageData.cpp
index b42e161b..71f62d5 100644
--- a/third_party/WebKit/Source/core/html/ImageData.cpp
+++ b/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -276,11 +276,15 @@
   return new ImageData(IntSize(width, height), data.View());
 }
 
-ImageData* ImageData::createImageData(
+ImageData* ImageData::CreateImageData(
     unsigned width,
     unsigned height,
     const ImageDataColorSettings& color_settings,
     ExceptionState& exception_state) {
+  if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
+      !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
+    return nullptr;
+
   if (!ImageData::ValidateConstructorArguments(
           kParamWidth | kParamHeight, nullptr, width, height, nullptr,
           &color_settings, &exception_state))
@@ -297,12 +301,17 @@
   return new ImageData(IntSize(width, height), buffer_view, &color_settings);
 }
 
-ImageData* ImageData::createImageData(ImageDataArray& data,
+ImageData* ImageData::CreateImageData(ImageDataArray& data,
                                       unsigned width,
                                       unsigned height,
                                       ImageDataColorSettings& color_settings,
                                       ExceptionState& exception_state) {
+  if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
+      !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
+    return nullptr;
+
   DOMArrayBufferView* buffer_view = nullptr;
+
   // When pixels data is provided, we need to override the storage format of
   // ImageDataColorSettings with the one that matches the data type of the
   // pixels.
@@ -574,6 +583,16 @@
   return nullptr;
 }
 
+DOMArrayBufferBase* ImageData::BufferBase() const {
+  if (data_)
+    return data_->BufferBase();
+  if (data_u16_)
+    return data_u16_->BufferBase();
+  if (data_f32_)
+    return data_f32_->BufferBase();
+  return nullptr;
+}
+
 // For ImageData, the color space is only specified by color settings.
 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
 sk_sp<SkColorSpace> ImageData::GetSkColorSpace() {
diff --git a/third_party/WebKit/Source/core/html/ImageData.h b/third_party/WebKit/Source/core/html/ImageData.h
index be0b419ef..c270c6e 100644
--- a/third_party/WebKit/Source/core/html/ImageData.h
+++ b/third_party/WebKit/Source/core/html/ImageData.h
@@ -90,15 +90,15 @@
                            unsigned height,
                            ExceptionState&);
 
-  ImageData* createImageData(unsigned width,
-                             unsigned height,
-                             const ImageDataColorSettings&,
-                             ExceptionState&);
-  ImageData* createImageData(ImageDataArray&,
-                             unsigned width,
-                             unsigned height,
-                             ImageDataColorSettings&,
-                             ExceptionState&);
+  static ImageData* CreateImageData(unsigned width,
+                                    unsigned height,
+                                    const ImageDataColorSettings&,
+                                    ExceptionState&);
+  static ImageData* CreateImageData(ImageDataArray&,
+                                    unsigned width,
+                                    unsigned height,
+                                    ImageDataColorSettings&,
+                                    ExceptionState&);
 
   void getColorSettings(ImageDataColorSettings& result) {
     result = color_settings_;
@@ -131,6 +131,8 @@
   const ImageDataArray& dataUnion() const { return data_union_; }
   void dataUnion(ImageDataArray& result) { result = data_union_; };
 
+  DOMArrayBufferBase* BufferBase() const;
+
   sk_sp<SkColorSpace> GetSkColorSpace();
   bool ImageDataInCanvasColorSettings(const CanvasColorSpace&,
                                       const CanvasPixelFormat&,
diff --git a/third_party/WebKit/Source/core/html/ImageData.idl b/third_party/WebKit/Source/core/html/ImageData.idl
index e29e039c..173ecfa 100644
--- a/third_party/WebKit/Source/core/html/ImageData.idl
+++ b/third_party/WebKit/Source/core/html/ImageData.idl
@@ -37,16 +37,6 @@
     Exposed=(Window,Worker),
     RaisesException=Constructor,
 ] interface ImageData {
-
-    // The following createImageData functions are used instead of the regular constructors
-    // as currently Blink IDL does not allow to put custom constructors behind a flag
-    // (crbug.com/672978). These must be replaced with regular constructor declaration
-    // as specified in the proposal before shipping.
-    // https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
-
-    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
-    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
-
     [RuntimeEnabled=ExperimentalCanvasFeatures] ImageDataColorSettings getColorSettings();
 
     readonly attribute unsigned long width;
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 6c418628..9caf61a 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -38,8 +38,11 @@
 namespace blink {
 
 BaseRenderingContext2D::BaseRenderingContext2D()
-    : clip_antialiasing_(kNotAntiAliased) {
+    : clip_antialiasing_(kNotAntiAliased), color_management_enabled_(false) {
   state_stack_.push_back(CanvasRenderingContext2DState::Create());
+  color_management_enabled_ =
+      RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() &&
+      RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
 }
 
 BaseRenderingContext2D::~BaseRenderingContext2D() {}
@@ -1508,10 +1511,26 @@
   return true;
 }
 
+ImageDataColorSettings
+BaseRenderingContext2D::GetColorSettingsAsImageDataColorSettings() const {
+  ImageDataColorSettings color_settings;
+  color_settings.setColorSpace(ColorSpaceAsString());
+  if (PixelFormat() == kF16CanvasPixelFormat)
+    color_settings.setStorageFormat(kFloat32ArrayStorageFormatName);
+  return color_settings;
+}
+
 ImageData* BaseRenderingContext2D::createImageData(
     ImageData* image_data,
     ExceptionState& exception_state) const {
-  ImageData* result = ImageData::Create(image_data->Size());
+  ImageData* result = nullptr;
+  if (color_management_enabled_) {
+    ImageDataColorSettings color_settings =
+        GetColorSettingsAsImageDataColorSettings();
+    result = ImageData::Create(image_data->Size(), &color_settings);
+  } else {
+    result = ImageData::Create(image_data->Size());
+  }
   if (!result)
     exception_state.ThrowRangeError("Out of memory at ImageData creation");
   return result;
@@ -1529,13 +1548,49 @@
   }
 
   IntSize size(abs(sw), abs(sh));
+  ImageData* result = nullptr;
+  if (color_management_enabled_) {
+    ImageDataColorSettings color_settings =
+        GetColorSettingsAsImageDataColorSettings();
+    result = ImageData::Create(size, &color_settings);
+  } else {
+    result = ImageData::Create(size);
+  }
 
-  ImageData* result = ImageData::Create(size);
   if (!result)
     exception_state.ThrowRangeError("Out of memory at ImageData creation");
   return result;
 }
 
+ImageData* BaseRenderingContext2D::createImageData(
+    unsigned width,
+    unsigned height,
+    ImageDataColorSettings& color_settings,
+    ExceptionState& exception_state) const {
+  return ImageData::CreateImageData(width, height, color_settings,
+                                    exception_state);
+}
+
+ImageData* BaseRenderingContext2D::createImageData(
+    ImageDataArray& data_array,
+    unsigned width,
+    unsigned height,
+    ExceptionState& exception_state) const {
+  ImageDataColorSettings color_settings;
+  return ImageData::CreateImageData(data_array, width, height, color_settings,
+                                    exception_state);
+}
+
+ImageData* BaseRenderingContext2D::createImageData(
+    ImageDataArray& data_array,
+    unsigned width,
+    unsigned height,
+    ImageDataColorSettings& color_settings,
+    ExceptionState& exception_state) const {
+  return ImageData::CreateImageData(data_array, width, height, color_settings,
+                                    exception_state);
+}
+
 ImageData* BaseRenderingContext2D::getImageData(
     int sx,
     int sy,
@@ -1598,8 +1653,14 @@
 
   IntRect image_data_rect(sx, sy, sw, sh);
   ImageBuffer* buffer = GetImageBuffer();
+  ImageDataColorSettings color_settings =
+      GetColorSettingsAsImageDataColorSettings();
   if (!buffer || isContextLost()) {
-    ImageData* result = ImageData::Create(image_data_rect.Size());
+    ImageData* result = nullptr;
+    if (color_management_enabled_)
+      result = ImageData::Create(image_data_rect.Size(), &color_settings);
+    else
+      result = ImageData::Create(image_data_rect.Size());
     if (!result)
       exception_state.ThrowRangeError("Out of memory at ImageData creation");
     return result;
@@ -1613,11 +1674,22 @@
 
   NeedsFinalizeFrame();
 
-  DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
-  return ImageData::Create(
-      image_data_rect.Size(),
-      NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create(
-          array_buffer, 0, array_buffer->ByteLength())));
+  if (!color_management_enabled_) {
+    DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
+    return ImageData::Create(
+        image_data_rect.Size(),
+        NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create(
+            array_buffer, 0, array_buffer->ByteLength())));
+  }
+
+  ImageDataStorageFormat storage_format =
+      ImageData::GetImageDataStorageFormat(color_settings.storageFormat());
+  DOMArrayBufferView* array_buffer_view =
+      ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+          contents, PixelFormat(), storage_format);
+  return ImageData::Create(image_data_rect.Size(),
+                           NotShared<DOMArrayBufferView>(array_buffer_view),
+                           &color_settings);
 }
 
 void BaseRenderingContext2D::putImageData(ImageData* data,
@@ -1639,14 +1711,15 @@
   if (!WTF::CheckMul(dirty_width, dirty_height).IsValid<int>()) {
     return;
   }
-
   usage_counters_.num_put_image_data_calls++;
   usage_counters_.area_put_image_data_calls += dirty_width * dirty_height;
-  if (data->data()->BufferBase()->IsNeutered()) {
+
+  if (data->BufferBase()->IsNeutered()) {
     exception_state.ThrowDOMException(kInvalidStateError,
                                       "The source data has been neutered.");
     return;
   }
+
   ImageBuffer* buffer = GetImageBuffer();
   if (!buffer)
     return;
@@ -1696,10 +1769,22 @@
   CheckOverdraw(dest_rect, 0, CanvasRenderingContext2DState::kNoImage,
                 kUntransformedUnclippedFill);
 
-  buffer->PutByteArray(kUnmultiplied, data->data()->Data(),
-                       IntSize(data->width(), data->height()), source_rect,
-                       IntPoint(dest_offset));
+  if (color_management_enabled_) {
+    unsigned data_length = data->width() * data->height() * 4;
+    if (PixelFormat() == kF16CanvasPixelFormat)
+      data_length *= 2;
+    std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[data_length]);
+    data->ImageDataInCanvasColorSettings(ColorSpace(), PixelFormat(),
+                                         converted_pixels);
 
+    buffer->PutByteArray(kUnmultiplied, converted_pixels.get(),
+                         IntSize(data->width(), data->height()), source_rect,
+                         IntPoint(dest_offset));
+  } else {
+    buffer->PutByteArray(kUnmultiplied, data->data()->Data(),
+                         IntSize(data->width(), data->height()), source_rect,
+                         IntPoint(dest_offset));
+  }
   DidDraw(dest_rect);
 }
 
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h
index be6a723..7d9d7c5 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.h
@@ -187,6 +187,20 @@
 
   ImageData* createImageData(ImageData*, ExceptionState&) const;
   ImageData* createImageData(int width, int height, ExceptionState&) const;
+  ImageData* createImageData(unsigned,
+                             unsigned,
+                             ImageDataColorSettings&,
+                             ExceptionState&) const;
+  ImageData* createImageData(ImageDataArray&,
+                             unsigned,
+                             unsigned,
+                             ExceptionState&) const;
+  ImageData* createImageData(ImageDataArray&,
+                             unsigned,
+                             unsigned,
+                             ImageDataColorSettings&,
+                             ExceptionState&) const;
+
   ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&);
   void putImageData(ImageData*, int dx, int dy, ExceptionState&);
   void putImageData(ImageData*,
@@ -238,6 +252,16 @@
 
   virtual void WillDrawImage(CanvasImageSource*) const {}
 
+  virtual CanvasColorSpace ColorSpace() const {
+    return kLegacyCanvasColorSpace;
+  };
+  virtual String ColorSpaceAsString() const {
+    return kLegacyCanvasColorSpaceName;
+  }
+  virtual CanvasPixelFormat PixelFormat() const {
+    return kRGBA8CanvasPixelFormat;
+  }
+
   void RestoreMatrixClipStack(PaintCanvas*) const;
 
   DECLARE_VIRTUAL_TRACE();
@@ -372,6 +396,10 @@
 
   void ClearCanvas();
   bool RectContainsTransformedRect(const FloatRect&, const SkIRect&) const;
+
+  ImageDataColorSettings GetColorSettingsAsImageDataColorSettings() const;
+
+  bool color_management_enabled_;
 };
 
 template <typename DrawFunc, typename ContainsFunc>
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
index 7110a2f5..4ef70aea 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -279,6 +279,18 @@
   canvas()->WillDrawImageTo2DContext(source);
 }
 
+CanvasColorSpace CanvasRenderingContext2D::ColorSpace() const {
+  return color_params().color_space();
+}
+
+String CanvasRenderingContext2D::ColorSpaceAsString() const {
+  return CanvasRenderingContext::ColorSpaceAsString();
+}
+
+CanvasPixelFormat CanvasRenderingContext2D::PixelFormat() const {
+  return color_params().pixel_format();
+}
+
 ColorBehavior CanvasRenderingContext2D::DrawImageColorBehavior() const {
   return CanvasRenderingContext::ColorBehaviorForMediaDrawnToCanvas();
 }
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
index 8782be3..70ecb783 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
@@ -243,6 +243,11 @@
   CanvasRenderingContext::ContextType GetContextType() const override {
     return CanvasRenderingContext::kContext2d;
   }
+
+  CanvasColorSpace ColorSpace() const override;
+  String ColorSpaceAsString() const override;
+  CanvasPixelFormat PixelFormat() const override;
+
   bool Is2d() const override { return true; }
   bool IsComposited() const override;
   bool IsAccelerated() const override;
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.idl b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.idl
index fcd7a1dc2..bb229a9 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.idl
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.idl
@@ -129,6 +129,10 @@
     [RaisesException] ImageData getImageData(long sx, long sy, long sw, long sh);
     [RaisesException] void putImageData(ImageData imagedata, long dx, long dy);
     [RaisesException] void putImageData(ImageData imagedata, long dx, long dy, long dirtyX, long dirtyY, long dirtyWidth, long dirtyHeight);
+    
+    // https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, optional ImageDataColorSettings imageDataColorSettings);
 
     // Context state
     // Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
index cfc096c7..3489a30 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -37,6 +37,7 @@
 #include "third_party/skia/include/core/SkColorSpaceXform.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkSwizzle.h"
 
 using ::testing::Mock;
 
@@ -1342,6 +1343,291 @@
       color_correct_rendering_default_mode_runtime_flag);
 }
 
+bool ConvertPixelsToColorSpaceAndPixelFormatForTest(
+    DOMArrayBufferView* data_array,
+    CanvasColorSpace src_color_space,
+    CanvasColorSpace dst_color_space,
+    CanvasPixelFormat dst_pixel_format,
+    std::unique_ptr<uint8_t[]>& converted_pixels) {
+  // Setting SkColorSpaceXform::apply parameters
+  SkColorSpaceXform::ColorFormat src_color_format =
+      SkColorSpaceXform::kRGBA_8888_ColorFormat;
+
+  unsigned data_length = data_array->byteLength() / data_array->TypeSize();
+  unsigned num_pixels = data_length / 4;
+  DOMUint8ClampedArray* u8_array = nullptr;
+  DOMUint16Array* u16_array = nullptr;
+  DOMFloat32Array* f32_array = nullptr;
+  void* src_data = nullptr;
+
+  switch (data_array->GetType()) {
+    case ArrayBufferView::ViewType::kTypeUint8Clamped:
+      u8_array = const_cast<DOMUint8ClampedArray*>(
+          static_cast<const DOMUint8ClampedArray*>(data_array));
+      src_data = static_cast<void*>(u8_array->Data());
+      break;
+
+    case ArrayBufferView::ViewType::kTypeUint16:
+      u16_array = const_cast<DOMUint16Array*>(
+          static_cast<const DOMUint16Array*>(data_array));
+      src_color_format =
+          SkColorSpaceXform::ColorFormat::kRGBA_U16_BE_ColorFormat;
+      src_data = static_cast<void*>(u16_array->Data());
+      break;
+
+    case ArrayBufferView::ViewType::kTypeFloat32:
+      f32_array = const_cast<DOMFloat32Array*>(
+          static_cast<const DOMFloat32Array*>(data_array));
+      src_color_format = SkColorSpaceXform::kRGBA_F32_ColorFormat;
+      src_data = static_cast<void*>(f32_array->Data());
+      break;
+    default:
+      NOTREACHED();
+      return false;
+  }
+
+  SkColorSpaceXform::ColorFormat dst_color_format =
+      SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
+  if (dst_pixel_format == kF16CanvasPixelFormat)
+    dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat;
+
+  sk_sp<SkColorSpace> src_sk_color_space = nullptr;
+  if (u8_array) {
+    src_sk_color_space = ImageData::GetSkColorSpaceForTest(
+        src_color_space, kRGBA8CanvasPixelFormat);
+  } else {
+    src_sk_color_space = ImageData::GetSkColorSpaceForTest(
+        src_color_space, kF16CanvasPixelFormat);
+  }
+
+  sk_sp<SkColorSpace> dst_sk_color_space =
+      ImageData::GetSkColorSpaceForTest(dst_color_space, dst_pixel_format);
+
+  // When the input dataArray is in Uint16, we normally should convert the
+  // values from Little Endian to Big Endian before passing the buffer to
+  // SkColorSpaceXform::apply. However, in this test scenario we are creating
+  // the Uin16 dataArray by multiplying a Uint8Clamped array members by 257,
+  // hence the Big Endian and Little Endian representations are the same.
+
+  std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(
+      src_sk_color_space.get(), dst_sk_color_space.get());
+
+  if (!xform->apply(dst_color_format, converted_pixels.get(), src_color_format,
+                    src_data, num_pixels, kUnpremul_SkAlphaType))
+    return false;
+  return true;
+}
+
+// The color settings of the surface of the canvas always remaines loyal to the
+// first created context 2D. Therefore, we have to test different canvas color
+// space settings for CanvasRenderingContext2D::putImageData() in different
+// tests.
+enum class CanvasColorSpaceSettings : uint8_t {
+  CANVAS_SRGB = 0,
+  CANVAS_LINEARSRGB = 1,
+  CANVAS_REC2020 = 2,
+  CANVAS_P3 = 3,
+
+  LAST = CANVAS_P3
+};
+
+// This test verifies the correct behavior of putImageData member function in
+// color managed mode.
+void TestPutImageDataOnCanvasWithColorSpaceSettings(
+    HTMLCanvasElement& canvas_element,
+    CanvasColorSpaceSettings canvas_colorspace_setting,
+    float color_tolerance) {
+  bool experimental_canvas_features_runtime_flag =
+      RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
+  bool color_correct_rendering_runtime_flag =
+      RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
+  RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true);
+  RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(true);
+
+  bool test_passed = true;
+  unsigned num_image_data_color_spaces = 3;
+  CanvasColorSpace image_data_color_spaces[] = {
+      kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace,
+  };
+
+  unsigned num_image_data_storage_formats = 3;
+  ImageDataStorageFormat image_data_storage_formats[] = {
+      kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat,
+      kFloat32ArrayStorageFormat,
+  };
+
+  CanvasColorSpace canvas_color_spaces[] = {
+      kSRGBCanvasColorSpace, kSRGBCanvasColorSpace, kRec2020CanvasColorSpace,
+      kP3CanvasColorSpace,
+  };
+
+  String canvas_color_space_names[] = {
+      kSRGBCanvasColorSpaceName, kSRGBCanvasColorSpaceName,
+      kRec2020CanvasColorSpaceName, kP3CanvasColorSpaceName};
+
+  CanvasPixelFormat canvas_pixel_formats[] = {
+      kRGBA8CanvasPixelFormat, kF16CanvasPixelFormat, kF16CanvasPixelFormat,
+      kF16CanvasPixelFormat,
+  };
+
+  String canvas_pixel_format_names[] = {
+      kRGBA8CanvasPixelFormatName, kF16CanvasPixelFormatName,
+      kF16CanvasPixelFormatName, kF16CanvasPixelFormatName};
+
+  // Source pixels in RGBA32
+  uint8_t u8_pixels[] = {255, 0,   0,   255,  // Red
+                         0,   0,   0,   0,    // Transparent
+                         255, 192, 128, 64,   // Decreasing values
+                         93,  117, 205, 11};  // Random values
+  unsigned data_length = 16;
+
+  uint16_t* u16_pixels = new uint16_t[data_length];
+  for (unsigned i = 0; i < data_length; i++)
+    u16_pixels[i] = u8_pixels[i] * 257;
+
+  float* f32_pixels = new float[data_length];
+  for (unsigned i = 0; i < data_length; i++)
+    f32_pixels[i] = u8_pixels[i] / 255.0;
+
+  DOMArrayBufferView* data_array = nullptr;
+
+  DOMUint8ClampedArray* data_u8 =
+      DOMUint8ClampedArray::Create(u8_pixels, data_length);
+  DCHECK(data_u8);
+  EXPECT_EQ(data_length, data_u8->length());
+  DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
+  DCHECK(data_u16);
+  EXPECT_EQ(data_length, data_u16->length());
+  DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
+  DCHECK(data_f32);
+  EXPECT_EQ(data_length, data_f32->length());
+
+  ImageData* image_data = nullptr;
+  ImageDataColorSettings color_settings;
+
+  // At most four bytes are needed for Float32 output per color component.
+  std::unique_ptr<uint8_t[]> pixels_converted_manually(
+      new uint8_t[data_length * 4]());
+
+  // Loop through different possible combinations of image data color space and
+  // storage formats and create the respective test image data objects.
+  for (unsigned i = 0; i < num_image_data_color_spaces; i++) {
+    color_settings.setColorSpace(
+        ImageData::CanvasColorSpaceName(image_data_color_spaces[i]));
+
+    for (unsigned j = 0; j < num_image_data_storage_formats; j++) {
+      switch (image_data_storage_formats[j]) {
+        case kUint8ClampedArrayStorageFormat:
+          data_array = static_cast<DOMArrayBufferView*>(data_u8);
+          color_settings.setStorageFormat(kUint8ClampedArrayStorageFormatName);
+          break;
+        case kUint16ArrayStorageFormat:
+          data_array = static_cast<DOMArrayBufferView*>(data_u16);
+          color_settings.setStorageFormat(kUint16ArrayStorageFormatName);
+          break;
+        case kFloat32ArrayStorageFormat:
+          data_array = static_cast<DOMArrayBufferView*>(data_f32);
+          color_settings.setStorageFormat(kFloat32ArrayStorageFormatName);
+          break;
+        default:
+          NOTREACHED();
+      }
+
+      image_data =
+          ImageData::CreateForTest(IntSize(2, 2), data_array, &color_settings);
+
+      unsigned k = (unsigned)(canvas_colorspace_setting);
+      // Convert the original data used to create ImageData to the
+      // canvas color space and canvas pixel format.
+      EXPECT_TRUE(ConvertPixelsToColorSpaceAndPixelFormatForTest(
+          data_array, image_data_color_spaces[i], canvas_color_spaces[k],
+          canvas_pixel_formats[k], pixels_converted_manually));
+
+      // Create a canvas and call putImageData and getImageData to make sure
+      // the conversion is done correctly.
+      CanvasContextCreationAttributes attributes;
+      attributes.setAlpha(true);
+      attributes.setColorSpace(canvas_color_space_names[k]);
+      attributes.setPixelFormat(canvas_pixel_format_names[k]);
+      CanvasRenderingContext2D* context =
+          static_cast<CanvasRenderingContext2D*>(
+              canvas_element.GetCanvasRenderingContext("2d", attributes));
+      NonThrowableExceptionState exception_state;
+      context->putImageData(image_data, 0, 0, exception_state);
+
+      void* pixels_from_get_image_data = nullptr;
+      if (canvas_pixel_formats[k] == kRGBA8CanvasPixelFormat) {
+        pixels_from_get_image_data =
+            context->getImageData(0, 0, 2, 2, exception_state)->data()->Data();
+        // Swizzle if needed
+        if (kN32_SkColorType == kBGRA_8888_SkColorType) {
+          SkSwapRB(static_cast<uint32_t*>(pixels_from_get_image_data),
+                   static_cast<uint32_t*>(pixels_from_get_image_data),
+                   data_length / 4);
+        }
+
+        unsigned char* cpixels1 =
+            static_cast<unsigned char*>(pixels_converted_manually.get());
+        unsigned char* cpixels2 =
+            static_cast<unsigned char*>(pixels_from_get_image_data);
+        for (unsigned m = 0; m < data_length; m++) {
+          if (abs(cpixels1[m] - cpixels2[m]) > color_tolerance)
+            test_passed = false;
+        }
+      } else {
+        pixels_from_get_image_data =
+            context->getImageData(0, 0, 2, 2, exception_state)
+                ->dataUnion()
+                .getAsFloat32Array()
+                .View()
+                ->Data();
+        float* fpixels1 = nullptr;
+        float* fpixels2 = nullptr;
+        void* vpointer = pixels_converted_manually.get();
+        fpixels1 = static_cast<float*>(vpointer);
+        fpixels2 = static_cast<float*>(pixels_from_get_image_data);
+        for (unsigned m = 0; m < data_length; m++) {
+          if (fpixels1[m] < 0)
+            fpixels1[m] = 0;
+          if (fabs(fpixels1[m] - fpixels2[m]) > color_tolerance) {
+            test_passed = false;
+          }
+        }
+
+        ASSERT_TRUE(test_passed);
+      }
+    }
+  }
+  delete[] u16_pixels;
+  delete[] f32_pixels;
+
+  RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(
+      experimental_canvas_features_runtime_flag);
+  RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(
+      color_correct_rendering_runtime_flag);
+}
+
+TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) {
+  TestPutImageDataOnCanvasWithColorSpaceSettings(
+      CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB, 0);
+}
+
+TEST_F(CanvasRenderingContext2DTest,
+       ColorManagedPutImageDataOnLinearSRGBCanvas) {
+  TestPutImageDataOnCanvasWithColorSpaceSettings(
+      CanvasElement(), CanvasColorSpaceSettings::CANVAS_LINEARSRGB, 0.15);
+}
+
+TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnRec2020Canvas) {
+  TestPutImageDataOnCanvasWithColorSpaceSettings(
+      CanvasElement(), CanvasColorSpaceSettings::CANVAS_REC2020, 0.1);
+}
+
+TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnP3Canvas) {
+  TestPutImageDataOnCanvasWithColorSpaceSettings(
+      CanvasElement(), CanvasColorSpaceSettings::CANVAS_P3, 0.1);
+}
+
 void OverrideScriptEnabled(Settings& settings) {
   // Simulate that we allow scripts, so that HTMLCanvasElement uses
   // LayoutHTMLCanvas.
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
index a3f2088e..667d8b10 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -245,6 +245,18 @@
   return this->GetImageBuffer();
 }
 
+CanvasColorSpace OffscreenCanvasRenderingContext2D::ColorSpace() const {
+  return color_params().color_space();
+}
+
+String OffscreenCanvasRenderingContext2D::ColorSpaceAsString() const {
+  return CanvasRenderingContext::ColorSpaceAsString();
+}
+
+CanvasPixelFormat OffscreenCanvasRenderingContext2D::PixelFormat() const {
+  return color_params().pixel_format();
+}
+
 bool OffscreenCanvasRenderingContext2D::IsAccelerated() const {
   return image_buffer_ && image_buffer_->IsAccelerated();
 }
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
index ede146f..c515145 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -113,6 +113,10 @@
   bool IsPaintable() const final;
 
   RefPtr<StaticBitmapImage> TransferToStaticBitmapImage();
+
+  CanvasColorSpace ColorSpace() const override;
+  String ColorSpaceAsString() const override;
+  CanvasPixelFormat PixelFormat() const override;
 };
 
 // TODO(fserb): remove this.
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
index 016eb1d..e2a0113 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
@@ -76,6 +76,12 @@
     [RaisesException] ImageData getImageData(long sx, long sy, long sw, long sh);
     [RaisesException] void putImageData(ImageData imagedata, long dx, long dy);
     [RaisesException] void putImageData(ImageData imagedata, long dx, long dy, long dirtyX, long dirtyY, long dirtyWidth, long dirtyHeight);
+ 
+    // If OffscreenCanva ships before color managed canvas, this method must remain behind flag.
+    // https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+
 
     // Line caps/joins
     attribute unrestricted double lineWidth; // (default 1)
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index bc001d9..991341f 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -289,7 +289,7 @@
     },
     {
       name: "CSSSelectorsFocusWithin",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "CSSSnapSize",
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp
index 80edcb1..a99b4744 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasColorParams.cpp
@@ -19,9 +19,21 @@
 }
 
 sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpaceForSkSurfaces() const {
-  if (color_space_ == kLegacyCanvasColorSpace)
-    return nullptr;
-  return GetGfxColorSpace().ToSkColorSpace();
+  switch (color_space_) {
+    case kLegacyCanvasColorSpace:
+      return nullptr;
+    case kSRGBCanvasColorSpace:
+      if (pixel_format_ == kF16CanvasPixelFormat)
+        return SkColorSpace::MakeSRGBLinear();
+      return SkColorSpace::MakeSRGB();
+    case kRec2020CanvasColorSpace:
+      return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
+                                   SkColorSpace::kRec2020_Gamut);
+    case kP3CanvasColorSpace:
+      return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
+                                   SkColorSpace::kDCIP3_D65_Gamut);
+  }
+  return nullptr;
 }
 
 SkColorType CanvasColorParams::GetSkColorType() const {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
index 0f6039a9..23e4a518 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -390,51 +390,21 @@
   WTF::ArrayBufferContents result(std::move(data), alloc_size_in_bytes,
                                   WTF::ArrayBufferContents::kNotShared);
 
-  // Skia does not support unpremultiplied read with an F16 to 8888 conversion
-  bool use_f16_workaround =
-      surface_->color_params().GetSkColorType() == kRGBA_F16_SkColorType;
-
-  SkAlphaType alpha_type = (multiplied == kPremultiplied || use_f16_workaround)
+  SkAlphaType alpha_type = (multiplied == kPremultiplied)
                                ? kPremul_SkAlphaType
                                : kUnpremul_SkAlphaType;
-  // The workaround path use a canvas draw under the hood, which can only
-  // use N32 at this time.
   SkColorType color_type =
-      use_f16_workaround ? kN32_SkColorType : kRGBA_8888_SkColorType;
+      (surface_->color_params().GetSkColorType() == kRGBA_F16_SkColorType)
+          ? kRGBA_F16_SkColorType
+          : kRGBA_8888_SkColorType;
 
-  // Only use sRGB when the surface has a color space.  Converting untagged
-  // pixels to a particular color space is not well-defined in Skia.
-  sk_sp<SkColorSpace> color_space =
-      surface_->color_params().GetSkColorSpaceForSkSurfaces();
-
-  SkImageInfo info = SkImageInfo::Make(rect.Width(), rect.Height(), color_type,
-                                       alpha_type, std::move(color_space));
+  SkImageInfo info = SkImageInfo::Make(
+      rect.Width(), rect.Height(), color_type, alpha_type,
+      surface_->color_params().GetSkColorSpaceForSkSurfaces());
 
   snapshot->readPixels(info, result.Data(), bytes_per_pixel * rect.Width(),
                        rect.X(), rect.Y());
   gpu_readback_invoked_in_current_frame_ = true;
-
-  if (use_f16_workaround) {
-    uint32_t* pixel = (uint32_t*)result.Data();
-    size_t pixel_count = alloc_size_in_bytes / sizeof(uint32_t);
-    // TODO(skbug.com/5853): make readPixels support RGBA output so that we no
-    // longer
-    // have to do this.
-    if (kN32_SkColorType == kBGRA_8888_SkColorType) {
-      // Convert BGRA to RGBA if necessary on this platform.
-      SkSwapRB(pixel, pixel, pixel_count);
-    }
-    // TODO(skbug.com/5853): We should really be doing the unpremultiply in
-    // linear space
-    // and skia should provide that service.
-    if (multiplied == kUnmultiplied) {
-      for (; pixel_count; --pixel_count) {
-        *pixel = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*pixel);
-        ++pixel;
-      }
-    }
-  }
-
   result.Transfer(contents);
   return true;
 }
diff --git a/tools/perf/benchmarks/blink_perf.js b/tools/perf/benchmarks/blink_perf.js
index 465e1ff..bb764cf 100644
--- a/tools/perf/benchmarks/blink_perf.js
+++ b/tools/perf/benchmarks/blink_perf.js
@@ -12,6 +12,24 @@
   this.isDone = true;
 };
 
+testRunner.supportTracing = true;
+
+// If this is true, blink_perf tests is put on paused waiting for tracing to
+// be started. |scheduleTestRun| should be invoked after tracing is started
+// to continue blink perf test.
+testRunner.isWaitingForTracingStart = false;
+
+testRunner.startTracing = function(tracingCategories, scheduleTestRun) {
+  this.tracingCategories = tracingCategories;
+  this.scheduleTestRun = scheduleTestRun;
+  this.isWaitingForTracingStart = true;
+}
+
+testRunner.stopTracingAndMeasure = function(traceEventsToMeasure, callback) {
+  testRunner.traceEventsToMeasure = traceEventsToMeasure;
+  callback();
+}
+
 window.GCController = {};
 
 GCController.collect = function() {
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 64a55a45..c30bcbcf 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -12,8 +12,14 @@
 from telemetry.page import legacy_page_test
 from telemetry.page import shared_page_state
 from telemetry import story
+from telemetry.timeline import bounds
+from telemetry.timeline import model as model_module
+from telemetry.timeline import tracing_config
+
 from telemetry.value import list_of_scalar_values
 from telemetry.value import scalar
+from telemetry.value import trace
+
 
 from benchmarks import pywebsocket_server
 from measurements import timeline_controller
@@ -73,6 +79,56 @@
   return ps
 
 
+def _ComputeTraceEventsThreadTimeForBlinkPerf(
+    renderer_thread, trace_events_to_measure):
+  """ Compute the CPU duration for each of |trace_events_to_measure| during
+  blink_perf test.
+
+  Args:
+    renderer_thread: the renderer thread which run blink_perf test.
+    trace_events_to_measure: a list of string names of trace events to measure
+    CPU duration for.
+
+  Returns:
+    a dictionary in which each key is a trace event' name (from
+    |trace_events_to_measure| list), and value is a list of numbers that
+    represents to total cpu time of that trace events in each blink_perf test.
+  """
+  trace_cpu_time_metrics = {}
+
+  # Collect the bounds of "blink_perf.runTest" events.
+  test_runs_bounds = []
+  for event in renderer_thread.async_slices:
+    if event.name == "blink_perf.runTest":
+      test_runs_bounds.append(bounds.Bounds.CreateFromEvent(event))
+  test_runs_bounds.sort(key=lambda b: b.min)
+
+  for t in trace_events_to_measure:
+    trace_cpu_time_metrics[t] = [0.0] * len(test_runs_bounds)
+
+  for event_name in trace_events_to_measure:
+    curr_test_runs_bound_index = 0
+    for event in renderer_thread.IterAllSlicesOfName(event_name):
+      while (curr_test_runs_bound_index < len(test_runs_bounds) and
+             event.start > test_runs_bounds[curr_test_runs_bound_index].max):
+        curr_test_runs_bound_index += 1
+      if curr_test_runs_bound_index >= len(test_runs_bounds):
+        break
+      curr_test_bound = test_runs_bounds[curr_test_runs_bound_index]
+      intersect_wall_time = bounds.Bounds.GetOverlapBetweenBounds(
+          curr_test_bound, bounds.Bounds.CreateFromEvent(event))
+      if event.thread_duration and event.duration:
+        intersect_cpu_time = (
+            intersect_wall_time * event.thread_duration / event.duration)
+      else:
+        intersect_cpu_time = intersect_wall_time
+      trace_cpu_time_metrics[event_name][curr_test_runs_bound_index] += (
+          intersect_cpu_time)
+
+  return trace_cpu_time_metrics
+
+
+
 class _BlinkPerfMeasurement(legacy_page_test.LegacyPageTest):
   """Tuns a blink performance test and reports the results."""
 
@@ -98,8 +154,53 @@
     if 'content-shell' in options.browser_type:
       options.AppendExtraBrowserArgs('--expose-internals-for-testing')
 
+  def _ContinueTestRunWithTracing(self, tab):
+    tracing_categories = tab.EvaluateJavaScript(
+        'testRunner.tracingCategories')
+    config = tracing_config.TracingConfig()
+    config.enable_chrome_trace = True
+    config.chrome_trace_config.category_filter.AddFilterString(
+        'blink.console')  # This is always required for js land trace event
+    config.chrome_trace_config.category_filter.AddFilterString(
+        tracing_categories)
+    tab.browser.platform.tracing_controller.StartTracing(config)
+    tab.EvaluateJavaScript('testRunner.scheduleTestRun()')
+    tab.WaitForJavaScriptCondition('testRunner.isDone')
+    return tab.browser.platform.tracing_controller.StopTracing()
+
+
+  def PrintAndCollectTraceEventMetrics(self, trace_cpu_time_metrics, results):
+    unit = 'ms'
+    print
+    for trace_event_name, cpu_times in trace_cpu_time_metrics.iteritems():
+      print 'CPU times of trace event "%s":' % trace_event_name
+      cpu_times_string = ', '.join(['{0:.10f}'.format(t) for t in cpu_times])
+      print 'values %s %s' % (cpu_times_string, unit)
+      avg = 0.0
+      if cpu_times:
+        avg = sum(cpu_times)/len(cpu_times)
+      print 'avg', '{0:.10f}'.format(avg), unit
+      results.AddValue(list_of_scalar_values.ListOfScalarValues(
+          results.current_page, name=trace_event_name, units=unit,
+          values=cpu_times))
+      print
+    print '\n'
+
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition('testRunner.isDone', timeout=600)
+    tab.WaitForJavaScriptCondition(
+        'testRunner.isDone || testRunner.isWaitingForTracingStart', timeout=600)
+    trace_cpu_time_metrics = {}
+    if tab.EvaluateJavaScript('testRunner.isWaitingForTracingStart'):
+      trace_data = self._ContinueTestRunWithTracing(tab)
+      trace_value = trace.TraceValue(page, trace_data)
+      results.AddValue(trace_value)
+
+      trace_events_to_measure = tab.EvaluateJavaScript(
+          'window.testRunner.traceEventsToMeasure')
+      model = model_module.TimelineModel(trace_data)
+      renderer_thread = model.GetRendererThreadFromTabId(tab.id)
+      trace_cpu_time_metrics = _ComputeTraceEventsThreadTimeForBlinkPerf(
+          renderer_thread, trace_events_to_measure)
 
     log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')
 
@@ -120,6 +221,8 @@
 
     print log
 
+    self.PrintAndCollectTraceEventMetrics(trace_cpu_time_metrics, results)
+
 
 # TODO(wangxianzhu): Convert the paint benchmarks to use the new blink_perf
 # tracing once it's ready.
diff --git a/tools/perf/benchmarks/blink_perf_unittest.py b/tools/perf/benchmarks/blink_perf_unittest.py
new file mode 100644
index 0000000..26be0772
--- /dev/null
+++ b/tools/perf/benchmarks/blink_perf_unittest.py
@@ -0,0 +1,183 @@
+# 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 unittest
+
+from telemetry import decorators
+from telemetry import story
+from telemetry.page import page as page_module
+from telemetry.testing import options_for_unittests
+from telemetry.testing import page_test_test_case
+from telemetry.timeline import async_slice
+from telemetry.timeline import model as model_module
+
+
+from benchmarks import blink_perf
+
+
+class BlinkPerfTest(page_test_test_case.PageTestTestCase):
+  _BLINK_PERF_TEST_DATA_DIR = os.path.join(os.path.dirname(__file__),
+      '..', '..', '..', 'third_party', 'WebKit', 'PerformanceTests',
+      'TestData')
+
+  _BLINK_PERF_RESOURCES_DIR = os.path.join(os.path.dirname(__file__),
+      '..', '..', '..', 'third_party', 'WebKit', 'PerformanceTests',
+      'resources')
+  def setUp(self):
+    self._options = options_for_unittests.GetCopy()
+    # pylint: disable=protected-access
+    self._measurement = blink_perf._BlinkPerfMeasurement()
+    # pylint: enable=protected-access
+
+  def _CreateStorySetForTestFile(self, test_file_name):
+    story_set = story.StorySet(base_dir=self._BLINK_PERF_TEST_DATA_DIR,
+        serving_dirs={self._BLINK_PERF_TEST_DATA_DIR,
+                      self._BLINK_PERF_RESOURCES_DIR})
+    page = page_module.Page('file://' + test_file_name, story_set,
+        base_dir=story_set.base_dir)
+    story_set.AddStory(page)
+    return story_set
+
+  @decorators.Disabled('win')  # crbug.com/715822
+  def testBlinkPerfTracingMetricsForMeasureTime(self):
+    results = self.RunMeasurement(measurement=self._measurement,
+        ps=self._CreateStorySetForTestFile('append-child-measure-time.html'),
+        options=self._options)
+    self.assertFalse(results.failures)
+    self.assertEquals(len(results.FindAllTraceValues()), 1)
+
+    frame_view_layouts = results.FindAllPageSpecificValuesNamed(
+        'FrameView::layout')
+    self.assertEquals(len(frame_view_layouts), 1)
+    self.assertGreater(frame_view_layouts[0].GetRepresentativeNumber, 0.1)
+
+    update_layout_trees = results.FindAllPageSpecificValuesNamed(
+        'UpdateLayoutTree')
+    self.assertEquals(len(update_layout_trees), 1)
+    self.assertGreater(update_layout_trees[0].GetRepresentativeNumber, 0.1)
+
+  @decorators.Disabled('android')  # crbug.com/715685
+  def testBlinkPerfTracingMetricsForMeasureFrameTime(self):
+    results = self.RunMeasurement(measurement=self._measurement,
+        ps=self._CreateStorySetForTestFile(
+            'color-changes-measure-frame-time.html'),
+        options=self._options)
+    self.assertFalse(results.failures)
+    self.assertEquals(len(results.FindAllTraceValues()), 1)
+
+    frame_view_prepaints = results.FindAllPageSpecificValuesNamed(
+        'FrameView::prePaint')
+    self.assertEquals(len(frame_view_prepaints), 1)
+    self.assertGreater(frame_view_prepaints[0].GetRepresentativeNumber, 0.1)
+
+    frame_view_painttrees = results.FindAllPageSpecificValuesNamed(
+        'FrameView::paintTree')
+    self.assertEquals(len(frame_view_painttrees), 1)
+    self.assertGreater(frame_view_painttrees[0].GetRepresentativeNumber, 0.1)
+
+
+# pylint: disable=protected-access
+# This is needed for testing _ComputeTraceEventsThreadTimeForBlinkPerf method.
+class ComputeTraceEventsMetricsForBlinkPerfTest(unittest.TestCase):
+
+  def _AddBlinkTestSlice(self, renderer_thread, start, end):
+    s = async_slice.AsyncSlice(
+        'blink', 'blink_perf.runTest',
+        timestamp=start, duration=end - start, start_thread=renderer_thread,
+        end_thread=renderer_thread)
+    renderer_thread.AddAsyncSlice(s)
+
+  def testTraceEventMetricsSingleBlinkTest(self):
+    model = model_module.TimelineModel()
+    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
+    renderer_main.name = 'CrRendererMain'
+
+    # Set up a main thread model that looks like:
+    #   [          blink_perf.run_test                ]
+    #   |     [ foo ]          [  bar ]      [        baz     ]
+    #   |     |     |          |      |      |        |       |
+    #   100   120   140        400    420    500      550     600
+    #             |                |                  |
+    # CPU dur:    15               18                 70
+    #
+    self._AddBlinkTestSlice(renderer_main, 100, 550)
+
+    renderer_main.BeginSlice('blink', 'foo', 120, 122)
+    renderer_main.EndSlice(140, 137)
+
+    renderer_main.BeginSlice('blink', 'bar', 400, 402)
+    renderer_main.EndSlice(420, 420)
+
+    # Since this "baz" slice has CPU duration = 70ms, wall-time duration = 100ms
+    # & its overalapped wall-time with "blink_perf.run_test" is 50 ms, its
+    # overlapped CPU time with "blink_perf.run_test" is
+    # 50 * 70 / 100 = 35ms.
+    renderer_main.BeginSlice('blink', 'baz', 500, 520)
+    renderer_main.EndSlice(600, 590)
+
+    self.assertEquals(
+        blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
+            renderer_main, ['foo', 'bar', 'baz']),
+        {'foo': [15], 'bar': [18], 'baz': [35]})
+
+
+  def testTraceEventMetricsMultiBlinkTest(self):
+    model = model_module.TimelineModel()
+    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
+    renderer_main.name = 'CrRendererMain'
+
+    # Set up a main thread model that looks like:
+    #   [          blink_perf.run_test    ]         [ blink_perf.run_test  ]
+    #   |     [ foo ]          [  bar ]   |     [   |    foo         ]     |
+    #   |     |     |          |      |   |     |   |     |          |     |
+    #   100   120   140        400    420 440   500 520              600   640
+    #             |                |                      |
+    # CPU dur:    15               18                     40
+    #
+    self._AddBlinkTestSlice(renderer_main, 100, 440)
+    self._AddBlinkTestSlice(renderer_main, 520, 640)
+
+    renderer_main.BeginSlice('blink', 'foo', 120, 122)
+    renderer_main.EndSlice(140, 137)
+
+    renderer_main.BeginSlice('blink', 'bar', 400, 402)
+    renderer_main.EndSlice(420, 420)
+
+    # Since this "foo" slice has CPU duration = 40ms, wall-time duration = 100ms
+    # & its overalapped wall-time with "blink_perf.run_test" is 80 ms, its
+    # overlapped CPU time with "blink_perf.run_test" is
+    # 80 * 40 / 100 = 32ms.
+    renderer_main.BeginSlice('blink', 'foo', 500, 520)
+    renderer_main.EndSlice(600, 560)
+
+    self.assertEquals(
+        blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
+            renderer_main, ['foo', 'bar', 'baz']),
+        {'foo': [15, 32], 'bar': [18, 0], 'baz': [0, 0]})
+
+  def testTraceEventMetricsNoThreadTimeAvailable(self):
+    model = model_module.TimelineModel()
+    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
+    renderer_main.name = 'CrRendererMain'
+
+    # Set up a main thread model that looks like:
+    #   [          blink_perf.run_test                ]
+    #   |     [ foo ]          [  bar ]               |
+    #   |     |     |          |      |               |
+    #   100   120   140        400    420             550
+    #             |                |
+    # CPU dur:    None             None
+    #
+    self._AddBlinkTestSlice(renderer_main, 100, 550)
+
+    renderer_main.BeginSlice('blink', 'foo', 120)
+    renderer_main.EndSlice(140)
+
+    renderer_main.BeginSlice('blink', 'bar', 400)
+    renderer_main.EndSlice(420)
+
+    self.assertEquals(
+        blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
+            renderer_main, ['foo', 'bar']),
+        {'foo': [20], 'bar': [20]})
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py
index b5c99a1..465ee822 100644
--- a/tools/perf/page_sets/system_health/loading_stories.py
+++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -356,6 +356,7 @@
   TAGS = [story_tags.JAVASCRIPT_HEAVY]
 
 
+@decorators.Disabled('all')  # crbug.com/715936
 class LoadDriveStory(_LoadingStory):
   NAME = 'load:tools:drive'
   URL = 'https://drive.google.com/drive/my-drive'
diff --git a/ui/base/clipboard/clipboard_android_unittest.cc b/ui/base/clipboard/clipboard_android_unittest.cc
deleted file mode 100644
index d52013d4..0000000
--- a/ui/base/clipboard/clipboard_android_unittest.cc
+++ /dev/null
@@ -1,90 +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.
-
-#include "ui/base/clipboard/clipboard_android.h"
-
-#include "base/android/context_utils.h"
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/clipboard/scoped_clipboard_writer.h"
-
-namespace ui {
-
-class ClipboardAndroidTest : public ::testing::Test {
- public:
-  ~ClipboardAndroidTest() override {
-    Clipboard::DestroyClipboardForCurrentThread();
-  };
-
- protected:
-  Clipboard& clipboard() { return *Clipboard::GetForCurrentThread(); }
-};
-
-// Test that if another application writes some text to the pasteboard the
-// clipboard properly invalidates other types.
-TEST_F(ClipboardAndroidTest, InternalClipboardInvalidation) {
-  // Write a Webkit smart paste tag to our clipboard.
-  {
-    ScopedClipboardWriter clipboard_writer(CLIPBOARD_TYPE_COPY_PASTE);
-    clipboard_writer.WriteWebSmartPaste();
-  }
-  EXPECT_TRUE(clipboard().IsFormatAvailable(
-      Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
-
-  //
-  // Simulate that another application copied something in the Clipboard
-  //
-  std::string new_value("Some text copied by some other app");
-  using base::android::ConvertUTF8ToJavaString;
-  using base::android::MethodID;
-  using base::android::ScopedJavaLocalRef;
-
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ASSERT_TRUE(env);
-
-  ScopedJavaLocalRef<jclass> context_class =
-      base::android::GetClass(env, "android/content/Context");
-
-  jmethodID get_system_service = MethodID::Get<MethodID::TYPE_INSTANCE>(
-      env, context_class.obj(), "getSystemService",
-      "(Ljava/lang/String;)Ljava/lang/Object;");
-
-  // Retrieve the system service.
-  ScopedJavaLocalRef<jstring> service_name =
-      ConvertUTF8ToJavaString(env, "clipboard");
-  ScopedJavaLocalRef<jobject> clipboard_manager(
-      env,
-      env->CallObjectMethod(base::android::GetApplicationContext(),
-                            get_system_service, service_name.obj()));
-  ASSERT_TRUE(clipboard_manager.obj() && !base::android::ClearException(env));
-
-  ScopedJavaLocalRef<jclass> clipboard_class =
-      base::android::GetClass(env, "android/text/ClipboardManager");
-  jmethodID set_text = MethodID::Get<MethodID::TYPE_INSTANCE>(
-      env, clipboard_class.obj(), "setText", "(Ljava/lang/CharSequence;)V");
-  ScopedJavaLocalRef<jstring> new_value_string =
-      ConvertUTF8ToJavaString(env, new_value.c_str());
-
-  // Will need to call toString as CharSequence is not always a String.
-  env->CallVoidMethod(clipboard_manager.obj(), set_text,
-                      new_value_string.obj());
-
-  // The WebKit smart paste tag should now be gone.
-  EXPECT_FALSE(clipboard().IsFormatAvailable(
-      Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
-
-  // Make sure some text is available
-  EXPECT_TRUE(clipboard().IsFormatAvailable(
-      Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
-
-  // Make sure the text is what we inserted while simulating the other app
-  std::string contents;
-  clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &contents);
-  EXPECT_EQ(contents, new_value);
-}
-
-}  // namespace ui
-
-#include "ui/base/clipboard/clipboard_test_template.h"