diff --git a/DEPS b/DEPS
index 918cee24..34aea06 100644
--- a/DEPS
+++ b/DEPS
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'c4fcad23b1438aa6ad19f518503f861b9e3815e1',
+  'pdfium_revision': '469f6da247ffe77d0ae6089e5d93db0b0c0bb37e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
diff --git a/ash/common/wm/default_state.cc b/ash/common/wm/default_state.cc
index f4cb18f..d2ace3b 100644
--- a/ash/common/wm/default_state.cc
+++ b/ash/common/wm/default_state.cc
@@ -167,6 +167,10 @@
   if (ProcessWorkspaceEvents(window_state, event))
     return;
 
+  // Do not change the PINNED window state if this is not unpin event.
+  if (window_state->IsTrustedPinned() && event->type() != WM_EVENT_NORMAL)
+    return;
+
   if (ProcessCompoundEvents(window_state, event))
     return;
 
diff --git a/ash/common/wm/window_state.cc b/ash/common/wm/window_state.cc
index 638ee72d..13c4bff3 100644
--- a/ash/common/wm/window_state.cc
+++ b/ash/common/wm/window_state.cc
@@ -87,6 +87,10 @@
          GetStateType() == WINDOW_STATE_TYPE_TRUSTED_PINNED;
 }
 
+bool WindowState::IsTrustedPinned() const {
+  return GetStateType() == WINDOW_STATE_TYPE_TRUSTED_PINNED;
+}
+
 bool WindowState::IsNormalStateType() const {
   return GetStateType() == WINDOW_STATE_TYPE_NORMAL ||
          GetStateType() == WINDOW_STATE_TYPE_DEFAULT;
diff --git a/ash/common/wm/window_state.h b/ash/common/wm/window_state.h
index c2ff99d9..53a5c15 100644
--- a/ash/common/wm/window_state.h
+++ b/ash/common/wm/window_state.h
@@ -97,6 +97,7 @@
   bool IsFullscreen() const;
   bool IsSnapped() const;
   bool IsPinned() const;
+  bool IsTrustedPinned() const;
 
   // True if the window's state type is WINDOW_STATE_TYPE_MAXIMIZED,
   // WINDOW_STATE_TYPE_FULLSCREEN or WINDOW_STATE_TYPE_PINNED.
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc
index e225d91..6431f4f 100644
--- a/ash/wm/window_state_unittest.cc
+++ b/ash/wm/window_state_unittest.cc
@@ -11,6 +11,7 @@
 #include "ash/common/wm/wm_event.h"
 #include "ash/test/ash_md_test_base.h"
 #include "ash/wm/window_state_aura.h"
+#include "ash/wm/window_util.h"
 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/test/test_window_delegate.h"
@@ -360,6 +361,33 @@
             maximized->GetBoundsInScreen().ToString());
 }
 
+TEST_P(WindowStateTest, TrustedPinned) {
+  std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
+  WindowState* window_state = GetWindowState(window.get());
+  EXPECT_FALSE(window_state->IsTrustedPinned());
+  wm::PinWindow(window.get(), true /* trusted */);
+  EXPECT_TRUE(window_state->IsTrustedPinned());
+
+  gfx::Rect work_area =
+      display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
+  EXPECT_EQ(work_area.ToString(), window->bounds().ToString());
+
+  // Sending non-unpin/non-workspace related event should be ignored.
+  {
+    const WMEvent fullscreen_event(WM_EVENT_FULLSCREEN);
+    window_state->OnWMEvent(&fullscreen_event);
+  }
+  EXPECT_TRUE(window_state->IsTrustedPinned());
+
+  // Update display triggers workspace event.
+  UpdateDisplay("300x200");
+  EXPECT_EQ("0,0 300x200", window->GetBoundsInScreen().ToString());
+
+  // Unpin should work.
+  window_state->Restore();
+  EXPECT_FALSE(window_state->IsTrustedPinned());
+}
+
 TEST_P(WindowStateTest, AllowSetBoundsInMaximized) {
   std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
   WindowState* window_state = GetWindowState(window.get());
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 26ffc2ec..8f6d8e42 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -249,6 +249,8 @@
     "arc/fileapi/arc_documents_provider_async_file_util.h",
     "arc/fileapi/arc_documents_provider_backend_delegate.cc",
     "arc/fileapi/arc_documents_provider_backend_delegate.h",
+    "arc/fileapi/arc_documents_provider_file_stream_reader.cc",
+    "arc/fileapi/arc_documents_provider_file_stream_reader.h",
     "arc/fileapi/arc_documents_provider_root.cc",
     "arc/fileapi/arc_documents_provider_root.h",
     "arc/fileapi/arc_documents_provider_root_map.cc",
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc
index 6572b4c..f15330f0 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_backend_delegate.cc
@@ -7,6 +7,8 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h"
 #include "content/public/browser/browser_thread.h"
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "storage/browser/fileapi/file_stream_writer.h"
@@ -37,8 +39,9 @@
     const base::Time& expected_modification_time,
     storage::FileSystemContext* context) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  NOTIMPLEMENTED();  // TODO(crbug.com/671511): Implement this function.
-  return nullptr;
+
+  return base::MakeUnique<ArcDocumentsProviderFileStreamReader>(url, offset,
+                                                                &roots_);
 }
 
 std::unique_ptr<storage::FileStreamWriter>
@@ -62,7 +65,7 @@
     const storage::FileSystemURL& url,
     const storage::URLCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  NOTIMPLEMENTED();  // TODO(crbug.com/671511): Implement this function.
+  NOTREACHED();  // Never called by chromeos::FileSystemBackend.
   callback.Run(GURL());
 }
 
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc
new file mode 100644
index 0000000..dee5497
--- /dev/null
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.cc
@@ -0,0 +1,117 @@
+// Copyright 2016 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 "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_map.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "url/gurl.h"
+
+using content::BrowserThread;
+
+namespace arc {
+
+ArcDocumentsProviderFileStreamReader::ArcDocumentsProviderFileStreamReader(
+    const storage::FileSystemURL& url,
+    int64_t offset,
+    ArcDocumentsProviderRootMap* roots)
+    : offset_(offset), content_url_resolved_(false), weak_ptr_factory_(this) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  base::FilePath path;
+  ArcDocumentsProviderRoot* root = roots->ParseAndLookup(url, &path);
+  if (!root) {
+    content_url_resolved_ = true;
+    return;
+  }
+  root->ResolveToContentUrl(
+      path,
+      base::Bind(&ArcDocumentsProviderFileStreamReader::OnResolveToContentUrl,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+ArcDocumentsProviderFileStreamReader::~ArcDocumentsProviderFileStreamReader() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+int ArcDocumentsProviderFileStreamReader::Read(
+    net::IOBuffer* buffer,
+    int buffer_length,
+    const net::CompletionCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!content_url_resolved_) {
+    pending_operations_.emplace_back(base::Bind(
+        &ArcDocumentsProviderFileStreamReader::RunPendingRead,
+        base::Unretained(this), base::Passed(make_scoped_refptr(buffer)),
+        buffer_length, callback));
+    return net::ERR_IO_PENDING;
+  }
+  if (!underlying_reader_)
+    return net::ERR_FILE_NOT_FOUND;
+  return underlying_reader_->Read(buffer, buffer_length, callback);
+}
+
+int64_t ArcDocumentsProviderFileStreamReader::GetLength(
+    const net::Int64CompletionCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!content_url_resolved_) {
+    pending_operations_.emplace_back(
+        base::Bind(&ArcDocumentsProviderFileStreamReader::RunPendingGetLength,
+                   base::Unretained(this), callback));
+    return net::ERR_IO_PENDING;
+  }
+  if (!underlying_reader_)
+    return net::ERR_FILE_NOT_FOUND;
+  return underlying_reader_->GetLength(callback);
+}
+
+void ArcDocumentsProviderFileStreamReader::OnResolveToContentUrl(
+    const GURL& content_url) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!content_url_resolved_);
+
+  if (content_url.is_valid()) {
+    underlying_reader_ = base::MakeUnique<ArcContentFileSystemFileStreamReader>(
+        content_url, offset_);
+  }
+  content_url_resolved_ = true;
+
+  std::vector<base::Closure> pending_operations;
+  pending_operations.swap(pending_operations_);
+  for (const base::Closure& callback : pending_operations) {
+    callback.Run();
+  }
+}
+
+void ArcDocumentsProviderFileStreamReader::RunPendingRead(
+    scoped_refptr<net::IOBuffer> buffer,
+    int buffer_length,
+    const net::CompletionCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(content_url_resolved_);
+  int result =
+      underlying_reader_
+          ? underlying_reader_->Read(buffer.get(), buffer_length, callback)
+          : net::ERR_FILE_NOT_FOUND;
+  if (result != net::ERR_IO_PENDING)
+    callback.Run(result);
+}
+
+void ArcDocumentsProviderFileStreamReader::RunPendingGetLength(
+    const net::Int64CompletionCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(content_url_resolved_);
+  int64_t result = underlying_reader_ ? underlying_reader_->GetLength(callback)
+                                      : net::ERR_FILE_NOT_FOUND;
+  if (result != net::ERR_IO_PENDING)
+    callback.Run(result);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h
new file mode 100644
index 0000000..9a392d4
--- /dev/null
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_file_stream_reader.h
@@ -0,0 +1,64 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_FILE_STREAM_READER_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_FILE_STREAM_READER_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "storage/browser/fileapi/file_stream_reader.h"
+
+class GURL;
+
+namespace storage {
+
+class FileSystemURL;
+
+}  // namespace storage
+
+namespace arc {
+
+class ArcDocumentsProviderRootMap;
+
+// FileStreamReader implementation for ARC documents provider file system.
+// It actually delegates operations to ArcContentFileSystemFileStreamReader.
+// TODO(crbug.com/678886): Write unit tests.
+class ArcDocumentsProviderFileStreamReader : public storage::FileStreamReader {
+ public:
+  // |roots| can be released soon after the constructor returns.
+  ArcDocumentsProviderFileStreamReader(const storage::FileSystemURL& url,
+                                       int64_t offset,
+                                       ArcDocumentsProviderRootMap* roots);
+  ~ArcDocumentsProviderFileStreamReader() override;
+
+  // storage::FileStreamReader override:
+  int Read(net::IOBuffer* buffer,
+           int buffer_length,
+           const net::CompletionCallback& callback) override;
+  int64_t GetLength(const net::Int64CompletionCallback& callback) override;
+
+ private:
+  void OnResolveToContentUrl(const GURL& content_url);
+  void RunPendingRead(scoped_refptr<net::IOBuffer> buffer,
+                      int buffer_length,
+                      const net::CompletionCallback& callback);
+  void RunPendingGetLength(const net::Int64CompletionCallback& callback);
+
+  const int64_t offset_;
+  bool content_url_resolved_;
+  std::unique_ptr<storage::FileStreamReader> underlying_reader_;
+  std::vector<base::Closure> pending_operations_;
+
+  base::WeakPtrFactory<ArcDocumentsProviderFileStreamReader> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderFileStreamReader);
+};
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_FILE_STREAM_READER_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
index 644415c7a..8bdf8d8 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/mime_util.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 using EntryList = storage::AsyncFileUtil::EntryList;
@@ -98,6 +99,16 @@
                        weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
+void ArcDocumentsProviderRoot::ResolveToContentUrl(
+    const base::FilePath& path,
+    const ResolveToContentUrlCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  ResolveToDocumentId(
+      path,
+      base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId,
+                 weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId(
     const GetFileInfoCallback& callback,
     const std::string& document_id) {
@@ -162,6 +173,17 @@
   callback.Run(base::File::FILE_OK, entry_list, false /* has_more */);
 }
 
+void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId(
+    const ResolveToContentUrlCallback& callback,
+    const std::string& document_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (document_id.empty()) {
+    callback.Run(GURL());
+    return;
+  }
+  callback.Run(BuildDocumentUrl(authority_, document_id));
+}
+
 void ArcDocumentsProviderRoot::ResolveToDocumentId(
     const base::FilePath& path,
     const ResolveToDocumentIdCallback& callback) {
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h
index de30a747..fd8f880 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h
@@ -17,6 +17,8 @@
 #include "components/arc/common/file_system.mojom.h"
 #include "storage/browser/fileapi/async_file_util.h"
 
+class GURL;
+
 namespace arc {
 
 // Represents a file system root in Android Documents Provider.
@@ -28,6 +30,8 @@
  public:
   using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback;
   using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback;
+  using ResolveToContentUrlCallback =
+      base::Callback<void(const GURL& content_url)>;
 
   ArcDocumentsProviderRoot(const std::string& authority,
                            const std::string& root_document_id);
@@ -42,6 +46,13 @@
   void ReadDirectory(const base::FilePath& path,
                      const ReadDirectoryCallback& callback);
 
+  // Resolves a file path into a content:// URL pointing to the file
+  // on DocumentsProvider. Returns URL that can be passed to
+  // ArcContentFileSystemFileSystemReader to read the content.
+  // On errors, an invalid GURL is returned.
+  void ResolveToContentUrl(const base::FilePath& path,
+                           const ResolveToContentUrlCallback& callback);
+
  private:
   // Thin representation of a document in documents provider.
   struct ThinDocument {
@@ -71,6 +82,10 @@
       base::File::Error error,
       NameToThinDocumentMap mapping);
 
+  void ResolveToContentUrlWithDocumentId(
+      const ResolveToContentUrlCallback& callback,
+      const std::string& document_id);
+
   // Resolves |path| to a document ID. Failures are indicated by an empty
   // document ID.
   void ResolveToDocumentId(const base::FilePath& path,
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
index 1bbef1c..b74552a 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -19,6 +19,7 @@
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "storage/common/fileapi/directory_entry.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using storage::DirectoryEntry;
 using EntryList = storage::AsyncFileUtil::EntryList;
@@ -309,4 +310,60 @@
   run_loop.Run();
 }
 
+TEST_F(ArcDocumentsProviderRootTest, ResolveToContentUrl) {
+  base::RunLoop run_loop;
+  root_->ResolveToContentUrl(
+      base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+      base::Bind(
+          [](base::RunLoop* run_loop, const GURL& url) {
+            EXPECT_EQ(GURL("content://org.chromium.test/document/photo-id"),
+                      url);
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcDocumentsProviderRootTest, ResolveToContentUrlRoot) {
+  base::RunLoop run_loop;
+  root_->ResolveToContentUrl(
+      base::FilePath(FILE_PATH_LITERAL("")),
+      base::Bind(
+          [](base::RunLoop* run_loop, const GURL& url) {
+            EXPECT_EQ(GURL("content://org.chromium.test/document/root-id"),
+                      url);
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcDocumentsProviderRootTest, ResolveToContentUrlNoSuchFile) {
+  base::RunLoop run_loop;
+  root_->ResolveToContentUrl(base::FilePath(FILE_PATH_LITERAL("missing")),
+                             base::Bind(
+                                 [](base::RunLoop* run_loop, const GURL& url) {
+                                   EXPECT_EQ(GURL(), url);
+                                   run_loop->Quit();
+                                 },
+                                 &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcDocumentsProviderRootTest, ResolveToContentUrlDups) {
+  base::RunLoop run_loop;
+  // "dup 2.mp4" should map to the 3rd instance of "dup.mp4" regardless of the
+  // order returned from FileSystemInstance.
+  root_->ResolveToContentUrl(
+      base::FilePath(FILE_PATH_LITERAL("dups/dup (2).mp4")),
+      base::Bind(
+          [](base::RunLoop* run_loop, const GURL& url) {
+            EXPECT_EQ(GURL("content://org.chromium.test/document/dup3-id"),
+                      url);
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc
index 34b7db7..8068a7f 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.cc
@@ -7,7 +7,10 @@
 #include <vector>
 
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/escape.h"
 #include "storage/browser/fileapi/file_system_url.h"
+#include "url/gurl.h"
 
 namespace arc {
 
@@ -52,4 +55,12 @@
   return true;
 }
 
+GURL BuildDocumentUrl(const std::string& authority,
+                      const std::string& document_id) {
+  return GURL(base::StringPrintf(
+      "content://%s/document/%s",
+      net::EscapeQueryParamValue(authority, false /* use_plus */).c_str(),
+      net::EscapeQueryParamValue(document_id, false /* use_plus */).c_str()));
+}
+
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h
index 87d6b9a9..38ae3c86 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h
@@ -11,6 +11,8 @@
 
 #include "base/files/file_path.h"
 
+class GURL;
+
 namespace storage {
 class FileSystemURL;
 }  // namespace storage
@@ -34,6 +36,10 @@
                                std::string* root_document_id,
                                base::FilePath* path);
 
+// C++ implementation of DocumentsContract.buildDocumentUri() in Android.
+GURL BuildDocumentUrl(const std::string& authority,
+                      const std::string& document_id);
+
 }  // namespace arc
 
 #endif  // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util_unittest.cc
index fceba1a..3374aaf 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util_unittest.cc
@@ -134,6 +134,11 @@
   EXPECT_EQ(FILE_PATH_LITERAL("home/みけねこ.jpg"), path.value());
 }
 
+TEST(ArcDocumentsProviderUtilTest, BuildDocumentUrl) {
+  EXPECT_EQ("content://Cat%20Provider/document/C%2B%2B",
+            BuildDocumentUrl("Cat Provider", "C++").spec());
+}
+
 }  // namespace
 
 }  // namespace arc
diff --git a/chrome/browser/content_settings/chrome_content_settings_utils.cc b/chrome/browser/content_settings/chrome_content_settings_utils.cc
index c9f5553..663e7c1 100644
--- a/chrome/browser/content_settings/chrome_content_settings_utils.cc
+++ b/chrome/browser/content_settings/chrome_content_settings_utils.cc
@@ -18,4 +18,9 @@
                             PLUGINS_ACTION_COUNT);
 }
 
+void RecordPopupsAction(PopupsAction action) {
+  UMA_HISTOGRAM_ENUMERATION("ContentSettings.Popups", action,
+                            POPUPS_ACTION_COUNT);
+}
+
 }  // namespace content_settings
diff --git a/chrome/browser/content_settings/chrome_content_settings_utils.h b/chrome/browser/content_settings/chrome_content_settings_utils.h
index a787e7ab3..650103f47 100644
--- a/chrome/browser/content_settings/chrome_content_settings_utils.h
+++ b/chrome/browser/content_settings/chrome_content_settings_utils.h
@@ -38,6 +38,20 @@
 
 void RecordPluginsAction(PluginsAction action);
 
+// UMA histogram for actions that a user can perform on the pop-up blocked page
+// action in the omnibox. The enum values correspond to histogram entries, so do
+// not remove any existing values.
+enum PopupsAction {
+  POPUPS_ACTION_DISPLAYED_BLOCKED_ICON_IN_OMNIBOX = 0,
+  POPUPS_ACTION_DISPLAYED_BUBBLE,
+  POPUPS_ACTION_SELECTED_ALWAYS_ALLOW_POPUPS_FROM,
+  POPUPS_ACTION_CLICKED_LIST_ITEM_CLICKED,
+  POPUPS_ACTION_CLICKED_MANAGE_POPUPS_BLOCKING,
+  POPUPS_ACTION_COUNT
+};
+
+void RecordPopupsAction(PopupsAction action);
+
 }  // namespace content_settings
 
 #endif  // CHROME_BROWSER_CONTENT_SETTINGS_CHROME_CONTENT_SETTINGS_UTILS_H_
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index f0693c38..3c1c8a3 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -357,6 +357,9 @@
     } else if (type == CONTENT_SETTINGS_TYPE_PLUGINS) {
       content_settings::RecordPluginsAction(
           content_settings::PLUGINS_ACTION_DISPLAYED_BLOCKED_ICON_IN_OMNIBOX);
+    } else if (type == CONTENT_SETTINGS_TYPE_POPUPS) {
+      content_settings::RecordPopupsAction(
+          content_settings::POPUPS_ACTION_DISPLAYED_BLOCKED_ICON_IN_OMNIBOX);
     }
   }
 }
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.css b/chrome/browser/resources/chromeos/network_ui/network_ui.css
index 958293cc..f211ee0 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.css
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.css
@@ -15,11 +15,6 @@
   padding: 0 4px;
 }
 
-#header cr-network-icon {
-  height: 40px;
-  width: 40px;
-}
-
 cr-network-select {
   padding: 5px;
   width: 500px;
@@ -61,11 +56,12 @@
   white-space: pre-wrap;
 }
 
-.state-table cr-network-icon {
-  height: 25px;
-  width: 25px;
+.state-table-icon-cell {
+  height: 32px;
+  width: 32px;
 }
 
 #advanced-options {
   margin-top: 10px;
+  text-align: center;
 }
diff --git a/chrome/browser/resources/md_history/lazy_load.crisper.js b/chrome/browser/resources/md_history/lazy_load.crisper.js
index bfd93f4..055c8c0 100644
--- a/chrome/browser/resources/md_history/lazy_load.crisper.js
+++ b/chrome/browser/resources/md_history/lazy_load.crisper.js
@@ -6,7 +6,7 @@
 // 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.
-cr.define("cr.ui",function(){function FocusGrid(){this.rows=[]}FocusGrid.prototype={ignoreFocusChange_:false,onFocus:function(row,e){if(this.ignoreFocusChange_)this.ignoreFocusChange_=false;else this.lastFocused_=e.currentTarget;this.rows.forEach(function(r){r.makeActive(r==row)})},onKeydown:function(row,e){var rowIndex=this.rows.indexOf(row);assert(rowIndex>=0);var newRow=-1;if(e.key=="ArrowUp")newRow=rowIndex-1;else if(e.key=="ArrowDown")newRow=rowIndex+1;else if(e.key=="PageUp")newRow=0;else if(e.key=="PageDown")newRow=this.rows.length-1;var rowToFocus=this.rows[newRow];if(rowToFocus){this.ignoreFocusChange_=true;rowToFocus.getEquivalentElement(this.lastFocused_).focus();e.preventDefault();return true}return false},destroy:function(){this.rows.forEach(function(row){row.destroy()});this.rows.length=0},getRowIndexForTarget:function(target){for(var i=0;i<this.rows.length;++i){if(this.rows[i].getElements().indexOf(target)>=0)return i}return-1},getRowForRoot:function(root){for(var i=0;i<this.rows.length;++i){if(this.rows[i].root==root)return this.rows[i]}return null},addRow:function(row){this.addRowBefore(row,null)},addRowBefore:function(row,nextRow){row.delegate=row.delegate||this;var nextRowIndex=nextRow?this.rows.indexOf(nextRow):-1;if(nextRowIndex==-1)this.rows.push(row);else this.rows.splice(nextRowIndex,0,row)},removeRow:function(row){var nextRowIndex=row?this.rows.indexOf(row):-1;if(nextRowIndex>-1)this.rows.splice(nextRowIndex,1)},ensureRowActive:function(){if(this.rows.length==0)return;for(var i=0;i<this.rows.length;++i){if(this.rows[i].isActive())return}this.rows[0].makeActive(true)}};return{FocusGrid:FocusGrid}});Polymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:true,readOnly:true}},observers:["_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)","_computeKeyboardClass(receivedFocusFromKeyboard)"],hostAttributes:{role:"button",tabindex:"0",animated:true},_calculateElevation:function(){var e=1;if(this.disabled){e=0}else if(this.active||this.pressed){e=4}else if(this.receivedFocusFromKeyboard){e=3}this._setElevation(e)},_computeKeyboardClass:function(receivedFocusFromKeyboard){this.toggleClass("keyboard-focus",receivedFocusFromKeyboard)},_spaceKeyDownHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,event);if(this.hasRipple()&&this.getRipple().ripples.length<1){this._ripple.uiDownAction()}},_spaceKeyUpHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,event);if(this.hasRipple()){this._ripple.uiUpAction()}}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];Polymer({is:"paper-button",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:true,value:false,observer:"_calculateElevation"}},_calculateElevation:function(){if(!this.raised){this._setElevation(0)}else{Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this)}}});Polymer.PaperItemBehaviorImpl={hostAttributes:{role:"option",tabindex:"0"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];Polymer({is:"paper-item",behaviors:[Polymer.PaperItemBehavior]});
+cr.define("cr.ui",function(){function FocusGrid(){this.rows=[]}FocusGrid.prototype={ignoreFocusChange_:false,onFocus:function(row,e){if(this.ignoreFocusChange_)this.ignoreFocusChange_=false;else this.lastFocused_=e.currentTarget;this.rows.forEach(function(r){r.makeActive(r==row)})},onKeydown:function(row,e){var rowIndex=this.rows.indexOf(row);assert(rowIndex>=0);var newRow=-1;if(e.key=="ArrowUp")newRow=rowIndex-1;else if(e.key=="ArrowDown")newRow=rowIndex+1;else if(e.key=="PageUp")newRow=0;else if(e.key=="PageDown")newRow=this.rows.length-1;var rowToFocus=this.rows[newRow];if(rowToFocus){this.ignoreFocusChange_=true;rowToFocus.getEquivalentElement(this.lastFocused_).focus();e.preventDefault();return true}return false},destroy:function(){this.rows.forEach(function(row){row.destroy()});this.rows.length=0},getRowIndexForTarget:function(target){for(var i=0;i<this.rows.length;++i){if(this.rows[i].getElements().indexOf(target)>=0)return i}return-1},getRowForRoot:function(root){for(var i=0;i<this.rows.length;++i){if(this.rows[i].root==root)return this.rows[i]}return null},addRow:function(row){this.addRowBefore(row,null)},addRowBefore:function(row,nextRow){row.delegate=row.delegate||this;var nextRowIndex=nextRow?this.rows.indexOf(nextRow):-1;if(nextRowIndex==-1)this.rows.push(row);else this.rows.splice(nextRowIndex,0,row)},removeRow:function(row){var nextRowIndex=row?this.rows.indexOf(row):-1;if(nextRowIndex>-1)this.rows.splice(nextRowIndex,1)},ensureRowActive:function(preferredRow){if(this.rows.length==0)return;for(var i=0;i<this.rows.length;++i){if(this.rows[i].isActive())return}if(!preferredRow||preferredRow>=this.rows.length)preferredRow=0;this.rows[preferredRow].makeActive(true)}};return{FocusGrid:FocusGrid}});Polymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:true,readOnly:true}},observers:["_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)","_computeKeyboardClass(receivedFocusFromKeyboard)"],hostAttributes:{role:"button",tabindex:"0",animated:true},_calculateElevation:function(){var e=1;if(this.disabled){e=0}else if(this.active||this.pressed){e=4}else if(this.receivedFocusFromKeyboard){e=3}this._setElevation(e)},_computeKeyboardClass:function(receivedFocusFromKeyboard){this.toggleClass("keyboard-focus",receivedFocusFromKeyboard)},_spaceKeyDownHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,event);if(this.hasRipple()&&this.getRipple().ripples.length<1){this._ripple.uiDownAction()}},_spaceKeyUpHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,event);if(this.hasRipple()){this._ripple.uiUpAction()}}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];Polymer({is:"paper-button",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:true,value:false,observer:"_calculateElevation"}},_calculateElevation:function(){if(!this.raised){this._setElevation(0)}else{Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this)}}});Polymer.PaperItemBehaviorImpl={hostAttributes:{role:"option",tabindex:"0"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];Polymer({is:"paper-item",behaviors:[Polymer.PaperItemBehavior]});
 // Copyright 2016 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.
@@ -18,7 +18,7 @@
 // Copyright 2016 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.
-var ForeignDeviceInternal;Polymer({is:"history-synced-device-manager",properties:{sessionList:{type:Array,observer:"updateSyncedDevices"},searchTerm:{type:String,observer:"searchTermChanged"},syncedDevices_:{type:Array,value:function(){return[]}},signInState:{type:Boolean,observer:"signInStateChanged_"},guestSession_:{type:Boolean,value:loadTimeData.getBoolean("isGuestSession")},fetchingSyncedTabs_:{type:Boolean,value:false},hasSeenForeignData_:Boolean,actionMenuModel_:String},listeners:{"open-menu":"onOpenMenu_","update-focus-grid":"updateFocusGrid_"},focusGrid_:null,attached:function(){this.focusGrid_=new cr.ui.FocusGrid;chrome.send("otherDevicesInitialized");md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.INITIALIZED,SyncedTabsHistogram.LIMIT)},detached:function(){this.focusGrid_.destroy()},getContentScrollTarget:function(){return this},createInternalDevice_:function(session){var tabs=[];var separatorIndexes=[];for(var i=0;i<session.windows.length;i++){var windowId=session.windows[i].sessionId;var newTabs=session.windows[i].tabs;if(newTabs.length==0)continue;newTabs.forEach(function(tab){tab.windowId=windowId});var windowAdded=false;if(!this.searchTerm){tabs=tabs.concat(newTabs);windowAdded=true}else{var searchText=this.searchTerm.toLowerCase();for(var j=0;j<newTabs.length;j++){var tab=newTabs[j];if(tab.title.toLowerCase().indexOf(searchText)!=-1){tabs.push(tab);windowAdded=true}}}if(windowAdded&&i!=session.windows.length-1)separatorIndexes.push(tabs.length-1)}return{device:session.name,lastUpdateTime:"– "+session.modifiedTime,opened:true,separatorIndexes:separatorIndexes,timestamp:session.timestamp,tabs:tabs,tag:session.tag}},onSignInTap_:function(){chrome.send("startSignInFlow")},onOpenMenu_:function(e){var menu=this.$.menu.get();this.actionMenuModel_=e.detail.tag;menu.showAt(e.detail.target);md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.SHOW_SESSION_MENU,SyncedTabsHistogram.LIMIT)},onOpenAllTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.OPEN_ALL,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionAllTabs(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},updateFocusGrid_:function(){if(!this.focusGrid_)return;this.focusGrid_.destroy();this.debounce("updateFocusGrid",function(){Polymer.dom(this.root).querySelectorAll("history-synced-device-card").reduce(function(prev,cur){return prev.concat(cur.createFocusRows())},[]).forEach(function(row){this.focusGrid_.addRow(row)}.bind(this));this.focusGrid_.ensureRowActive()})},onDeleteSessionTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HIDE_FOR_NOW,SyncedTabsHistogram.LIMIT);browserService.deleteForeignSession(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},clearDisplayedSyncedDevices_:function(){this.syncedDevices_=[]},showNoSyncedMessage:function(signInState,syncedDevicesLength,guestSession){if(guestSession)return true;return signInState&&syncedDevicesLength==0},showSignInGuide:function(signInState,guestSession){var show=!signInState&&!guestSession;if(show){md_history.BrowserService.getInstance().recordAction("Signin_Impression_FromRecentTabs")}return show},noSyncedTabsMessage:function(){var stringName=this.fetchingSyncedTabs_?"loading":"noSyncedResults";if(this.searchTerm!=="")stringName="noSearchResults";return loadTimeData.getString(stringName)},updateSyncedDevices:function(sessionList){this.fetchingSyncedTabs_=false;if(!sessionList)return;if(sessionList.length>0&&!this.hasSeenForeignData_){this.hasSeenForeignData_=true;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HAS_FOREIGN_DATA,SyncedTabsHistogram.LIMIT)}var devices=[];sessionList.forEach(function(session){var device=this.createInternalDevice_(session);if(device.tabs.length!=0)devices.push(device)}.bind(this));this.syncedDevices_=devices},signInStateChanged_:function(){this.fire("history-view-changed");if(!this.signInState){this.clearDisplayedSyncedDevices_();return}this.fetchingSyncedTabs_=true},searchTermChanged:function(searchTerm){this.clearDisplayedSyncedDevices_();this.updateSyncedDevices(this.sessionList)}});
+var ForeignDeviceInternal;Polymer({is:"history-synced-device-manager",properties:{sessionList:{type:Array,observer:"updateSyncedDevices"},searchTerm:{type:String,observer:"searchTermChanged"},syncedDevices_:{type:Array,value:function(){return[]}},signInState:{type:Boolean,observer:"signInStateChanged_"},guestSession_:{type:Boolean,value:loadTimeData.getBoolean("isGuestSession")},fetchingSyncedTabs_:{type:Boolean,value:false},hasSeenForeignData_:Boolean,actionMenuModel_:String},listeners:{"open-menu":"onOpenMenu_","update-focus-grid":"updateFocusGrid_"},focusGrid_:null,attached:function(){this.focusGrid_=new cr.ui.FocusGrid;chrome.send("otherDevicesInitialized");md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.INITIALIZED,SyncedTabsHistogram.LIMIT)},detached:function(){this.focusGrid_.destroy()},getContentScrollTarget:function(){return this},createInternalDevice_:function(session){var tabs=[];var separatorIndexes=[];for(var i=0;i<session.windows.length;i++){var windowId=session.windows[i].sessionId;var newTabs=session.windows[i].tabs;if(newTabs.length==0)continue;newTabs.forEach(function(tab){tab.windowId=windowId});var windowAdded=false;if(!this.searchTerm){tabs=tabs.concat(newTabs);windowAdded=true}else{var searchText=this.searchTerm.toLowerCase();for(var j=0;j<newTabs.length;j++){var tab=newTabs[j];if(tab.title.toLowerCase().indexOf(searchText)!=-1){tabs.push(tab);windowAdded=true}}}if(windowAdded&&i!=session.windows.length-1)separatorIndexes.push(tabs.length-1)}return{device:session.name,lastUpdateTime:"– "+session.modifiedTime,opened:true,separatorIndexes:separatorIndexes,timestamp:session.timestamp,tabs:tabs,tag:session.tag}},onSignInTap_:function(){chrome.send("startSignInFlow")},onOpenMenu_:function(e){var menu=this.$.menu.get();this.actionMenuModel_=e.detail.tag;menu.showAt(e.detail.target);md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.SHOW_SESSION_MENU,SyncedTabsHistogram.LIMIT)},onOpenAllTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.OPEN_ALL,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionAllTabs(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},updateFocusGrid_:function(){if(!this.focusGrid_)return;this.focusGrid_.destroy();this.debounce("updateFocusGrid",function(){Polymer.dom(this.root).querySelectorAll("history-synced-device-card").reduce(function(prev,cur){return prev.concat(cur.createFocusRows())},[]).forEach(function(row){this.focusGrid_.addRow(row)}.bind(this));this.focusGrid_.ensureRowActive(1)})},onDeleteSessionTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HIDE_FOR_NOW,SyncedTabsHistogram.LIMIT);browserService.deleteForeignSession(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},clearDisplayedSyncedDevices_:function(){this.syncedDevices_=[]},showNoSyncedMessage:function(signInState,syncedDevicesLength,guestSession){if(guestSession)return true;return signInState&&syncedDevicesLength==0},showSignInGuide:function(signInState,guestSession){var show=!signInState&&!guestSession;if(show){md_history.BrowserService.getInstance().recordAction("Signin_Impression_FromRecentTabs")}return show},noSyncedTabsMessage:function(){var stringName=this.fetchingSyncedTabs_?"loading":"noSyncedResults";if(this.searchTerm!=="")stringName="noSearchResults";return loadTimeData.getString(stringName)},updateSyncedDevices:function(sessionList){this.fetchingSyncedTabs_=false;if(!sessionList)return;if(sessionList.length>0&&!this.hasSeenForeignData_){this.hasSeenForeignData_=true;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HAS_FOREIGN_DATA,SyncedTabsHistogram.LIMIT)}var devices=[];sessionList.forEach(function(session){var device=this.createInternalDevice_(session);if(device.tabs.length!=0)devices.push(device)}.bind(this));this.syncedDevices_=devices},signInStateChanged_:function(){this.fire("history-view-changed");if(!this.signInState){this.clearDisplayedSyncedDevices_();return}this.fetchingSyncedTabs_=true},searchTermChanged:function(searchTerm){this.clearDisplayedSyncedDevices_();this.updateSyncedDevices(this.sessionList)}});
 // Copyright 2016 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.
diff --git a/chrome/browser/resources/md_history/synced_device_manager.js b/chrome/browser/resources/md_history/synced_device_manager.js
index e943d48..ad4da3d 100644
--- a/chrome/browser/resources/md_history/synced_device_manager.js
+++ b/chrome/browser/resources/md_history/synced_device_manager.js
@@ -190,7 +190,7 @@
           .forEach(function(row) {
             this.focusGrid_.addRow(row);
           }.bind(this));
-      this.focusGrid_.ensureRowActive();
+      this.focusGrid_.ensureRowActive(1);
     });
   },
 
diff --git a/chrome/browser/resources/options/browser_options.css b/chrome/browser/resources/options/browser_options.css
index 4523f0d..c0c4b19 100644
--- a/chrome/browser/resources/options/browser_options.css
+++ b/chrome/browser/resources/options/browser_options.css
@@ -221,7 +221,7 @@
 }
 
 .network-icon {
-  -webkit-margin-end: 8px;
+  -webkit-margin-end: 10px;
   background-position: left top;
   background-size: 25px;
   height: 25px;
diff --git a/chrome/browser/resources/options/chromeos/network_list.js b/chrome/browser/resources/options/chromeos/network_list.js
index be57afb..1baa9e2 100644
--- a/chrome/browser/resources/options/chromeos/network_list.js
+++ b/chrome/browser/resources/options/chromeos/network_list.js
@@ -243,7 +243,10 @@
     set iconType(type) {
       if (isNetworkType(type)) {
         var networkIcon = this.getNetworkIcon();
-        networkIcon.networkType = type;
+        networkIcon.networkState = {
+          GUID: '',
+          Type: /** @type {CrOnc.Type} */ (type),
+        };
       } else {
         // Special cases. e.g. 'add-connection'. Background images are
         // defined in browser_options.css.
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
index 42062b22..66e0f11 100644
--- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html
+++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -27,10 +27,7 @@
       }
 
       cr-network-icon {
-        -webkit-margin-end: 15px;
-        height: 32px;
-        margin-top: -4px;  /* Align better with text */
-        width: 32px;
+        -webkit-padding-end: 8px;
       }
 
       cr-policy-network-indicator {
@@ -76,6 +73,7 @@
         /* TODO(stevenjb): Finalize font-size / style for this. */
         font-size: 125%;
         font-weight: 500;
+        padding-left: 8px;
       }
 
       #networkState[connected] {
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.html b/chrome/browser/resources/settings/internet_page/internet_page.html
index 6b21dd0f..682242b 100644
--- a/chrome/browser/resources/settings/internet_page/internet_page.html
+++ b/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -24,6 +24,7 @@
 
       iron-icon {
         -webkit-margin-end: 12px;
+        -webkit-margin-start: 4px;
         height: 24px;
         width: 24px;
       }
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chrome/browser/resources/settings/internet_page/network_summary_item.html
index ce5d71d..f5be1048 100644
--- a/chrome/browser/resources/settings/internet_page/network_summary_item.html
+++ b/chrome/browser/resources/settings/internet_page/network_summary_item.html
@@ -1,5 +1,4 @@
 <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/cr_elements/network/cr_network_list.html">
 <link rel="import" href="chrome://resources/cr_elements/network/cr_network_list_item.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index 0a3395aa..4d61157 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -65,8 +65,6 @@
 
 namespace {
 
-const int kAllowButtonIndex = 0;
-
 // These states must match the order of appearance of the radio buttons
 // in the XIB file for the Mac port.
 enum RPHState {
@@ -107,6 +105,8 @@
 
 }  // namespace
 
+const int ContentSettingBubbleModel::kAllowButtonIndex = 0;
+
 // ContentSettingSimpleBubbleModel ---------------------------------------------
 
 ContentSettingSimpleBubbleModel::ContentSettingSimpleBubbleModel(
@@ -190,6 +190,11 @@
     content_settings::RecordPluginsAction(
         content_settings::PLUGINS_ACTION_CLICKED_MANAGE_PLUGIN_BLOCKING);
   }
+
+  if (content_type() == CONTENT_SETTINGS_TYPE_POPUPS) {
+    content_settings::RecordPopupsAction(
+        content_settings::POPUPS_ACTION_CLICKED_MANAGE_POPUPS_BLOCKING);
+  }
 }
 
 void ContentSettingSimpleBubbleModel::SetCustomLink() {
@@ -546,7 +551,7 @@
   ContentSettingPopupBubbleModel(Delegate* delegate,
                                  WebContents* web_contents,
                                  Profile* profile);
-  ~ContentSettingPopupBubbleModel() override {}
+  ~ContentSettingPopupBubbleModel() override;
 
  private:
   void OnListItemClicked(int index) override;
@@ -582,12 +587,26 @@
                         title, true, blocked_popup.first);
     add_list_item(popup_item);
   }
+  content_settings::RecordPopupsAction(
+      content_settings::POPUPS_ACTION_DISPLAYED_BUBBLE);
 }
 
 void ContentSettingPopupBubbleModel::OnListItemClicked(int index) {
   if (web_contents()) {
     auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents());
     helper->ShowBlockedPopup(item_id_from_item_index(index));
+
+    content_settings::RecordPopupsAction(
+        content_settings::POPUPS_ACTION_CLICKED_LIST_ITEM_CLICKED);
+  }
+}
+
+ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel(){
+  // User selected to always allow pop-ups from.
+  if (settings_changed() && selected_item() == kAllowButtonIndex) {
+    // Increases the counter.
+    content_settings::RecordPopupsAction(
+        content_settings::POPUPS_ACTION_SELECTED_ALWAYS_ALLOW_POPUPS_FROM);
   }
 }
 
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
index 165b372..a15f8b3 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -181,6 +181,8 @@
     rappor_service_ = rappor_service;
   }
 
+  static const int kAllowButtonIndex;
+
  protected:
   ContentSettingBubbleModel(
       Delegate* delegate,
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
index 84cf40e..acbfd81 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
@@ -228,3 +228,57 @@
   EXPECT_EQ(GURL("chrome://settings/contentExceptions#media-stream-camera"),
             GetActiveTab()->GetLastCommittedURL());
 }
+
+class ContentSettingBubbleModelPopupTest : public InProcessBrowserTest {
+ protected:
+  void SetUpInProcessBrowserTestFixture() override {
+    https_server_.reset(
+        new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
+    https_server_->ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
+    ASSERT_TRUE(https_server_->Start());
+  }
+  std::unique_ptr<net::EmbeddedTestServer> https_server_;
+};
+
+// Tests that each popup action is counted in the right bucket.
+IN_PROC_BROWSER_TEST_F(ContentSettingBubbleModelPopupTest,
+                       PopupsActionsCount){
+  GURL url(https_server_->GetURL("/popup_blocker/popup-many.html"));
+  base::HistogramTester histograms;
+  histograms.ExpectTotalCount("ContentSettings.Popups", 0);
+
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  histograms.ExpectBucketCount(
+        "ContentSettings.Popups",
+        content_settings::POPUPS_ACTION_DISPLAYED_BLOCKED_ICON_IN_OMNIBOX, 1);
+
+  // Creates the ContentSettingPopupBubbleModel in order to emulate clicks.
+  std::unique_ptr<ContentSettingBubbleModel> model(
+      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+          browser()->content_setting_bubble_model_delegate(),
+          browser()->tab_strip_model()->GetActiveWebContents(),
+          browser()->profile(), CONTENT_SETTINGS_TYPE_POPUPS));
+
+  histograms.ExpectBucketCount(
+        "ContentSettings.Popups",
+        content_settings::POPUPS_ACTION_DISPLAYED_BUBBLE, 1);
+
+  model->OnListItemClicked(0);
+  histograms.ExpectBucketCount(
+        "ContentSettings.Popups",
+        content_settings::POPUPS_ACTION_CLICKED_LIST_ITEM_CLICKED, 1);
+
+  model->OnManageLinkClicked();
+  histograms.ExpectBucketCount(
+        "ContentSettings.Popups",
+        content_settings::POPUPS_ACTION_CLICKED_MANAGE_POPUPS_BLOCKING, 1);
+
+  model->OnRadioClicked(model->kAllowButtonIndex);
+  delete model.release();
+  histograms.ExpectBucketCount(
+        "ContentSettings.Popups",
+        content_settings::POPUPS_ACTION_SELECTED_ALWAYS_ALLOW_POPUPS_FROM, 1);
+
+  histograms.ExpectTotalCount("ContentSettings.Popups", 5);
+}
diff --git a/chrome/browser/ui/views/external_protocol_dialog.h b/chrome/browser/ui/views/external_protocol_dialog.h
index ad2efc3..3c53e7d2 100644
--- a/chrome/browser/ui/views/external_protocol_dialog.h
+++ b/chrome/browser/ui/views/external_protocol_dialog.h
@@ -13,6 +13,10 @@
 
 class ProtocolDialogDelegate;
 
+namespace test {
+class ExternalProtocolDialogTestApi;
+}
+
 namespace views {
 class MessageBoxView;
 }
@@ -40,6 +44,8 @@
   ui::ModalType GetModalType() const override;
 
  private:
+  friend class test::ExternalProtocolDialogTestApi;
+
   const std::unique_ptr<const ProtocolDialogDelegate> delegate_;
 
   // The message box view whose commands we handle.
diff --git a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
new file mode 100644
index 0000000..082dd03
--- /dev/null
+++ b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
@@ -0,0 +1,172 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/external_protocol_dialog_delegate.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/external_protocol_dialog.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/views/controls/message_box_view.h"
+#include "url/gurl.h"
+
+namespace test {
+
+class ExternalProtocolDialogTestApi {
+ public:
+  explicit ExternalProtocolDialogTestApi(ExternalProtocolDialog* dialog)
+      : dialog_(dialog) {}
+
+  void SetCheckBoxSelected(bool checked) {
+    dialog_->message_box_view_->SetCheckBoxSelected(checked);
+  }
+
+ private:
+  ExternalProtocolDialog* dialog_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExternalProtocolDialogTestApi);
+};
+
+}  // namespace test
+
+// Wrapper dialog delegate that sets |called|, |accept|, |cancel|, and
+// |dont_block| bools based on what is called by the ExternalProtocolDialog.
+class TestExternalProtocolDialogDelegate
+    : public ExternalProtocolDialogDelegate {
+ public:
+  TestExternalProtocolDialogDelegate(const GURL& url,
+                                     int render_process_host_id,
+                                     int routing_id,
+                                     bool* called,
+                                     bool* accept,
+                                     bool* cancel,
+                                     bool* dont_block)
+      : ExternalProtocolDialogDelegate(url, render_process_host_id, routing_id),
+        called_(called),
+        accept_(accept),
+        cancel_(cancel),
+        dont_block_(dont_block) {}
+
+  // ExternalProtocolDialogDelegate:
+  void DoAccept(const GURL& url, bool dont_block) const override {
+    // Don't call the base impl because it will actually launch |url|.
+    *called_ = true;
+    *accept_ = true;
+    *cancel_ = false;
+    *dont_block_ = dont_block;
+  }
+
+  void DoCancel(const GURL& url, bool dont_block) const override {
+    // Don't call the base impl because it will actually launch |url|.
+    *called_ = true;
+    *accept_ = false;
+    *cancel_ = true;
+    *dont_block_ = dont_block;
+  }
+
+ private:
+  bool* called_;
+  bool* accept_;
+  bool* cancel_;
+  bool* dont_block_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestExternalProtocolDialogDelegate);
+};
+
+class ExternalProtocolDialogBrowserTest : public InProcessBrowserTest {
+ public:
+  ExternalProtocolDialogBrowserTest() {}
+
+  void ShowDialog() {
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    int render_process_host_id = web_contents->GetRenderProcessHost()->GetID();
+    int routing_id = web_contents->GetRenderViewHost()->GetRoutingID();
+    dialog_ = new ExternalProtocolDialog(
+        base::MakeUnique<TestExternalProtocolDialogDelegate>(
+            GURL("telnet://12345"), render_process_host_id, routing_id,
+            &called_, &accept_, &cancel_, &dont_block_),
+        render_process_host_id, routing_id);
+  }
+
+  void SetChecked(bool checked) {
+    test::ExternalProtocolDialogTestApi(dialog_).SetCheckBoxSelected(checked);
+  }
+
+ protected:
+  ExternalProtocolDialog* dialog_ = nullptr;
+  bool called_ = false;
+  bool accept_ = false;
+  bool cancel_ = false;
+  bool dont_block_ = false;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExternalProtocolDialogBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest, TestAccept) {
+  ShowDialog();
+  EXPECT_TRUE(dialog_->Accept());
+  EXPECT_TRUE(called_);
+  EXPECT_TRUE(accept_);
+  EXPECT_FALSE(cancel_);
+  EXPECT_FALSE(dont_block_);
+}
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest,
+                       TestAcceptWithChecked) {
+  ShowDialog();
+  SetChecked(true);
+  EXPECT_TRUE(dialog_->Accept());
+  EXPECT_TRUE(called_);
+  EXPECT_TRUE(accept_);
+  EXPECT_FALSE(cancel_);
+  EXPECT_TRUE(dont_block_);
+}
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest, TestCancel) {
+  ShowDialog();
+  EXPECT_TRUE(dialog_->Cancel());
+  EXPECT_TRUE(called_);
+  EXPECT_FALSE(accept_);
+  EXPECT_TRUE(cancel_);
+  EXPECT_FALSE(dont_block_);
+}
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest,
+                       TestCancelWithChecked) {
+  ShowDialog();
+  SetChecked(true);
+  EXPECT_TRUE(dialog_->Cancel());
+  EXPECT_TRUE(called_);
+  EXPECT_FALSE(accept_);
+  EXPECT_TRUE(cancel_);
+  EXPECT_TRUE(dont_block_);
+}
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest, TestClose) {
+  // Closing the dialog should always call DoCancel() with |dont_block| = false.
+  ShowDialog();
+  EXPECT_TRUE(dialog_->Close());
+  EXPECT_TRUE(called_);
+  EXPECT_FALSE(accept_);
+  EXPECT_TRUE(cancel_);
+  EXPECT_FALSE(dont_block_);
+}
+
+IN_PROC_BROWSER_TEST_F(ExternalProtocolDialogBrowserTest,
+                       TestCloseWithChecked) {
+  // Closing the dialog should always call DoCancel() with |dont_block| = false.
+  ShowDialog();
+  SetChecked(true);
+  EXPECT_TRUE(dialog_->Close());
+  EXPECT_TRUE(called_);
+  EXPECT_FALSE(accept_);
+  EXPECT_TRUE(cancel_);
+  EXPECT_FALSE(dont_block_);
+}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ab0ced4f..b1e4261 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2126,7 +2126,10 @@
       ]
       deps += [ "//ui/views" ]
       if (!is_chromeos && (!is_mac || mac_views_browser)) {
-        sources += [ "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc" ]
+        sources += [
+          "../browser/ui/views/external_protocol_dialog_browsertest.cc",
+          "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc",
+        ]
       }
       if (!is_mac || mac_views_browser) {
         sources += [
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
index 4000955..14ced50 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -364,7 +364,7 @@
       // TODO(alokp): WebMediaPlayerImpl currently only handles HAVE_ENOUGH.
       // See WebMediaPlayerImpl::OnPipelineBufferingStateChanged,
       // http://crbug.com/144683.
-      LOG(WARNING) << "Ignoring buffering notification.";
+      NOTIMPLEMENTED();
     } else {
       client_.buffering_state_cb.Run(::media::BUFFERING_HAVE_ENOUGH);
     }
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index 2f22a46..c8b13ea 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -833,6 +833,9 @@
     services->SetServiceProperty(kCellularServicePath,
                                  shill::kNetworkTechnologyProperty,
                                  technology_value);
+    base::FundamentalValue strength_value(50);
+    services->SetServiceProperty(
+        kCellularServicePath, shill::kSignalStrengthProperty, strength_value);
 
     if (activated) {
       services->SetServiceProperty(
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 3fcf141..7cf6e74 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -128,6 +128,26 @@
   instance->Detach();
 }
 
+bool HasSentStartWorker(EmbeddedWorkerInstance::StartingPhase phase) {
+  switch (phase) {
+    case EmbeddedWorkerInstance::NOT_STARTING:
+    case EmbeddedWorkerInstance::ALLOCATING_PROCESS:
+    case EmbeddedWorkerInstance::REGISTERING_TO_DEVTOOLS:
+      return false;
+    case EmbeddedWorkerInstance::SENT_START_WORKER:
+    case EmbeddedWorkerInstance::SCRIPT_DOWNLOADING:
+    case EmbeddedWorkerInstance::SCRIPT_READ_STARTED:
+    case EmbeddedWorkerInstance::SCRIPT_READ_FINISHED:
+    case EmbeddedWorkerInstance::SCRIPT_LOADED:
+    case EmbeddedWorkerInstance::SCRIPT_EVALUATED:
+    case EmbeddedWorkerInstance::THREAD_STARTED:
+      return true;
+    case EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE:
+      NOTREACHED();
+  }
+  return false;
+}
+
 }  // namespace
 
 // Lives on IO thread, proxies notifications to DevToolsManager that lives on
@@ -492,7 +512,7 @@
   inflight_start_task_->Start(std::move(params), callback);
 }
 
-ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
+bool EmbeddedWorkerInstance::Stop() {
   DCHECK(status_ == EmbeddedWorkerStatus::STARTING ||
          status_ == EmbeddedWorkerStatus::RUNNING)
       << static_cast<int>(status_);
@@ -500,28 +520,36 @@
   // Abort an inflight start task.
   inflight_start_task_.reset();
 
-  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_IPC_FAILED;
   if (ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) {
-    status = SERVICE_WORKER_OK;
+    if (status_ == EmbeddedWorkerStatus::STARTING &&
+        !HasSentStartWorker(starting_phase())) {
+      // Don't send the StopWorker message when the StartWorker message hasn't
+      // been sent.
+      // TODO(shimazu): Invoke OnStopping/OnStopped after the legacy IPC path is
+      // removed.
+      OnDetached();
+      return false;
+    }
     client_->StopWorker(base::Bind(&EmbeddedWorkerRegistry::OnWorkerStopped,
                                    base::Unretained(registry_.get()),
                                    process_id(), embedded_worker_id()));
   } else {
-    status = registry_->StopWorker(process_id(), embedded_worker_id_);
-  }
-  UMA_HISTOGRAM_ENUMERATION("ServiceWorker.SendStopWorker.Status", status,
-                            SERVICE_WORKER_ERROR_MAX_VALUE);
-  // StopWorker could fail if we were starting up and don't have a process yet,
-  // or we can no longer communicate with the process. So just detach.
-  if (status != SERVICE_WORKER_OK) {
-    OnDetached();
-    return status;
+    ServiceWorkerStatusCode status =
+        registry_->StopWorker(process_id(), embedded_worker_id_);
+    UMA_HISTOGRAM_ENUMERATION("ServiceWorker.SendStopWorker.Status", status,
+                              SERVICE_WORKER_ERROR_MAX_VALUE);
+    // StopWorker could fail if we were starting up and don't have a process
+    // yet, or we can no longer communicate with the process. So just detach.
+    if (status != SERVICE_WORKER_OK) {
+      OnDetached();
+      return false;
+    }
   }
 
   status_ = EmbeddedWorkerStatus::STOPPING;
   for (auto& observer : listener_list_)
     observer.OnStopping();
-  return status;
+  return true;
 }
 
 void EmbeddedWorkerInstance::StopIfIdle() {
@@ -867,6 +895,7 @@
   devtools_proxy_.reset();
   process_handle_.reset();
   status_ = EmbeddedWorkerStatus::STOPPED;
+  starting_phase_ = NOT_STARTING;
   thread_id_ = kInvalidEmbeddedWorkerThreadId;
 }
 
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 01e2b02..3152613 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -114,9 +114,8 @@
 
   // Stops the worker. It is invalid to call this when the worker is
   // not in STARTING or RUNNING status.
-  // This returns false if stopping a worker fails immediately, e.g. when
-  // IPC couldn't be sent to the worker.
-  ServiceWorkerStatusCode Stop();
+  // This returns false when StopWorker IPC couldn't be sent to the worker.
+  bool Stop();
 
   // Stops the worker if the worker is not being debugged (i.e. devtools is
   // not attached). This method is called by a stop-worker timer to kill
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index 60efd265..723f6f1 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -221,7 +221,7 @@
   EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
 
   // Stop the worker.
-  EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
+  EXPECT_TRUE(worker->Stop());
   EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, worker->status());
   base::RunLoop().RunUntilIdle();
 
@@ -283,7 +283,7 @@
     // The worker should be using the default render process.
     EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
 
-    EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
+    EXPECT_TRUE(worker->Stop());
     base::RunLoop().RunUntilIdle();
   }
 
@@ -309,7 +309,7 @@
     EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
     // The worker should be using the new render process.
     EXPECT_EQ(helper_->new_render_process_id(), worker->process_id());
-    EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
+    EXPECT_TRUE(worker->Stop());
     base::RunLoop().RunUntilIdle();
   }
 }
@@ -354,7 +354,7 @@
 
   // Calling Stop() actually stops the worker regardless of whether devtools
   // is attached or not.
-  EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
+  EXPECT_TRUE(worker->Stop());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
 }
@@ -520,13 +520,7 @@
   // "PROCESS_ALLOCATED" event should not be recorded.
   ASSERT_EQ(1u, events_.size());
   EXPECT_EQ(DETACHED, events_[0].type);
-  if (is_mojo_enabled()) {
-    // STOPPING should be recorded here because EmbeddedWorkerInstance must be
-    // detached while executing RunUntilIdle.
-    EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, events_[0].status);
-  } else {
-    EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
-  }
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
   events_.clear();
 
   // Restart the worker.
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 2370600..21c34b4 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -494,19 +494,27 @@
                        TRACE_EVENT_SCOPE_THREAD, "Script", script_url_.spec(),
                        "Status", VersionStatusToString(status_));
 
-  if (running_status() == EmbeddedWorkerStatus::STOPPED) {
-    RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
-    return;
-  }
-
-  if (stop_callbacks_.empty()) {
-    ServiceWorkerStatusCode status = embedded_worker_->Stop();
-    if (status != SERVICE_WORKER_OK) {
-      RunSoon(base::Bind(callback, status));
+  switch (running_status()) {
+    case EmbeddedWorkerStatus::STARTING:
+    case EmbeddedWorkerStatus::RUNNING:
+      // Stop() returns false when it's called before StartWorker message hasn't
+      // been sent to the renderer process even though EmbeddedWorkerInstance is
+      // stopped properly.
+      // TODO(shimazu): Remove this check after Stop() hides the IPC behavior.
+      // See also a TODO on EmbeddedWorkerInstance::Stop.
+      if (!embedded_worker_->Stop()) {
+        RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_IPC_FAILED));
+        return;
+      }
+      stop_callbacks_.push_back(callback);
       return;
-    }
+    case EmbeddedWorkerStatus::STOPPING:
+      stop_callbacks_.push_back(callback);
+      return;
+    case EmbeddedWorkerStatus::STOPPED:
+      RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
+      return;
   }
-  stop_callbacks_.push_back(callback);
 }
 
 void ServiceWorkerVersion::ScheduleUpdate() {
diff --git a/content/child/site_isolation_stats_gatherer.cc b/content/child/site_isolation_stats_gatherer.cc
index aeea241a..9350a5b 100644
--- a/content/child/site_isolation_stats_gatherer.cc
+++ b/content/child/site_isolation_stats_gatherer.cc
@@ -126,8 +126,7 @@
 
   // TODO(csharrison): Add a path for IsSameSite/IsValidCorsHeaderSet to take an
   // Origin.
-  GURL frame_origin_url = frame_origin.GetURL();
-  if (CrossSiteDocumentClassifier::IsSameSite(frame_origin_url, response_url))
+  if (CrossSiteDocumentClassifier::IsSameSite(frame_origin, response_url))
     return nullptr;
 
   CrossSiteDocumentMimeType canonical_mime_type =
@@ -146,8 +145,9 @@
   info.headers->EnumerateHeader(NULL, "access-control-allow-origin",
                                 &access_control_origin);
   if (CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-          frame_origin_url, response_url, access_control_origin))
+          frame_origin, response_url, access_control_origin)) {
     return nullptr;
+  }
 
   // Real XSD data collection starts from here.
   std::string no_sniff;
@@ -155,7 +155,6 @@
 
   std::unique_ptr<SiteIsolationResponseMetaData> resp_data(
       new SiteIsolationResponseMetaData);
-  resp_data->frame_origin = frame_origin_url.spec();
   resp_data->response_url = response_url;
   resp_data->resource_type = resource_type;
   resp_data->canonical_mime_type = canonical_mime_type;
diff --git a/content/child/site_isolation_stats_gatherer.h b/content/child/site_isolation_stats_gatherer.h
index 3baa38ea..dea0f521 100644
--- a/content/child/site_isolation_stats_gatherer.h
+++ b/content/child/site_isolation_stats_gatherer.h
@@ -54,7 +54,6 @@
 struct SiteIsolationResponseMetaData {
   SiteIsolationResponseMetaData();
 
-  std::string frame_origin;
   GURL response_url;
   ResourceType resource_type;
   CrossSiteDocumentMimeType canonical_mime_type;
diff --git a/content/common/cross_site_document_classifier.cc b/content/common/cross_site_document_classifier.cc
index cc87c08d..7e2522e 100644
--- a/content/common/cross_site_document_classifier.cc
+++ b/content/common/cross_site_document_classifier.cc
@@ -82,9 +82,9 @@
   return url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme);
 }
 
-bool CrossSiteDocumentClassifier::IsSameSite(const GURL& frame_origin,
+bool CrossSiteDocumentClassifier::IsSameSite(const url::Origin& frame_origin,
                                              const GURL& response_url) {
-  if (!frame_origin.is_valid() || !response_url.is_valid())
+  if (frame_origin.unique() || !response_url.is_valid())
     return false;
 
   if (frame_origin.scheme() != response_url.scheme())
@@ -93,7 +93,7 @@
   // SameDomainOrHost() extracts the effective domains (public suffix plus one)
   // from the two URLs and compare them.
   return net::registry_controlled_domains::SameDomainOrHost(
-      frame_origin, response_url,
+      response_url, frame_origin,
       net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
 }
 
@@ -102,7 +102,7 @@
 // when frame is sub.a.com and it is not allowed to access a document
 // with sub1.a.com. But under Site Isolation, it's allowed.
 bool CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-    const GURL& frame_origin,
+    const url::Origin& frame_origin,
     const GURL& website_origin,
     const std::string& access_control_origin) {
   // Many websites are sending back "\"*\"" instead of "*". This is
diff --git a/content/common/cross_site_document_classifier.h b/content/common/cross_site_document_classifier.h
index e32ee52..5c9bafe2 100644
--- a/content/common/cross_site_document_classifier.h
+++ b/content/common/cross_site_document_classifier.h
@@ -9,6 +9,7 @@
 #include "base/strings/string_piece.h"
 #include "content/common/content_export.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 
@@ -40,7 +41,8 @@
   static bool IsBlockableScheme(const GURL& frame_origin);
 
   // Returns whether the two urls belong to the same sites.
-  static bool IsSameSite(const GURL& frame_origin, const GURL& response_url);
+  static bool IsSameSite(const url::Origin& frame_origin,
+                         const GURL& response_url);
 
   // Returns whether there's a valid CORS header for frame_origin.  This is
   // simliar to CrossOriginAccessControl::passesAccessControlCheck(), but we use
@@ -50,7 +52,7 @@
   // not allowed by actual CORS rules by ignoring 1) credentials and 2)
   // methods. Preflight requests don't matter here since they are not used to
   // decide whether to block a document or not on the client side.
-  static bool IsValidCorsHeaderSet(const GURL& frame_origin,
+  static bool IsValidCorsHeaderSet(const url::Origin& frame_origin,
                                    const GURL& website_origin,
                                    const std::string& access_control_origin);
 
diff --git a/content/common/cross_site_document_classifier_unittest.cc b/content/common/cross_site_document_classifier_unittest.cc
index 53f1058..c65c33e 100644
--- a/content/common/cross_site_document_classifier_unittest.cc
+++ b/content/common/cross_site_document_classifier_unittest.cc
@@ -30,40 +30,47 @@
   GURL a_com_url0("https://mock1.a.com:8080/page1.html");
   GURL a_com_url1("https://mock2.a.com:9090/page2.html");
   GURL a_com_url2("https://a.com/page3.html");
-  EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(a_com_url0, a_com_url1));
-  EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(a_com_url1, a_com_url2));
-  EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(a_com_url2, a_com_url0));
+  url::Origin a_com_origin0(a_com_url0);
+  EXPECT_TRUE(
+      CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, a_com_url1));
+  EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(url::Origin(a_com_url1),
+                                                      a_com_url2));
+  EXPECT_TRUE(CrossSiteDocumentClassifier::IsSameSite(url::Origin(a_com_url2),
+                                                      a_com_url0));
 
   GURL b_com_url0("https://mock1.b.com/index.html");
-  EXPECT_FALSE(CrossSiteDocumentClassifier::IsSameSite(a_com_url0, b_com_url0));
+  EXPECT_FALSE(
+      CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, b_com_url0));
 
   GURL about_blank_url("about:blank");
   EXPECT_FALSE(
-      CrossSiteDocumentClassifier::IsSameSite(a_com_url0, about_blank_url));
+      CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, about_blank_url));
 
   GURL chrome_url("chrome://extension");
-  EXPECT_FALSE(CrossSiteDocumentClassifier::IsSameSite(a_com_url0, chrome_url));
+  EXPECT_FALSE(
+      CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, chrome_url));
 
   GURL empty_url("");
-  EXPECT_FALSE(CrossSiteDocumentClassifier::IsSameSite(a_com_url0, empty_url));
+  EXPECT_FALSE(
+      CrossSiteDocumentClassifier::IsSameSite(a_com_origin0, empty_url));
 }
 
 TEST(CrossSiteDocumentClassifierTest, IsValidCorsHeaderSet) {
-  GURL frame_origin("http://www.google.com");
-  GURL site_origin("http://www.yahoo.com");
+  url::Origin frame_origin(GURL("http://www.google.com"));
+  GURL site_origin_url("http://www.yahoo.com");
 
   EXPECT_TRUE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "*"));
+      frame_origin, site_origin_url, "*"));
   EXPECT_FALSE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "\"*\""));
+      frame_origin, site_origin_url, "\"*\""));
   EXPECT_TRUE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "http://mail.google.com"));
+      frame_origin, site_origin_url, "http://mail.google.com"));
   EXPECT_FALSE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "https://mail.google.com"));
+      frame_origin, site_origin_url, "https://mail.google.com"));
   EXPECT_FALSE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "http://yahoo.com"));
+      frame_origin, site_origin_url, "http://yahoo.com"));
   EXPECT_FALSE(CrossSiteDocumentClassifier::IsValidCorsHeaderSet(
-      frame_origin, site_origin, "www.google.com"));
+      frame_origin, site_origin_url, "www.google.com"));
 }
 
 TEST(CrossSiteDocumentClassifierTest, SniffForHTML) {
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
index aeee244d..778f3eb1 100644
--- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
+++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -49,6 +49,7 @@
     mojom::ServiceWorkerEventDispatcherRequest dispatcher_request) {
   DCHECK(ChildThreadImpl::current());
   DCHECK(!wrapper_);
+  DCHECK(!embedded_worker_id_);
   TRACE_EVENT0("ServiceWorker",
                "EmbeddedWorkerInstanceClientImpl::StartWorker");
   embedded_worker_id_ = params.embedded_worker_id;
@@ -67,13 +68,14 @@
 
 void EmbeddedWorkerInstanceClientImpl::StopWorker(
     const StopWorkerCallback& callback) {
+  // StopWorker must be called after StartWorker is called.
   DCHECK(ChildThreadImpl::current());
+  DCHECK(wrapper_);
   DCHECK(embedded_worker_id_);
-  // StopWorker is possible to be called twice or before StartWorker().
-  if (stop_callback_ || !wrapper_)
-    return;
+  DCHECK(!stop_callback_);
+
   TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerInstanceClientImpl::StopWorker");
-  stop_callback_ = std::move(callback);
+  stop_callback_ = callback;
   dispatcher_->RecordStopWorkerTimer(embedded_worker_id_.value());
   wrapper_->worker()->terminateWorkerContext();
 }
diff --git a/content/test/data/gpu/functional_3d_css.html b/content/test/data/gpu/functional_3d_css.html
index 6bee8d0b1..b16b3e9 100644
--- a/content/test/data/gpu/functional_3d_css.html
+++ b/content/test/data/gpu/functional_3d_css.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<style> 
+<style>
   div {
     width:200px;
     height:100px;
@@ -10,7 +10,13 @@
   }
 </style>
 </head>
-<body>
+<body onload="finished()">
 <div>3D CSS</div>
+<script>
+function finished() {
+  domAutomationController.setAutomationId(0);
+  domAutomationController.send("FINISHED");
+}
+</script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/content/test/data/gpu/functional_canvas_demo.html b/content/test/data/gpu/functional_canvas_demo.html
index cf6ef03d..8183db73a 100644
--- a/content/test/data/gpu/functional_canvas_demo.html
+++ b/content/test/data/gpu/functional_canvas_demo.html
@@ -11,6 +11,8 @@
   var ctx = c.getContext('2d');
   ctx.fillStyle = "#000000";
   ctx.fillRect(10, 10, 250, 250);
+  domAutomationController.setAutomationId(0);
+  domAutomationController.send("FINISHED");
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/content/test/data/gpu/functional_files/context.js b/content/test/data/gpu/functional_files/context.js
index af56f6f..90ba336 100644
--- a/content/test/data/gpu/functional_files/context.js
+++ b/content/test/data/gpu/functional_files/context.js
@@ -10,9 +10,14 @@
   // Try to grab the standard context.
   gl_context = canvas.getContext("webgl") ||
                canvas.getContext("experimental-webgl");
-  // If we don't have a GL context, give up now
+  // If we don't have a GL context, give up now.
   if (!gl_context) {
-    alert("Unable to initialize WebGL. Your browser may not support it.");
+    err = "Unable to initialize WebGL. Your browser may not support it.";
+    if (domAutomationController) {
+      console.log(err);
+    } else {
+      alert(err);
+    }
   }
 }
 
@@ -30,4 +35,7 @@
     gl_context.clear(gl_context.COLOR_BUFFER_BIT |
                      gl_context.DEPTH_BUFFER_BIT);
   }
-}
\ No newline at end of file
+
+  domAutomationController.setAutomationId(0);
+  domAutomationController.send("FINISHED");
+}
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 28cc68be4..f0af56fd 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -1115,14 +1115,6 @@
 }
 
 TELEMETRY_TESTS = {
-  'gpu_process_launch_tests': {
-      'target_name': 'gpu_process',
-      'tester_configs': [
-        {
-          'allow_on_android': True,
-        }
-      ],
-  },
   'hardware_accelerated_feature': {
     'tester_configs': [
       {
@@ -1173,6 +1165,14 @@
       },
     ]
   },
+  'gpu_process_launch_tests': {
+      'target_name': 'gpu_process',
+      'tester_configs': [
+        {
+          'allow_on_android': True,
+        }
+      ],
+  },
   'pixel_test': {
     'target_name': 'pixel',
     'args': [
diff --git a/content/test/gpu/gpu_tests/gpu_process.py b/content/test/gpu/gpu_tests/gpu_process.py
deleted file mode 100644
index 187b6b7..0000000
--- a/content/test/gpu/gpu_tests/gpu_process.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 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.
-from gpu_tests import gpu_process_expectations as expectations
-from gpu_tests import gpu_test_base
-import page_sets
-
-from telemetry.page import legacy_page_test
-
-test_harness_script = r"""
-  var domAutomationController = {};
-  domAutomationController._finished = false;
-  domAutomationController.setAutomationId = function(id) {}
-  domAutomationController.send = function(msg) {
-    domAutomationController._finished = true;
-  }
-
-  window.domAutomationController = domAutomationController;
-
-  function GetDriverBugWorkarounds() {
-    var query_result = document.querySelector('.workarounds-list');
-    var browser_list = []
-    for (var i=0; i < query_result.childElementCount; i++)
-      browser_list.push(query_result.children[i].textContent);
-    return browser_list;
-  };
-"""
-
-class GpuProcessValidator(gpu_test_base.ValidatorBase):
-  def __init__(self):
-    super(GpuProcessValidator, self).__init__(
-        needs_browser_restart_after_each_page=True)
-
-  def CustomizeBrowserOptions(self, options):
-    options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    if hasattr(page, 'Validate'):
-      page.Validate(tab, results)
-    else:
-      has_gpu_channel_js = 'chrome.gpuBenchmarking.hasGpuChannel()'
-      has_gpu_channel = tab.EvaluateJavaScript(has_gpu_channel_js)
-      if not has_gpu_channel:
-        raise legacy_page_test.Failure('No GPU channel detected')
-
-class GpuProcess(gpu_test_base.TestBase):
-  """Tests that accelerated content triggers the creation of a GPU process"""
-  test = GpuProcessValidator
-
-  @classmethod
-  def Name(cls):
-    return 'gpu_process'
-
-  def _CreateExpectations(self):
-    return expectations.GpuProcessExpectations()
-
-  def CreateStorySet(self, options):
-    browser_type = options.browser_options.browser_type
-    is_platform_android = browser_type.startswith('android')
-    story_set = page_sets.GpuProcessTestsStorySet(self.GetExpectations(),
-                                                  is_platform_android)
-    for page in story_set:
-      page.script_to_evaluate_on_commit = test_harness_script
-    return story_set
diff --git a/content/test/gpu/gpu_tests/gpu_process_expectations.py b/content/test/gpu/gpu_tests/gpu_process_expectations.py
index d9f4b410..656f572 100644
--- a/content/test/gpu/gpu_tests/gpu_process_expectations.py
+++ b/content/test/gpu/gpu_tests/gpu_process_expectations.py
@@ -9,23 +9,21 @@
 class GpuProcessExpectations(GpuTestExpectations):
   def SetExpectations(self):
     # Accelerated 2D canvas is not available on Linux due to driver instability
-    self.Fail('GpuProcess.canvas2d', ['linux'], bug=254724)
+    self.Fail('GpuProcess_canvas2d', ['linux'], bug=254724)
 
-    self.Fail('GpuProcess.video', ['linux'], bug=257109)
+    self.Fail('GpuProcess_video', ['linux'], bug=257109)
 
     # Chrome on Android doesn't support software fallback.
-    self.Skip('GpuProcess.no_gpu_process', ['android'], bug=643282)
+    self.Skip('GpuProcess_no_gpu_process', ['android'], bug=643282)
+    self.Skip('GpuProcess_skip_gpu_process', ['android'], bug=(610951, 610023))
 
-    # Nexus 5X
-    # Skip this test because expecting it to fail will still run it.
-    self.Skip('GpuProcess.skip_gpu_process',
-              ['android', ('qualcomm', 'Adreno (TM) 418')], bug=610951)
+    # There is no Android multi-gpu configuration and the helper
+    # gpu_info_collector.cc::IdentifyActiveGPU is not even called.
+    self.Skip('GpuProcess_identify_active_gpu1', ['android'])
+    self.Skip('GpuProcess_identify_active_gpu2', ['android'])
+    self.Skip('GpuProcess_identify_active_gpu3', ['android'])
+    self.Skip('GpuProcess_identify_active_gpu4', ['android'])
 
-    # Nexus 9
-    # Skip this test because expecting it to fail will still run it.
-    self.Skip('GpuProcess.skip_gpu_process',
-              ['android', 'nvidia'], bug=610023)
-
-    # There are currently no blacklist entries disabling all GPU
-    # functionality on Mac OS.
-    self.Fail('GpuProcess.no_gpu_process', ['mac'], bug=579255)
+    # There is currently no entry in kSoftwareRenderingListJson that enables
+    # a software GL driver on Android.
+    self.Skip('GpuProcess_software_gpu_process', ['android'])
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
new file mode 100644
index 0000000..af7bedb
--- /dev/null
+++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -0,0 +1,528 @@
+# 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 logging
+import os
+import sys
+
+from gpu_tests import gpu_integration_test
+from gpu_tests import gpu_process_expectations
+from gpu_tests import path_util
+
+data_path = os.path.join(
+    path_util.GetChromiumSrcDir(), 'content', 'test', 'data')
+
+test_harness_script = r"""
+  var domAutomationController = {};
+  domAutomationController._finished = false;
+  domAutomationController.setAutomationId = function(id) {}
+  domAutomationController.send = function(msg) {
+    domAutomationController._finished = true;
+  }
+
+  window.domAutomationController = domAutomationController;
+
+  function GetDriverBugWorkarounds() {
+    var query_result = document.querySelector('.workarounds-list');
+    var browser_list = []
+    for (var i=0; i < query_result.childElementCount; i++)
+      browser_list.push(query_result.children[i].textContent);
+    return browser_list;
+  };
+"""
+
+class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
+  # We store a deep copy of the original browser finder options in
+  # order to be able to restart the browser multiple times, with a
+  # different set of command line arguments each time.
+  _original_finder_options = None
+
+  # We keep track of the set of command line arguments used to launch
+  # the browser most recently in order to figure out whether we need
+  # to relaunch it, if a new pixel test requires a different set of
+  # arguments.
+  _last_launched_browser_args = set()
+
+  @classmethod
+  def Name(cls):
+    """The name by which this test is invoked on the command line."""
+    return 'gpu_process'
+
+  @classmethod
+  def setUpClass(cls):
+    super(cls, GpuProcessIntegrationTest).setUpClass()
+    cls._original_finder_options = cls._finder_options.Copy()
+    cls.CustomizeBrowserArgs([])
+    cls.StartBrowser()
+    cls.SetStaticServerDirs([data_path])
+
+  @classmethod
+  def CustomizeBrowserArgs(cls, browser_args):
+    if not browser_args:
+      browser_args = []
+    cls._finder_options = cls._original_finder_options.Copy()
+    browser_options = cls._finder_options.browser_options
+    # All tests receive the following options. They aren't recorded in
+    # the _last_launched_browser_args.
+    browser_options.AppendExtraBrowserArgs([
+      '--enable-gpu-benchmarking',
+      # TODO(kbr): figure out why the following option seems to be
+      # needed on Android for robustness.
+      # https://github.com/catapult-project/catapult/issues/3122
+      '--no-first-run'])
+    # Append the new arguments.
+    browser_options.AppendExtraBrowserArgs(browser_args)
+    cls._last_launched_browser_args = set(browser_args)
+    cls.SetBrowserOptions(cls._finder_options)
+
+  @classmethod
+  def RestartBrowserIfNecessaryWithArgs(cls, browser_args):
+    if not browser_args:
+      browser_args = []
+    if set(browser_args) != cls._last_launched_browser_args:
+      logging.info('Restarting browser with arguments: ' + str(browser_args))
+      cls.StopBrowser()
+      cls.CustomizeBrowserArgs(browser_args)
+      cls.StartBrowser()
+      cls.tab = cls.browser.tabs[0]
+
+  @classmethod
+  def _CreateExpectations(cls):
+    return gpu_process_expectations.GpuProcessExpectations()
+
+  @classmethod
+  def GenerateGpuTests(cls, options):
+    # The browser test runner synthesizes methods with the exact name
+    # given in GenerateGpuTests, so in order to hand-write our tests but
+    # also go through the _RunGpuTest trampoline, the test needs to be
+    # slightly differently named.
+
+    # Also note that since functional_video.html refers to files in
+    # ../media/ , the serving dir must be the common parent directory.
+    tests = (('GpuProcess_canvas2d', 'gpu/functional_canvas_demo.html'),
+             ('GpuProcess_css3d', 'gpu/functional_3d_css.html'),
+             ('GpuProcess_webgl', 'gpu/functional_webgl.html'),
+             ('GpuProcess_video', 'gpu/functional_video.html'),
+             ('GpuProcess_gpu_info_complete', 'gpu/functional_3d_css.html'),
+             ('GpuProcess_no_gpu_process', 'about:blank'),
+             ('GpuProcess_driver_bug_workarounds_in_gpu_process', 'chrome:gpu'),
+             ('GpuProcess_readback_webgl_gpu_process', 'chrome:gpu'),
+             ('GpuProcess_driver_bug_workarounds_upon_gl_renderer',
+              'chrome:gpu'),
+             ('GpuProcess_only_one_workaround', 'chrome:gpu'),
+             ('GpuProcess_skip_gpu_process', 'chrome:gpu'),
+             ('GpuProcess_identify_active_gpu1', 'chrome:gpu'),
+             ('GpuProcess_identify_active_gpu2', 'chrome:gpu'),
+             ('GpuProcess_identify_active_gpu3', 'chrome:gpu'),
+             ('GpuProcess_identify_active_gpu4', 'chrome:gpu'),
+             ('GpuProcess_software_gpu_process', 'about:blank'))
+
+    # The earlier has_transparent_visuals_gpu_process and
+    # no_transparent_visuals_gpu_process tests became no-ops in
+    # http://crrev.com/2347383002 and were deleted.
+
+    for t in tests:
+      yield (t[0], t[1], ('_' + t[0]))
+
+  def RunActualGpuTest(self, test_path, *args):
+    test_name = args[0]
+    getattr(self, test_name)(test_path)
+
+  ######################################
+  # Helper functions for the tests below
+
+  def _Navigate(self, test_path):
+    url = self.UrlOfStaticFilePath(test_path)
+    # It's crucial to use the action_runner, rather than the tab's
+    # Navigate method directly. It waits for the document ready state
+    # to become interactive or better, avoiding critical race
+    # conditions.
+    self.tab.action_runner.Navigate(
+      url, script_to_evaluate_on_commit=test_harness_script)
+
+  def _NavigateAndWait(self, test_path):
+    self._Navigate(test_path)
+    self.tab.action_runner.WaitForJavaScriptCondition(
+      'window.domAutomationController._finished', timeout_in_seconds=10)
+
+  def _VerifyGpuProcessPresent(self):
+    tab = self.tab
+    has_gpu_channel_js = 'chrome.gpuBenchmarking.hasGpuChannel()'
+    has_gpu_channel = tab.EvaluateJavaScript(has_gpu_channel_js)
+    if not has_gpu_channel:
+      self.fail('No GPU channel detected')
+
+  def _ValidateDriverBugWorkaroundsImpl(self, process_kind, is_expected,
+                                    workaround_name):
+    tab = self.tab
+    if process_kind == "browser_process":
+      gpu_driver_bug_workarounds = tab.EvaluateJavaScript(
+        'GetDriverBugWorkarounds()')
+    elif process_kind == "gpu_process":
+      gpu_driver_bug_workarounds = tab.EvaluateJavaScript(
+        'chrome.gpuBenchmarking.getGpuDriverBugWorkarounds()')
+
+    is_present = workaround_name in gpu_driver_bug_workarounds
+    failure = False
+    if is_expected and not is_present:
+      failure = True
+      error_message = "is missing"
+    elif not is_expected and is_present:
+      failure = True
+      error_message = "is not expected"
+
+    if failure:
+      print 'Test failed. Printing page contents:'
+      print tab.EvaluateJavaScript('document.body.innerHTML')
+      self.fail('%s %s in %s workarounds: %s'
+                % (workaround_name, error_message, process_kind,
+                   gpu_driver_bug_workarounds))
+
+  def _ValidateDriverBugWorkarounds(self, expected_workaround,
+                                    unexpected_workaround):
+    if not expected_workaround and not unexpected_workaround:
+      return
+    if expected_workaround:
+      self._ValidateDriverBugWorkaroundsImpl(
+        "browser_process", True, expected_workaround)
+      self._ValidateDriverBugWorkaroundsImpl(
+        "gpu_process", True, expected_workaround)
+    if unexpected_workaround:
+      self._ValidateDriverBugWorkaroundsImpl(
+        "browser_process", False, unexpected_workaround)
+      self._ValidateDriverBugWorkaroundsImpl(
+        "gpu_process", False, unexpected_workaround)
+
+  # This can only be called from one of the tests, i.e., after the
+  # browser's been brought up once.
+  def _RunningOnAndroid(self):
+    options = self.__class__._original_finder_options.browser_options
+    return options.browser_type.startswith('android')
+
+  def _CompareAndCaptureDriverBugWorkarounds(self):
+    tab = self.tab
+    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
+    if not tab.EvaluateJavaScript(has_gpu_process_js):
+      self.fail('No GPU process detected')
+
+    has_gpu_channel_js = 'chrome.gpuBenchmarking.hasGpuChannel()'
+    if not tab.EvaluateJavaScript(has_gpu_channel_js):
+      self.fail('No GPU channel detected')
+
+    browser_list = tab.EvaluateJavaScript('GetDriverBugWorkarounds()')
+    gpu_list = tab.EvaluateJavaScript(
+      'chrome.gpuBenchmarking.getGpuDriverBugWorkarounds()')
+
+    diff = set(browser_list).symmetric_difference(set(gpu_list))
+    if len(diff) > 0:
+      print 'Test failed. Printing page contents:'
+      print tab.EvaluateJavaScript('document.body.innerHTML')
+      self.fail('Browser and GPU process list of driver bug'
+                'workarounds are not equal: %s != %s, diff: %s' %
+                (browser_list, gpu_list, list(diff)))
+
+    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
+    disabled_gl_extensions = None
+    for info in basic_infos:
+      if info['description'].startswith('Disabled Extensions'):
+        disabled_gl_extensions = info['value']
+        break
+
+    return gpu_list, disabled_gl_extensions
+
+  def _VerifyActiveAndInactiveGPUs(
+      self, expected_active_gpu, expected_inactive_gpus):
+    tab = self.tab
+    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
+    active_gpu = []
+    inactive_gpus = []
+    index = 0
+    for info in basic_infos:
+      description = info['description']
+      value = info['value']
+      if description.startswith('GPU%d' % index) and value.startswith('VENDOR'):
+        if value.endswith('*ACTIVE*'):
+          active_gpu.append(value)
+        else:
+          inactive_gpus.append(value)
+        index += 1
+    if active_gpu != expected_active_gpu:
+      self.fail('Active GPU field is wrong %s' % active_gpu)
+    if inactive_gpus != expected_inactive_gpus:
+      self.fail('Inactive GPU field is wrong %s' % inactive_gpus)
+
+  ######################################
+  # The actual tests
+
+  def _GpuProcess_canvas2d(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._NavigateAndWait(test_path)
+    self._VerifyGpuProcessPresent()
+
+  def _GpuProcess_css3d(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._NavigateAndWait(test_path)
+    self._VerifyGpuProcessPresent()
+
+  def _GpuProcess_webgl(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._NavigateAndWait(test_path)
+    self._VerifyGpuProcessPresent()
+
+  def _GpuProcess_video(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._NavigateAndWait(test_path)
+    self._VerifyGpuProcessPresent()
+
+  def _GpuProcess_gpu_info_complete(self, test_path):
+    # Regression test for crbug.com/454906
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._NavigateAndWait(test_path)
+    tab = self.tab
+    if not tab.browser.supports_system_info:
+      self.fail('Browser must support system info')
+    system_info = tab.browser.GetSystemInfo()
+    if not system_info.gpu:
+      self.fail('Target machine must have a GPU')
+    if not system_info.gpu.aux_attributes:
+      self.fail('Browser must support GPU aux attributes')
+    if not 'gl_renderer' in system_info.gpu.aux_attributes:
+      self.fail('Browser must have gl_renderer in aux attribs')
+    if len(system_info.gpu.aux_attributes['gl_renderer']) <= 0:
+      self.fail('Must have a non-empty gl_renderer string')
+
+  def _GpuProcess_no_gpu_process(self, test_path):
+    options = self.__class__._original_finder_options.browser_options
+    if options.browser_type.startswith('android'):
+      # Android doesn't support starting up the browser without any
+      # GPU process. This test is skipped on Android in
+      # gpu_process_expectations.py, but we must at least be able to
+      # bring up the browser in order to detect that the test
+      # shouldn't run. Faking a vendor and device ID can get the
+      # browser into a state where it won't launch.
+      return
+    elif sys.platform in ('cygwin', 'win32'):
+      # Hit id 34 from kSoftwareRenderingListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-vendor-id=0x5333',
+        '--gpu-testing-device-id=0x8811'])
+    elif sys.platform.startswith('linux'):
+      # Hit id 50 from kSoftwareRenderingListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-no-complete-info-collection',
+        '--gpu-testing-vendor-id=0x10de',
+        '--gpu-testing-device-id=0x0de1',
+        '--gpu-testing-gl-vendor=VMware',
+        '--gpu-testing-gl-renderer=softpipe',
+        '--gpu-testing-gl-version="2.1 Mesa 10.1"'])
+    elif sys.platform == 'darwin':
+      # Hit id 112 from kSoftwareRenderingListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-vendor-id=0x8086',
+        '--gpu-testing-device-id=0x0116'])
+    self._Navigate(test_path)
+    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
+    has_gpu_process = self.tab.EvaluateJavaScript(has_gpu_process_js)
+    if has_gpu_process:
+      self.fail('GPU process detected')
+
+  def _GpuProcess_driver_bug_workarounds_in_gpu_process(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--use_gpu_driver_workaround_for_testing'])
+    self._Navigate(test_path)
+    self._ValidateDriverBugWorkarounds(
+      'use_gpu_driver_workaround_for_testing', None)
+
+  def _GpuProcess_readback_webgl_gpu_process(self, test_path):
+    # This test was designed to only run on desktop Linux.
+    options = self.__class__._original_finder_options.browser_options
+    is_platform_android = options.browser_type.startswith('android')
+    if sys.platform.startswith('linux') and not is_platform_android:
+      # Hit id 110 from kSoftwareRenderingListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-vendor-id=0x10de',
+        '--gpu-testing-device-id=0x0de1',
+        '--gpu-testing-gl-vendor=VMware',
+        '--gpu-testing-gl-renderer=Gallium 0.4 ' \
+        'on llvmpipe (LLVM 3.4, 256 bits)',
+        '--gpu-testing-gl-version="3.0 Mesa 11.2"'])
+      self._Navigate(test_path)
+      feature_status_js = 'browserBridge.gpuInfo.featureStatus.featureStatus'
+      feature_status_list = self.tab.EvaluateJavaScript(feature_status_js)
+      result = True
+      for name, status in feature_status_list.items():
+        if name == 'multiple_raster_threads':
+          result = result and status == 'enabled_on'
+        elif name == 'native_gpu_memory_buffers':
+          result = result and status == 'disabled_software'
+        elif name == 'webgl':
+          result = result and status == 'enabled_readback'
+        elif name == 'webgl2':
+          result = result and status == 'unavailable_off'
+        else:
+          result = result and status == 'unavailable_software'
+      if not result:
+        self.fail('WebGL readback setup failed: %s' % feature_status_list)
+
+  def _GpuProcess_driver_bug_workarounds_upon_gl_renderer(self, test_path):
+    is_platform_android = self._RunningOnAndroid()
+    if is_platform_android:
+      # Hit id 108 from kGpuDriverBugListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-gl-vendor=NVIDIA Corporation',
+        '--gpu-testing-gl-renderer=NVIDIA Tegra',
+        '--gpu-testing-gl-version=OpenGL ES 3.1 NVIDIA 343.00'])
+    elif sys.platform in ('cygwin', 'win32'):
+      # Hit id 51 and 87 from kGpuDriverBugListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-vendor-id=0x1002',
+        '--gpu-testing-device-id=0x6779',
+        '--gpu-testing-driver-date=11-20-2014',
+        '--gpu-testing-gl-vendor=Google Inc.',
+        '--gpu-testing-gl-renderer=ANGLE ' \
+        '(AMD Radeon HD 6450 Direct3D11 vs_5_0 ps_5_0)',
+        '--gpu-testing-gl-version=OpenGL ES 2.0 (ANGLE 2.1.0.0c0d8006a9dd)'])
+    elif sys.platform.startswith('linux'):
+      # Hit id 40 from kGpuDriverBugListJson.
+      self.RestartBrowserIfNecessaryWithArgs([
+        '--gpu-testing-vendor-id=0x0101',
+        '--gpu-testing-device-id=0x0102',
+        '--gpu-testing-gl-vendor=ARM',
+        '--gpu-testing-gl-renderer=Mali-400 MP'])
+    elif sys.platform == 'darwin':
+      # Currently on osx no workaround relies on gl-renderer.
+      return
+    self._Navigate(test_path)
+    if is_platform_android:
+      self._ValidateDriverBugWorkarounds(
+        'unpack_overlapping_rows_separately_unpack_buffer', None)
+    elif sys.platform in ('cygwin', 'win32'):
+      self._ValidateDriverBugWorkarounds(
+        'texsubimage_faster_than_teximage', 'disable_d3d11')
+    elif sys.platform.startswith('linux'):
+      self._ValidateDriverBugWorkarounds('disable_discard_framebuffer', None)
+    else:
+      self.fail('Unexpected platform ' + sys.platform)
+
+  def _GpuProcess_only_one_workaround(self, test_path):
+    # Start this test by launching the browser with no command line
+    # arguments.
+    self.RestartBrowserIfNecessaryWithArgs([])
+    self._Navigate(test_path)
+    self._VerifyGpuProcessPresent()
+    recorded_workarounds, recorded_disabled_gl_extensions = (
+      self._CompareAndCaptureDriverBugWorkarounds())
+    # Add the testing workaround to the recorded workarounds.
+    recorded_workarounds.append('use_gpu_driver_workaround_for_testing')
+    # Relaunch the browser with OS-specific command line arguments.
+    browser_args = ['--use_gpu_driver_workaround_for_testing',
+                    '--disable-gpu-driver-bug-workarounds']
+    # Inject some info to make sure the flags above are effective.
+    if sys.platform == 'darwin':
+      # Hit id 33 from kGpuDriverBugListJson.
+      browser_args.extend(['--gpu-testing-gl-vendor=Imagination'])
+    else:
+      # Hit id 5 from kGpuDriverBugListJson.
+      browser_args.extend(['--gpu-testing-vendor-id=0x10de',
+                           '--gpu-testing-device-id=0x0001'])
+      # no multi gpu on Android.
+      if not self._RunningOnAndroid():
+        browser_args.extend(['--gpu-testing-secondary-vendor-ids=',
+                             '--gpu-testing-secondary-device-ids='])
+    for workaround in recorded_workarounds:
+      browser_args.append('--' + workaround)
+    browser_args.append('--disable-gl-extensions=' +
+                        recorded_disabled_gl_extensions)
+    self.RestartBrowserIfNecessaryWithArgs(browser_args)
+    self._Navigate(test_path)
+    self._VerifyGpuProcessPresent()
+    new_workarounds, new_disabled_gl_extensions = (
+      self._CompareAndCaptureDriverBugWorkarounds())
+    diff = set(recorded_workarounds).symmetric_difference(new_workarounds)
+    tab = self.tab
+    if len(diff) > 0:
+      print 'Test failed. Printing page contents:'
+      print tab.EvaluateJavaScript('document.body.innerHTML')
+      self.fail(
+        'GPU process and expected list of driver bug '
+        'workarounds are not equal: %s != %s, diff: %s' %
+        (recorded_workarounds, new_workarounds, list(diff)))
+    if recorded_disabled_gl_extensions != new_disabled_gl_extensions:
+      print 'Test failed. Printing page contents:'
+      print tab.EvaluateJavaScript('document.body.innerHTML')
+      self.fail(
+        'The expected disabled gl extensions are '
+        'incorrect: %s != %s:' %
+        (recorded_disabled_gl_extensions, new_disabled_gl_extensions))
+
+  def _GpuProcess_skip_gpu_process(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--disable-gpu',
+      '--skip-gpu-data-loading'])
+    self._Navigate(test_path)
+    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
+    has_gpu_process = self.tab.EvaluateJavaScript(has_gpu_process_js)
+    if has_gpu_process:
+      self.fail('GPU process detected')
+
+  def _GpuProcess_identify_active_gpu1(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-testing-vendor-id=0x8086',
+      '--gpu-testing-device-id=0x040a',
+      '--gpu-testing-secondary-vendor-ids=0x10de',
+      '--gpu-testing-secondary-device-ids=0x0de1',
+      '--gpu-testing-gl-vendor=nouveau'])
+    self._Navigate(test_path)
+    self._VerifyActiveAndInactiveGPUs(
+      ['VENDOR = 0x10de, DEVICE= 0x0de1 *ACTIVE*'],
+      ['VENDOR = 0x8086, DEVICE= 0x040a'])
+
+  def _GpuProcess_identify_active_gpu2(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-testing-vendor-id=0x8086',
+      '--gpu-testing-device-id=0x040a',
+      '--gpu-testing-secondary-vendor-ids=0x10de',
+      '--gpu-testing-secondary-device-ids=0x0de1',
+      '--gpu-testing-gl-vendor=Intel'])
+    self._Navigate(test_path)
+    self._VerifyActiveAndInactiveGPUs(
+      ['VENDOR = 0x8086, DEVICE= 0x040a *ACTIVE*'],
+      ['VENDOR = 0x10de, DEVICE= 0x0de1'])
+
+  def _GpuProcess_identify_active_gpu3(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-testing-vendor-id=0x8086',
+      '--gpu-testing-device-id=0x040a',
+      '--gpu-testing-secondary-vendor-ids=0x10de;0x1002',
+      '--gpu-testing-secondary-device-ids=0x0de1;0x6779',
+      '--gpu-testing-gl-vendor=X.Org',
+      '--gpu-testing-gl-renderer=AMD R600'])
+    self._Navigate(test_path)
+    self._VerifyActiveAndInactiveGPUs(
+      ['VENDOR = 0x1002, DEVICE= 0x6779 *ACTIVE*'],
+      ['VENDOR = 0x8086, DEVICE= 0x040a',
+       'VENDOR = 0x10de, DEVICE= 0x0de1'])
+
+  def _GpuProcess_identify_active_gpu4(self, test_path):
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-testing-vendor-id=0x10de',
+      '--gpu-testing-device-id=0x0de1',
+      '--gpu-testing-secondary-vendor-ids=',
+      '--gpu-testing-secondary-device-ids=',
+      '--gpu-testing-gl-vendor=nouveau'])
+    self._Navigate(test_path)
+    self._VerifyActiveAndInactiveGPUs(
+      ['VENDOR = 0x10de, DEVICE= 0x0de1 *ACTIVE*'],
+      [])
+
+  def _GpuProcess_software_gpu_process(self, test_path):
+    # Hit exception from id 50 from kSoftwareRenderingListJson.
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-testing-vendor-id=0x10de',
+      '--gpu-testing-device-id=0x0de1',
+      '--gpu-testing-gl-vendor=VMware',
+      '--gpu-testing-gl-renderer=SVGA3D',
+      '--gpu-testing-gl-version=2.1 Mesa 10.1'])
+    self._Navigate(test_path)
+    self._VerifyGpuProcessPresent()
diff --git a/content/test/gpu/gpu_tests/lint_unittest.py b/content/test/gpu/gpu_tests/lint_unittest.py
index efc45c4..ce556a7 100644
--- a/content/test/gpu/gpu_tests/lint_unittest.py
+++ b/content/test/gpu/gpu_tests/lint_unittest.py
@@ -38,11 +38,5 @@
 
 
 class LintTest(unittest.TestCase):
-
   def testPassingPylintCheckForGpuTestsDir(self):
     self.assertTrue(LintCheckPassed(os.path.abspath(os.path.dirname(__file__))))
-
-  def testPassingPylintCheckForPageSetsDir(self):
-    self.assertTrue(LintCheckPassed(
-      os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'page_sets'
-                  )))
diff --git a/content/test/gpu/page_sets/__init__.py b/content/test/gpu/page_sets/__init__.py
deleted file mode 100644
index b4ddfbf..0000000
--- a/content/test/gpu/page_sets/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import sys
-
-from telemetry.core import discover
-from telemetry.story import story_set
-
-from page_sets.gpu_process_tests import GpuProcessTestsStorySet
diff --git a/content/test/gpu/page_sets/gpu_process_tests.py b/content/test/gpu/page_sets/gpu_process_tests.py
deleted file mode 100644
index c993a431..0000000
--- a/content/test/gpu/page_sets/gpu_process_tests.py
+++ /dev/null
@@ -1,778 +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.
-import sys
-from telemetry.story import story_set as story_set_module
-from telemetry.page import legacy_page_test
-
-from gpu_tests import gpu_test_base
-
-class GpuProcessSharedPageState(gpu_test_base.GpuSharedPageState):
-
-  gpu_switches = ['--gpu-no-complete-info-collection',
-                  '--gpu-testing-os-version',
-                  '--gpu-testing-vendor-id',
-                  '--gpu-testing-device-id',
-                  '--gpu-testing-secondary-vendor-ids',
-                  '--gpu-testing-secondary-device-ids',
-                  '--gpu-testing-driver-date',
-                  '--gpu-testing-gl-vendor',
-                  '--gpu-testing-gl-renderer',
-                  '--gpu-testing-gl-version']
-
-  def __init__(self, test, finder_options, story_set):
-    super(GpuProcessSharedPageState, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options.extra_browser_args
-
-    # Clear all existing gpu testing switches.
-    old_gpu_switches = []
-    for opt in options:
-      for gpu_switch in self.gpu_switches:
-        if opt.startswith(gpu_switch):
-          old_gpu_switches.append(opt)
-    options.difference_update(old_gpu_switches)
-
-
-class IdentifyActiveGpuPageBase(gpu_test_base.PageBase):
-
-  def __init__(self, name=None, page_set=None, shared_page_state_class=None,
-               expectations=None, active_gpu=None, inactive_gpus=None):
-    super(IdentifyActiveGpuPageBase, self).__init__(
-      url='chrome:gpu',
-      name=name,
-      page_set=page_set,
-      shared_page_state_class=shared_page_state_class,
-      expectations=expectations)
-    self.active_gpu = active_gpu
-    self.inactive_gpus = inactive_gpus
-
-  def Validate(self, tab, results):
-    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
-    active_gpu = []
-    inactive_gpus = []
-    index = 0
-    for info in basic_infos:
-      description = info['description']
-      value = info['value']
-      if description.startswith('GPU%d' % index) and value.startswith('VENDOR'):
-        if value.endswith('*ACTIVE*'):
-          active_gpu.append(value)
-        else:
-          inactive_gpus.append(value)
-        index += 1
-
-    if active_gpu != self.active_gpu:
-      raise legacy_page_test.Failure(
-          'Active GPU field is wrong %s' % active_gpu)
-
-    if inactive_gpus != self.inactive_gpus:
-      raise legacy_page_test.Failure(
-          'Inactive GPU field is wrong %s' % inactive_gpus)
-
-
-class DriverBugWorkaroundsTestsPage(gpu_test_base.PageBase):
-  def __init__(self, page_set=None, name='',
-               shared_page_state_class=None,
-               expectations=None,
-               expected_workaround=None,
-               unexpected_workaround=None):
-    super(DriverBugWorkaroundsTestsPage, self).__init__(
-        url='chrome:gpu',
-        page_set=page_set,
-        name=name,
-        shared_page_state_class=shared_page_state_class,
-        expectations=expectations)
-    self.expected_workaround = expected_workaround
-    self.unexpected_workaround = unexpected_workaround
-
-  def _Validate(self, tab, process_kind, is_expected, workaround_name):
-    if process_kind == "browser_process":
-      gpu_driver_bug_workarounds = tab.EvaluateJavaScript( \
-        'GetDriverBugWorkarounds()')
-    elif process_kind == "gpu_process":
-      gpu_driver_bug_workarounds = tab.EvaluateJavaScript( \
-        'chrome.gpuBenchmarking.getGpuDriverBugWorkarounds()')
-
-    is_present = workaround_name in gpu_driver_bug_workarounds
-
-    failure = False
-    if is_expected and not is_present:
-      failure = True
-      error_message = "is missing"
-    elif not is_expected and is_present:
-      failure = True
-      error_message = "is not expected"
-
-    if failure:
-      print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript('document.body.innerHTML')
-      raise legacy_page_test.Failure('%s %s in Browser process workarounds: %s'
-        % (workaround_name, error_message, gpu_driver_bug_workarounds))
-
-  def Validate(self, tab, results):
-    if not self.expected_workaround and not self.unexpected_workaround:
-      return
-
-    if self.expected_workaround:
-      self._Validate(tab, "browser_process", True, self.expected_workaround)
-      self._Validate(tab, "gpu_process", True, self.expected_workaround)
-
-    if self.unexpected_workaround:
-      self._Validate(tab, "browser_process", False, self.unexpected_workaround)
-      self._Validate(tab, "gpu_process", False, self.unexpected_workaround)
-
-
-class EqualBugWorkaroundsBasePage(gpu_test_base.PageBase):
-  def __init__(self, name=None, page_set=None, shared_page_state_class=None,
-               expectations=None):
-    super(EqualBugWorkaroundsBasePage, self).__init__(
-      url='chrome:gpu',
-      name=name,
-      page_set=page_set,
-      shared_page_state_class=shared_page_state_class,
-      expectations=expectations)
-
-  def Validate(self, tab, results):
-    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
-    if not tab.EvaluateJavaScript(has_gpu_process_js):
-      raise legacy_page_test.Failure('No GPU process detected')
-
-    has_gpu_channel_js = 'chrome.gpuBenchmarking.hasGpuChannel()'
-    if not tab.EvaluateJavaScript(has_gpu_channel_js):
-      raise legacy_page_test.Failure('No GPU channel detected')
-
-    browser_list = tab.EvaluateJavaScript('GetDriverBugWorkarounds()')
-    gpu_list = tab.EvaluateJavaScript( \
-      'chrome.gpuBenchmarking.getGpuDriverBugWorkarounds()')
-
-    diff = set(browser_list).symmetric_difference(set(gpu_list))
-    if len(diff) > 0:
-      print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript('document.body.innerHTML')
-      raise legacy_page_test.Failure(
-        'Browser and GPU process list of driver bug'
-        'workarounds are not equal: %s != %s, diff: %s' %
-        (browser_list, gpu_list, list(diff)))
-
-    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
-    disabled_gl_extensions = None
-    for info in basic_infos:
-      if info['description'].startswith('Disabled Extensions'):
-        disabled_gl_extensions = info['value']
-        break
-
-    return gpu_list, disabled_gl_extensions
-
-
-class GpuProcessTestsPage(gpu_test_base.PageBase):
-  def __init__(self, url, name, story_set, expectations):
-    super(GpuProcessTestsPage, self).__init__(url=url,
-        shared_page_state_class=gpu_test_base.GpuSharedPageState,
-        page_set=story_set,
-        name=name,
-        expectations=expectations)
-
-
-class FunctionalVideoPage(GpuProcessTestsPage):
-
-  def __init__(self, story_set, expectations):
-    super(FunctionalVideoPage, self).__init__(
-      url='file://../../data/gpu/functional_video.html',
-      name='GpuProcess.video',
-      story_set=story_set,
-      expectations=expectations)
-
-  def RunNavigateSteps(self, action_runner):
-    super(FunctionalVideoPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition(
-        'domAutomationController._finished', timeout_in_seconds=30)
-
-
-class GpuInfoCompletePage(GpuProcessTestsPage):
-
-  def __init__(self, story_set, expectations):
-    super(GpuInfoCompletePage, self).__init__(
-      url='file://../../data/gpu/functional_3d_css.html',
-      name='GpuProcess.gpu_info_complete',
-      story_set=story_set,
-      expectations=expectations)
-
-  def Validate(self, tab, results):
-    # Regression test for crbug.com/454906
-    if not tab.browser.supports_system_info:
-      raise legacy_page_test.Failure('Browser must support system info')
-    system_info = tab.browser.GetSystemInfo()
-    if not system_info.gpu:
-      raise legacy_page_test.Failure('Target machine must have a GPU')
-    if not system_info.gpu.aux_attributes:
-      raise legacy_page_test.Failure('Browser must support GPU aux attributes')
-    if not 'gl_renderer' in system_info.gpu.aux_attributes:
-      raise legacy_page_test.Failure(
-          'Browser must have gl_renderer in aux attribs')
-    if len(system_info.gpu.aux_attributes['gl_renderer']) <= 0:
-      raise legacy_page_test.Failure(
-          'Must have a non-empty gl_renderer string')
-
-
-class NoGpuProcessSharedPageState(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(NoGpuProcessSharedPageState, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-
-    if options.browser_type.startswith('android'):
-      # Android doesn't support starting up the browser without any
-      # GPU process. This test is skipped on Android in
-      # gpu_process_expectations.py, but we must at least be able to
-      # bring up the browser in order to detect that the test
-      # shouldn't run. Faking a vendor and device ID can get the
-      # browser into a state where it won't launch.
-      pass
-    elif sys.platform in ('cygwin', 'win32'):
-      # Hit id 34 from kSoftwareRenderingListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x5333')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x8811')
-    elif sys.platform.startswith('linux'):
-      # Hit id 50 from kSoftwareRenderingListJson.
-      options.AppendExtraBrowserArgs('--gpu-no-complete-info-collection')
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=VMware')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=softpipe')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-version="2.1 Mesa 10.1"')
-    elif sys.platform == 'darwin':
-      # Hit id 81 from kSoftwareRenderingListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-os-version=10.7')
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x15ad')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0393')
-
-
-class NoGpuProcessPage(gpu_test_base.PageBase):
-
-  def __init__(self, story_set, expectations):
-    super(NoGpuProcessPage, self).__init__(
-      url='about:blank',
-      name='GpuProcess.no_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=NoGpuProcessSharedPageState,
-      expectations=expectations)
-
-  def Validate(self, tab, results):
-    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
-    has_gpu_process = tab.EvaluateJavaScript(has_gpu_process_js)
-    if has_gpu_process:
-      raise legacy_page_test.Failure('GPU process detected')
-
-
-class SoftwareGpuProcessSharedPageState(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(SoftwareGpuProcessSharedPageState, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-
-    # Hit exception from id 50 from kSoftwareRenderingListJson.
-    options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de')
-    options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1')
-    options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=VMware')
-    options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=SVGA3D')
-    options.AppendExtraBrowserArgs('--gpu-testing-gl-version=2.1 Mesa 10.1')
-
-
-class SoftwareGpuProcessPage(gpu_test_base.PageBase):
-
-  def __init__(self, story_set, expectations):
-    super(SoftwareGpuProcessPage, self).__init__(
-      url='about:blank',
-      name='GpuProcess.software_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=SoftwareGpuProcessSharedPageState,
-      expectations=expectations)
-
-
-class SkipGpuProcessSharedPageState(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(SkipGpuProcessSharedPageState, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-
-    options.AppendExtraBrowserArgs('--disable-gpu')
-    options.AppendExtraBrowserArgs('--skip-gpu-data-loading')
-
-
-class SkipGpuProcessPage(gpu_test_base.PageBase):
-
-  def __init__(self, story_set, expectations):
-    super(SkipGpuProcessPage, self).__init__(
-      url='chrome:gpu',
-      name='GpuProcess.skip_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=SkipGpuProcessSharedPageState,
-      expectations=expectations)
-
-  def Validate(self, tab, results):
-    has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()'
-    has_gpu_process = tab.EvaluateJavaScript(has_gpu_process_js)
-    if has_gpu_process:
-      raise legacy_page_test.Failure('GPU process detected')
-
-
-class DriverBugWorkaroundsShared(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(DriverBugWorkaroundsShared, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-    options.AppendExtraBrowserArgs('--use_gpu_driver_workaround_for_testing')
-
-
-class DriverBugWorkaroundsInGpuProcessPage(DriverBugWorkaroundsTestsPage):
-  def __init__(self, story_set, expectations):
-    super(DriverBugWorkaroundsInGpuProcessPage, self).__init__(
-      name='GpuProcess.driver_bug_workarounds_in_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=DriverBugWorkaroundsShared,
-      expectations=expectations,
-      expected_workaround='use_gpu_driver_workaround_for_testing')
-
-  def Validate(self, tab, results):
-    super(DriverBugWorkaroundsInGpuProcessPage, self).Validate(tab, results)
-
-
-class DriverBugWorkaroundsUponGLRendererShared(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(DriverBugWorkaroundsUponGLRendererShared, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-    if options.browser_type.startswith('android'):
-      # Hit id 108 from kGpuDriverBugListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=' \
-                                     'NVIDIA Corporation')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=NVIDIA Tegra')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-version=' \
-                                     'OpenGL ES 3.1 NVIDIA 343.00')
-    elif sys.platform in ('cygwin', 'win32'):
-      # Hit id 51 and 87 from kGpuDriverBugListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x1002')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x6779')
-      options.AppendExtraBrowserArgs('--gpu-testing-driver-date=11-20-2014')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=Google Inc.')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=ANGLE ' \
-        '(AMD Radeon HD 6450 Direct3D11 vs_5_0 ps_5_0)')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-version=OpenGL ES 2.0 ' \
-        '(ANGLE 2.1.0.0c0d8006a9dd)')
-    elif sys.platform.startswith('linux'):
-      # Hit id 40 from kGpuDriverBugListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x0101')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0102')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=ARM')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=Mali-400 MP')
-    elif sys.platform == 'darwin':
-      # Currently on osx no workaround relies on gl-renderer.
-      pass
-
-
-class DriverBugWorkaroundsUponGLRendererPage(DriverBugWorkaroundsTestsPage):
-  def __init__(self, story_set, expectations, is_platform_android):
-    self.expected_workaround = None
-    self.unexpected_workaround = None
-
-    if is_platform_android:
-      self.expected_workaround = \
-          "unpack_overlapping_rows_separately_unpack_buffer"
-    elif sys.platform in ('cygwin', 'win32'):
-      self.expected_workaround = "texsubimage_faster_than_teximage"
-      self.unexpected_workaround = "disable_d3d11"
-    elif sys.platform.startswith('linux'):
-      self.expected_workaround = "disable_discard_framebuffer"
-    elif sys.platform == 'darwin':
-      pass
-    super(DriverBugWorkaroundsUponGLRendererPage, self).__init__(
-      name='GpuProcess.driver_bug_workarounds_upon_gl_renderer',
-      page_set=story_set,
-      shared_page_state_class=DriverBugWorkaroundsUponGLRendererShared,
-      expectations=expectations,
-      expected_workaround=self.expected_workaround,
-      unexpected_workaround=self.unexpected_workaround)
-
-  def Validate(self, tab, results):
-    super(DriverBugWorkaroundsUponGLRendererPage, self).Validate(tab, results)
-
-
-class IdentifyActiveGpuSharedPageState1(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(IdentifyActiveGpuSharedPageState1, self).__init__(
-      test, finder_options, story_set)
-    opts = finder_options.browser_options
-
-    opts.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x8086')
-    opts.AppendExtraBrowserArgs('--gpu-testing-device-id=0x040a')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-vendor-ids=0x10de')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-device-ids=0x0de1')
-    opts.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=nouveau')
-
-
-class IdentifyActiveGpuPage1(IdentifyActiveGpuPageBase):
-  def __init__(self, story_set, expectations):
-    active_gpu = ['VENDOR = 0x10de, DEVICE= 0x0de1 *ACTIVE*']
-    inactive_gpus = ['VENDOR = 0x8086, DEVICE= 0x040a']
-
-    super(IdentifyActiveGpuPage1, self).__init__(
-      name='GpuProcess.identify_active_gpu1',
-      page_set=story_set,
-      shared_page_state_class=IdentifyActiveGpuSharedPageState1,
-      expectations=expectations,
-      active_gpu=active_gpu,
-      inactive_gpus=inactive_gpus)
-
-  def Validate(self, tab, results):
-    super(IdentifyActiveGpuPage1, self).Validate(tab, results)
-
-
-class IdentifyActiveGpuSharedPageState2(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(IdentifyActiveGpuSharedPageState2, self).__init__(
-      test, finder_options, story_set)
-    opts = finder_options.browser_options
-
-    opts.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x8086')
-    opts.AppendExtraBrowserArgs('--gpu-testing-device-id=0x040a')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-vendor-ids=0x10de')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-device-ids=0x0de1')
-    opts.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=Intel')
-
-
-class IdentifyActiveGpuPage2(IdentifyActiveGpuPageBase):
-  def __init__(self, story_set, expectations):
-    active_gpu = ['VENDOR = 0x8086, DEVICE= 0x040a *ACTIVE*']
-    inactive_gpus = ['VENDOR = 0x10de, DEVICE= 0x0de1']
-
-    super(IdentifyActiveGpuPage2, self).__init__(
-      name='GpuProcess.identify_active_gpu2',
-      page_set=story_set,
-      shared_page_state_class=IdentifyActiveGpuSharedPageState2,
-      expectations=expectations,
-      active_gpu=active_gpu,
-      inactive_gpus=inactive_gpus)
-
-  def Validate(self, tab, results):
-    super(IdentifyActiveGpuPage2, self).Validate(tab, results)
-
-
-class IdentifyActiveGpuSharedPageState3(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(IdentifyActiveGpuSharedPageState3, self).__init__(
-      test, finder_options, story_set)
-    opts = finder_options.browser_options
-
-    opts.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x8086')
-    opts.AppendExtraBrowserArgs('--gpu-testing-device-id=0x040a')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-vendor-ids= \
-                                0x10de;0x1002')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-device-ids= \
-                                0x0de1;0x6779')
-    opts.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=X.Org')
-    opts.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=AMD R600')
-
-
-class IdentifyActiveGpuPage3(IdentifyActiveGpuPageBase):
-  def __init__(self, story_set, expectations):
-    active_gpu = ['VENDOR = 0x1002, DEVICE= 0x6779 *ACTIVE*']
-    inactive_gpus = ['VENDOR = 0x8086, DEVICE= 0x040a', \
-                     'VENDOR = 0x10de, DEVICE= 0x0de1']
-
-    super(IdentifyActiveGpuPage3, self).__init__(
-      name='GpuProcess.identify_active_gpu3',
-      page_set=story_set,
-      shared_page_state_class=IdentifyActiveGpuSharedPageState3,
-      expectations=expectations,
-      active_gpu=active_gpu,
-      inactive_gpus=inactive_gpus)
-
-  def Validate(self, tab, results):
-    super(IdentifyActiveGpuPage3, self).Validate(tab, results)
-
-
-class IdentifyActiveGpuSharedPageState4(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(IdentifyActiveGpuSharedPageState4, self).__init__(
-      test, finder_options, story_set)
-    opts = finder_options.browser_options
-
-    opts.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de')
-    opts.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-vendor-ids=')
-    opts.AppendExtraBrowserArgs('--gpu-testing-secondary-device-ids=')
-    opts.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=nouveau')
-
-
-class IdentifyActiveGpuPage4(IdentifyActiveGpuPageBase):
-  def __init__(self, story_set, expectations):
-    active_gpu = ['VENDOR = 0x10de, DEVICE= 0x0de1 *ACTIVE*']
-    inactive_gpus = []
-
-    super(IdentifyActiveGpuPage4, self).__init__(
-      name='GpuProcess.identify_active_gpu4',
-      page_set=story_set,
-      shared_page_state_class=IdentifyActiveGpuSharedPageState4,
-      expectations=expectations,
-      active_gpu=active_gpu,
-      inactive_gpus=inactive_gpus)
-
-  def Validate(self, tab, results):
-    super(IdentifyActiveGpuPage4, self).Validate(tab, results)
-
-
-class ReadbackWebGLGpuProcessSharedPageState(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(ReadbackWebGLGpuProcessSharedPageState, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-    is_platform_android = options.browser_type.startswith('android')
-
-    if sys.platform.startswith('linux') and not is_platform_android:
-      # Hit id 110 from kSoftwareRenderingListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de')
-      options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=VMware')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=Gallium 0.4 ' \
-        'on llvmpipe (LLVM 3.4, 256 bits)')
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-version="3.0 Mesa 11.2"')
-
-class ReadbackWebGLGpuProcessPage(gpu_test_base.PageBase):
-  def __init__(self, story_set, expectations, is_platform_android):
-    super(ReadbackWebGLGpuProcessPage, self).__init__(
-      url='chrome:gpu',
-      name='GpuProcess.readback_webgl_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=ReadbackWebGLGpuProcessSharedPageState,
-      expectations=expectations)
-    self.is_platform_android = is_platform_android
-
-  def Validate(self, tab, results):
-    if sys.platform.startswith('linux') and not self.is_platform_android:
-      feature_status_js = 'browserBridge.gpuInfo.featureStatus.featureStatus'
-      feature_status_list = tab.EvaluateJavaScript(feature_status_js)
-      result = True
-      for name, status in feature_status_list.items():
-        if name == 'multiple_raster_threads':
-          result = result and status == 'enabled_on'
-        elif name == 'native_gpu_memory_buffers':
-          result = result and status == 'disabled_software'
-        elif name == 'webgl':
-          result = result and status == 'enabled_readback'
-        elif name == 'webgl2':
-          result = result and status == 'unavailable_off'
-        else:
-          result = result and status == 'unavailable_software'
-      if not result:
-        raise legacy_page_test.Failure('WebGL readback setup failed: %s' \
-          % feature_status_list)
-
-
-class HasTransparentVisualsShared(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(HasTransparentVisualsShared, self).__init__(
-      test, finder_options, story_set)
-    options = finder_options.browser_options
-    if sys.platform.startswith('linux'):
-      # Hit id 173 from kGpuDriverBugListJson.
-      options.AppendExtraBrowserArgs('--gpu-testing-gl-version=3.0 Mesa ' \
-                                     '12.1')
-
-class HasTransparentVisualsGpuProcessPage(DriverBugWorkaroundsTestsPage):
-  def __init__(self, story_set, expectations):
-    super(HasTransparentVisualsGpuProcessPage, self).__init__(
-      name='GpuProcess.has_transparent_visuals_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=HasTransparentVisualsShared,
-      expectations=expectations,
-      expected_workaround=None,
-      unexpected_workaround=None)
-
-  def Validate(self, tab, results):
-    if sys.platform.startswith('linux'):
-      super(HasTransparentVisualsGpuProcessPage, self).Validate(tab, results)
-
-
-class NoTransparentVisualsShared(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(NoTransparentVisualsShared, self).__init__(
-      test, finder_options, story_set)
-
-class NoTransparentVisualsGpuProcessPage(DriverBugWorkaroundsTestsPage):
-  def __init__(self, story_set, expectations):
-    super(NoTransparentVisualsGpuProcessPage, self).__init__(
-      name='GpuProcess.no_transparent_visuals_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=NoTransparentVisualsShared,
-      expectations=expectations,
-      expected_workaround=None,
-      unexpected_workaround=None)
-
-  def Validate(self, tab, results):
-    if sys.platform.startswith('linux'):
-      super(NoTransparentVisualsGpuProcessPage, self).Validate(tab, results)
-
-
-class TransferWorkaroundSharedPageState(GpuProcessSharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(TransferWorkaroundSharedPageState, self).__init__(
-      test, finder_options, story_set)
-
-  # Extra browser args need to be added here. Adding them in RunStory would be
-  # too late.
-  def WillRunStory(self, results):
-    if self.WarmUpDone():
-      options = self._finder_options.browser_options
-      options.AppendExtraBrowserArgs('--use_gpu_driver_workaround_for_testing')
-      options.AppendExtraBrowserArgs('--disable-gpu-driver-bug-workarounds')
-
-      # Inject some info to make sure the flag above is effective.
-      if sys.platform == 'darwin':
-        # Hit id 33 from kGpuDriverBugListJson.
-        options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=Imagination')
-      else:
-        # Hit id 5 from kGpuDriverBugListJson.
-        options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de')
-        options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0001')
-        # no multi gpu on Android.
-        if not options.browser_type.startswith('android'):
-          options.AppendExtraBrowserArgs('--gpu-testing-secondary-vendor-ids=')
-          options.AppendExtraBrowserArgs('--gpu-testing-secondary-device-ids=')
-
-      for workaround in self.RecordedWorkarounds():
-        options.AppendExtraBrowserArgs('--' + workaround)
-      options.AppendExtraBrowserArgs('--disable-gl-extensions=' + \
-                                     self.DisabledGLExts())
-    super(TransferWorkaroundSharedPageState, self).WillRunStory(results)
-
-  # self._current_page is None in WillRunStory so do the transfer here.
-  def RunStory(self, results):
-    if self.WarmUpDone():
-      self._current_page.expected_workarounds = self.RecordedWorkarounds()
-      self._current_page.expected_disabled_exts = self.DisabledGLExts()
-      self.AddTestingWorkaround(self._current_page.expected_workarounds)
-    super(TransferWorkaroundSharedPageState, self).RunStory(results)
-
-  def WarmUpDone(self):
-    return self._previous_page is not None and \
-           self.RecordedWorkarounds() is not None
-
-  def RecordedWorkarounds(self):
-    return self._previous_page.recorded_workarounds
-
-  def DisabledGLExts(self):
-    return self._previous_page.recorded_disabled_exts
-
-  def AddTestingWorkaround(self, workarounds):
-    if workarounds is not None:
-      workarounds.append('use_gpu_driver_workaround_for_testing')
-
-
-class EqualBugWorkaroundsPage(EqualBugWorkaroundsBasePage):
-  def __init__(self, story_set, expectations):
-    super(EqualBugWorkaroundsPage, self).__init__(
-      name='GpuProcess.equal_bug_workarounds_in_browser_and_gpu_process',
-      page_set=story_set,
-      shared_page_state_class=TransferWorkaroundSharedPageState,
-      expectations=expectations)
-    self.recorded_workarounds = None
-    self.recorded_disabled_exts = None
-
-  def Validate(self, tab, results):
-    recorded_info = super(EqualBugWorkaroundsPage, self).Validate(tab, results)
-    gpu_list, disabled_gl_extensions = recorded_info
-
-    self.recorded_workarounds = gpu_list
-    self.recorded_disabled_exts = disabled_gl_extensions
-
-
-class OnlyOneWorkaroundPage(EqualBugWorkaroundsBasePage):
-  def __init__(self, story_set, expectations):
-    super(OnlyOneWorkaroundPage, self).__init__(
-      name='GpuProcess.only_one_workaround',
-      page_set=story_set,
-      shared_page_state_class=TransferWorkaroundSharedPageState,
-      expectations=expectations)
-    self.expected_workarounds = None
-    self.expected_disabled_exts = None
-
-  def Validate(self, tab, results):
-    # Requires EqualBugWorkaroundsPage to succeed. If it has failed then just
-    # pass to not overload the logs.
-    if self.expected_workarounds is None:
-      return
-
-    recorded_info = super(OnlyOneWorkaroundPage, self).Validate(tab, results)
-    gpu_list, disabled_gl_extensions = recorded_info
-
-    diff = set(self.expected_workarounds).symmetric_difference(set(gpu_list))
-    if len(diff) > 0:
-      print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript('document.body.innerHTML')
-      raise legacy_page_test.Failure(
-        'GPU process and expected list of driver bug'
-        'workarounds are not equal: %s != %s, diff: %s' %
-        (self.expected_workarounds, gpu_list, list(diff)))
-
-    if self.expected_disabled_exts != disabled_gl_extensions:
-      print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript('document.body.innerHTML')
-      raise legacy_page_test.Failure(
-        'The expected disabled gl extensions are '
-        'incorrect: %s != %s:' %
-        (self.expected_disabled_exts, disabled_gl_extensions))
-
-
-class GpuProcessTestsStorySet(story_set_module.StorySet):
-
-  """ Tests that accelerated content triggers the creation of a GPU process """
-
-  def __init__(self, expectations, is_platform_android):
-    super(GpuProcessTestsStorySet, self).__init__(
-      serving_dirs=set(['../../../../content/test/data']))
-
-    urls_and_names_list = [
-      ('file://../../data/gpu/functional_canvas_demo.html',
-       'GpuProcess.canvas2d'),
-      ('file://../../data/gpu/functional_3d_css.html',
-       'GpuProcess.css3d'),
-      ('file://../../data/gpu/functional_webgl.html',
-       'GpuProcess.webgl')
-    ]
-
-    for url, name in urls_and_names_list:
-      self.AddStory(GpuProcessTestsPage(url, name, self, expectations))
-
-    self.AddStory(FunctionalVideoPage(self, expectations))
-    self.AddStory(GpuInfoCompletePage(self, expectations))
-    self.AddStory(NoGpuProcessPage(self, expectations))
-    self.AddStory(DriverBugWorkaroundsInGpuProcessPage(self, expectations))
-    self.AddStory(ReadbackWebGLGpuProcessPage(self, expectations,
-                                              is_platform_android))
-    self.AddStory(DriverBugWorkaroundsUponGLRendererPage(self, expectations,
-                                                         is_platform_android))
-    self.AddStory(EqualBugWorkaroundsPage(self, expectations))
-    self.AddStory(OnlyOneWorkaroundPage(self, expectations))
-
-    if not is_platform_android:
-      self.AddStory(SkipGpuProcessPage(self, expectations))
-      self.AddStory(HasTransparentVisualsGpuProcessPage(self, expectations))
-      self.AddStory(NoTransparentVisualsGpuProcessPage(self, expectations))
-
-      # There is no Android multi-gpu configuration and the helper
-      # gpu_info_collector.cc::IdentifyActiveGPU is not even called.
-      self.AddStory(IdentifyActiveGpuPage1(self, expectations))
-      self.AddStory(IdentifyActiveGpuPage2(self, expectations))
-      self.AddStory(IdentifyActiveGpuPage3(self, expectations))
-      self.AddStory(IdentifyActiveGpuPage4(self, expectations))
-
-      # There is currently no entry in kSoftwareRenderingListJson that enables
-      # a software GL driver on Android.
-      self.AddStory(SoftwareGpuProcessPage(self, expectations))
-
-  @property
-  def allow_mixed_story_states(self):
-    # Return True here in order to be able to run pages with different browser
-    # command line arguments.
-    return True
diff --git a/content/test/gpu/page_sets/page_set_unittest.py b/content/test/gpu/page_sets/page_set_unittest.py
deleted file mode 100644
index f10d80d..0000000
--- a/content/test/gpu/page_sets/page_set_unittest.py
+++ /dev/null
@@ -1,15 +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.
-
-import os
-
-from telemetry.testing import story_set_smoke_test
-
-
-class StorySetUnitTest(story_set_smoke_test.StorySetSmokeTest):
-
-  def testSmoke(self):
-    story_sets_dir = os.path.dirname(os.path.realpath(__file__))
-    top_level_dir = os.path.dirname(story_sets_dir)
-    self.RunSmokeTest(story_sets_dir, top_level_dir)
diff --git a/docs/testing/writing_layout_tests.md b/docs/testing/writing_layout_tests.md
index f2767c2..13d563b 100644
--- a/docs/testing/writing_layout_tests.md
+++ b/docs/testing/writing_layout_tests.md
@@ -338,7 +338,6 @@
 ```html
 <!doctype html>
 <meta charset="utf-8">
-<title>JavaScript: the true literal</title>
 <link rel="help" href="https://tc39.github.io/ecma262/#sec-boolean-literals">
 <meta name="assert" value="The true literal is equal to itself and immutable">
 <script src="/resources/testharness.js"></script>
@@ -375,9 +374,7 @@
 
 Some points that are not immediately obvious from the example:
 
-* The `<meta name="assert">` describes the purpose of the entire file, and
-  is not redundant to `<title>`. Don't add a `<meta name="assert">` when the
-  information in the `<title>` is sufficient.
+* The `<meta name="assert">` describes the purpose of the entire file.
 * When calling an `assert_` function that compares two values, the first
   argument is the actual value (produced by the functionality being tested), and
   the second argument is the expected value (known good, golden). The order
@@ -393,9 +390,6 @@
   redundant.
     * Do not start test case descriptions with redundant terms like "Testing"
       or "Test for".
-    * Test files with a single test case should omit the test case description.
-      The file's `<title>` should be sufficient to describe the scenario being
-      tested.
 * Asynchronous tests have a few subtleties.
     * The `async_test` wrapper calls its function with a test case argument that
       is used to signal when the test case is done, and to connect assertion
@@ -516,7 +510,6 @@
 ```html
 <!doctype html>
 <meta charset="utf-8">
-<title>DOM: Event.isTrusted for UI events</title>
 <link rel="help" href="https://dom.spec.whatwg.org/#dom-event-istrusted">
 <link rel="help" href="https://dom.spec.whatwg.org/#constructing-events">
 <meta name="assert"
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.cc b/net/base/registry_controlled_domains/registry_controlled_domain.cc
index 5f29f89..37775828 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain.cc
+++ b/net/base/registry_controlled_domains/registry_controlled_domain.cc
@@ -365,6 +365,12 @@
          SameDomainOrHost(origin1, origin2.value(), filter);
 }
 
+bool SameDomainOrHost(const GURL& gurl,
+                      const url::Origin& origin,
+                      PrivateRegistryFilter filter) {
+  return SameDomainOrHost(gurl.host_piece(), origin.host(), filter);
+}
+
 size_t GetRegistryLength(
     const GURL& gurl,
     UnknownRegistryFilter unknown_filter,
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.h b/net/base/registry_controlled_domains/registry_controlled_domain.h
index 429a577..9f3101a 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain.h
+++ b/net/base/registry_controlled_domains/registry_controlled_domain.h
@@ -204,6 +204,9 @@
 NET_EXPORT bool SameDomainOrHost(const url::Origin& origin1,
                                  const base::Optional<url::Origin>& origin2,
                                  PrivateRegistryFilter filter);
+NET_EXPORT bool SameDomainOrHost(const GURL& gurl,
+                                 const url::Origin& origin,
+                                 PrivateRegistryFilter filter);
 
 // Finds the length in bytes of the registrar portion of the host in the
 // given GURL.  Returns std::string::npos if the GURL is invalid or has no
diff --git a/net/data/ftp/dir-listing-ls-34 b/net/data/ftp/dir-listing-ls-34
deleted file mode 100644
index 1cd77dd..0000000
--- a/net/data/ftp/dir-listing-ls-34
+++ /dev/null
@@ -1,2 +0,0 @@
--rw-rw-r--   1 ftpuser  ftpusers    1761280 Dec 20  2002 controle_embarqu‚_avec_labview_real_time_et_compactfieldpoint.ppt
--rw-rw-r--   1 ftpuser  ftpusers     329216 Dec 20  2002 optimisez_l'acquisition_de_donn‚es_sous_labview.ppt
diff --git a/net/data/ftp/dir-listing-ls-34.expected b/net/data/ftp/dir-listing-ls-34.expected
deleted file mode 100644
index d197cb3..0000000
--- a/net/data/ftp/dir-listing-ls-34.expected
+++ /dev/null
@@ -1,17 +0,0 @@
--
-controle_embarqu�_avec_labview_real_time_et_compactfieldpoint.ppt
-1761280
-2002
-12
-20
-0
-0
-
--
-optimisez_l'acquisition_de_donnFs_sous_labview.ppt
-329216
-2002
-12
-20
-0
-0
diff --git a/net/ftp/ftp_directory_listing_parser.cc b/net/ftp/ftp_directory_listing_parser.cc
index 1096ae0..151c1b9 100644
--- a/net/ftp/ftp_directory_listing_parser.cc
+++ b/net/ftp/ftp_directory_listing_parser.cc
@@ -28,7 +28,7 @@
                   std::vector<FtpDirectoryListingEntry>* entries) {
   for (size_t i = 0; i < entries->size(); i++) {
     if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(),
-                               base::OnStringConversionError::SUBSTITUTE,
+                               base::OnStringConversionError::FAIL,
                                &entries->at(i).raw_name)) {
       return ERR_ENCODING_CONVERSION_FAILED;
     }
@@ -91,7 +91,7 @@
 
   base::string16 converted_text;
   if (base::CodepageToUTF16(text, encoding_name,
-                            base::OnStringConversionError::SUBSTITUTE,
+                            base::OnStringConversionError::FAIL,
                             &converted_text)) {
     const char* const kNewlineSeparators[] = {"\n", "\r\n"};
 
diff --git a/net/ftp/ftp_directory_listing_parser_unittest.cc b/net/ftp/ftp_directory_listing_parser_unittest.cc
index a7f5bcf..dc75ade5 100644
--- a/net/ftp/ftp_directory_listing_parser_unittest.cc
+++ b/net/ftp/ftp_directory_listing_parser_unittest.cc
@@ -158,7 +158,6 @@
     {"dir-listing-ls-31", OK},
     {"dir-listing-ls-32", OK},  // busybox
     {"dir-listing-ls-33", OK},
-    {"dir-listing-ls-34", OK},  // Broken encoding. Should not fail.
 
     {"dir-listing-netware-1", OK},
     {"dir-listing-netware-2", OK},
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index d48234855..9b416e9 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -152,10 +152,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -551,10 +551,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -884,10 +884,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1241,10 +1241,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1567,10 +1567,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1893,10 +1893,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -2242,10 +2242,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -2596,10 +2596,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -2963,10 +2963,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -3356,10 +3356,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -3749,10 +3749,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -4142,10 +4142,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -4595,10 +4595,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -5014,10 +5014,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -5420,10 +5420,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -5751,10 +5751,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -6095,10 +6095,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -6468,10 +6468,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -6833,10 +6833,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -7196,10 +7196,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -7582,10 +7582,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -8008,10 +8008,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -8413,10 +8413,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -8776,10 +8776,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -9859,10 +9859,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -10296,10 +10296,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -10749,10 +10749,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -11225,10 +11225,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -11688,10 +11688,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -12102,10 +12102,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -12539,10 +12539,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -12949,10 +12949,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -13443,10 +13443,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -13896,10 +13896,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -14349,10 +14349,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -14920,10 +14920,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -15396,10 +15396,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -15836,10 +15836,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -16324,10 +16324,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json
index 32c48b8e..27ebb49 100644
--- a/testing/buildbot/chromium.gpu.json
+++ b/testing/buildbot/chromium.gpu.json
@@ -114,10 +114,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -412,10 +412,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -694,10 +694,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -992,10 +992,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1279,10 +1279,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1590,10 +1590,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -1879,10 +1879,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -2177,10 +2177,10 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
-        "isolate_name": "telemetry_gpu_test",
+        "isolate_name": "telemetry_gpu_integration_test",
         "name": "gpu_process_launch_tests",
         "override_compile_targets": [
-          "telemetry_gpu_test_run"
+          "telemetry_gpu_integration_test_run"
         ],
         "swarming": {
           "can_use_on_swarming_builders": true,
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
index 8ac073d1..6c85d3f 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -144,41 +144,29 @@
 # layout_test_runtime_flags_.have_top_loading_frame()
 crbug.com/645641 imported/wpt/html/syntax/parsing/html5lib_tests19.html [ Crash Failure ]
 
-# https://crbug.com/670409 - multiple virtual/mojo-loading/http/tests fail with OOPIFs
-# The failures below seem unique / specific to the combination of
-# 1) --site-per-process mode and 2) virtual/mojo-loading virtual test suite.
-crbug.com/670409 virtual/mojo-loading/http/tests/feature-policy/vibrate-enabledforall.php [ Failure ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/command-line-api-inspect.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/debugger/fetch-breakpoints.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector-enabled/reattach-after-editing-styles.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector-enabled/shadow-dom-rules-restart.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/network/async-xhr-json-mime-type.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/network/network-filters.html [ Failure ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/network/preview-searchable.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/persistence/persistence-tabbed-editor-tabs-order.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/search/source-frame-replace-2.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/tracing/timeline-script-parse.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/media/media-source/mediasource-seek-beyond-duration.html [ Failure ]
-crbug.com/670409 virtual/mojo-loading/http/tests/misc/webtiming-no-origin.html [ Crash ]
-crbug.com/670409 virtual/mojo-loading/http/tests/misc/webtiming-ssl.php [ Crash ]
-crbug.com/670409 virtual/mojo-loading/http/tests/permissions/chromium/test-request-window.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/security/create-document-unique-origin.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure ]
-crbug.com/670409 virtual/mojo-loading/http/tests/serviceworker/foreign-fetch-basics.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/serviceworker/foreign-fetch-cors.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/xmlhttprequest/response-text.html [ Failure ]
+# http/ flaky tests w/ --site-per-process
+crbug.com/678481 http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
+crbug.com/678481 virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout Pass ]
+crbug.com/678482 http/tests/inspector/debugger/fetch-breakpoints.html [ Timeout Pass ]
+crbug.com/678482 virtual/mojo-loading/http/tests/inspector/debugger/fetch-breakpoints.html [ Timeout Pass ]
+crbug.com/678484 http/tests/inspector-enabled/reattach-after-editing-styles.html [ Timeout Pass ]
+crbug.com/678484 virtual/mojo-loading/http/tests/inspector-enabled/reattach-after-editing-styles.html [ Timeout Pass ]
+crbug.com/678485 http/tests/inspector-enabled/shadow-dom-rules-restart.html [ Timeout ]
+crbug.com/678485 virtual/mojo-loading/http/tests/inspector-enabled/shadow-dom-rules-restart.html [ Timeout ]
+crbug.com/678491 http/tests/misc/webtiming-no-origin.html [ Crash Pass ]
+crbug.com/678491 virtual/mojo-loading/http/tests/misc/webtiming-no-origin.html [ Crash Pass ]
 
-# https://crbug.com/670409 - multiple virtual/mojo-loading/http/tests fail with OOPIFs
-# The failures below are mentioned in other expectation files (i.e. in
-# SlowTests or RandomOrderExpectations), but since expectations are
-# unfortunately not inherited automatically (e.g. see https://crbug.com/594216)
-# we need to repeat the expectations below.
-crbug.com/670409 virtual/mojo-loading/http/tests/inspector/network/network-datareceived.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/perf/large-inlined-script.html [ Timeout ]
-crbug.com/670409 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/require-sri-for/require-sri-for-script-preload-allowed.php [ Failure ]
-crbug.com/670409 virtual/mojo-loading/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html [ Timeout ]
+# These tests sometimes fail on usual bots but crash w/ --site-per-process.
+crbug.com/678492 http/tests/misc/webtiming-ssl.php [ Crash ]
+crbug.com/678492 virtual/mojo-loading/http/tests/misc/webtiming-ssl.php [ Crash ]
+
+# Slow tests. These are listed in SlowTests listed here also because
+# expectations are unfortunately not inherited automatically (e.g. see
+# https://crbug.com/594216)
+crbug.com/451577 http/tests/inspector/network/network-datareceived.html [ Timeout Pass ]
+crbug.com/451577 virtual/mojo-loading/http/tests/inspector/network/network-datareceived.html [ Timeout Pass ]
+crbug.com/24182 http/tests/perf/large-inlined-script.html [ Timeout Pass ]
+crbug.com/24182 virtual/mojo-loading/http/tests/perf/large-inlined-script.html [ Timeout Pass ]
 
 # https://crbug.com/672570: autoplay-crossorigin.html fails w/ --site-per-process
 crbug.com/672570 http/tests/media/autoplay-crossorigin.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5d8d2a7d..6552fc2 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -182,22 +182,17 @@
 # LayoutNG - is a new layout system for Blink.
 
 #### css2.1/20110323
-#### Passed: 175
-#### Skipped: 234
+#### Passed: 202
+#### Skipped: 207
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-001.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-002.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-003.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-004.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-005.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-006.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-007.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-008.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-009.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-010.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-011.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-height-012.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-001.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-002.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-003.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-004.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-005.htm [ Skip ]
@@ -207,22 +202,10 @@
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-010.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-011.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-max-height-012.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-001.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-002.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-003.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-004.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-005.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-006.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-007.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-008.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-009.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-010.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-011.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-012.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-013.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-014.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-015.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-016.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-017.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-018.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-non-replaced-width-019.htm [ Skip ]
@@ -237,9 +220,6 @@
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-004.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-005.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-007.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-008.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-009.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-010.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-011.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-012.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-014.htm [ Skip ]
@@ -248,13 +228,11 @@
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-018.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-019.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-021.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-022.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-023.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-024.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-025.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-026.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-028.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-029.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-030.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-031.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-height-032.htm [ Skip ]
@@ -284,19 +262,11 @@
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-width-071.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/absolute-replaced-width-076.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-001.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004a.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004b.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004c.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004d.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004e.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-004f.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-005b.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-005d.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-007.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-009a.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-009b.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-009e.htm [ Skip ]
-crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-containing-block-initial-009f.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-non-replaced-width-margin-000.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/abspos-replaced-width-margin-000.htm [ Skip ]
 crbug.com/635619 virtual/layout_ng/css2.1/20110323/background-intrinsic-001.htm [ Skip ]
@@ -769,8 +739,6 @@
 crbug.com/248938 [ Win Debug ] virtual/threaded/animations/transition-and-animation-2.html [ Timeout ]
 crbug.com/248938 virtual/threaded/animations/change-one-anim.html [ Failure Pass ]
 crbug.com/326139 crbug.com/390125 media/video-frame-accurate-seek.html [ Failure Pass ]
-crbug.com/248938 virtual/threaded/transitions/cancel-transition.html [ Pass Failure ]
-crbug.com/248938 [ Linux ] virtual/threaded/transitions/move-after-transition.html [ Pass Timeout ]
 crbug.com/248938 virtual/threaded/transitions/start-transform-transition.html [ Pass Failure ]
 crbug.com/248938 virtual/threaded/animations/animation-iteration-event-destroy-renderer.html [ Pass Timeout ]
 crbug.com/248938 virtual/threaded/animations/transition-and-animation-3.html [ Pass Timeout ]
@@ -2241,7 +2209,7 @@
 crbug.com/663855 fast/text/ellipsis-rtl-text-in-ltr-flow-underline.html [ Pass Failure ]
 crbug.com/663855 fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition.html [ Pass Failure ]
 crbug.com/663855 fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition.html [ Pass Failure ]
-crbug.com/663855 [ Win ] fast/text/ellipsis-stroked.html [ Pass Failure ]
+crbug.com/663855 fast/text/ellipsis-stroked.html [ Pass Failure ]
 crbug.com/663858 fast/text/emphasis.html [ Pass Failure ]
 crbug.com/663858 fast/text/emphasis-vertical.html [ Pass Failure ]
 crbug.com/663872 http/tests/fetch/serviceworker-proxied/thorough/cookie-nocors.html [ Pass Failure ]
@@ -2391,4 +2359,23 @@
 crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ]
 crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ]
 
-crbug.com/678388 [ Trusty Mac10.10 Mac10.11 Debug ] fast/text/ellipsis-stroked.html [ Pass Failure ]
+crbug.com/678486 http/tests/inspector/network/network-filters.html [ Pass Failure ]
+crbug.com/678486 virtual/mojo-loading/http/tests/inspector/network/network-filters.html [ Pass Failure ]
+crbug.com/678487 http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
+crbug.com/678487 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
+crbug.com/678488 http/tests/inspector/search/source-frame-replace-2.html [ Timeout Pass ]
+crbug.com/678488 virtual/mojo-loading/http/tests/inspector/search/source-frame-replace-2.html [ Timeout Pass ]
+crbug.com/678489 http/tests/inspector/tracing/timeline-script-parse.html [ Timeout Pass ]
+crbug.com/678489 virtual/mojo-loading/http/tests/inspector/tracing/timeline-script-parse.html [ Timeout Pass ]
+crbug.com/678490 http/tests/media/media-source/mediasource-seek-beyond-duration.html [ Failure Pass ]
+crbug.com/678490 virtual/mojo-loading/http/tests/media/media-source/mediasource-seek-beyond-duration.html [ Failure Pass ]
+crbug.com/678492 http/tests/misc/webtiming-ssl.php [ Failure Pass ]
+crbug.com/678492 virtual/mojo-loading/http/tests/misc/webtiming-ssl.php [ Failure Pass ]
+crbug.com/678493 http/tests/permissions/chromium/test-request-window.html [ Timeout Pass ]
+crbug.com/678493 virtual/mojo-loading/http/tests/permissions/chromium/test-request-window.html [ Timeout Pass ]
+crbug.com/678496 http/tests/serviceworker/foreign-fetch-basics.html [ Timeout Pass ]
+crbug.com/678496 virtual/mojo-loading/http/tests/serviceworker/foreign-fetch-basics.html [ Timeout Pass ]
+crbug.com/678498 http/tests/serviceworker/foreign-fetch-cors.html [ Timeout Pass ]
+crbug.com/678498 virtual/mojo-loading/http/tests/serviceworker/foreign-fetch-cors.html [ Timeout Pass ]
+crbug.com/678499 http/tests/security/contentSecurityPolicy/require-sri-for/require-sri-for-script-preload-allowed.php [ Failure Pass ]
+crbug.com/678499 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/require-sri-for/require-sri-for-script-preload-allowed.php [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.png
deleted file mode 100644
index 36c959e9..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.txt
deleted file mode 100644
index a889a11..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/transitions/move-after-transition-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x162
-  LayoutBlockFlow {HTML} at (0,0) size 800x162
-    LayoutBlockFlow {BODY} at (8,16) size 784x138
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 384x19
-          text run at (0,0) width 384: "At the end of the test the green box should obscure the red box."
-      LayoutBlockFlow {DIV} at (0,138) size 784x0
-layer at (8,52) size 402x102
-  LayoutBlockFlow (relative positioned) {DIV} at (0,36) size 402x102 [border: (1px solid #000000)]
-layer at (159,53) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (151,1) size 100x100 [bgcolor=#FF0000]
-layer at (9,53) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (1,1) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.png
deleted file mode 100644
index 36c959e9..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.txt
deleted file mode 100644
index a889a11..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/transitions/move-after-transition-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x162
-  LayoutBlockFlow {HTML} at (0,0) size 800x162
-    LayoutBlockFlow {BODY} at (8,16) size 784x138
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 384x19
-          text run at (0,0) width 384: "At the end of the test the green box should obscure the red box."
-      LayoutBlockFlow {DIV} at (0,138) size 784x0
-layer at (8,52) size 402x102
-  LayoutBlockFlow (relative positioned) {DIV} at (0,36) size 402x102 [border: (1px solid #000000)]
-layer at (159,53) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (151,1) size 100x100 [bgcolor=#FF0000]
-layer at (9,53) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (1,1) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.png
deleted file mode 100644
index d6fca0a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.txt
deleted file mode 100644
index 3cf12f5..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/transitions/move-after-transition-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x160
-  LayoutBlockFlow {HTML} at (0,0) size 800x160
-    LayoutBlockFlow {BODY} at (8,16) size 784x136
-      LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 406x18
-          text run at (0,0) width 406: "At the end of the test the green box should obscure the red box."
-      LayoutBlockFlow {DIV} at (0,136) size 784x0
-layer at (8,50) size 402x102
-  LayoutBlockFlow (relative positioned) {DIV} at (0,34) size 402x102 [border: (1px solid #000000)]
-layer at (159,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (151,1) size 100x100 [bgcolor=#FF0000]
-layer at (9,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (1,1) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.png
deleted file mode 100644
index d6fca0a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.txt
deleted file mode 100644
index 3cf12f5..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/transitions/move-after-transition-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x160
-  LayoutBlockFlow {HTML} at (0,0) size 800x160
-    LayoutBlockFlow {BODY} at (8,16) size 784x136
-      LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 406x18
-          text run at (0,0) width 406: "At the end of the test the green box should obscure the red box."
-      LayoutBlockFlow {DIV} at (0,136) size 784x0
-layer at (8,50) size 402x102
-  LayoutBlockFlow (relative positioned) {DIV} at (0,34) size 402x102 [border: (1px solid #000000)]
-layer at (159,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (151,1) size 100x100 [bgcolor=#FF0000]
-layer at (9,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (1,1) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.png b/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.png
deleted file mode 100644
index 9c7bc24..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.txt b/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.txt
deleted file mode 100644
index 3f5f2f8..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/transitions/move-after-transition-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x160
-  LayoutBlockFlow {HTML} at (0,0) size 800x160
-    LayoutBlockFlow {BODY} at (8,16) size 784x136
-      LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 406x17
-          text run at (0,0) width 406: "At the end of the test the green box should obscure the red box."
-      LayoutBlockFlow {DIV} at (0,136) size 784x0
-layer at (8,50) size 402x102
-  LayoutBlockFlow (relative positioned) {DIV} at (0,34) size 402x102 [border: (1px solid #000000)]
-layer at (159,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (151,1) size 100x100 [bgcolor=#FF0000]
-layer at (9,51) size 100x100
-  LayoutBlockFlow (positioned) {DIV} at (1,1) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/transitions/cancel-transition-expected.txt b/third_party/WebKit/LayoutTests/transitions/cancel-transition-expected.txt
deleted file mode 100644
index 3ac9d81..0000000
--- a/third_party/WebKit/LayoutTests/transitions/cancel-transition-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Test removes the transition properties while the transition is running, then adds them back in. If working properly the transitions should start from the beginning. But there was a bug that would cause the transition to continue to run (although with no visible effect). So when you restarted, it would pick up where it left off.
-
-left
-translate
-left: PASS, transform: PASS
diff --git a/third_party/WebKit/LayoutTests/transitions/cancel-transition.html b/third_party/WebKit/LayoutTests/transitions/cancel-transition.html
index 9b7a489..7ff24f2 100644
--- a/third_party/WebKit/LayoutTests/transitions/cancel-transition.html
+++ b/third_party/WebKit/LayoutTests/transitions/cancel-transition.html
@@ -1,7 +1,9 @@
 <!DOCTYPE html>
-
 <html>
 <head>
+    <meta charset="utf-8">
+    <script src="../resources/testharness.js"></script>
+    <script src="../resources/testharnessreport.js"></script>
     <style>
         #container {
             width: 700px;
@@ -19,86 +21,51 @@
         #container.run #left {
             left: 450px;
             transition-property: left;
-            transition-duration: 1s;
+            transition-duration: 4s;
             transition-timing-function: linear;
         }
         #container.run #translate {
             transform: translate(400px, 0px);
             transition-property: transform;
-            transition-duration: 1s;
+            transition-duration: 4s;
+            transition-delay: -1s;
             transition-timing-function: linear;
         }
     </style>
-    <script>
-        if (window.testRunner) {
-            testRunner.dumpAsText();
-            testRunner.waitUntilDone();
-        }
-
-        function isEqual(actual, desired, tolerance)
-        {
-            var diff = Math.abs(actual - desired);
-            return diff < tolerance;
-        }
-
-        function cancelTransition()
-        {
-            document.getElementById("container").className = "";
-            document.body.offsetHeight;
-        }
-
-        function restartTransition()
-        {
-            document.getElementById("container").className = "run";
-            document.body.offsetHeight;
-            // The transition should restart at the beginning here. After 250 it should be halfway done.
-            setTimeout(check, 500);
-        }
-
-        function check()
-        {
-            var left = parseFloat(window.getComputedStyle(document.getElementById('left')).left);
-            result = "left: ";
-            if (!isEqual(left, 250, 50))
-                result += "<span style='color:red'>FAIL (was: " + left + ", expected: 250)</span>";
-            else
-                result += "<span style='color:green'>PASS</span>";
-
-            result += ", transform: ";
-
-            var transform = window.getComputedStyle(document.getElementById('translate')).transform;
-            transform = transform.split("(");
-            transform = transform[1].split(",");
-            if (!isEqual(transform[4], 200, 50))
-                result += "<span style='color:red'>FAIL (was: " + transform[4] + ", expected: 200)</span>";
-            else
-                result += "<span style='color:green'>PASS</span>";
-
-            document.getElementById('result').innerHTML = result;
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }
-
-        function start()
-        {
-            document.getElementById("container").className = "run";
-            document.body.offsetHeight;
-            setTimeout("cancelTransition()", 200);
-            setTimeout("restartTransition()", 400);
-        }
-    </script>
 </head>
-<body onload="start()">
-<p>
-    Test removes the transition properties while the transition is running, then adds them back in.
-    If working properly the transitions should start from the beginning. But there was a bug that
-    would cause the transition to continue to run (although with no visible effect). So when you
-    restarted, it would pick up where it left off.
-</p>
-<div id="container">
-    <div id="left">left</div>
-    <div id="translate">translate</div>
-</div>
-<div id="result"></div>
+<body>
+    <!--
+        Test removes the transition properties while the transition is running, then adds them back in.
+        If working properly the transitions should start from the beginning. But there was a bug that
+        would cause the transition to continue to run (although with no visible effect). So when you
+        restarted, it would pick up where it left off.
+        https://bugs.webkit.org/show_bug.cgi?id=26163
+    -->
+    <div id="container">
+        <div id="left">left</div>
+        <div id="translate">translate</div>
+    </div>
+    <script>
+        'use strict';
+
+        function waitSeveralFrames() {
+            return container.animate({opacity: ['1', '1']}, 100).finished;
+        }
+
+        async_test(t => {
+            getComputedStyle(container).height; // force style recalc
+            container.className = 'run';
+            getComputedStyle(container).height; // force style recalc - transition will start
+            waitSeveralFrames().then(t.step_func(() => {
+                assert_greater_than(parseFloat(getComputedStyle(left).left), 50);
+                container.className = '';
+                getComputedStyle(container).height; // force style recalc - transition will cancel
+            })).then(waitSeveralFrames).then(t.step_func_done(() => {
+                container.className = 'run'; // restart transition
+                assert_equals(getComputedStyle(left).left, '50px');
+                assert_equals(getComputedStyle(translate).transform, 'matrix(1, 0, 0, 1, 100, 0)');
+            }));
+        }, 'Transition restarts from the beginning');
+    </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/transitions/move-after-transition-expected.html b/third_party/WebKit/LayoutTests/transitions/move-after-transition-expected.html
new file mode 100644
index 0000000..2d0f3b85
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/transitions/move-after-transition-expected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    #container {
+      position: relative;
+      width: 400px;
+      height: 100px;
+      border: 1px solid  black;
+    }
+    .box {
+      position: absolute;
+      width: 100px;
+      height: 100px;
+      background-color: green;
+    }
+    .indicator {
+      left: 150px;
+      top: 0;
+      background-color: red;
+    }
+    #tester {
+      transform-style: preserve-3d;
+      transform: translateX(150px);
+    }
+   </style>
+</head>
+<body>
+
+  <p>At the end of the test the green box should obscure the red box.</p>
+  <div id="container">
+    <div class="indicator box"></div>
+    <div id="tester" class="hardware box"></div>
+  </div>
+
+  <div id="result">
+  </div>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/transitions/move-after-transition.html b/third_party/WebKit/LayoutTests/transitions/move-after-transition.html
index 6774e8e..232bcf4 100644
--- a/third_party/WebKit/LayoutTests/transitions/move-after-transition.html
+++ b/third_party/WebKit/LayoutTests/transitions/move-after-transition.html
@@ -9,14 +9,12 @@
       height: 100px;
       border: 1px solid  black;
     }
-    
     .box {
       position: absolute;
       width: 100px;
       height: 100px;
       background-color: green;
     }
-    
     .indicator {
       left: 150px;
       top: 0;
@@ -25,30 +23,33 @@
     #container.moved .software {
       left: 300px;
     }
-
     #container.moved .hardware {
       transform: translateX(300px);
     }
-
     .hardware {
       transform-style: preserve-3d;
-      -webkit-transition: transform 300ms linear;
+      transition: transform 300ms linear;
       transform: translateX(0);
     }
-
    </style>
-   <script src="../animations/resources/animation-test-helpers.js"></script>
    <script type="text/javascript">
+    'use strict';
+    function waitForCompositor() {
+      var container = document.getElementById('container');
+      return container.animate({opacity: [1, 1]}, 1).ready;
+    }
 
     function testEnded()
     {
       var testDiv = document.getElementById('tester');
-      testDiv.style.webkitTransitionProperty = 'none';
-      testDiv.style.webkitTransitionDuration = '0';
+      testDiv.style.transitionProperty = 'none';
+      testDiv.style.transitionDuration = '0';
 
-      testDiv.style.webkitTransform = 'translateX(150px)';
-      if (window.testRunner)
-        testRunner.notifyDone();
+      testDiv.style.transform = 'translateX(150px)';
+      waitForCompositor().then(() => {
+        if (window.testRunner)
+          testRunner.notifyDone();
+      });
     }
     
     function startTest()
@@ -56,7 +57,8 @@
       if (window.testRunner)
         testRunner.waitUntilDone();
 
-      document.getElementById('tester').addEventListener('webkitTransitionEnd', testEnded, false);
+      document.body.offsetHeight; // Force style recalc
+      document.getElementById('tester').addEventListener('transitionend', testEnded, false);
       document.getElementById('container').className = 'moved';
     }
     
diff --git a/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h b/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
index ba58a2bc..dd1f6dd 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
@@ -187,13 +187,13 @@
       clearException();
     }
   }
-
   void throwDOMException(ExceptionCode, const String& message) override;
   void throwTypeError(const String& message) override;
   void throwSecurityError(const String& sanitizedMessage,
                           const String& unsanitizedMessage) override;
   void throwRangeError(const String& message) override;
   void rethrowV8Exception(v8::Local<v8::Value>) override;
+  ExceptionState& returnThis() { return *this; }
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ExceptionStatePlaceholder.h b/third_party/WebKit/Source/bindings/core/v8/ExceptionStatePlaceholder.h
index 8594909..83c10d7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ExceptionStatePlaceholder.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ExceptionStatePlaceholder.h
@@ -38,27 +38,7 @@
 
 namespace blink {
 
-class IgnorableExceptionState final : public ExceptionState {
-  WTF_MAKE_NONCOPYABLE(IgnorableExceptionState);
-
- public:
-  IgnorableExceptionState()
-      : ExceptionState(nullptr,
-                       ExceptionState::UnknownContext,
-                       nullptr,
-                       nullptr) {}
-
-  ExceptionState& returnThis() { return *this; }
-
-  void throwDOMException(ExceptionCode, const String& message) override {}
-  void throwRangeError(const String& message) override{};
-  void throwSecurityError(const String& sanitizedMessage,
-                          const String& unsanitizedMessage) override {}
-  void throwTypeError(const String& message) override {}
-  void rethrowV8Exception(v8::Local<v8::Value>) override{};
-};
-
-#define IGNORE_EXCEPTION (::blink::IgnorableExceptionState().returnThis())
+#define IGNORE_EXCEPTION (::blink::DummyExceptionStateForTesting().returnThis())
 
 #if ENABLE(ASSERT)
 
@@ -88,7 +68,8 @@
 
 #else
 
-#define ASSERT_NO_EXCEPTION (::blink::IgnorableExceptionState().returnThis())
+#define ASSERT_NO_EXCEPTION \
+  (::blink::DummyExceptionStateForTesting().returnThis())
 
 #endif
 
diff --git a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
index 28a69dd0..a2cfd7a 100644
--- a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
@@ -229,7 +229,7 @@
 
 {##############################################################################}
 {% macro attribute_cache_property_callback(attribute) %}
-static v8::Local<v8::Private> {{attribute.name}}CachedAccessorCallback(v8::Isolate* isolate)
+v8::Local<v8::Private> {{attribute.name}}CachedAccessorCallback(v8::Isolate* isolate)
 {
     return V8PrivateProperty::get{{attribute.cached_accessor_name}}(isolate).getPrivate();
 }
diff --git a/third_party/WebKit/Source/build/scripts/css_properties.py b/third_party/WebKit/Source/build/scripts/css_properties.py
index f26f765..e201550 100755
--- a/third_party/WebKit/Source/build/scripts/css_properties.py
+++ b/third_party/WebKit/Source/build/scripts/css_properties.py
@@ -62,8 +62,6 @@
         in_generator.Writer.__init__(self, file_paths)
 
         properties = self.in_file.name_dictionaries
-        self._descriptors = [property for property in properties if property['descriptor_only']]
-
         self._aliases = [property for property in properties if property['alias_for']]
         properties = [property for property in properties if not property['alias_for']]
 
diff --git a/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py b/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
index 058367e..9e5cfacf 100755
--- a/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
+++ b/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
@@ -24,8 +24,8 @@
     def generate_css_property_metadata_cpp(self):
         return {
             'properties': self._properties,
-            'descriptors': self._descriptors,
-            'switches': [('interpolable', 'isInterpolableProperty'),
+            'switches': [('descriptor_only', 'isDescriptorOnly'),
+                         ('interpolable', 'isInterpolableProperty'),
                          ('inherited', 'isInheritedProperty'),
                          ('supports_percentage', 'propertySupportsPercentage'),
                          ('repeated', 'propertyIsRepeated')
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
index 917fe756..b9fe6ea 100644
--- a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
@@ -62,8 +62,4 @@
   }
 }
 
-bool CSSPropertyMetadata::isDescriptorOnly(CSSPropertyID property) {
-    return property >= {{descriptors[0].property_id}} && property <= {{descriptors[-1].property_id}};
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp
index 9f15de8..50acd02 100644
--- a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp
@@ -6,6 +6,8 @@
 
 #include "core/animation/InterpolationEnvironment.h"
 #include "core/animation/StringKeyframe.h"
+#include "core/css/CSSInheritedValue.h"
+#include "core/css/CSSInitialValue.h"
 #include "core/css/resolver/StyleBuilder.h"
 
 namespace blink {
@@ -35,22 +37,30 @@
 DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSValueNonInterpolableValue);
 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSValueNonInterpolableValue);
 
-InterpolationValue CSSValueInterpolationType::maybeConvertSingle(
-    const PropertySpecificKeyframe& keyframe,
-    const InterpolationEnvironment&,
-    const InterpolationValue&,
-    ConversionCheckers&) const {
-  if (keyframe.isNeutral())
-    return nullptr;
+InterpolationValue CSSValueInterpolationType::maybeConvertInitial(
+    const StyleResolverState& state,
+    ConversionCheckers& conversionCheckers) const {
+  return maybeConvertValue(*CSSInitialValue::create(), state,
+                           conversionCheckers);
+}
 
-  return InterpolationValue(
-      InterpolableList::create(0),
-      CSSValueNonInterpolableValue::create(
-          toCSSPropertySpecificKeyframe(keyframe).value()));
+InterpolationValue CSSValueInterpolationType::maybeConvertInherit(
+    const StyleResolverState& state,
+    ConversionCheckers& conversionCheckers) const {
+  return maybeConvertValue(*CSSInheritedValue::create(), state,
+                           conversionCheckers);
+}
+
+InterpolationValue CSSValueInterpolationType::maybeConvertValue(
+    const CSSValue& value,
+    const StyleResolverState& state,
+    ConversionCheckers& conversionCheckers) const {
+  return InterpolationValue(InterpolableList::create(0),
+                            CSSValueNonInterpolableValue::create(&value));
 }
 
 void CSSValueInterpolationType::applyStandardPropertyValue(
-    const InterpolableValue&,
+    const InterpolableValue& interpolableValue,
     const NonInterpolableValue* nonInterpolableValue,
     StyleResolverState& state) const {
   StyleBuilder::applyProperty(
diff --git a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
index 606859b..5cc8b3b 100644
--- a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
@@ -25,39 +25,25 @@
     return nullptr;
   }
 
-  InterpolationValue maybeConvertSingle(const PropertySpecificKeyframe&,
-                                        const InterpolationEnvironment&,
-                                        const InterpolationValue& underlying,
-                                        ConversionCheckers&) const final;
-
   InterpolationValue maybeConvertStandardPropertyUnderlyingValue(
       const StyleResolverState&) const final {
     return nullptr;
   }
 
-  // As we override CSSInterpolationType::maybeConvertSingle, these are never
-  // called.
   InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
                                          ConversionCheckers&) const final {
-    NOTREACHED();
+    // This type will never interpolate or composite with the underlying value.
+    // Returning nullptr here means no value will be applied and the value in
+    // ComputedStyle will remain unchanged.
     return nullptr;
   }
   InterpolationValue maybeConvertInitial(const StyleResolverState&,
-                                         ConversionCheckers&) const final {
-    NOTREACHED();
-    return nullptr;
-  }
+                                         ConversionCheckers&) const final;
   InterpolationValue maybeConvertInherit(const StyleResolverState&,
-                                         ConversionCheckers&) const final {
-    NOTREACHED();
-    return nullptr;
-  }
+                                         ConversionCheckers&) const final;
   InterpolationValue maybeConvertValue(const CSSValue& value,
                                        const StyleResolverState&,
-                                       ConversionCheckers&) const final {
-    NOTREACHED();
-    return nullptr;
-  }
+                                       ConversionCheckers&) const final;
 
   void composite(UnderlyingValueOwner& underlyingValueOwner,
                  double underlyingFraction,
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 5914630..b63267b 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -344,6 +344,7 @@
     "parser/SizesAttributeParser.cpp",
     "parser/SizesCalcParser.cpp",
     "properties/CSSPropertyAPI.h",
+    "properties/CSSPropertyAPITextUnderlinePosition.cpp",
     "properties/CSSPropertyAPITransformOrigin.cpp",
     "properties/CSSPropertyAPITranslate.cpp",
     "properties/CSSPropertyAPIWebkitPadding.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index ddc5904..9221264 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -384,7 +384,7 @@
 text-shadow interpolable, inherited, converter=convertShadowList
 text-size-adjust inherited, converter=convertTextSizeAdjust, type_name=TextSizeAdjust
 text-transform inherited, keyword_only, keywords=[capitalize|uppercase|lowercase|none], initial_keyword=none
-text-underline-position runtime_flag=CSS3TextDecorations, inherited, type_name=TextUnderlinePosition
+text-underline-position runtime_flag=CSS3TextDecorations, inherited, type_name=TextUnderlinePosition, api_class
 top typedom_types=[Length], keywords=[auto], supports_percentage, interpolable, initial=initialOffset, converter=convertLengthOrAuto
 touch-action converter=convertFlags<TouchAction>, type_name=TouchAction
 transform typedom_types=[Transform], keywords=[none], interpolable, converter=convertTransformOperations
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 2ae3529..b4ebb79b 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -3709,11 +3709,6 @@
       return consumeInteger(m_range, 0);
     case CSSPropertyOrder:
       return consumeInteger(m_range);
-    case CSSPropertyTextUnderlinePosition:
-      // auto | [ under || [ left | right ] ], but we only support auto | under
-      // for now
-      ASSERT(RuntimeEnabledFeatures::css3TextDecorationsEnabled());
-      return consumeIdent<CSSValueAuto, CSSValueUnder>(m_range);
     case CSSPropertyVerticalAlign:
       return consumeVerticalAlign(m_range, m_context.mode());
     case CSSPropertyShapeOutside:
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp
new file mode 100644
index 0000000..5a6ce600
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPITextUnderlinePosition.cpp
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAPITextUnderlinePosition.h"
+
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
+namespace blink {
+
+const CSSValue* CSSPropertyAPITextUnderlinePosition::parseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context) {
+  // auto | [ under || [ left | right ] ], but we only support auto | under
+  // for now
+  DCHECK(RuntimeEnabledFeatures::css3TextDecorationsEnabled());
+  // auto | [ under || [ left | right ] ], but we only support auto | under
+  // for now
+  DCHECK(RuntimeEnabledFeatures::css3TextDecorationsEnabled());
+  return CSSPropertyParserHelpers::consumeIdent<CSSValueAuto, CSSValueUnder>(
+      range);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
index 838f8cf..9cf2e7d 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
@@ -210,7 +210,7 @@
 void IntersectionObserver::clearWeakMembers(Visitor* visitor) {
   if (ThreadHeap::isHeapObjectAlive(root()))
     return;
-  IgnorableExceptionState exceptionState;
+  DummyExceptionStateForTesting exceptionState;
   disconnect(exceptionState);
   m_root = nullptr;
 }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 072efbe..a02b9a71 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -745,6 +745,27 @@
     return;
   }
 
+  switch (document()->getEngagementLevel()) {
+    case mojom::blink::EngagementLevel::NONE:
+      UseCounter::count(document(), UseCounter::AlertEngagementNone);
+      break;
+    case mojom::blink::EngagementLevel::MINIMAL:
+      UseCounter::count(document(), UseCounter::AlertEngagementMinimal);
+      break;
+    case mojom::blink::EngagementLevel::LOW:
+      UseCounter::count(document(), UseCounter::AlertEngagementLow);
+      break;
+    case mojom::blink::EngagementLevel::MEDIUM:
+      UseCounter::count(document(), UseCounter::AlertEngagementMedium);
+      break;
+    case mojom::blink::EngagementLevel::HIGH:
+      UseCounter::count(document(), UseCounter::AlertEngagementHigh);
+      break;
+    case mojom::blink::EngagementLevel::MAX:
+      UseCounter::count(document(), UseCounter::AlertEngagementMax);
+      break;
+  }
+
   if (v8::MicrotasksScope::IsRunningMicrotasks(scriptState->isolate())) {
     UseCounter::count(document(), UseCounter::During_Microtask_Alert);
   }
@@ -774,6 +795,27 @@
     return false;
   }
 
+  switch (document()->getEngagementLevel()) {
+    case mojom::blink::EngagementLevel::NONE:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementNone);
+      break;
+    case mojom::blink::EngagementLevel::MINIMAL:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementMinimal);
+      break;
+    case mojom::blink::EngagementLevel::LOW:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementLow);
+      break;
+    case mojom::blink::EngagementLevel::MEDIUM:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementMedium);
+      break;
+    case mojom::blink::EngagementLevel::HIGH:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementHigh);
+      break;
+    case mojom::blink::EngagementLevel::MAX:
+      UseCounter::count(document(), UseCounter::ConfirmEngagementMax);
+      break;
+  }
+
   if (v8::MicrotasksScope::IsRunningMicrotasks(scriptState->isolate())) {
     UseCounter::count(document(), UseCounter::During_Microtask_Confirm);
   }
@@ -805,6 +847,27 @@
     return String();
   }
 
+  switch (document()->getEngagementLevel()) {
+    case mojom::blink::EngagementLevel::NONE:
+      UseCounter::count(document(), UseCounter::PromptEngagementNone);
+      break;
+    case mojom::blink::EngagementLevel::MINIMAL:
+      UseCounter::count(document(), UseCounter::PromptEngagementMinimal);
+      break;
+    case mojom::blink::EngagementLevel::LOW:
+      UseCounter::count(document(), UseCounter::PromptEngagementLow);
+      break;
+    case mojom::blink::EngagementLevel::MEDIUM:
+      UseCounter::count(document(), UseCounter::PromptEngagementMedium);
+      break;
+    case mojom::blink::EngagementLevel::HIGH:
+      UseCounter::count(document(), UseCounter::PromptEngagementHigh);
+      break;
+    case mojom::blink::EngagementLevel::MAX:
+      UseCounter::count(document(), UseCounter::PromptEngagementMax);
+      break;
+  }
+
   if (v8::MicrotasksScope::IsRunningMicrotasks(scriptState->isolate())) {
     UseCounter::count(document(), UseCounter::During_Microtask_Prompt);
   }
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 68806e32..0be3320 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1401,6 +1401,24 @@
     NavigatorVibrateEngagementMedium = 1728,
     NavigatorVibrateEngagementHigh = 1729,
     NavigatorVibrateEngagementMax = 1730,
+    AlertEngagementNone = 1731,
+    AlertEngagementMinimal = 1732,
+    AlertEngagementLow = 1733,
+    AlertEngagementMedium = 1734,
+    AlertEngagementHigh = 1735,
+    AlertEngagementMax = 1736,
+    ConfirmEngagementNone = 1737,
+    ConfirmEngagementMinimal = 1738,
+    ConfirmEngagementLow = 1739,
+    ConfirmEngagementMedium = 1740,
+    ConfirmEngagementHigh = 1741,
+    ConfirmEngagementMax = 1742,
+    PromptEngagementNone = 1743,
+    PromptEngagementMinimal = 1744,
+    PromptEngagementLow = 1745,
+    PromptEngagementMedium = 1746,
+    PromptEngagementHigh = 1747,
+    PromptEngagementMax = 1748,
 
     // Add new features immediately above this line. Don't change assigned
     // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
index c83bf5a..22653a0 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
@@ -13,61 +13,63 @@
 
 namespace {
 
-// Extends Length::valueForLength with default value if length type is auto.
-LayoutUnit CustomValueForLength(const Length& length,
-                                LayoutUnit max_value,
-                                LayoutUnit default_value = NGSizeIndefinite) {
-  if (length.isAuto())
-    return default_value;
-  DCHECK(!length.isPercentOrCalc() || max_value != NGSizeIndefinite);
-  return valueForLength(length, max_value);
-}
-
 bool AbsoluteHorizontalNeedsEstimate(const ComputedStyle& style) {
-  return style.width().isAuto() &&
-         (style.left().isAuto() || style.right().isAuto());
+  Length width = style.width();
+  return width.isIntrinsic() ||
+         (width.isAuto() && (style.left().isAuto() || style.right().isAuto()));
 }
 
 bool AbsoluteVerticalNeedsEstimate(const ComputedStyle& style) {
-  return style.height().isAuto() &&
-         (style.top().isAuto() || style.bottom().isAuto());
+  Length height = style.height();
+  return height.isIntrinsic() ||
+         (height.isAuto() && (style.top().isAuto() || style.bottom().isAuto()));
 }
 
 // Implement absolute horizontal size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
-void ComputeAbsoluteHorizontal(const NGConstraintSpace& space,
-                               const ComputedStyle& style,
-                               const NGStaticPosition& static_position,
-                               const Optional<LayoutUnit>& child_auto_width,
-                               NGAbsolutePhysicalPosition* position) {
-  // Always use inline_size for percent resolution.
-  // TODO(atotic) test whether inline_size is correct in vertical modes.
-  LayoutUnit percentage_resolution_size =
-      space.PercentageResolutionSize().inline_size;
+void ComputeAbsoluteHorizontal(
+    const NGConstraintSpace& space,
+    const ComputedStyle& style,
+    const NGStaticPosition& static_position,
+    const Optional<MinAndMaxContentSizes>& child_minmax,
+    NGAbsolutePhysicalPosition* position) {
+  NGLogicalSize percentage_logical = space.PercentageResolutionSize();
+  NGPhysicalSize percentage_physical =
+      percentage_logical.ConvertToPhysical(space.WritingMode());
   LayoutUnit border_left(style.borderLeftWidth());
   LayoutUnit border_right(style.borderRightWidth());
-  LayoutUnit padding_left = CustomValueForLength(
-      style.paddingLeft(), percentage_resolution_size, LayoutUnit());
-  LayoutUnit padding_right = CustomValueForLength(
-      style.paddingRight(), percentage_resolution_size, LayoutUnit());
-  LayoutUnit margin_left =
-      CustomValueForLength(style.marginLeft(), percentage_resolution_size);
-  LayoutUnit margin_right =
-      CustomValueForLength(style.marginRight(), percentage_resolution_size);
-  LayoutUnit left =
-      CustomValueForLength(style.left(), percentage_resolution_size);
-  LayoutUnit right =
-      CustomValueForLength(style.right(), percentage_resolution_size);
+  LayoutUnit padding_left =
+      valueForLength(style.paddingLeft(), percentage_logical.inline_size);
+  LayoutUnit padding_right =
+      valueForLength(style.paddingRight(), percentage_logical.inline_size);
+  Optional<LayoutUnit> margin_left;
+  if (!style.marginLeft().isAuto())
+    margin_left =
+        valueForLength(style.marginLeft(), percentage_logical.inline_size);
+  Optional<LayoutUnit> margin_right;
+  if (!style.marginRight().isAuto())
+    margin_right =
+        valueForLength(style.marginRight(), percentage_logical.inline_size);
+  Optional<LayoutUnit> left;
+  if (!style.left().isAuto())
+    left = valueForLength(style.left(), percentage_physical.width);
+  Optional<LayoutUnit> right;
+  if (!style.right().isAuto())
+    right = valueForLength(style.right(), percentage_physical.width);
   LayoutUnit border_padding =
       border_left + border_right + padding_left + padding_right;
-  // TODO(atotic): This should use Resolve{Inline,Block}Length
-  LayoutUnit width =
-      CustomValueForLength(style.width(), percentage_resolution_size);
-
-  // Normalize width to border-box sizing.
-  if (style.boxSizing() == EBoxSizing::BoxSizingContentBox &&
-      width != NGSizeIndefinite)
-    width += border_padding;
+  Optional<LayoutUnit> width;
+  if (!style.width().isAuto()) {
+    if (space.WritingMode() == kHorizontalTopBottom) {
+      width = ResolveInlineLength(space, style, child_minmax, style.width(),
+                                  LengthResolveType::kContentSize);
+    } else {
+      LayoutUnit computed_width =
+          child_minmax.has_value() ? child_minmax->max_content : LayoutUnit();
+      width = ResolveBlockLength(space, style, style.width(), computed_width,
+                                 LengthResolveType::kContentSize);
+    }
+  }
 
   NGPhysicalSize container_size =
       space.AvailableSize().ConvertToPhysical(space.WritingMode());
@@ -75,29 +77,27 @@
 
   // Solving the equation:
   // left + marginLeft + width + marginRight + right  = container width
-  if (left == NGSizeIndefinite && right == NGSizeIndefinite &&
-      width == NGSizeIndefinite) {
+  if (!left && !right && !width) {
     // Standard: "If all three of left, width, and right are auto:"
-    if (margin_left == NGSizeIndefinite)
+    if (!margin_left)
       margin_left = LayoutUnit();
-    if (margin_right == NGSizeIndefinite)
+    if (!margin_right)
       margin_right = LayoutUnit();
-    DCHECK(child_auto_width.has_value());
-    width = *child_auto_width;
+    DCHECK(child_minmax.has_value());
+    width = child_minmax->ShrinkToFit(container_size.width);
     if (space.Direction() == TextDirection::Ltr) {
-      left = static_position.LeftPosition(container_size.width, width,
-                                          margin_left, margin_right);
+      left = static_position.LeftPosition(container_size.width, *width,
+                                          *margin_left, *margin_right);
     } else {
-      right = static_position.RightPosition(container_size.width, width,
-                                            margin_left, margin_right);
+      right = static_position.RightPosition(container_size.width, *width,
+                                            *margin_left, *margin_right);
     }
-  } else if (left != NGSizeIndefinite && right != NGSizeIndefinite &&
-             width != NGSizeIndefinite) {
+  } else if (left && right && width) {
     // Standard: "If left, right, and width are not auto:"
     // Compute margins.
-    LayoutUnit margin_space = container_size.width - left - right - width;
+    LayoutUnit margin_space = container_size.width - *left - *right - *width;
     // When both margins are auto.
-    if (margin_left == NGSizeIndefinite && margin_right == NGSizeIndefinite) {
+    if (!margin_left && !margin_right) {
       if (margin_space > 0) {
         margin_left = margin_space / 2;
         margin_right = margin_space / 2;
@@ -111,102 +111,118 @@
           margin_left = margin_space;
         }
       }
-    } else if (margin_left == NGSizeIndefinite) {
+    } else if (!margin_left) {
       margin_left = margin_space;
-    } else if (margin_right == NGSizeIndefinite) {
+    } else if (!margin_right) {
       margin_right = margin_space;
     } else {
       // Are values overconstrained?
-      if (margin_left + margin_right != margin_space) {
+      if (*margin_left + *margin_right != margin_space) {
         // Relax the end.
         if (space.Direction() == TextDirection::Ltr)
-          right -= margin_left + margin_right - margin_space;
+          right = *right - *margin_left + *margin_right - margin_space;
         else
-          left -= margin_left + margin_right - margin_space;
+          left = *left - *margin_left + *margin_right - margin_space;
       }
     }
   }
 
   // Set unknown margins.
-  if (margin_left == NGSizeIndefinite)
+  if (!margin_left)
     margin_left = LayoutUnit();
-  if (margin_right == NGSizeIndefinite)
+  if (!margin_right)
     margin_right = LayoutUnit();
 
   // Rules 1 through 3, 2 out of 3 are unknown.
-  if (left == NGSizeIndefinite && width == NGSizeIndefinite) {
+  if (!left && !width) {
     // Rule 1: left/width are unknown.
-    DCHECK_NE(right, NGSizeIndefinite);
-    DCHECK(child_auto_width.has_value());
-    width = *child_auto_width;
-  } else if (left == NGSizeIndefinite && right == NGSizeIndefinite) {
+    DCHECK(right.has_value());
+    DCHECK(child_minmax.has_value());
+    width = child_minmax->ShrinkToFit(container_size.width);
+  } else if (!left && !right) {
     // Rule 2.
-    DCHECK_NE(width, NGSizeIndefinite);
+    DCHECK(width.has_value());
     if (space.Direction() == TextDirection::Ltr)
-      left = static_position.LeftPosition(container_size.width, width,
-                                          margin_left, margin_right);
+      left = static_position.LeftPosition(container_size.width, *width,
+                                          *margin_left, *margin_right);
     else
-      right = static_position.RightPosition(container_size.width, width,
-                                            margin_left, margin_right);
-  } else if (width == NGSizeIndefinite && right == NGSizeIndefinite) {
+      right = static_position.RightPosition(container_size.width, *width,
+                                            *margin_left, *margin_right);
+  } else if (!width && !right) {
     // Rule 3.
-    DCHECK(child_auto_width.has_value());
-    width = *child_auto_width;
+    DCHECK(child_minmax.has_value());
+    width = child_minmax->ShrinkToFit(container_size.width);
   }
 
   // Rules 4 through 6, 1 out of 3 are unknown.
-  if (left == NGSizeIndefinite) {
-    left = container_size.width - right - width - margin_left - margin_right;
-  } else if (right == NGSizeIndefinite) {
-    right = container_size.width - left - width - margin_left - margin_right;
-  } else if (width == NGSizeIndefinite) {
-    width = container_size.width - left - right - margin_left - margin_right;
+  if (!left) {
+    left =
+        container_size.width - *right - *width - *margin_left - *margin_right;
+  } else if (!right) {
+    right =
+        container_size.width - *left - *width - *margin_left - *margin_right;
+  } else if (!width) {
+    width =
+        container_size.width - *left - *right - *margin_left - *margin_right;
   }
   DCHECK_EQ(container_size.width,
-            left + right + margin_left + margin_right + width);
+            *left + *right + *margin_left + *margin_right + *width);
 
   // Negative widths are not allowed.
-  width = std::max(width, border_padding);
+  width = std::max(*width, border_padding);
 
-  position->inset.left = left + margin_left;
-  position->inset.right = right + margin_right;
-  position->size.width = width;
+  position->inset.left = *left + *margin_left;
+  position->inset.right = *right + *margin_right;
+  position->size.width = *width;
 }
 
 // Implements absolute vertical size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-height
-void ComputeAbsoluteVertical(const NGConstraintSpace& space,
-                             const ComputedStyle& style,
-                             const NGStaticPosition& static_position,
-                             const Optional<LayoutUnit>& child_auto_height,
-                             NGAbsolutePhysicalPosition* position) {
-  // TODO(atotic) check percentage resolution for vertical writing modes.
-  LayoutUnit percentage_inline_size =
-      space.PercentageResolutionSize().inline_size;
-  LayoutUnit percentage_block_size =
-      space.PercentageResolutionSize().block_size;
+void ComputeAbsoluteVertical(
+    const NGConstraintSpace& space,
+    const ComputedStyle& style,
+    const NGStaticPosition& static_position,
+    const Optional<MinAndMaxContentSizes>& child_minmax,
+    NGAbsolutePhysicalPosition* position) {
+  NGLogicalSize percentage_logical = space.PercentageResolutionSize();
+  NGPhysicalSize percentage_physical =
+      percentage_logical.ConvertToPhysical(space.WritingMode());
+
   LayoutUnit border_top(style.borderTopWidth());
   LayoutUnit border_bottom(style.borderBottomWidth());
-  LayoutUnit padding_top = CustomValueForLength(
-      style.paddingTop(), percentage_inline_size, LayoutUnit());
-  LayoutUnit padding_bottom = CustomValueForLength(
-      style.paddingBottom(), percentage_inline_size, LayoutUnit());
-  LayoutUnit margin_top =
-      CustomValueForLength(style.marginTop(), percentage_inline_size);
-  LayoutUnit margin_bottom =
-      CustomValueForLength(style.marginBottom(), percentage_inline_size);
-  LayoutUnit top = CustomValueForLength(style.top(), percentage_block_size);
-  LayoutUnit bottom =
-      CustomValueForLength(style.bottom(), percentage_block_size);
+  LayoutUnit padding_top =
+      valueForLength(style.paddingTop(), percentage_logical.inline_size);
+  LayoutUnit padding_bottom =
+      valueForLength(style.paddingBottom(), percentage_logical.inline_size);
+  Optional<LayoutUnit> margin_top;
+  if (!style.marginTop().isAuto())
+    margin_top =
+        valueForLength(style.marginTop(), percentage_logical.inline_size);
+  Optional<LayoutUnit> margin_bottom;
+  if (!style.marginBottom().isAuto())
+    margin_bottom =
+        valueForLength(style.marginBottom(), percentage_logical.inline_size);
+  Optional<LayoutUnit> top;
+  if (!style.top().isAuto())
+    top = valueForLength(style.top(), percentage_physical.height);
+  Optional<LayoutUnit> bottom;
+  if (!style.bottom().isAuto())
+    bottom = valueForLength(style.bottom(), percentage_physical.height);
   LayoutUnit border_padding =
       border_top + border_bottom + padding_top + padding_bottom;
-  // TODO(atotic): This should use Resolve{Inline,Block}Length.
-  LayoutUnit height =
-      CustomValueForLength(style.height(), percentage_block_size);
 
-  if (style.boxSizing() == EBoxSizing::BoxSizingContentBox &&
-      height != NGSizeIndefinite)
-    height += border_padding;
+  Optional<LayoutUnit> height;
+  if (!style.height().isAuto()) {
+    if (space.WritingMode() == kHorizontalTopBottom) {
+      LayoutUnit computed_height =
+          child_minmax.has_value() ? child_minmax->max_content : LayoutUnit();
+      height = ResolveBlockLength(space, style, style.height(), computed_height,
+                                  LengthResolveType::kContentSize);
+    } else {
+      height = ResolveInlineLength(space, style, child_minmax, style.height(),
+                                   LengthResolveType::kContentSize);
+    }
+  }
 
   NGPhysicalSize container_size =
       space.AvailableSize().ConvertToPhysical(space.WritingMode());
@@ -215,24 +231,22 @@
   // Solving the equation:
   // top + marginTop + height + marginBottom + bottom
   // + border_padding = container height
-  if (top == NGSizeIndefinite && bottom == NGSizeIndefinite &&
-      height == NGSizeIndefinite) {
+  if (!top && !bottom && !height) {
     // Standard: "If all three of top, height, and bottom are auto:"
-    if (margin_top == NGSizeIndefinite)
+    if (!margin_top)
       margin_top = LayoutUnit();
-    if (margin_bottom == NGSizeIndefinite)
+    if (!margin_bottom)
       margin_bottom = LayoutUnit();
-    DCHECK(child_auto_height.has_value());
-    height = *child_auto_height;
-    top = static_position.TopPosition(container_size.height, height, margin_top,
-                                      margin_bottom);
-  } else if (top != NGSizeIndefinite && bottom != NGSizeIndefinite &&
-             height != NGSizeIndefinite) {
+    DCHECK(child_minmax.has_value());
+    height = child_minmax->ShrinkToFit(container_size.height);
+    top = static_position.TopPosition(container_size.height, *height,
+                                      *margin_top, *margin_bottom);
+  } else if (top && bottom && height) {
     // Standard: "If top, bottom, and height are not auto:"
     // Compute margins.
-    LayoutUnit margin_space = container_size.height - top - bottom - height;
+    LayoutUnit margin_space = container_size.height - *top - *bottom - *height;
     // When both margins are auto.
-    if (margin_top == NGSizeIndefinite && margin_bottom == NGSizeIndefinite) {
+    if (!margin_top && !margin_bottom) {
       if (margin_space > 0) {
         margin_top = margin_space / 2;
         margin_bottom = margin_space / 2;
@@ -241,59 +255,62 @@
         margin_top = LayoutUnit();
         margin_bottom = margin_space;
       }
-    } else if (margin_top == NGSizeIndefinite) {
+    } else if (!margin_top) {
       margin_top = margin_space;
-    } else if (margin_bottom == NGSizeIndefinite) {
+    } else if (!margin_bottom) {
       margin_bottom = margin_space;
     } else {
       // Are values overconstrained?
-      if (margin_top + margin_bottom != margin_space) {
+      if (*margin_top + *margin_bottom != margin_space) {
         // Relax the end.
-        bottom -= margin_top + margin_bottom - margin_space;
+        bottom = *bottom - *margin_top + *margin_bottom - margin_space;
       }
     }
   }
 
   // Set unknown margins.
-  if (margin_top == NGSizeIndefinite)
+  if (!margin_top)
     margin_top = LayoutUnit();
-  if (margin_bottom == NGSizeIndefinite)
+  if (!margin_bottom)
     margin_bottom = LayoutUnit();
 
   // Rules 1 through 3, 2 out of 3 are unknown, fix 1.
-  if (top == NGSizeIndefinite && height == NGSizeIndefinite) {
+  if (!top && !height) {
     // Rule 1.
-    DCHECK_NE(bottom, NGSizeIndefinite);
-    DCHECK(child_auto_height.has_value());
-    height = *child_auto_height;
-  } else if (top == NGSizeIndefinite && bottom == NGSizeIndefinite) {
+    DCHECK(bottom.has_value());
+    DCHECK(child_minmax.has_value());
+    height = child_minmax->ShrinkToFit(container_size.height);
+  } else if (!top && !bottom) {
     // Rule 2.
-    DCHECK_NE(height, NGSizeIndefinite);
-    top = static_position.TopPosition(container_size.height, height, margin_top,
-                                      margin_bottom);
-  } else if (height == NGSizeIndefinite && bottom == NGSizeIndefinite) {
+    DCHECK(height.has_value());
+    top = static_position.TopPosition(container_size.height, *height,
+                                      *margin_top, *margin_bottom);
+  } else if (!height && !bottom) {
     // Rule 3.
-    DCHECK(child_auto_height.has_value());
-    height = *child_auto_height;
+    DCHECK(child_minmax.has_value());
+    height = child_minmax->ShrinkToFit(container_size.height);
   }
 
   // Rules 4 through 6, 1 out of 3 are unknown.
-  if (top == NGSizeIndefinite) {
-    top = container_size.height - bottom - height - margin_top - margin_bottom;
-  } else if (bottom == NGSizeIndefinite) {
-    bottom = container_size.height - top - height - margin_top - margin_bottom;
-  } else if (height == NGSizeIndefinite) {
-    height = container_size.height - top - bottom - margin_top - margin_bottom;
+  if (!top) {
+    top = container_size.height - *bottom - *height - *margin_top -
+          *margin_bottom;
+  } else if (!bottom) {
+    bottom =
+        container_size.height - *top - *height - *margin_top - *margin_bottom;
+  } else if (!height) {
+    height =
+        container_size.height - *top - *bottom - *margin_top - *margin_bottom;
   }
   DCHECK_EQ(container_size.height,
-            top + bottom + margin_top + margin_bottom + height);
+            *top + *bottom + *margin_top + *margin_bottom + *height);
 
   // Negative heights are not allowed.
-  height = std::max(height, border_padding);
+  height = std::max(*height, border_padding);
 
-  position->inset.top = top + margin_top;
-  position->inset.bottom = bottom + margin_bottom;
-  position->size.height = height;
+  position->inset.top = *top + *margin_top;
+  position->inset.bottom = *bottom + *margin_bottom;
+  position->size.height = *height;
 }
 
 }  // namespace
@@ -323,14 +340,15 @@
     const NGConstraintSpace& space,
     const ComputedStyle& style,
     const NGStaticPosition& static_position,
-    const Optional<LayoutUnit>& child_inline_size) {
+    const Optional<MinAndMaxContentSizes>& child_minmax) {
   NGAbsolutePhysicalPosition position;
   if (style.isHorizontalWritingMode())
-    ComputeAbsoluteHorizontal(space, style, static_position, child_inline_size,
+    ComputeAbsoluteHorizontal(space, style, static_position, child_minmax,
                               &position);
-  else
-    ComputeAbsoluteVertical(space, style, static_position, child_inline_size,
+  else {
+    ComputeAbsoluteVertical(space, style, static_position, child_minmax,
                             &position);
+  }
   return position;
 }
 
@@ -340,12 +358,21 @@
     const NGStaticPosition& static_position,
     const Optional<LayoutUnit>& child_block_size,
     NGAbsolutePhysicalPosition* position) {
+  // After partial size has been computed, child block size is either
+  // unknown, or fully computed, there is no minmax.
+  // To express this, a 'fixed' minmax is created where
+  // min and max are the same.
+  Optional<MinAndMaxContentSizes> child_minmax;
+  if (child_block_size.has_value()) {
+    child_minmax = MinAndMaxContentSizes{*child_block_size, *child_block_size};
+  }
   if (style.isHorizontalWritingMode())
-    ComputeAbsoluteVertical(space, style, static_position, child_block_size,
+    ComputeAbsoluteVertical(space, style, static_position, child_minmax,
                             position);
-  else
-    ComputeAbsoluteHorizontal(space, style, static_position, child_block_size,
+  else {
+    ComputeAbsoluteHorizontal(space, style, static_position, child_minmax,
                               position);
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
index a161e49..1513af4 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
@@ -50,7 +50,7 @@
     const NGConstraintSpace& space,
     const ComputedStyle& style,
     const NGStaticPosition&,
-    const Optional<LayoutUnit>& child_inline_size);
+    const Optional<MinAndMaxContentSizes>& child_minmax);
 
 // Compute rest of NGPhysicalRect that depends on child's block_size.
 CORE_EXPORT void ComputeFullAbsoluteWithChildBlockSize(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
index 1a287e7..81093f4 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
@@ -111,7 +111,8 @@
   LayoutUnit width =
       container_size_.inline_size - left - margin_left - right - margin_right;
 
-  Optional<LayoutUnit> estimated_inline;
+  Optional<MinAndMaxContentSizes> estimated_inline;
+  MinAndMaxContentSizes minmax_60{LayoutUnit(60), LayoutUnit(60)};
 
   style_->setBorderLeftWidth(border_left.toInt());
   style_->setBorderRightWidth(border_right.toInt());
@@ -135,26 +136,26 @@
   // All auto => width is estimated_inline, left is 0.
   SetHorizontalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
   EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
-  estimated_inline = LayoutUnit(60);
+  estimated_inline = minmax_60;
   p = ComputePartialAbsoluteWithChildInlineSize(
       *ltr_space_, *style_, static_position, estimated_inline);
-  EXPECT_EQ(*estimated_inline, p.size.width);
+  EXPECT_EQ(minmax_60.min_content, p.size.width);
   EXPECT_EQ(LayoutUnit(0), p.inset.left);
 
   // All auto => width is estimated_inline, static_position is right
   SetHorizontalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
   EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
-  estimated_inline = LayoutUnit(60);
+  estimated_inline = minmax_60;
   p = ComputePartialAbsoluteWithChildInlineSize(
       *ltr_space_, *style_, static_right_position, estimated_inline);
-  EXPECT_EQ(*estimated_inline, p.size.width);
+  EXPECT_EQ(minmax_60.min_content, p.size.width);
   EXPECT_EQ(LayoutUnit(0), p.inset.right);
 
   // All auto + RTL.
   p = ComputePartialAbsoluteWithChildInlineSize(
       *rtl_space_, *style_, static_position, estimated_inline);
-  EXPECT_EQ(*estimated_inline, p.size.width);
-  EXPECT_EQ(container_size_.inline_size - *estimated_inline, p.inset.right);
+  EXPECT_EQ(minmax_60.min_content, p.size.width);
+  EXPECT_EQ(container_size_.inline_size - minmax_60.min_content, p.inset.right);
 
   // left, right, and left are known, compute margins.
   SetHorizontalStyle(left, NGAuto, width, NGAuto, right);
@@ -204,10 +205,10 @@
   // Rule 1 left and width are auto.
   SetHorizontalStyle(NGAuto, margin_left, NGAuto, margin_right, right);
   EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
-  estimated_inline = LayoutUnit(60);
+  estimated_inline = minmax_60;
   p = ComputePartialAbsoluteWithChildInlineSize(
       *ltr_space_, *style_, static_position, estimated_inline);
-  EXPECT_EQ(*estimated_inline, p.size.width);
+  EXPECT_EQ(minmax_60.min_content, p.size.width);
 
   // Rule 2 left and right are auto LTR.
   SetHorizontalStyle(NGAuto, margin_left, width, margin_right, NGAuto);
@@ -230,13 +231,13 @@
   // Rule 3 width and right are auto.
   SetHorizontalStyle(left, margin_left, NGAuto, margin_right, NGAuto);
   EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
-  estimated_inline = LayoutUnit(60);
+  estimated_inline = minmax_60;
   p = ComputePartialAbsoluteWithChildInlineSize(
       *ltr_space_, *style_, static_position, estimated_inline);
   EXPECT_EQ(
-      container_size_.inline_size - *estimated_inline - left - margin_left,
+      container_size_.inline_size - minmax_60.min_content - left - margin_left,
       p.inset.right);
-  EXPECT_EQ(*estimated_inline, p.size.width);
+  EXPECT_EQ(minmax_60.min_content, p.size.width);
 
   // Rule 4: left is auto.
   SetHorizontalStyle(NGAuto, margin_left, width, margin_right, right);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
index 241640e4..5c875fa 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -8,6 +8,7 @@
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_length_utils.h"
+#include "core/layout/ng/ng_physical_fragment.h"
 #include "core/style/ComputedStyle.h"
 #include "core/layout/ng/ng_fragment.h"
 
@@ -34,6 +35,7 @@
   NGConstraintSpaceBuilder space_builder(
       FromPlatformWritingMode(container_style->getWritingMode()));
   space_builder.SetAvailableSize(space_size);
+  space_builder.SetPercentageResolutionSize(space_size);
   space_builder.SetIsNewFormattingContext(true);
   space_builder.SetTextDirection(container_style->direction());
   parent_space_ = space_builder.ToConstraintSpace();
@@ -107,8 +109,7 @@
   if (AbsoluteNeedsChildInlineSize(*node_->Style())) {
     MinAndMaxContentSizes size;
     if (node_->ComputeMinAndMaxContentSizes(&size)) {
-      inline_estimate_ =
-          size.ShrinkToFit(parent_space_->AvailableSize().inline_size);
+      inline_estimate_ = size;
       return true;
     }
     return false;
@@ -145,7 +146,7 @@
     if (block_estimate_)
       available_size.block_size = *block_estimate_;
     builder.SetAvailableSize(available_size);
-    builder.SetPercentageResolutionSize(available_size);
+    builder.SetPercentageResolutionSize(parent_space_->AvailableSize());
     if (block_estimate_)
       builder.SetIsFixedSizeBlock(true);
     builder.SetIsFixedSizeInline(true);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
index 32810925..1949eed 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -63,7 +63,7 @@
   Member<NGConstraintSpace> node_space_;
   Member<NGFragment> node_fragment_;
   NGAbsolutePhysicalPosition node_position_;
-  Optional<LayoutUnit> inline_estimate_;
+  Optional<MinAndMaxContentSizes> inline_estimate_;
   Optional<LayoutUnit> block_estimate_;
 };
 
diff --git a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
index dbda6a66..53e68a2 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.cpp
@@ -13,7 +13,7 @@
 namespace blink {
 
 NavigatorCredentials::NavigatorCredentials(Navigator& navigator)
-    : ContextClient(navigator.frame()) {}
+    : Supplement<Navigator>(navigator) {}
 
 NavigatorCredentials& NavigatorCredentials::from(Navigator& navigator) {
   NavigatorCredentials* supplement = static_cast<NavigatorCredentials*>(
@@ -34,7 +34,7 @@
 }
 
 CredentialsContainer* NavigatorCredentials::credentials() {
-  if (!m_credentialsContainer && frame())
+  if (!m_credentialsContainer)
     m_credentialsContainer = CredentialsContainer::create();
   return m_credentialsContainer.get();
 }
@@ -42,7 +42,6 @@
 DEFINE_TRACE(NavigatorCredentials) {
   visitor->trace(m_credentialsContainer);
   Supplement<Navigator>::trace(visitor);
-  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
index e5668d1..c4fed6f 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
+++ b/third_party/WebKit/Source/modules/credentialmanager/NavigatorCredentials.h
@@ -5,7 +5,6 @@
 #ifndef NavigatorCredentials_h
 #define NavigatorCredentials_h
 
-#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -17,8 +16,7 @@
 
 class NavigatorCredentials final
     : public GarbageCollected<NavigatorCredentials>,
-      public Supplement<Navigator>,
-      public ContextClient {
+      public Supplement<Navigator> {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorCredentials);
 
  public:
diff --git a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
index 083969b..108b38a0 100644
--- a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
+++ b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.cpp
@@ -36,12 +36,11 @@
 
 namespace blink {
 
-NavigatorDoNotTrack::NavigatorDoNotTrack(LocalFrame* frame)
-    : ContextClient(frame) {}
+NavigatorDoNotTrack::NavigatorDoNotTrack(Navigator& navigator)
+    : Supplement<Navigator>(navigator) {}
 
 DEFINE_TRACE(NavigatorDoNotTrack) {
   Supplement<Navigator>::trace(visitor);
-  ContextClient::trace(visitor);
 }
 
 const char* NavigatorDoNotTrack::supplementName() {
@@ -52,7 +51,7 @@
   NavigatorDoNotTrack* supplement = static_cast<NavigatorDoNotTrack*>(
       Supplement<Navigator>::from(navigator, supplementName()));
   if (!supplement) {
-    supplement = new NavigatorDoNotTrack(navigator.frame());
+    supplement = new NavigatorDoNotTrack(navigator);
     provideTo(navigator, supplementName(), supplement);
   }
   return *supplement;
@@ -63,9 +62,10 @@
 }
 
 String NavigatorDoNotTrack::doNotTrack() {
-  if (!frame() || !frame()->loader().client())
+  LocalFrame* frame = host()->frame();
+  if (!frame || !frame->loader().client())
     return String();
-  return frame()->loader().client()->doNotTrackValue();
+  return frame->loader().client()->doNotTrackValue();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
index 87bdc89..d44bafc 100644
--- a/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
+++ b/third_party/WebKit/Source/modules/donottrack/NavigatorDoNotTrack.h
@@ -31,7 +31,6 @@
 #ifndef NavigatorDoNotTrack_h
 #define NavigatorDoNotTrack_h
 
-#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
@@ -39,12 +38,10 @@
 
 namespace blink {
 
-class LocalFrame;
 class Navigator;
 
 class NavigatorDoNotTrack final : public GarbageCollected<NavigatorDoNotTrack>,
-                                  public Supplement<Navigator>,
-                                  public ContextClient {
+                                  public Supplement<Navigator> {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorDoNotTrack);
 
  public:
@@ -56,7 +53,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  explicit NavigatorDoNotTrack(LocalFrame*);
+  explicit NavigatorDoNotTrack(Navigator&);
   static const char* supplementName();
 };
 
diff --git a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
index e74f11a..8be08ed 100644
--- a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
+++ b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.cpp
@@ -30,8 +30,8 @@
 
 namespace blink {
 
-NavigatorGeolocation::NavigatorGeolocation(LocalFrame* frame)
-    : ContextClient(frame) {}
+NavigatorGeolocation::NavigatorGeolocation(Navigator& navigator)
+    : Supplement<Navigator>(navigator) {}
 
 const char* NavigatorGeolocation::supplementName() {
   return "NavigatorGeolocation";
@@ -41,7 +41,7 @@
   NavigatorGeolocation* supplement = static_cast<NavigatorGeolocation*>(
       Supplement<Navigator>::from(navigator, supplementName()));
   if (!supplement) {
-    supplement = new NavigatorGeolocation(navigator.frame());
+    supplement = new NavigatorGeolocation(navigator);
     provideTo(navigator, supplementName(), supplement);
   }
   return *supplement;
@@ -52,15 +52,14 @@
 }
 
 Geolocation* NavigatorGeolocation::geolocation() {
-  if (!m_geolocation && frame())
-    m_geolocation = Geolocation::create(frame()->document());
+  if (!m_geolocation && host()->frame())
+    m_geolocation = Geolocation::create(host()->frame()->document());
   return m_geolocation;
 }
 
 DEFINE_TRACE(NavigatorGeolocation) {
   visitor->trace(m_geolocation);
   Supplement<Navigator>::trace(visitor);
-  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
index 6916e26..424fcf7 100644
--- a/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
+++ b/third_party/WebKit/Source/modules/geolocation/NavigatorGeolocation.h
@@ -20,21 +20,18 @@
 #ifndef NavigatorGeolocation_h
 #define NavigatorGeolocation_h
 
-#include "core/dom/ContextLifecycleObserver.h"
 #include "core/frame/Navigator.h"
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
-class LocalFrame;
 class Geolocation;
 class Navigator;
 
 class NavigatorGeolocation final
     : public GarbageCollected<NavigatorGeolocation>,
-      public Supplement<Navigator>,
-      public ContextClient {
+      public Supplement<Navigator> {
   USING_GARBAGE_COLLECTED_MIXIN(NavigatorGeolocation);
 
  public:
@@ -45,7 +42,7 @@
   DECLARE_TRACE();
 
  private:
-  explicit NavigatorGeolocation(LocalFrame*);
+  explicit NavigatorGeolocation(Navigator&);
 
   static const char* supplementName();
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index babe5424..994c4a2 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -7653,6 +7653,14 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSettings.Popups" enum="ContentSettingPopupAction">
+  <owner>charleszhao@chromium.org</owner>
+  <summary>
+    Tracks whether the popup content blocked puzzle piece was shown in the
+    Omnibox, and how the user interacted with it.
+  </summary>
+</histogram>
+
 <histogram name="ContextMenu.SaveLinkType" enum="ContextMenuSaveLinkType">
   <owner>qinmin@chromium.org</owner>
   <summary>
@@ -59409,6 +59417,10 @@
   <summary>
     The result of trying to send the IPC message to a renderer process telling
     it to stop an embedded worker. Recorded in EmbeddedWorkerInstance::Stop.
+    This was previously recorded for both the IPC and Mojo service worker
+    implementations, but as of Jan 2017, this is only recorded for the IPC
+    implementation. This histogram will be removed after the IPC implementation
+    is removed.
   </summary>
 </histogram>
 
@@ -80435,6 +80447,14 @@
   <int value="6" label="Clicked 'Learn more'"/>
 </enum>
 
+<enum name="ContentSettingPopupAction" type="int">
+  <int value="0" label="Displayed popup-blocked icon in Omnibox"/>
+  <int value="1" label="Displayed bubble"/>
+  <int value="2" label="Clicked 'Always allow pop-ups from'"/>
+  <int value="3" label="Clicked one of the list items"/>
+  <int value="4" label="Clicked 'Manage pop-up blocking'"/>
+</enum>
+
 <enum name="ContentSettingScheme" type="int">
   <int value="0" label="(wildcard)"/>
   <int value="1" label="(other)"/>
@@ -88368,6 +88388,24 @@
   <int value="1728" label="NavigatorVibrateEngagementMedium"/>
   <int value="1729" label="NavigatorVibrateEngagementHigh"/>
   <int value="1730" label="NavigatorVibrateEngagementMax"/>
+  <int value="1731" label="AlertEngagementNone"/>
+  <int value="1732" label="AlertEngagementMinimal"/>
+  <int value="1733" label="AlertEngagementLow"/>
+  <int value="1734" label="AlertEngagementMedium"/>
+  <int value="1735" label="AlertEngagementHigh"/>
+  <int value="1736" label="AlertEngagementMax"/>
+  <int value="1737" label="ConfirmEngagementNone"/>
+  <int value="1738" label="ConfirmEngagementMinimal"/>
+  <int value="1739" label="ConfirmEngagementLow"/>
+  <int value="1740" label="ConfirmEngagementMedium"/>
+  <int value="1741" label="ConfirmEngagementHigh"/>
+  <int value="1742" label="ConfirmEngagementMax"/>
+  <int value="1743" label="PromptEngagementNone"/>
+  <int value="1744" label="PromptEngagementMinimal"/>
+  <int value="1745" label="PromptEngagementLow"/>
+  <int value="1746" label="PromptEngagementMedium"/>
+  <int value="1747" label="PromptEngagementHigh"/>
+  <int value="1748" label="PromptEngagementMax"/>
 </enum>
 
 <enum name="FetchRequestMode" type="int">
diff --git a/tools/perf/benchmarks/loading.py b/tools/perf/benchmarks/loading.py
index ca094d8a..167f4eb 100644
--- a/tools/perf/benchmarks/loading.py
+++ b/tools/perf/benchmarks/loading.py
@@ -30,6 +30,12 @@
     if possible_browser.browser_type == 'reference':
       return True
 
+    # crbug.com/676612
+    if ((possible_browser.platform.GetDeviceTypeName() == 'Nexus 6' or
+         possible_browser.platform.GetDeviceTypeName() == 'AOSP on Shamu') and
+        possible_browser.browser_type == 'android-webview'):
+      return True
+
     return False
 
   @classmethod
diff --git a/ui/webui/resources/cr_elements/network/badge_1x.png b/ui/webui/resources/cr_elements/network/badge_1x.png
deleted file mode 100644
index 2d11aee..0000000
--- a/ui/webui/resources/cr_elements/network/badge_1x.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_3g.png b/ui/webui/resources/cr_elements/network/badge_3g.png
deleted file mode 100644
index cfe578b..0000000
--- a/ui/webui/resources/cr_elements/network/badge_3g.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_4g.png b/ui/webui/resources/cr_elements/network/badge_4g.png
deleted file mode 100644
index 0729051..0000000
--- a/ui/webui/resources/cr_elements/network/badge_4g.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_edge.png b/ui/webui/resources/cr_elements/network/badge_edge.png
deleted file mode 100644
index 1620182..0000000
--- a/ui/webui/resources/cr_elements/network/badge_edge.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_evdo.png b/ui/webui/resources/cr_elements/network/badge_evdo.png
deleted file mode 100644
index 7742ace..0000000
--- a/ui/webui/resources/cr_elements/network/badge_evdo.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_gsm.png b/ui/webui/resources/cr_elements/network/badge_gsm.png
deleted file mode 100644
index b6690aa..0000000
--- a/ui/webui/resources/cr_elements/network/badge_gsm.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_hspa.png b/ui/webui/resources/cr_elements/network/badge_hspa.png
deleted file mode 100644
index c1760fe..0000000
--- a/ui/webui/resources/cr_elements/network/badge_hspa.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_hspa_plus.png b/ui/webui/resources/cr_elements/network/badge_hspa_plus.png
deleted file mode 100644
index ff2ac509..0000000
--- a/ui/webui/resources/cr_elements/network/badge_hspa_plus.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_lte.png b/ui/webui/resources/cr_elements/network/badge_lte.png
deleted file mode 100644
index 16d3157..0000000
--- a/ui/webui/resources/cr_elements/network/badge_lte.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_lte_advanced.png b/ui/webui/resources/cr_elements/network/badge_lte_advanced.png
deleted file mode 100644
index d97c035d..0000000
--- a/ui/webui/resources/cr_elements/network/badge_lte_advanced.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_roaming.png b/ui/webui/resources/cr_elements/network/badge_roaming.png
deleted file mode 100644
index 7036c55..0000000
--- a/ui/webui/resources/cr_elements/network/badge_roaming.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/badge_secure.png b/ui/webui/resources/cr_elements/network/badge_secure.png
deleted file mode 100644
index a1c76eeb..0000000
--- a/ui/webui/resources/cr_elements/network/badge_secure.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/compiled_resources2.gyp b/ui/webui/resources/cr_elements/network/compiled_resources2.gyp
index decd8225..ee80363a 100644
--- a/ui/webui/resources/cr_elements/network/compiled_resources2.gyp
+++ b/ui/webui/resources/cr_elements/network/compiled_resources2.gyp
@@ -6,6 +6,7 @@
     {
       'target_name': 'cr_network_icon',
       'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         'cr_onc_types',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/ui/webui/resources/cr_elements/network/cr_network_icon.html b/ui/webui/resources/cr_elements/network/cr_network_icon.html
index ff14df1..9e71673 100644
--- a/ui/webui/resources/cr_elements/network/cr_network_icon.html
+++ b/ui/webui/resources/cr_elements/network/cr_network_icon.html
@@ -1,96 +1,53 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/network/network_icons.html">
 
 <dom-module id="cr-network-icon">
   <template>
     <style>
-      /* Note: we use display: block here to avoid positioning issues related to
-         the use of overflow: hidden. */
       :host {
-        display: block;
-        height: 50px;
         overflow: hidden;
+        padding: 2px;
         position: relative;
-        width: 50px;
+      }
+
+      /* Included for options UI. TODO(stevenjb): Remove. */
+      [hidden] {
+        display: none !important;
       }
 
       #icon {
-        height: 100%;
-        position: absolute;
-        width: 100%;
+        height: 20px;
+        width: 20px;
       }
 
-      #icon.multi-level {
-        height: 500%;
-      }
-
-      #icon.level0 {
-        top: 0px;
-      }
-
-      #icon.level1 {
-        top: -100%;
-      }
-
-      #icon.level2 {
-        top: -200%;
-      }
-
-      #icon.level3 {
-        top: -300%;
-      }
-
-      #icon.level4 {
-        top: -400%;
-      }
-
-      /* Connecting animation */
-
-      #icon.connecting {
-        -webkit-animation: levels 1s infinite;
-        -webkit-animation-timing-function: steps(4, start);
-      }
-
-      @-webkit-keyframes levels {
-        from {
-          top: 0%;
-        }
-        to {
-          top: -400%;
-        }
-      }
-
-      /* Badges. */
-      /* Note: These use left/right because we do not reverse the badges for
-       * RTL. */
-
       /* Upper-left corner */
       #technology {
-        height: 40%;
-        left: 0px;
+        height: 20px;
+        left: 0;
         position: absolute;
-        top: 0px;
+        top: 1px;
+        width: 20px;
       }
 
       /* Lower-right corner */
-      #roaming,
       #secure {
-        height: 40%;
-        left: 60%;
+        height: 20px;
+        left: 16px;
         position: absolute;
-        top: 60%;
-        width: 40%;
+        top: 16px;
+        width: 20px;
       }
     </style>
-    <img id="icon" src$="[[toImageSrc_(iconType_)]]" alt="">
-    <img id="technology" alt="" src$="[[toBadgeImageSrc_(technology_)]]"
-        hidden$="[[!technology_]]">
-    <img id="roaming" alt=""
-        src="chrome://resources/cr_elements/network/badge_roaming.png"
-        hidden$="[[!roaming_]]">
-    <img id="secure" alt=""
-        src="chrome://resources/cr_elements/network/badge_secure.png"
-        hidden$="[[!secure_]]">
+    <iron-icon id="icon" icon="[[getIcon_(networkState, isListItem)]]">
+    </iron-icon>
+    <iron-icon id="technology" hidden ="[[!showTechnology_(networkState)]]"
+        icon="[[getTechnology_(networkState)]]">
+    </iron-icon>
+    <iron-icon id="secure" hidden ="[[!showSecure_(networkState)]]"
+        icon="network:badge-secure">
+    </iron-icon>
   </template>
   <script src="cr_network_icon.js"></script>
 </dom-module>
diff --git a/ui/webui/resources/cr_elements/network/cr_network_icon.js b/ui/webui/resources/cr_elements/network/cr_network_icon.js
index 4bccaf7..3f946aa 100644
--- a/ui/webui/resources/cr_elements/network/cr_network_icon.js
+++ b/ui/webui/resources/cr_elements/network/cr_network_icon.js
@@ -7,292 +7,143 @@
  * state properties.
  */
 
-/**
- * @typedef {{
- *   showBadges: boolean,
- *   showDisconnected: boolean,
- *   strength: number
- * }}
- */
-var NetworkIconParamType;
+Polymer({
+  is: 'cr-network-icon',
 
-(function() {
-  /** @const {string} */ var RESOURCE_IMAGE_BASE =
-      'chrome://resources/cr_elements/network/';
+  properties: {
+    /**
+     * If set, the ONC properties will be used to display the icon. This may
+     * either be the complete set of NetworkProperties or the subset of
+     * NetworkStateProperties.
+     * @type {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined}
+     */
+    networkState: Object,
 
-  /** @const {string} */ var RESOURCE_IMAGE_EXT = '.png';
+    /**
+     * If true, the icon is part of a list of networks and may be displayed
+     * differently, e.g. the disconnected image will never be shown for
+     * list items.
+     */
+    isListItem: {
+      type: Boolean,
+      value: false,
+    },
+  },
 
   /**
- * Gets the icon type from the network type. This allows multiple types
- * (i.e. Cellular, WiMAX) to map to the same icon type (i.e. mobile).
- * @param {chrome.networkingPrivate.NetworkType} networkType
- * @return {string} The icon type: ethernet, wifi, mobile, or vpn.
- */
-  function getIconTypeFromNetworkType(networkType) {
-    if (!networkType || networkType == CrOnc.Type.ETHERNET)
-      return 'ethernet';
-    else if (networkType == CrOnc.Type.WI_FI)
-      return 'wifi';
-    else if (networkType == CrOnc.Type.CELLULAR)
-      return 'mobile';
-    else if (networkType == CrOnc.Type.WI_MAX)
-      return 'mobile';
-    else if (networkType == CrOnc.Type.VPN)
-      return 'vpn';
+   * @return {string} The name of the svg icon image to show.
+   * @private
+   */
+  getIcon_: function() {
+    let showDisconnected =
+        !this.isListItem && (!this.networkState.ConnectionState ||
+                             this.networkState.ConnectionState ==
+                                 CrOnc.ConnectionState.NOT_CONNECTED);
 
-    console.error('Unrecognized network type for icon: ' + networkType);
-    return 'ethernet';
-  }
+    switch (this.networkState.Type) {
+      case CrOnc.Type.ETHERNET: {
+        return 'network:settings-ethernet';
+      }
+      case CrOnc.Type.VPN: {
+        return 'network:vpn-key';
+      }
+      case CrOnc.Type.CELLULAR: {
+        let strength =
+            showDisconnected ? 0 : CrOnc.getSignalStrength(this.networkState);
+        let index = this.strengthToIndex_(strength);
+        return 'network:signal-cellular-' + index.toString(10) + '-bar';
+      }
+      case CrOnc.Type.WI_FI:
+      case CrOnc.Type.WI_MAX: {
+        if (showDisconnected)
+          return 'network:signal-wifi-off';
+        let strength = CrOnc.getSignalStrength(this.networkState);
+        let index = this.strengthToIndex_(strength);
+        return 'network:signal-wifi-' + index.toString(10) + '-bar';
+      }
+      default:
+        assertNotReached();
+    }
+    return '';
+  },
 
   /**
-   * Polymer class definition for 'cr-network-icon'.
-   */
-  Polymer({
-    is: 'cr-network-icon',
-
-    properties: {
-      /**
-       * If set, the ONC properties will be used to display the icon. This may
-       * either be the complete set of NetworkProperties or the subset of
-       * NetworkStateProperties.
-       * @type
-       * {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined}
-       */
-      networkState: {
-        type: Object,
-        observer: 'networkStateChanged_',
-      },
-
-      /**
-       * If set, the ONC network type will be used to display the icon.
-       * @type {?chrome.networkingPrivate.NetworkType}
-       */
-      networkType: {
-        type: String,
-        value: null,
-        observer: 'networkTypeChanged_',
-      },
-
-      /**
-       * If true, the icon is part of a list of networks and may be displayed
-       * differently, e.g. the disconnected image will never be shown for
-       * list items.
-       */
-      isListItem: {
-        type: Boolean,
-        value: false,
-        observer: 'isListItemChanged_',
-      },
-
-      /** The icon type to use for the base image of the icon. */
-      iconType_: {
-        type: String,
-        value: 'ethernet',
-      },
-
-      /** Set to true to show a badge for roaming networks. */
-      roaming_: {
-        type: Boolean,
-        value: false,
-      },
-
-      /** Set to true to show a badge for secure networks. */
-      secure_: {
-        type: Boolean,
-        value: false,
-      },
-
-      /** Set to the name of a technology to show show a badge. */
-      technology_: {
-        type: String,
-        value: '',
-      },
-    },
-
-    /**
-     * Polymer networkState changed method. Updates the icon based on the
-     * network state.
-     * @private
-     */
-    networkStateChanged_: function() {
-      if (!this.networkState)
-        return;
-
-      this.networkType = null;
-      this.iconType_ = getIconTypeFromNetworkType(this.networkState.Type);
-      var strength = CrOnc.getSignalStrength(this.networkState);
-      var params = /** @type {NetworkIconParamType} */ {
-        showBadges: true,
-        showDisconnected: !this.isListItem,
-        strength: strength
-      };
-      this.setIcon_(params);
-    },
-
-    /**
-     * Polymer networkType changed method. Updates the icon based on the type
-     * of network, showing a disconnected icon where appropriate and no badges.
-     * @private
-     */
-    networkTypeChanged_: function() {
-      if (!this.networkType)
-        return;
-
-      this.networkState = undefined;
-      this.iconType_ = getIconTypeFromNetworkType(this.networkType);
-      var params = /** @type {NetworkIconParamType} */ {
-        showBadges: false,
-        showDisconnected: true,
-        strength: 0,
-      };
-      this.setIcon_(params);
-    },
-
-    /**
-     * Polymer isListItem changed method.
-     * @private
-     */
-    isListItemChanged_: function() {
-      if (this.networkState)
-        this.networkStateChanged_();
-      else if (this.networkType)
-        this.networkTypeChanged_();
-    },
-
-    /**
-   * Returns the url for an image based on identifier |id|.
-   * @param {string} id The identifier describing the image.
-   * @return {string} The url to use for the image 'src' property.
+   * @param {number} strength The signal strength from [0 - 100].
+   * @return {number} An index from 0-4 corresponding to |strength|.
    * @private
    */
-    toImageSrc_: function(id) {
-      return id ? RESOURCE_IMAGE_BASE + id + RESOURCE_IMAGE_EXT : '';
-    },
+  strengthToIndex_: function(strength) {
+    if (strength == 0)
+      return 0;
+    return Math.min(Math.trunc((strength - 1) / 25) + 1, 4);
+  },
 
-    /**
-   * Returns the url for a badge image based on identifier |id|.
-   * @param {string} id The identifier describing the badge.
-   * @return {string} The url to use for the badge image 'src' property.
+  /**
+   * @return {boolean}
    * @private
    */
-    toBadgeImageSrc_: function(id) {
-      return id ? this.toImageSrc_('badge_' + id) : '';
-    },
+  showTechnology_: function() {
+    return this.getTechnology_() != '';
+  },
 
-    /**
-     * Sets the icon and badge based on the current state and |strength|.
-     * @param {!NetworkIconParamType} params Set of params describing the icon.
-     * @private
-     */
-    setIcon_: function(params) {
-      var icon = this.$.icon;
+  /**
+   * @return {string}
+   * @private
+   */
+  getTechnology_: function() {
+    let networkState = this.networkState;
+    let type = networkState.Type;
+    if (type == CrOnc.Type.WI_MAX)
+      return 'network:4g';
+    if (type == CrOnc.Type.CELLULAR && networkState.Cellular) {
+      let technology =
+          this.getTechnologyId_(networkState.Cellular.NetworkTechnology);
+      if (technology != '')
+        return 'network:' + technology;
+    }
+    return '';
+  },
 
-      var multiLevel = (this.iconType_ == 'wifi' || this.iconType_ == 'mobile');
+  /**
+   * @param {string|undefined} networkTechnology
+   * @return {string}
+   * @private
+   */
+  getTechnologyId_: function(networkTechnology) {
+    switch (networkTechnology) {
+      case CrOnc.NetworkTechnology.CDMA1XRTT:
+        return 'badge-1x';
+      case CrOnc.NetworkTechnology.EDGE:
+        return 'badge-edge';
+      case CrOnc.NetworkTechnology.EVDO:
+        return 'badge-evdo';
+      case CrOnc.NetworkTechnology.GPRS:
+      case CrOnc.NetworkTechnology.GSM:
+        return 'badge-gsm';
+      case CrOnc.NetworkTechnology.HSPA:
+        return 'badge-hspa';
+      case CrOnc.NetworkTechnology.HSPA_PLUS:
+        return 'badge-hspa-plus';
+      case CrOnc.NetworkTechnology.LTE:
+        return 'badge-lte';
+      case CrOnc.NetworkTechnology.LTE_ADVANCED:
+        return 'badge-lte-advanced';
+      case CrOnc.NetworkTechnology.UMTS:
+        return 'badge-3g';
+    }
+    return '';
+  },
 
-      if (this.networkState && multiLevel) {
-        this.setMultiLevelIcon_(params);
-      } else {
-        icon.classList.toggle('multi-level', multiLevel);
-        icon.classList.toggle('level0', multiLevel);
-        icon.classList.toggle('level1', false);
-        icon.classList.toggle('level2', false);
-        icon.classList.toggle('level3', false);
-        icon.classList.toggle('level4', false);
-      }
-
-      this.setIconBadges_(params);
-    },
-
-    /**
-     * Toggles icon classes based on strength and connecting properties.
-     * |this.networkState| is expected to be specified.
-     * @param {!NetworkIconParamType} params Set of params describing the icon.
-     * @private
-     */
-    setMultiLevelIcon_: function(params) {
-      // Set the strength or connecting properties.
-      var networkState = this.networkState;
-
-      var connectionState = networkState.ConnectionState;
-      var connecting = false;
-      var strength = -1;
-      if (connectionState == CrOnc.ConnectionState.CONNECTING) {
-        strength = 0;
-        connecting = true;
-      } else if (
-          connectionState == CrOnc.ConnectionState.CONNECTED ||
-          !params.showDisconnected) {
-        strength = params.strength || 0;
-      }
-
-      var icon = this.$.icon;
-      icon.classList.toggle('multi-level', true);
-      icon.classList.toggle('connecting', connecting);
-      icon.classList.toggle('level0', strength < 0);
-      icon.classList.toggle('level1', strength >= 0 && strength <= 25);
-      icon.classList.toggle('level2', strength > 25 && strength <= 50);
-      icon.classList.toggle('level3', strength > 50 && strength <= 75);
-      icon.classList.toggle('level4', strength > 75);
-    },
-
-    /**
-     * Sets the icon badge visibility properties: roaming, secure, technology.
-     * @param {!NetworkIconParamType} params Set of params describing the icon.
-     * @private
-     */
-    setIconBadges_: function(params) {
-      var networkState = this.networkState;
-
-      var type = (params.showBadges && networkState) ? networkState.Type : '';
-      if (type == CrOnc.Type.WI_FI) {
-        this.roaming_ = false;
-        var security = networkState.WiFi ? networkState.WiFi.Security : '';
-        this.secure_ = !!security && security != 'None';
-        this.technology_ = '';
-      } else if (type == CrOnc.Type.WI_MAX) {
-        this.roaming_ = false;
-        this.secure_ = false;
-        this.technology_ = '4g';
-      } else if (type == CrOnc.Type.CELLULAR && networkState.Cellular) {
-        this.roaming_ =
-            networkState.Cellular.RoamingState == CrOnc.RoamingState.ROAMING;
-        this.secure_ = false;
-        var oncTechnology = networkState.Cellular.NetworkTechnology;
-        switch (oncTechnology) {
-          case CrOnc.NetworkTechnology.CDMA1XRTT:
-            this.technology_ = '1x';
-            break;
-          case CrOnc.NetworkTechnology.EDGE:
-            this.technology_ = 'edge';
-            break;
-          case CrOnc.NetworkTechnology.EVDO:
-            this.technology_ = 'evdo';
-            break;
-          case CrOnc.NetworkTechnology.GPRS:
-          case CrOnc.NetworkTechnology.GSM:
-            this.technology_ = 'gsm';
-            break;
-          case CrOnc.NetworkTechnology.HSPA:
-            this.technology_ = 'hspa';
-            break;
-          case CrOnc.NetworkTechnology.HSPA_PLUS:
-            this.technology_ = 'hspa_plus';
-            break;
-          case CrOnc.NetworkTechnology.LTE:
-            this.technology_ = 'lte';
-            break;
-          case CrOnc.NetworkTechnology.LTE_ADVANCED:
-            this.technology_ = 'lte_advanced';
-            break;
-          case CrOnc.NetworkTechnology.UMTS:
-            this.technology_ = '3g';
-            break;
-        }
-      } else {
-        this.roaming_ = false;
-        this.secure_ = false;
-        this.technology_ = '';
-      }
-    },
-  });
-})();
+  /**
+   * @return {boolean}
+   * @private
+   */
+  showSecure_: function() {
+    let networkState = this.networkState;
+    if (networkState.Type == CrOnc.Type.WI_FI && networkState.WiFi) {
+      let security = networkState.WiFi.Security;
+      return !!security && security != 'None';
+    }
+    return false;
+  },
+});
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_item.html b/ui/webui/resources/cr_elements/network/cr_network_list_item.html
index 616385f..eed8280 100644
--- a/ui/webui/resources/cr_elements/network/cr_network_list_item.html
+++ b/ui/webui/resources/cr_elements/network/cr_network_list_item.html
@@ -23,21 +23,16 @@
         flex-direction: row;
       }
 
-      #divIcon {
-        display: flex;
-        flex-direction: column;
-        flex: 0 0 auto;
-        justify-content: center;
-        width: 32px;
-      }
-
       #divOuter {
+        -webkit-margin-after: 4px;
+        -webkit-margin-before: 4px;
+        -webkit-margin-end: 12px;
+        -webkit-margin-start: 4px;
         align-items: center;
         border-style: none;
         display: flex;
         flex-direction: row;
         height: 32px;
-        margin: 4px 12px;
       }
 
       #divOuter[first-custom-item] {
@@ -71,28 +66,30 @@
         color: var(--google-green-500);
       }
 
-      cr-network-icon,
       iron-icon {
         height: 24px;
         width: 24px;
       }
 
+      cr-network-icon,
+      iron-icon {
+        -webkit-padding-end: 8px;
+      }
+
       cr-policy-network-indicator {
         padding: 0 var(--cr-icon-padding);
       }
     </style>
     <div id="divOuter" actionable$="[[isListItem]]"
         first-custom-item$="[[item.isFirstCustomItem]]">
-      <div id="divIcon">
-        <template is="dom-if" if="[[networkState]]">
-          <cr-network-icon is-list-item="[[isListItem]]"
-              network-state="[[networkState]]">
-          </cr-network-icon>
-        </template>
-        <template is="dom-if" if="[[item.polymerIcon]]">
-          <iron-icon icon="[[item.polymerIcon]]"></iron-icon>
-        </template>
-      </div>
+      <template is="dom-if" if="[[networkState]]">
+        <cr-network-icon is-list-item="[[isListItem]]"
+            network-state="[[networkState]]">
+        </cr-network-icon>
+      </template>
+      <template is="dom-if" if="[[item.polymerIcon]]">
+        <iron-icon icon="[[item.polymerIcon]]"></iron-icon>
+      </template>
       <div id="divText" class="layout horizontal flex">
         <div id="itemName" connected$="[[isConnected_(networkState)]]">
           [[getItemName_(item, isListItem)]]
diff --git a/ui/webui/resources/cr_elements/network/cr_network_list_item.js b/ui/webui/resources/cr_elements/network/cr_network_list_item.js
index 4ec86667..68921209 100644
--- a/ui/webui/resources/cr_elements/network/cr_network_list_item.js
+++ b/ui/webui/resources/cr_elements/network/cr_network_list_item.js
@@ -96,12 +96,12 @@
   },
 
   /** @private */
-  isStateTextVisible_() {
+  isStateTextVisible_: function() {
     return !!this.networkState && (!this.isListItem || this.isConnected_());
   },
 
   /** @private */
-  isStateTextConnected_() {
+  isStateTextConnected_: function() {
     return this.isListItem && this.isConnected_();
   },
 
diff --git a/ui/webui/resources/cr_elements/network/ethernet.png b/ui/webui/resources/cr_elements/network/ethernet.png
deleted file mode 100644
index 2db7fa0a..0000000
--- a/ui/webui/resources/cr_elements/network/ethernet.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/mobile.png b/ui/webui/resources/cr_elements/network/mobile.png
deleted file mode 100644
index 9c2d026..0000000
--- a/ui/webui/resources/cr_elements/network/mobile.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/network_icons.html b/ui/webui/resources/cr_elements/network/network_icons.html
new file mode 100644
index 0000000..66a8853
--- /dev/null
+++ b/ui/webui/resources/cr_elements/network/network_icons.html
@@ -0,0 +1,38 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="network" size="20">
+  <svg>
+    <defs>
+      <!-- These icons were converted from source .svg files. -->
+
+      <!-- Badges -->
+      <g id="badge-1x"><path d="M0 1h1V0h1v5H1V2H0M3 2h1v1H3V2zm1 1h1v1H4V3zM3 4h1v1H3V4zm2 0h1v1H5V4zm0-2h1v1H5V2z"/></g>
+      <g id="badge-3g"><path d="M9 0H5v5h4V2H7v1h1v1H6V1h3M3 3v2h1V0H0v1h3v1H1v1h2zM0 4h3v1H0V4z"/></g>
+      <g id="badge-4g"><path d="M3 4v1h1V0H3v3H0v1h3zM0 2h1v1H0V2zm1-1h1v1H1V1zm1-1h1v1H2V0zM9 0H5v5h4V2H7v1h1v1H6V1h3"/></g>
+      <g id="badge-edge"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0"/></g>
+      <g id="badge-evdo"><path d="M0 0v5h3V4H1V3h1V2H1V1h2V0M4 0h1v2H4V0zm1 2h1v2H5V2zm2 0h1v2H7V2zm1-2h1v2H8V0zM6 4h1v1H6V4z"/></g>
+      <g id="badge-gsm"><path d="M4 0H0v5h4V2H2v1h1v1H1V1h3"/></g>
+      <g id="badge-hspa"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0"/></g>
+      <g id="badge-hspa-plus"><path d="M0 0h1v2h2V0h1v5H3V3H1v2H0M7 1V0H6v1H5v1h1v1h1V2h1V1H7z"/></g>
+      <g id="badge-lte"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0"/></g>
+      <g id="badge-lte-advanced"><path d="M0 0v5h3V4H1V0M3 0h5v1H6v4H5V1H3M9 0v5h3V4h-2V3h1V2h-1V1h2V0M15 1V0h-1v1h-1v1h1v1h1V2h1V1h-1z"/></g>
+      <g id="badge-secure"><path d="M1 4c0-.552.45-1 .99-1h4.02c.546 0 .99.444.99 1v3c0 .552-.45 1-.99 1H1.99C1.445 8 1 7.556 1 7V4zm2.5 1h1v1h-1V5z"/><path d="M2 1h1v3H2V1zm3 0h1v3H5V1zm.5-1v1h-3V0h3z"/></g>
+
+      <!-- Network Icons -->
+      <g id="settings-ethernet"><path d="M6.015 6L2 10.5 6.015 15 7 14.227 3.663 10.5 7 6.773 6.015 6zM7 11h1v-1H7v1zm5-1h-1v1h1v-1zm-3 1h1v-1H9v1zm3-4.227l3.337 3.727L12 14.227l.985.773L17 10.5 12.985 6 12 6.773z"/></g>
+      <g id="signal-cellular-0-bar"><path fill-opacity=".3" d="M2 18h16V2"/></g>
+      <g id="signal-cellular-1-bar"><path fill-opacity=".3" d="M2.094 18H18V1.984"/><path d="M8 12l-6 6h6"/></g>
+      <g id="signal-cellular-2-bar"><path fill-opacity=".3" d="M2 18h16V2"/><path d="M11.003 9L1 18h10.003"/></g>
+      <g id="signal-cellular-3-bar"><path fill-opacity=".3" d="M2 18h16.02V2"/><path d="M14 6L2 18h12"/></g>
+      <g id="signal-cellular-4-bar"><path d="M2 18h16V2"/></g>
+      <g id="signal-wifi-0-bar"><path d="M10.01 17.99L20 5.46C19.613 5.164 15.765 2 10 2 4.227 2 .387 5.165 0 5.46l9.99 12.53.01.01.01-.01z" fill-opacity=".3"/></g>
+      <g id="signal-wifi-1-bar"><path d="M10.01 17.99L20 5.46C19.613 5.164 15.765 2 10 2 4.227 2 .387 5.165 0 5.46l9.99 12.53.01.01.01-.01z" fill-opacity=".3"/><path d="M5.558 12.402L10 17.992V18l.008-.008 4.442-5.59c-.233-.177-1.925-1.57-4.45-1.57-2.525 0-4.217 1.393-4.442 1.57z"/></g>
+      <g id="signal-wifi-2-bar"><path d="M10.01 17.99L20 5.46C19.613 5.164 15.765 2 10 2 4.227 2 .387 5.165 0 5.46l9.99 12.53.01.01.01-.01z" fill-opacity=".3"/><path d="M3.992 10.452l6 7.548H10l.008-.008 6-7.55c-.3-.226-2.59-2.11-6.008-2.11-3.417 0-5.708 1.884-6.008 2.12z"/></g>
+      <g id="signal-wifi-3-bar"><path d="M10.01 17.99L20 5.46C19.613 5.164 15.765 2 10 2 4.227 2 .387 5.165 0 5.46l9.99 12.53.01.01.01-.01z" fill-opacity=".3"/><path d="M2.942 9.143l7.05 8.85L10 18l.008-.008 7.05-8.85C16.7 8.867 14.008 6.668 10 6.668s-6.7 2.2-7.058 2.476z"/></g>
+      <g id="signal-wifi-4-bar"><path d="M10.01 17.99L20 5.46C19.613 5.164 15.765 2 10 2 4.227 2 .387 5.165 0 5.46l9.99 12.53.01.01.01-.01z"/></g>
+      <g id="signal-wifi-off"><path d="M9.7 2.3c-1.25 0-2.408.158-3.458.4l8.608 8.6 4.55-5.667C19.025 5.35 15.292 2.3 9.7 2.3zM2.425 1L1.367 2.067l1.708 1.716C1.292 4.6.192 5.483 0 5.633L10 18l2.958-4.342 2.767 2.767 1.058-1.058-2.883-2.884L2.425 1z"/></g>
+      <g id="vpn-key"><path d="M6.364 5C3.956 5 2 7.018 2 9.5S3.956 14 6.364 14c1.898 0 3.512-1.252 4.11-3H13.5v3h3v-3H18V8h-7.527c-.597-1.747-2.21-3-4.11-3zm0 6c-.8 0-1.455-.675-1.455-1.5S5.563 8 6.363 8c.8 0 1.454.675 1.454 1.5S7.164 11 6.364 11z"/></g>
+    </defs>
+  </svg>
+</iron-iconset-svg>
diff --git a/ui/webui/resources/cr_elements/network/vpn.png b/ui/webui/resources/cr_elements/network/vpn.png
deleted file mode 100644
index 5503851..0000000
--- a/ui/webui/resources/cr_elements/network/vpn.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements/network/wifi.png b/ui/webui/resources/cr_elements/network/wifi.png
deleted file mode 100644
index f3c281f..0000000
--- a/ui/webui/resources/cr_elements/network/wifi.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/cr_elements_images_chromeos.grdp b/ui/webui/resources/cr_elements_images_chromeos.grdp
deleted file mode 100644
index 96dc03d1..0000000
--- a/ui/webui/resources/cr_elements_images_chromeos.grdp
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_CDMA1XRTT"
-           file="cr_elements/network/badge_1x.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_3G"
-           file="cr_elements/network/badge_3g.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_4G"
-           file="cr_elements/network/badge_4g.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EDGE"
-           file="cr_elements/network/badge_edge.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EVDO"
-           file="cr_elements/network/badge_evdo.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_GPRS"
-           file="cr_elements/network/badge_gsm.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA"
-           file="cr_elements/network/badge_hspa.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA_PLUS"
-           file="cr_elements/network/badge_hspa_plus.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE"
-           file="cr_elements/network/badge_lte.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE_ADVANCED"
-           file="cr_elements/network/badge_lte_advanced.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_ROAMING"
-           file="cr_elements/network/badge_roaming.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_SECURE"
-           file="cr_elements/network/badge_secure.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_ETHERNET"
-           file="cr_elements/network/ethernet.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_MOBILE"
-           file="cr_elements/network/mobile.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_VPN"
-           file="cr_elements/network/vpn.png" 
-           type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_WIFI"
-           file="cr_elements/network/wifi.png" 
-           type="BINDATA" />
-</grit-part>
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp
index 2988c82..ff28ec4 100644
--- a/ui/webui/resources/cr_elements_resources.grdp
+++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -72,6 +72,10 @@
     <structure name="IDR_CR_ELEMENTS_CR_ONC_TYPES_JS"
                file="../../webui/resources/cr_elements/network/cr_onc_types.js"
                type="chrome_html" />
+    <structure name="IDR_CR_ELEMENTS_NETWORK_ICONS_HTML"
+               file="../../webui/resources/cr_elements/network/network_icons.html"
+               type="chrome_html"
+               preprocess="true" />
   </if>
   <structure name="IDR_CR_ELEMENTS_CR_POLICY_INDICATOR_CSS"
              file="../../webui/resources/cr_elements/policy/cr_policy_indicator.css"
diff --git a/ui/webui/resources/js/cr/ui/focus_grid.js b/ui/webui/resources/js/cr/ui/focus_grid.js
index 40c782e..000fb051 100644
--- a/ui/webui/resources/js/cr/ui/focus_grid.js
+++ b/ui/webui/resources/js/cr/ui/focus_grid.js
@@ -146,8 +146,11 @@
     /**
      * Makes sure that at least one row is active. Should be called once, after
      * adding all rows to FocusGrid.
+     * @param {number=} preferredRow The row to select if no other row is
+     *     active. Selects the first item if this is beyond the range of the
+     *     grid.
      */
-    ensureRowActive: function() {
+    ensureRowActive: function(preferredRow) {
       if (this.rows.length == 0)
         return;
 
@@ -156,7 +159,7 @@
           return;
       }
 
-      this.rows[0].makeActive(true);
+      (this.rows[preferredRow || 0] || this.rows[0]).makeActive(true);
     },
   };
 
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index bf588f6..6b70e902 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -196,10 +196,6 @@
                file="images/throbber_small.svg" type="BINDATA" />
       <include name="IDR_WEBUI_IMAGES_TRASH"
                file="images/trash.png" type="BINDATA" />
-
-      <if expr="chromeos">
-        <part file="cr_elements_images_chromeos.grdp" />
-      </if>
     </includes>
     <structures>
       <structure name="IDR_WEBUI_CSS_ACTION_LINK"