diff --git a/DEPS b/DEPS
index f8a2e52d..6a778af5 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': '313c42553b5355fc7e2625114d58da6f8dc71e51',
+  'pdfium_revision': '8f2fa901ed692f95a134b2bed6a0af3ec14e06df',
   # 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.
@@ -232,7 +232,7 @@
     Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'd66ea106e37dd2428cfc117821a95ee1eff92f23', # commit position 16876
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'ecefa58dfa5b471817398f09c332a36e8ed8eeab', # commit position 16890
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS
index e5506e4..370dde6 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -66,7 +66,9 @@
                   '|media/video/capture/android'
     },
     'android_studio': {
-      'filepath': 'build/android/gradle/'
+      'filepath': 'build/android/gradle/' \
+                  '|docs/android_studio.md' \
+                  '|tools/android/android_studio'
     },
     'android_tab': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/Tab'
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 6e976fc..e9dfb5e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4256,6 +4256,8 @@
     "browsing_data/mock_browsing_data_media_license_helper.h",
     "browsing_data/mock_browsing_data_quota_helper.cc",
     "browsing_data/mock_browsing_data_quota_helper.h",
+    "browsing_data/mock_browsing_data_remover.cc",
+    "browsing_data/mock_browsing_data_remover.h",
     "browsing_data/mock_browsing_data_service_worker_helper.cc",
     "browsing_data/mock_browsing_data_service_worker_helper.h",
     "download/download_test_file_activity_observer.cc",
diff --git a/chrome/browser/browsing_data/mock_browsing_data_remover.cc b/chrome/browser/browsing_data/mock_browsing_data_remover.cc
new file mode 100644
index 0000000..0bf01cf
--- /dev/null
+++ b/chrome/browser/browsing_data/mock_browsing_data_remover.cc
@@ -0,0 +1,181 @@
+// 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 "chrome/browser/browsing_data/mock_browsing_data_remover.h"
+
+#include "content/public/browser/browsing_data_filter_builder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+base::Time some_time;
+}
+
+MockBrowsingDataRemover::MockBrowsingDataRemover(
+    content::BrowserContext* context) {}
+
+MockBrowsingDataRemover::~MockBrowsingDataRemover() {
+  DCHECK(!expected_calls_.size()) << "Expectations were set but not verified.";
+}
+
+void MockBrowsingDataRemover::Shutdown() {}
+
+void MockBrowsingDataRemover::Remove(const base::Time& delete_begin,
+                                     const base::Time& delete_end,
+                                     int remove_mask,
+                                     int origin_type_mask) {
+  RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
+                 std::unique_ptr<content::BrowsingDataFilterBuilder>(),
+                 nullptr);
+}
+
+void MockBrowsingDataRemover::RemoveAndReply(const base::Time& delete_begin,
+                                             const base::Time& delete_end,
+                                             int remove_mask,
+                                             int origin_type_mask,
+                                             Observer* observer) {
+  DCHECK(observer);
+  RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
+                 std::unique_ptr<content::BrowsingDataFilterBuilder>(),
+                 observer);
+}
+
+void MockBrowsingDataRemover::RemoveWithFilter(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask,
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder) {
+  DCHECK_EQ(0, remove_mask & ~FILTERABLE_DATATYPES);
+  DCHECK(filter_builder);
+  RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
+                 std::move(filter_builder), nullptr);
+}
+
+void MockBrowsingDataRemover::RemoveWithFilterAndReply(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask,
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+    Observer* observer) {
+  DCHECK_EQ(0, remove_mask & ~FILTERABLE_DATATYPES);
+  DCHECK(filter_builder);
+  DCHECK(observer);
+  RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
+                 std::move(filter_builder), observer);
+}
+
+void MockBrowsingDataRemover::RemoveInternal(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask,
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+    BrowsingDataRemover::Observer* observer) {
+  actual_calls_.emplace_back(delete_begin, delete_end, remove_mask,
+                             origin_type_mask, std::move(filter_builder),
+                             true /* should_compare_filter */);
+
+  // |observer| is not recorded in |actual_calls_| to be compared with
+  // expectations, because it's created internally in ClearSiteData() and
+  // it's unknown to this. However, it is tested implicitly, because we use
+  // it for the completion callback, so an incorrect |observer| will fail
+  // the test by waiting for the callback forever.
+  DCHECK(observer);
+  observer->OnBrowsingDataRemoverDone();
+}
+
+void MockBrowsingDataRemover::AddObserver(Observer* observer) {}
+
+void MockBrowsingDataRemover::RemoveObserver(Observer* observer) {}
+
+const base::Time& MockBrowsingDataRemover::GetLastUsedBeginTime() {
+  NOTIMPLEMENTED();
+  return some_time;
+}
+
+const base::Time& MockBrowsingDataRemover::GetLastUsedEndTime() {
+  NOTIMPLEMENTED();
+  return some_time;
+}
+
+int MockBrowsingDataRemover::GetLastUsedRemovalMask() {
+  NOTIMPLEMENTED();
+  return -1;
+}
+
+int MockBrowsingDataRemover::GetLastUsedOriginTypeMask() {
+  NOTIMPLEMENTED();
+  return -1;
+}
+
+void MockBrowsingDataRemover::SetEmbedderDelegate(
+    std::unique_ptr<BrowsingDataRemoverDelegate> embedder_delegate) {
+  NOTIMPLEMENTED();
+}
+
+BrowsingDataRemoverDelegate* MockBrowsingDataRemover::GetEmbedderDelegate()
+    const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void MockBrowsingDataRemover::ExpectCall(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask,
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder) {
+  expected_calls_.emplace_back(delete_begin, delete_end, remove_mask,
+                               origin_type_mask, std::move(filter_builder),
+                               true /* should_compare_filter */);
+}
+
+void MockBrowsingDataRemover::ExpectCallDontCareAboutFilterBuilder(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask) {
+  expected_calls_.emplace_back(
+      delete_begin, delete_end, remove_mask, origin_type_mask,
+      std::unique_ptr<content::BrowsingDataFilterBuilder>(),
+      false /* should_compare_filter */);
+}
+
+void MockBrowsingDataRemover::VerifyAndClearExpectations() {
+  EXPECT_EQ(expected_calls_, actual_calls_);
+  expected_calls_.clear();
+  actual_calls_.clear();
+}
+
+MockBrowsingDataRemover::CallParameters::CallParameters(
+    const base::Time& delete_begin,
+    const base::Time& delete_end,
+    int remove_mask,
+    int origin_type_mask,
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+    bool should_compare_filter)
+    : delete_begin_(delete_begin),
+      delete_end_(delete_end),
+      remove_mask_(remove_mask),
+      origin_type_mask_(origin_type_mask),
+      filter_builder_(std::move(filter_builder)),
+      should_compare_filter_(should_compare_filter) {}
+MockBrowsingDataRemover::CallParameters::~CallParameters() {}
+
+bool MockBrowsingDataRemover::CallParameters::operator==(
+    const CallParameters& other) const {
+  const CallParameters& a = *this;
+  const CallParameters& b = other;
+
+  if (a.delete_begin_ != b.delete_begin_ || a.delete_end_ != b.delete_end_ ||
+      a.remove_mask_ != b.remove_mask_ ||
+      a.origin_type_mask_ != b.origin_type_mask_) {
+    return false;
+  }
+
+  if (!a.should_compare_filter_ || !b.should_compare_filter_)
+    return true;
+  return *a.filter_builder_ == *b.filter_builder_;
+}
diff --git a/chrome/browser/browsing_data/mock_browsing_data_remover.h b/chrome/browser/browsing_data/mock_browsing_data_remover.h
new file mode 100644
index 0000000..e220a082
--- /dev/null
+++ b/chrome/browser/browsing_data/mock_browsing_data_remover.h
@@ -0,0 +1,115 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_BROWSING_DATA_MOCK_BROWSING_DATA_REMOVER_H_
+#define CHROME_BROWSER_BROWSING_DATA_MOCK_BROWSING_DATA_REMOVER_H_
+
+#include <list>
+
+#include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+}
+
+// A BrowsingDataRemover that only records Remove*() calls.
+// Some of the other methods are NOTIMPLEMENTED() as they are not needed for
+// existing testcases.
+class MockBrowsingDataRemover : public BrowsingDataRemover,
+                                public KeyedService {
+ public:
+  explicit MockBrowsingDataRemover(content::BrowserContext* context);
+
+  ~MockBrowsingDataRemover() override;
+
+  // KeyedService:
+  void Shutdown() override;
+
+  // BrowsingDataRemover:
+  void Remove(const base::Time& delete_begin,
+              const base::Time& delete_end,
+              int remove_mask,
+              int origin_type_mask) override;
+  void RemoveAndReply(const base::Time& delete_begin,
+                      const base::Time& delete_end,
+                      int remove_mask,
+                      int origin_type_mask,
+                      Observer* observer) override;
+  void RemoveWithFilter(const base::Time& delete_begin,
+                        const base::Time& delete_end,
+                        int remove_mask,
+                        int origin_type_mask,
+                        std::unique_ptr<content::BrowsingDataFilterBuilder>
+                            filter_builder) override;
+  void RemoveWithFilterAndReply(
+      const base::Time& delete_begin,
+      const base::Time& delete_end,
+      int remove_mask,
+      int origin_type_mask,
+      std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+      Observer* observer) override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  const base::Time& GetLastUsedBeginTime() override;
+  const base::Time& GetLastUsedEndTime() override;
+  int GetLastUsedRemovalMask() override;
+  int GetLastUsedOriginTypeMask() override;
+  void SetEmbedderDelegate(
+      std::unique_ptr<BrowsingDataRemoverDelegate> embedder_delegate) override;
+  BrowsingDataRemoverDelegate* GetEmbedderDelegate() const override;
+
+  // Add an expected call for testing.
+  void ExpectCall(
+      const base::Time& delete_begin,
+      const base::Time& delete_end,
+      int remove_mask,
+      int origin_type_mask,
+      std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder);
+
+  // Add an expected call that doesn't have to match the filter_builder.
+  void ExpectCallDontCareAboutFilterBuilder(const base::Time& delete_begin,
+                                            const base::Time& delete_end,
+                                            int remove_mask,
+                                            int origin_type_mask);
+
+  // Verify that expected and actual calls match.
+  void VerifyAndClearExpectations();
+
+ private:
+  class CallParameters {
+   public:
+    CallParameters(
+        const base::Time& delete_begin,
+        const base::Time& delete_end,
+        int remove_mask,
+        int origin_type_mask,
+        std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+        bool should_compare_filter);
+    ~CallParameters();
+
+    bool operator==(const CallParameters& other) const;
+
+   private:
+    base::Time delete_begin_;
+    base::Time delete_end_;
+    int remove_mask_;
+    int origin_type_mask_;
+    std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder_;
+    bool should_compare_filter_;
+  };
+
+  void RemoveInternal(
+      const base::Time& delete_begin,
+      const base::Time& delete_end,
+      int remove_mask,
+      int origin_type_mask,
+      std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder,
+      Observer* observer);
+
+  std::list<CallParameters> actual_calls_;
+  std::list<CallParameters> expected_calls_;
+};
+
+#endif  // CHROME_BROWSER_BROWSING_DATA_MOCK_BROWSING_DATA_REMOVER_H_
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index d70e22d..70725c8 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -19,7 +19,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
-#include "chrome/browser/browsing_data/browsing_data_remover_impl.h"
+#include "chrome/browser/browsing_data/mock_browsing_data_remover.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -343,113 +343,6 @@
 
 namespace {
 
-// A BrowsingDataRemover that only records calls.
-// TODO(msramek): Once BrowsingDataRemoverImpl moves to content/ (non-public),
-// it will not be possible to inherit from it here. However, at that time
-// this functionality will become redundant, as it will no longer be necessary
-// to call to chrome/ to perform deletion. Remove it then.
-class MockBrowsingDataRemover : public BrowsingDataRemoverImpl {
- public:
-  explicit MockBrowsingDataRemover(content::BrowserContext* context)
-      : BrowsingDataRemoverImpl(context) {}
-
-  ~MockBrowsingDataRemover() override {
-    DCHECK(!expected_calls_.size())
-        << "Expectations were set but not verified.";
-  }
-
-  void RemoveInternal(const base::Time& delete_begin,
-                      const base::Time& delete_end,
-                      int remove_mask,
-                      int origin_type_mask,
-                      std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
-                      BrowsingDataRemover::Observer* observer) override {
-    actual_calls_.emplace_back(delete_begin, delete_end, remove_mask,
-                               origin_type_mask, std::move(filter_builder),
-                               true /* should_compare_filter */);
-
-    // |observer| is not recorded in |actual_calls_| to be compared with
-    // expectations, because it's created internally in ClearSiteData() and
-    // it's unknown to this. However, it is tested implicitly, because we use
-    // it for the completion callback, so an incorrect |observer| will fail
-    // the test by waiting for the callback forever.
-    DCHECK(observer);
-    observer->OnBrowsingDataRemoverDone();
-  }
-
-  void ExpectCall(
-      const base::Time& delete_begin,
-      const base::Time& delete_end,
-      int remove_mask,
-      int origin_type_mask,
-      std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
-    expected_calls_.emplace_back(delete_begin, delete_end, remove_mask,
-                                 origin_type_mask, std::move(filter_builder),
-                                 true /* should_compare_filter */);
-  }
-
-  void ExpectCallDontCareAboutFilterBuilder(const base::Time& delete_begin,
-                                            const base::Time& delete_end,
-                                            int remove_mask,
-                                            int origin_type_mask) {
-    expected_calls_.emplace_back(delete_begin, delete_end, remove_mask,
-                                 origin_type_mask,
-                                 std::unique_ptr<BrowsingDataFilterBuilder>(),
-                                 false /* should_compare_filter */);
-  }
-
-  void VerifyAndClearExpectations() {
-    EXPECT_EQ(expected_calls_, actual_calls_);
-    expected_calls_.clear();
-    actual_calls_.clear();
-  }
-
- private:
-  class CallParameters {
-   public:
-    CallParameters(const base::Time& delete_begin,
-                   const base::Time& delete_end,
-                   int remove_mask,
-                   int origin_type_mask,
-                   std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
-                   bool should_compare_filter)
-        : delete_begin_(delete_begin),
-          delete_end_(delete_end),
-          remove_mask_(remove_mask),
-          origin_type_mask_(origin_type_mask),
-          filter_builder_(std::move(filter_builder)),
-          should_compare_filter_(should_compare_filter) {}
-    ~CallParameters() {}
-
-    bool operator==(const CallParameters& other) const {
-      const CallParameters& a = *this;
-      const CallParameters& b = other;
-
-      if (a.delete_begin_ != b.delete_begin_ ||
-          a.delete_end_ != b.delete_end_ ||
-          a.remove_mask_ != b.remove_mask_ ||
-          a.origin_type_mask_ != b.origin_type_mask_) {
-        return false;
-      }
-
-      if (!a.should_compare_filter_ || !b.should_compare_filter_)
-        return true;
-      return *a.filter_builder_ == *b.filter_builder_;
-    }
-
-   private:
-    base::Time delete_begin_;
-    base::Time delete_end_;
-    int remove_mask_;
-    int origin_type_mask_;
-    std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_;
-    bool should_compare_filter_;
-  };
-
-  std::list<CallParameters> actual_calls_;
-  std::list<CallParameters> expected_calls_;
-};
-
 // Tests for ChromeContentBrowserClient::ClearSiteData().
 class ChromeContentBrowserClientClearSiteDataTest : public testing::Test {
  public:
diff --git a/chrome/browser/metrics/google_update_metrics_provider_win.cc b/chrome/browser/metrics/google_update_metrics_provider_win.cc
index 3e50a42..d2999ca 100644
--- a/chrome/browser/metrics/google_update_metrics_provider_win.cc
+++ b/chrome/browser/metrics/google_update_metrics_provider_win.cc
@@ -118,11 +118,8 @@
   google_update_metrics.last_checked =
       GoogleUpdateSettings::GetGoogleUpdateLastChecked(is_system_install);
   GoogleUpdateSettings::GetUpdateDetailForGoogleUpdate(
-      is_system_install,
       &google_update_metrics.google_update_data);
-  GoogleUpdateSettings::GetUpdateDetail(
-      is_system_install,
-      &google_update_metrics.product_data);
+  GoogleUpdateSettings::GetUpdateDetail(&google_update_metrics.product_data);
   return google_update_metrics;
 }
 
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js b/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js
index ab17296..f16f9e7 100644
--- a/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js
+++ b/chrome/browser/resources/chromeos/chromevox/braille/braille_display_manager.js
@@ -57,8 +57,8 @@
    * @type {!cvox.BrailleDisplayState}
    * @private
    */
-  this.displayState_ = {available: false, textRowCount: undefined,
-      textColumnCount: undefined};
+  this.displayState_ = {available: false, textRowCount: 0,
+      textColumnCount: 0};
   /**
    * State reported from the chrome api, reflecting a real hardware
    * display.
@@ -110,6 +110,37 @@
 
 
 /**
+ * Alpha threshold for a pixel to be possibly displayed as a raised dot when
+ * converting an image to braille, where 255 means only fully-opaque
+ * pixels can be raised (if their luminance passes the luminance threshold),
+ * and 0 means that alpha is effectively ignored and only luminance matters.
+ * @const
+ * @private
+ */
+cvox.BrailleDisplayManager.ALPHA_THRESHOLD_ = 255;
+
+
+/**
+ * Luminance threshold for a pixel to be displayed as a raised dot when
+ * converting an image to braille, on a scale of 0 (black) to 255 (white).
+ * A pixel whose luminance is less than the given threshold will be raised.
+ * @const
+ * @private
+ */
+cvox.BrailleDisplayManager.LUMINANCE_THRESHOLD_ = 128;
+
+
+/**
+ * Array mapping an index in an 8-dot braille cell, in column-first order,
+ * to its corresponding bit mask in the standard braille cell encoding.
+ * @const
+ * @private
+ */
+cvox.BrailleDisplayManager.COORDS_TO_BRAILLE_DOT_ =
+    [0x1, 0x2, 0x4, 0x40, 0x8, 0x10, 0x20, 0x80];
+
+
+/**
  * @param {!cvox.NavBraille} content Content to send to the braille display.
  * @param {!cvox.ExpandingBrailleTranslator.ExpansionType} expansionType
  *     If the text has a {@code ValueSpan}, this indicates how that part
@@ -123,6 +154,92 @@
 
 
 /**
+ * Takes an image, in the form of a data url, and displays it in braille
+ * onto the physical braille display and the virtual braille captions display.
+ * @param {!string} imageUrl The image, in the form of a data url.
+ */
+cvox.BrailleDisplayManager.prototype.setImageContent = function(imageUrl) {
+  if (!this.displayState_.available) {
+    return;
+  }
+
+  // The number of dots in a braille cell.
+  // TODO(dmazzoni): Both multi-line braille displays we're testing with
+  // are 6-dot (2 x 3), but we should have a way to detect that via brltty.
+  var cellWidth = 2;
+  var cellHeight = 3;
+  var maxCellHeight = 4;
+
+  var rows = this.displayState_.textRowCount;
+  var columns = this.displayState_.textColumnCount;
+  var imageDataUrl = imageUrl;
+  var imgElement = document.createElement('img');
+  imgElement.src = imageDataUrl;
+  imgElement.onload = (function() {
+    var canvas = document.createElement('canvas');
+    var context = canvas.getContext('2d');
+    canvas.width = columns * cellWidth;
+    canvas.height = rows * cellHeight;
+    context.drawImage(imgElement, 0, 0, canvas.width, canvas.height);
+    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
+    var data = imageData.data;
+    var outputData = [];
+
+    // Convert image to black and white by thresholding the luminance for
+    // all opaque (non-transparent) pixels.
+    for (var i = 0; i < data.length; i += 4) {
+      var red = data[i];
+      var green = data[i + 1];
+      var blue = data[i + 2];
+      var alpha = data[i + 3];
+      var luminance =
+          0.2126 * red +
+          0.7152 * green +
+          0.0722 * blue;
+      // Show braille pin if the alpha is greater than the threshold and
+      // the luminance is less than the threshold.
+      var show = (alpha >= cvox.BrailleDisplayManager.ALPHA_THRESHOLD_ &&
+          luminance < cvox.BrailleDisplayManager.LUMINANCE_THRESHOLD_);
+      outputData.push(show);
+    }
+
+    // Convert black-and-white array to the proper encoding for Braille cells.
+    var brailleBuf = new ArrayBuffer(rows * columns);
+    var view = new Uint8Array(brailleBuf);
+    for (var i = 0; i < rows; i++) {
+      for (var j = 0; j < columns; j++) {
+        // Index in braille array
+        var brailleIndex = i * columns + j;
+        for (var cellColumn = 0; cellColumn < cellWidth; cellColumn++) {
+          for (var cellRow = 0; cellRow < cellHeight; cellRow++) {
+            var bitmapIndex =
+                (i * columns * cellHeight + j + cellRow * columns) * cellWidth
+                + cellColumn;
+            if (outputData[bitmapIndex]) {
+              view[brailleIndex] +=
+                  cvox.BrailleDisplayManager.COORDS_TO_BRAILLE_DOT_[
+                      cellColumn * maxCellHeight + cellRow];
+            }
+          }
+        }
+      }
+    }
+
+    if (this.realDisplayState_.available) {
+      chrome.brailleDisplayPrivate.writeDots(
+          brailleBuf,
+          this.displayState_.textColumnCount,
+          this.displayState_.textRowCount);
+    }
+    if (cvox.BrailleCaptionsBackground.isEnabled()) {
+      cvox.BrailleCaptionsBackground.setImageContent(
+          brailleBuf, rows, columns);
+    }
+  }).bind(this);
+};
+
+
+/**
  * Sets the command listener.  When a command is invoked, the listener will be
  * called with the BrailleKeyEvent corresponding to the command and the content
  * that was present on the display when the command was invoked.  The content
@@ -136,8 +253,19 @@
 
 
 /**
- * @param {!cvox.BrailleDisplayState} newState Display state reported
- *     by the extension API.
+ * @return {!cvox.BrailleDisplayState} The current display state.
+ */
+cvox.BrailleDisplayManager.prototype.getDisplayState = function() {
+  return this.displayState_;
+};
+
+
+/**
+ * @param {{available: boolean, textRowCount: (number|undefined),
+ *     textColumnCount: (number|undefined)}} newState Display state reported
+ *     by the extension API. Note that the type is almost the same as
+ *     cvox.BrailleDisplayState except that the extension API allows
+ *     some fields to be undefined, while cvox.BrailleDisplayState does not.
  * @private
  */
 cvox.BrailleDisplayManager.prototype.refreshDisplayState_ = function(
@@ -154,7 +282,11 @@
     }
     this.refresh_();
   }.bind(this);
-  this.realDisplayState_ = newState;
+  this.realDisplayState_ = {
+    available: newState.available,
+    textRowCount: newState.textRowCount || 0,
+    textColumnCount: newState.textColumnCount || 0
+  };
   if (newState.available) {
     processDisplayState(newState);
     // Update the dimensions of the virtual braille captions display to those
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js b/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js
index e108c68..9d411ff 100644
--- a/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js
+++ b/chrome/browser/resources/chromeos/chromevox/braille/braille_key_types.js
@@ -127,6 +127,7 @@
 /**
  * The state of a braille display as represented in the
  * chrome.brailleDisplayPrivate API.
- * @typedef {{available: boolean, textCellCount: (number|undefined)}}
+ * @typedef {{available: boolean, textRowCount: number,
+ *     textColumnCount: number}}
  */
 cvox.BrailleDisplayState;
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js
index caad634..796122d8 100644
--- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js
+++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/braille_captions_background.js
@@ -90,6 +90,28 @@
 };
 
 /**
+ * @param {ArrayBuffer} cells Braille cells shown on the display.
+ * @param {number} rows Number of rows to display.
+ * @param {number} columns Number of columns to display.
+ */
+cvox.BrailleCaptionsBackground.setImageContent = function(cells, rows,
+    columns) {
+  var self = cvox.BrailleCaptionsBackground;
+  // Convert the cells to Unicode braille pattern characters.
+  var byteBuf = new Uint8Array(cells);
+  var brailleChars = '';
+
+  for (var i = 0; i < byteBuf.length; ++i) {
+    brailleChars += String.fromCharCode(
+        self.BRAILLE_UNICODE_BLOCK_START | byteBuf[i]);
+  }
+
+  var groups = [['Image', brailleChars]];
+  var data = {groups: groups, rows: rows, cols: columns};
+  (new PanelCommand(PanelCommandType.UPDATE_BRAILLE, data)).send();
+};
+
+/**
  * @param {string} brailleChars Braille characters shown on the display.
  * @param {string} text Text of the shown braille.
  * @param {Array<number>} brailleToText Map of Braille cells to the first
@@ -167,6 +189,6 @@
       });
     });
   } else {
-    callback({available: false});
+    callback({available: false, textRowCount: 0, textColumnCount: 0});
   }
 };
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json b/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
index 15a6048..de5c4bf 100644
--- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
+++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
@@ -726,6 +726,16 @@
       }
     },
     {
+      "command": "viewGraphicAsBraille",
+      "sequence": {
+        "cvoxModifier": true,
+        "keys": {
+          "keyCode": [71],
+          "altKey": [true]
+        }
+      }
+    },
+    {
       "command": "toggleSelection",
       "sequence": {
         "cvoxModifier": true,
diff --git a/chrome/browser/resources/chromeos/chromevox/common/command_store.js b/chrome/browser/resources/chromeos/chromevox/common/command_store.js
index 3503a78..71e69f8 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/command_store.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/command_store.js
@@ -669,6 +669,9 @@
                 announce: true,
                 msgId: 'braille_bottom',
                 category: 'braille'},
+  'viewGraphicAsBraille': {announce: true,
+                         msgId: 'view_graphic_as_braille',
+                         category: 'braille'},
 
   // Developer commands.
   'enableConsoleTts': {announce: false,
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
index 04f3bd5..2208f0bb 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -486,4 +486,14 @@
   };
 };
 
+/**
+ * Matches against nodes that we may be able to retrieve image data from.
+ * @param {!AutomationNode} node
+ * @return {boolean}
+ */
+AutomationPredicate.supportsImageData = AutomationPredicate.roles([
+    Role.CANVAS,
+    Role.IMAGE,
+    Role.VIDEO]);
+
 });  // goog.scope
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index 9eb0047..cdcd119 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -397,6 +397,10 @@
    * @override
    */
   setCurrentRange: function(newRange) {
+    // Clear anything that was frozen on the braille display whenever
+    // the user navigates.
+    cvox.ChromeVox.braille.thaw();
+
     if (newRange && !newRange.isValid())
       return;
 
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
index e483f40..e7c95ba5 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
@@ -9,10 +9,12 @@
 goog.provide('CommandHandler');
 
 goog.require('ChromeVoxState');
+goog.require('CustomAutomationEvent');
 goog.require('Output');
 goog.require('cvox.ChromeVoxBackground');
 
 goog.scope(function() {
+var AutomationEvent = chrome.automation.AutomationEvent;
 var AutomationNode = chrome.automation.AutomationNode;
 var Dir = constants.Dir;
 var EventType = chrome.automation.EventType;
@@ -578,7 +580,9 @@
           .withRichSpeechAndBraille(current, null, Output.EventType.NAVIGATE)
           .go();
       return false;
-
+    case 'viewGraphicAsBraille':
+      CommandHandler.viewGraphicAsBraille_(current);
+      return false;
     // Table commands.
     case 'previousRow':
       dir = Dir.BACKWARD;
@@ -774,4 +778,69 @@
   }
 };
 
+/**
+ * To support viewGraphicAsBraille_(), the current image node.
+ * @type {AutomationNode?};
+ */
+CommandHandler.imageNode_;
+
+/**
+ * Called when an image frame is received on a node.
+ * @param {!(AutomationEvent|CustomAutomationEvent)} event The event.
+ * @private
+ */
+CommandHandler.onImageFrameUpdated_ = function(event) {
+  var target = event.target;
+  if (target != CommandHandler.imageNode_)
+    return;
+
+  if (!AutomationUtil.isDescendantOf(
+      ChromeVoxState.instance.currentRange.start.node,
+      CommandHandler.imageNode_)) {
+    CommandHandler.imageNode_.removeEventListener(
+        EventType.IMAGE_FRAME_UPDATED,
+        CommandHandler.onImageFrameUpdated_, false);
+    CommandHandler.imageNode_ = null;
+    return;
+  }
+
+  if (target.imageDataUrl) {
+    cvox.ChromeVox.braille.writeRawImage(target.imageDataUrl);
+    cvox.ChromeVox.braille.freeze();
+  }
+};
+
+/**
+ * Handle the command to view the first graphic within the current range
+ * as braille.
+ * @param {!AutomationNode} current The current range.
+ * @private
+ */
+CommandHandler.viewGraphicAsBraille_ = function(current) {
+  if (CommandHandler.imageNode_) {
+    CommandHandler.imageNode_.removeEventListener(
+        EventType.IMAGE_FRAME_UPDATED,
+        CommandHandler.onImageFrameUpdated_, false);
+    CommandHandler.imageNode_ = null;
+  }
+
+  // Find the first node within the current range that supports image data.
+  var imageNode = AutomationUtil.findNodePost(
+      current.start.node, Dir.FORWARD,
+      AutomationPredicate.supportsImageData);
+  if (!imageNode)
+    return;
+
+  imageNode.addEventListener(EventType.IMAGE_FRAME_UPDATED,
+                             this.onImageFrameUpdated_, false);
+  CommandHandler.imageNode_ = imageNode;
+  if (imageNode.imageDataUrl) {
+    var event = new CustomAutomationEvent(
+        EventType.IMAGE_FRAME_UPDATED, imageNode, 'page');
+    CommandHandler.onImageFrameUpdated_(event);
+  } else {
+    imageNode.getImageData(0, 0);
+  }
+};
+
 }); //  goog.scope
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css
index 1aa972b..9577d1b 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css
@@ -119,6 +119,10 @@
   width: 100%;
 }
 
+::-webkit-scrollbar {
+  display: none;
+}
+
 .braille-table-holder {
   flex-grow: 1;
 }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js
index cd33c16..35147fc 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js
@@ -505,7 +505,9 @@
   }
 
   var row1, row2;
+  // Number of rows already written.
   rowCount = 0;
+  // Number of cells already written in this row.
   var cellCount = cols;
   for (var i = 0; i < groups.length; i++) {
     if (cellCount == cols) {
@@ -535,32 +537,42 @@
     bottomCell.setAttribute('data-companionIDs', i + '-textCell');
     bottomCell.className = 'unhighlighted-cell';
     if (cellCount + groups[i][1].length > cols) {
-      bottomCell.innerHTML = groups[i][1].substring(0, cols - cellCount);
-      if (rowCount == rows)
-        break;
-      rowCount++;
-      row1 = this.brailleTableElement_.insertRow(-1);
-      if (sideBySide) {
-        // Side by side.
-        row2 = this.brailleTableElement2_.insertRow(-1);
-      } else {
-        // Interleaved.
-        row2 = this.brailleTableElement_.insertRow(-1);
-      }
-      var bottomCell2 = row2.insertCell(-1);
-      bottomCell2.id = i + '-brailleCell2';
-      bottomCell2.setAttribute('data-companionIDs',
-          i + '-textCell ' + i + '-brailleCell');
-      bottomCell.setAttribute('data-companionIDs',
-          bottomCell.getAttribute('data-companionIDs') +
-          ' ' + i + '-brailleCell2');
-      topCell.setAttribute('data-companionID2',
-          bottomCell.getAttribute('data-companionIDs') +
-          ' ' + i + '-brailleCell2');
+      var brailleText = groups[i][1];
+      while (cellCount + brailleText.length > cols) {
+        // At this point we already have a bottomCell to fill, so fill it.
+        bottomCell.innerHTML = brailleText.substring(0, cols - cellCount);
+        // Update to see what we still have to fill.
+        brailleText = brailleText.substring(cols - cellCount);
+        // Make new row.
+        if (rowCount == rows)
+          break;
+        rowCount++;
+        row1 = this.brailleTableElement_.insertRow(-1);
+        if (sideBySide) {
+          // Side by side.
+          row2 = this.brailleTableElement2_.insertRow(-1);
+        } else {
+          // Interleaved.
+          row2 = this.brailleTableElement_.insertRow(-1);
+        }
+        var bottomCell2 = row2.insertCell(-1);
+        bottomCell2.id = i + '-brailleCell2';
+        bottomCell2.setAttribute('data-companionIDs',
+            i + '-textCell ' + i + '-brailleCell');
+        bottomCell.setAttribute('data-companionIDs',
+            bottomCell.getAttribute('data-companionIDs') +
+            ' ' + i + '-brailleCell2');
+        topCell.setAttribute('data-companionID2',
+            bottomCell.getAttribute('data-companionIDs') +
+            ' ' + i + '-brailleCell2');
 
-      bottomCell2.className = 'unhighlighted-cell';
-      bottomCell2.innerHTML = groups[i][1].substring(cols - cellCount);
-      cellCount = bottomCell2.innerHTML.length;
+        bottomCell2.className = 'unhighlighted-cell';
+        bottomCell = bottomCell2;
+        cellCount = 0;
+      }
+      // Fill the rest.
+      bottomCell.innerHTML = brailleText;
+      cellCount = brailleText.length;
     } else {
       bottomCell.innerHTML = groups[i][1];
       cellCount += groups[i][1].length;
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js
index 35a1d684..9b145cb 100644
--- a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js
+++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille.js
@@ -72,6 +72,30 @@
 };
 
 
+/** @override */
+cvox.ChromeBraille.prototype.writeRawImage = function(imageDataUrl) {
+  // Do Nothing.
+};
+
+
+/** @override */
+cvox.ChromeBraille.prototype.freeze = function() {
+  // Do Nothing.
+};
+
+
+/** @override */
+cvox.ChromeBraille.prototype.thaw = function() {
+  // Do Nothing.
+};
+
+
+/** @override */
+cvox.ChromeBraille.prototype.getDisplayState = function() {
+  return {available: false, textRowCount: 0, textColumnCount: 0};
+};
+
+
 /** @private */
 cvox.ChromeBraille.prototype.updateLastContentId_ = function() {
   this.lastContentId_ = cvox.ExtensionBridge.uniqueId() + '.' +
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
index 7ac49299..d168672 100644
--- a/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
+++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/braille_background.js
@@ -58,15 +58,48 @@
   this.inputHandler_ = opt_inputHandlerForTest ||
       new cvox.BrailleInputHandler(this.translatorManager_);
   this.inputHandler_.init();
+
+  /** @private {boolean} */
+  this.frozen_ = false;
 };
 
 
 /** @override */
 cvox.BrailleBackground.prototype.write = function(params) {
+  if (this.frozen_) {
+    return;
+  }
   this.setContent_(params, null);
 };
 
 
+/** @override */
+cvox.BrailleBackground.prototype.writeRawImage = function(imageDataUrl) {
+  if (this.frozen_) {
+    return;
+  }
+  this.displayManager_.setImageContent(imageDataUrl);
+};
+
+
+/** @override */
+cvox.BrailleBackground.prototype.freeze = function() {
+  this.frozen_ = true;
+};
+
+
+/** @override */
+cvox.BrailleBackground.prototype.thaw = function() {
+  this.frozen_ = false;
+};
+
+
+/** @override */
+cvox.BrailleBackground.prototype.getDisplayState = function() {
+  return this.displayManager_.getDisplayState();
+};
+
+
 /**
  * @return {cvox.BrailleTranslatorManager} The translator manager used by this
  *     instance.
diff --git a/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js b/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js
index 9ecba721..754a961 100644
--- a/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js
+++ b/chrome/browser/resources/chromeos/chromevox/host/interface/braille_interface.js
@@ -27,3 +27,29 @@
  */
 cvox.BrailleInterface.prototype.write =
     function(params) { };
+
+/**
+ * Takes an image in the form of a data url and outputs it to a Braille
+ * display.
+ * @param {!string} imageDataUrl The image to output, in the form of a
+ * dataUrl.
+ */
+cvox.BrailleInterface.prototype.writeRawImage =
+    function(imageDataUrl) { };
+
+/**
+ * Freeze whatever is on the braille display until the next call to thaw().
+ */
+cvox.BrailleInterface.prototype.freeze = function() { };
+
+
+/**
+ * Un-freeze the braille display so that it can be written to again.
+ */
+cvox.BrailleInterface.prototype.thaw = function() { };
+
+
+/**
+ * @return {!cvox.BrailleDisplayState} The current display state.
+ */
+cvox.BrailleInterface.prototype.getDisplayState = function() { };
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
index b5b47be6..64392049 100644
--- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
+++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -2355,6 +2355,9 @@
       <message desc="Describes dots on a refreshable braille display pressed with the space key. For example, dots 1 2 3 4 8 chord" name="IDS_CHROMEVOX_BRAILLE_CHORD">
         $1 chord
       </message>
+      <message desc="The description of the command that allows the user to view a graphic as a dot pattern on a refreshable braille display." name="IDS_CHROMEVOX_VIEW_GRAPHIC_AS_BRAILLE">
+        View Graphic As Braille
+      </message>
       <message desc="Spoken to describe an access key.  An access key consists of a single letter. When pressed along with a modifier (usually alt, but depends on platform), a targetted node will be activated." name="IDS_CHROMEVOX_ACCESS_KEY">
         has access key, <ph name="key">$1</ph>
       </message>
diff --git a/chrome/browser/ssl/common_name_mismatch_handler.cc b/chrome/browser/ssl/common_name_mismatch_handler.cc
index 6519a13..9a7c9f3e 100644
--- a/chrome/browser/ssl/common_name_mismatch_handler.cc
+++ b/chrome/browser/ssl/common_name_mismatch_handler.cc
@@ -11,6 +11,7 @@
 #include "net/base/load_flags.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_request_status.h"
 
 CommonNameMismatchHandler::CommonNameMismatchHandler(
@@ -37,7 +38,36 @@
 
   check_url_callback_ = callback;
 
-  url_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::HEAD, this);
+  // Create traffic annotation tag.
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("ssl_name_mismatch_lookup", R"(
+        semantics {
+          sender: "SSL Name Mismatch Handler"
+          description:
+            "If Chromium cannot make a secure connection to a site, this can "
+            "be because the site is misconfigured. The site may be serving a "
+            "security certificate intended for another site. If the SSL Common "
+            "Name Mismatch Handling feature is enabled, Chromium will try to "
+            "detect if one of the domains listed in the site's certificate is "
+            "available by issuing requests to those domains. If the response "
+            "indicates that an alternative site for which the certificate is "
+            "valid is available, Chromium will automatically redirect the user "
+            "to the alternative site."
+          trigger: "Resource load."
+          data: "An HTTP HEAD request to the alternative site."
+          destination: WEBSITE
+        }
+        policy {
+          cookies_allowed: false
+          setting:
+            "Users can disable this feature by command line flag "
+            "'--disable-feature=SSLCommonNameMismatchHandling'."
+          policy_exception_justification:
+            "Not implemented."
+        })");
+
+  url_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::HEAD, this,
+                                         traffic_annotation);
   url_fetcher_->SetAutomaticallyRetryOn5xx(false);
   url_fetcher_->SetRequestContext(request_context_.get());
 
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc
index 311cc75e..aec8fe2 100644
--- a/chrome/browser/ui/ash/system_tray_client.cc
+++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -359,9 +359,9 @@
   // Get the Chrome update severity.
   ash::mojom::UpdateSeverity severity = GetUpdateSeverity(detector);
 
-  // Flash updates are elevated severity unless the Chrome severity is higher.
+  // Flash updates are low severity unless the Chrome severity is higher.
   if (flash_update_available_)
-    severity = std::max(severity, ash::mojom::UpdateSeverity::ELEVATED);
+    severity = std::max(severity, ash::mojom::UpdateSeverity::LOW);
 
   system_tray_->ShowUpdateIcon(severity, detector->is_factory_reset_required());
 }
diff --git a/chrome/browser/ui/webui/devtools_ui.cc b/chrome/browser/ui/webui/devtools_ui.cc
index 522b4cd..afafafeb 100644
--- a/chrome/browser/ui/webui/devtools_ui.cc
+++ b/chrome/browser/ui/webui/devtools_ui.cc
@@ -23,6 +23,7 @@
 #include "content/public/common/user_agent.h"
 #include "net/base/filename_util.h"
 #include "net/base/load_flags.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -239,8 +240,32 @@
         new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
     return;
   }
-  net::URLFetcher* fetcher =
-      net::URLFetcher::Create(url, net::URLFetcher::GET, this).release();
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("devtools_hard_coded_data_source", R"(
+        semantics {
+          sender: "Developer Tools Remote Data Request From Google"
+          description:
+            "This service fetches Chrome DevTools front-end files from the "
+            "cloud for the remote debugging scenario."
+          trigger:
+            "When user attaches to mobile phone for debugging."
+          data: "None"
+          destination: GOOGLE_OWNED_SERVICE
+        }
+        policy {
+          cookies_allowed: true
+          cookies_store: "user"
+          setting: "This feature cannot be disabled by settings."
+          policy {
+            DeveloperToolsDisabled {
+              policy_options {mode: MANDATORY}
+              value: True
+            }
+          }
+        })");
+  net::URLFetcher* fetcher = net::URLFetcher::Create(url, net::URLFetcher::GET,
+                                                     this, traffic_annotation)
+                                 .release();
   pending_[fetcher] = callback;
   fetcher->SetRequestContext(request_context_.get());
   fetcher->Start();
@@ -254,8 +279,37 @@
         new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
     return;
   }
-  net::URLFetcher* fetcher =
-      net::URLFetcher::Create(url, net::URLFetcher::GET, this).release();
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("devtools_free_data_source", R"(
+        semantics {
+          sender: "Developer Tools Remote Data Request"
+          description:
+            "This service fetches Chrome DevTools front-end files from the "
+            "cloud for the remote debugging scenario. This can only happen if "
+            "a URL was passed on the commandline via flag "
+            "'--custom-devtools-frontend'. This URL overrides the default "
+            "fetching from a Google website, see "
+            "devtools_hard_coded_data_source."
+          trigger:
+            "When command line flag --custom-devtools-frontend is specified "
+            "and DevTools is opened."
+          data: "None"
+          destination: WEBSITE
+        }
+        policy {
+          cookies_allowed: true
+          cookies_store: "user"
+          setting: "This feature cannot be disabled by settings."
+          policy {
+            DeveloperToolsDisabled {
+              policy_options {mode: MANDATORY}
+              DeveloperToolsDisabled: True
+            }
+          }
+        })");
+  net::URLFetcher* fetcher = net::URLFetcher::Create(url, net::URLFetcher::GET,
+                                                     this, traffic_annotation)
+                                 .release();
   pending_[fetcher] = callback;
   fetcher->SetRequestContext(request_context_.get());
   fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE);
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc
index 47f07a6..683586a 100644
--- a/chrome/installer/util/google_update_settings.cc
+++ b/chrome/installer/util/google_update_settings.cc
@@ -837,17 +837,14 @@
   return product_found;
 }
 
-bool GoogleUpdateSettings::GetUpdateDetailForGoogleUpdate(bool system_install,
-                                                          ProductData* data) {
-  return GetUpdateDetailForApp(system_install,
-                               google_update::kGoogleUpdateUpgradeCode,
-                               data);
+bool GoogleUpdateSettings::GetUpdateDetailForGoogleUpdate(ProductData* data) {
+  return GetUpdateDetailForApp(!InstallUtil::IsPerUserInstall(),
+                               google_update::kGoogleUpdateUpgradeCode, data);
 }
 
-bool GoogleUpdateSettings::GetUpdateDetail(bool system_install,
-                                           ProductData* data) {
-  return GetUpdateDetailForApp(system_install, install_static::GetAppGuid(),
-                               data);
+bool GoogleUpdateSettings::GetUpdateDetail(ProductData* data) {
+  return GetUpdateDetailForApp(!InstallUtil::IsPerUserInstall(),
+                               install_static::GetAppGuid(), data);
 }
 
 bool GoogleUpdateSettings::SetExperimentLabels(
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h
index d14fb21..99174f5 100644
--- a/chrome/installer/util/google_update_settings.h
+++ b/chrome/installer/util/google_update_settings.h
@@ -311,12 +311,11 @@
 
   // Returns product data for Google Update.  (Equivalent to calling
   // GetUpdateDetailForAppGuid with the app guid for Google Update itself.)
-  static bool GetUpdateDetailForGoogleUpdate(bool system_install,
-                                             ProductData* data);
+  static bool GetUpdateDetailForGoogleUpdate(ProductData* data);
 
   // Returns product data for the current product. (Equivalent to calling
   // GetUpdateDetailForApp with the app guid stored in BrowserDistribution.)
-  static bool GetUpdateDetail(bool system_install, ProductData* data);
+  static bool GetUpdateDetail(ProductData* data);
 
   // Sets |experiment_labels| as the Google Update experiment_labels value in
   // the ClientState key for this Chrome product, if appropriate. If
diff --git a/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py b/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
index 55fabcd3..df1f9c8 100644
--- a/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
+++ b/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
@@ -27,7 +27,7 @@
   def AddResults(self, tab, results):
     results_json = None
     try:
-      results_json = tab.EvaluateJavaScript2(
+      results_json = tab.EvaluateJavaScript(
           'JSON.stringify(window.perfResults)')
     except exceptions.EvaluateException:
       pass
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
index 2dd858c..5fc9ff92 100644
--- a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
@@ -18,7 +18,7 @@
   def ChooseSink(self, tab, sink_name):
     """Chooses a specific sink in the list."""
 
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         var sinks = window.document.getElementById("media-router-container").
             shadowRoot.getElementById("sink-list").getElementsByTagName("span");
         for (var i=0; i<sinks.length; i++) {
@@ -33,7 +33,7 @@
     """Closes media router dialog."""
 
     try:
-      tab.ExecuteJavaScript2(
+      tab.ExecuteJavaScript(
           'window.document.getElementById("media-router-container").' +
           'shadowRoot.getElementById("container-header").shadowRoot.' +
           'getElementById("close-button").click();')
@@ -51,7 +51,7 @@
       if tab.url == 'chrome://media-router/':
         if self.CheckIfExistingRoute(tab, sink_name):
           self.ChooseSink(tab, sink_name)
-          tab.ExecuteJavaScript2(
+          tab.ExecuteJavaScript(
               "window.document.getElementById('media-router-container')."
               "shadowRoot.getElementById('route-details').shadowRoot."
               "getElementById('close-route-button').click();")
@@ -62,7 +62,7 @@
   def CheckIfExistingRoute(self, tab, sink_name):
     """"Checks if there is existing route for the specific sink."""
 
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         var sinks = window.document.getElementById('media-router-container').
           allSinks;
         var sink_id = null;
@@ -82,7 +82,7 @@
           }
         }""",
         sink_name=sink_name)
-    route = tab.EvaluateJavaScript2('!!window.__telemetry_route_id')
+    route = tab.EvaluateJavaScript('!!window.__telemetry_route_id')
     logging.info('Is there existing route? ' + str(route))
     return route
 
@@ -90,7 +90,7 @@
                              error_message, timeout=5):
     """Executes async javascript function and waits until it finishes."""
 
-    action_runner.ExecuteJavaScript2(script)
+    action_runner.ExecuteJavaScript(script)
     self._WaitForResult(action_runner, verify_func, error_message,
                         timeout=timeout)
 
@@ -99,7 +99,7 @@
 
     self._WaitForResult(
         action_runner,
-        lambda: tab.EvaluateJavaScript2(
+        lambda: tab.EvaluateJavaScript(
              '!!window.document.getElementById('
              '"media-router-container") &&'
              'window.document.getElementById('
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
index 512caf7..701a1b3 100644
--- a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
@@ -62,7 +62,7 @@
     # Wait for 5s after Chrome is opened in order to get consistent results.
     action_runner.Wait(5)
     with action_runner.CreateInteraction('Idle'):
-      action_runner.ExecuteJavaScript2('collectPerfData();')
+      action_runner.ExecuteJavaScript('collectPerfData();')
       action_runner.Wait(SESSION_TIME)
 
 
@@ -83,7 +83,7 @@
 
       self._WaitForResult(
           action_runner,
-          lambda: action_runner.EvaluateJavaScript2('initialized'),
+          lambda: action_runner.EvaluateJavaScript('initialized'),
           'Failed to initialize',
           timeout=30)
       self.CloseExistingRoute(action_runner, sink_name)
@@ -103,7 +103,7 @@
 
       self._WaitForResult(
         action_runner,
-        lambda: action_runner.EvaluateJavaScript2('currentSession'),
+        lambda: action_runner.EvaluateJavaScript('currentSession'),
          'Failed to start session',
          timeout=10)
 
@@ -112,18 +112,18 @@
           action_runner,
           js_template.Render(
               'loadMedia({{ url }});', url=utils.GetInternalVideoURL()),
-          lambda: action_runner.EvaluateJavaScript2('currentMedia'),
+          lambda: action_runner.EvaluateJavaScript('currentMedia'),
           'Failed to load media',
           timeout=120)
 
       action_runner.Wait(5)
-      action_runner.ExecuteJavaScript2('collectPerfData();')
+      action_runner.ExecuteJavaScript('collectPerfData();')
       action_runner.Wait(SESSION_TIME)
       # Stop session
       self.ExecuteAsyncJavaScript(
           action_runner,
           'stopSession();',
-          lambda: not action_runner.EvaluateJavaScript2('currentSession'),
+          lambda: not action_runner.EvaluateJavaScript('currentSession'),
           'Failed to stop session',
           timeout=30)
 
@@ -170,7 +170,7 @@
           self.WaitUntilDialogLoaded(action_runner, tab)
           if not self.CheckIfExistingRoute(tab, sink_name):
             raise page.page_test.Failure('Failed to start mirroring session.')
-      action_runner.ExecuteJavaScript2('collectPerfData();')
+      action_runner.ExecuteJavaScript('collectPerfData();')
       action_runner.Wait(SESSION_TIME)
       self.CloseExistingRoute(action_runner, sink_name)
 
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index ab40288..7418f1f 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -21,7 +21,6 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "base/test/scoped_task_scheduler.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_checker.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -233,7 +232,6 @@
 
   void OnPauseCompleted();
 
-  base::test::ScopedTaskScheduler task_scheduler_;
   MediaPipelineDeviceParams::MediaSyncType sync_type_;
   MediaPipelineDeviceParams::AudioStreamType audio_type_;
   std::unique_ptr<TaskRunnerImpl> task_runner_;
@@ -905,6 +903,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, Mp3Playback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("sfx.mp3");
   PauseBeforeEos();
@@ -913,6 +913,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, AacPlayback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("sfx.m4a");
   PauseBeforeEos();
@@ -921,6 +923,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, VorbisPlayback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeIgnorePts);
   ConfigureForAudioOnly("sfx.ogg");
   Start();
@@ -930,6 +934,8 @@
 // TODO(kmackay) FFmpegDemuxForTest can't handle AC3 or EAC3.
 
 TEST_F(AudioVideoPipelineDeviceTest, OpusPlayback_Optional) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("bear-opus.ogg");
   PauseBeforeEos();
@@ -938,6 +944,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, FlacPlayback_Optional) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("bear.flac");
   PauseBeforeEos();
@@ -946,6 +954,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, H264Playback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear.h264", true /* raw_h264 */);
   PauseBeforeEos();
@@ -954,6 +964,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, WebmPlaybackWithPause) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   // Setup to pause for 100ms every 500ms
   AddPause(base::TimeDelta::FromMilliseconds(500),
@@ -965,6 +977,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, Vp8Playback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear-vp8a.webm", false /* raw_h264 */);
   Start();
@@ -972,6 +986,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, WebmPlayback) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForFile("bear-640x360.webm");
   PauseBeforeEos();
@@ -982,6 +998,7 @@
 // TODO(kmackay) FFmpegDemuxForTest can't handle HEVC or VP9.
 
 TEST_F(AudioVideoPipelineDeviceTest, AudioBackendStates) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
   Initialize();
   MediaPipelineBackend::AudioDecoder* audio_decoder =
       backend()->CreateAudioDecoder();
@@ -998,6 +1015,7 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, AudioEffectsBackendStates) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
   set_audio_type(MediaPipelineDeviceParams::kAudioStreamSoundEffects);
   set_sync_type(MediaPipelineDeviceParams::kModeIgnorePts);
   Initialize();
@@ -1015,6 +1033,7 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, VideoBackendStates) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
   Initialize();
   MediaPipelineBackend::VideoDecoder* video_decoder =
       backend()->CreateVideoDecoder();
@@ -1031,6 +1050,7 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, AudioImmediateEos) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
   Initialize();
   MediaPipelineBackend::AudioDecoder* audio_decoder =
       backend()->CreateAudioDecoder();
@@ -1043,10 +1063,10 @@
   SetAudioFeeder(std::move(feeder));
 
   StartImmediateEosTest();
-  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, VideoImmediateEos) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
   Initialize();
   MediaPipelineBackend::VideoDecoder* video_decoder =
       backend()->CreateVideoDecoder();
@@ -1059,10 +1079,11 @@
   SetVideoFeeder(std::move(feeder));
 
   StartImmediateEosTest();
-  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, Mp3Playback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("sfx.mp3");
   PauseBeforeEos();
@@ -1072,6 +1093,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, AacPlayback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("sfx.m4a");
   PauseBeforeEos();
@@ -1081,6 +1104,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, VorbisPlayback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeIgnorePts);
   ConfigureForAudioOnly("sfx.ogg");
   AddEffectsStreams();
@@ -1091,6 +1116,8 @@
 // TODO(kmackay) FFmpegDemuxForTest can't handle AC3 or EAC3.
 
 TEST_F(AudioVideoPipelineDeviceTest, OpusPlayback_WithEffectsStreams_Optional) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("bear-opus.ogg");
   PauseBeforeEos();
@@ -1100,6 +1127,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, FlacPlayback_WithEffectsStreams_Optional) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForAudioOnly("bear.flac");
   PauseBeforeEos();
@@ -1109,6 +1138,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, H264Playback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear.h264", true /* raw_h264 */);
   PauseBeforeEos();
@@ -1118,6 +1149,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, WebmPlaybackWithPause_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   // Setup to pause for 100ms every 500ms
   AddPause(base::TimeDelta::FromMilliseconds(500),
@@ -1130,6 +1163,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, Vp8Playback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear-vp8a.webm", false /* raw_h264 */);
   AddEffectsStreams();
@@ -1138,6 +1173,8 @@
 }
 
 TEST_F(AudioVideoPipelineDeviceTest, WebmPlayback_WithEffectsStreams) {
+  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
+
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForFile("bear-640x360.webm");
   PauseBeforeEos();
diff --git a/components/proximity_auth/e2e_test/cros.py b/components/proximity_auth/e2e_test/cros.py
index a1ef764..6b407d3e 100644
--- a/components/proximity_auth/e2e_test/cros.py
+++ b/components/proximity_auth/e2e_test/cros.py
@@ -71,21 +71,21 @@
 
   @property
   def is_lockscreen(self):
-    return self._oobe.EvaluateJavaScript2(
+    return self._oobe.EvaluateJavaScript(
         '!document.getElementById("sign-out-user-item").hidden')
 
   @property
   def auth_type(self):
-    return self._oobe.EvaluateJavaScript2(
+    return self._oobe.EvaluateJavaScript(
         '{{ @pod }}.authType', pod=self._GET_POD_JS)
 
   @property
   def smart_lock_state(self):
-    icon_shown = self._oobe.EvaluateJavaScript2(
+    icon_shown = self._oobe.EvaluateJavaScript(
         '!{{ @pod }}.customIconElement.hidden', pod=self._GET_POD_JS)
     if not icon_shown:
       return self.SmartLockState.NOT_SHOWN
-    class_list_dict = self._oobe.EvaluateJavaScript2(
+    class_list_dict = self._oobe.EvaluateJavaScript(
         '{{ @pod }}.customIconElement.querySelector(".custom-icon").classList',
         pod=self._GET_POD_JS)
     class_list = [v for k,v in class_list_dict.items() if k != 'length']
@@ -126,10 +126,10 @@
     assert(self.auth_type == self.AuthType.OFFLINE_PASSWORD or
            self.auth_type == self.AuthType.FORCE_OFFLINE_PASSWORD)
     oobe = self._oobe
-    oobe.EvaluateJavaScript2(
+    oobe.EvaluateJavaScript(
         '{{ @pod }}.passwordElement.value = {{ password }}',
         pod=self._GET_POD_JS, password=self._chromeos.password)
-    oobe.EvaluateJavaScript2(
+    oobe.EvaluateJavaScript(
         '{{ @pod }}.activate()', pod=self._GET_POD_JS)
     util.WaitFor(lambda: (self._chromeos.session_state ==
                           ChromeOS.SessionState.IN_SESSION),
@@ -138,7 +138,7 @@
   def UnlockWithClick(self):
     """ Clicks the user pod to unlock or sign-in. """
     assert(self.auth_type == self.AuthType.USER_CLICK)
-    self._oobe.EvaluateJavaScript2(
+    self._oobe.EvaluateJavaScript(
         '{{ @pod }}.activate()', pod=self._GET_POD_JS)
 
 
@@ -157,7 +157,7 @@
   @property
   def is_smart_lock_enabled(self):
     ''' Returns true if the settings show that Smart Lock is enabled. '''
-    return self._tab.EvaluateJavaScript2(
+    return self._tab.EvaluateJavaScript(
         '!document.getElementById("easy-unlock-enabled").hidden')
 
   def TurnOffSmartLock(self):
@@ -171,22 +171,22 @@
     """
     assert(self.is_smart_lock_enabled)
     tab = self._tab
-    tab.EvaluateJavaScript2(
+    tab.EvaluateJavaScript(
         'document.getElementById("easy-unlock-turn-off-button").click()')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         '!document.getElementById("easy-unlock-turn-off-overlay").hidden && '
         'document.getElementById("easy-unlock-turn-off-confirm") != null',
         timeout=10)
-    tab.EvaluateJavaScript2(
+    tab.EvaluateJavaScript(
         'document.getElementById("easy-unlock-turn-off-confirm").click()')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         '!document.getElementById("easy-unlock-disabled").hidden', timeout=15)
 
   def StartSetup(self):
     """ Starts the Smart Lock setup flow by clicking the button.
     """
     assert(not self.is_smart_lock_enabled)
-    self._tab.EvaluateJavaScript2(
+    self._tab.EvaluateJavaScript(
         'document.getElementById("easy-unlock-setup-button").click()')
 
   def StartSetupAndReturnApp(self):
@@ -241,7 +241,7 @@
     Raises:
       ValueError: The current state is unknown.
     '''
-    state = self._app_page.EvaluateJavaScript2(
+    state = self._app_page.EvaluateJavaScript(
         'document.body.getAttribute("step")')
     if state == 'scan':
       return SmartLockApp.PairingState.SCAN
@@ -250,7 +250,7 @@
     elif state == 'promote-smart-lock-for-android':
       return SmartLockApp.PairingState.PROMOTE_SMARTLOCK_FOR_ANDROID
     elif state == 'complete':
-      button_text = self._app_page.EvaluateJavaScript2(
+      button_text = self._app_page.EvaluateJavaScript(
           'document.getElementById("pairing-button").textContent')
       button_text = button_text.strip().lower()
       if button_text == 'try it out':
@@ -304,7 +304,7 @@
       TimeoutException: Timed out starting the trial run.
     """
     assert(self.pairing_state == self.PairingState.CLICK_FOR_TRIAL_RUN)
-    self._app_page.EvaluateJavaScript2(
+    self._app_page.EvaluateJavaScript(
         'document.getElementById("pairing-button").click()')
     util.WaitFor(lambda: (self._chromeos.session_state ==
                           ChromeOS.SessionState.LOCK_SCREEN),
@@ -316,22 +316,22 @@
     The app must be in the TRIAL_RUN_COMPLETED state.
     """
     assert(self.pairing_state == self.PairingState.TRIAL_RUN_COMPLETED)
-    self._app_page.EvaluateJavaScript2(
+    self._app_page.EvaluateJavaScript(
         'document.getElementById("pairing-button").click()')
 
   def _ClickPairingButton(self):
     # Waits are needed because the clicks occur before the button label changes.
     time.sleep(1)
-    self._app_page.EvaluateJavaScript2(
+    self._app_page.EvaluateJavaScript(
         'document.getElementById("pairing-button").click()')
     time.sleep(1)
-    self._app_page.WaitForJavaScriptCondition2(
+    self._app_page.WaitForJavaScriptCondition(
         '!document.getElementById("pairing-button").disabled', timeout=60)
     time.sleep(1)
-    self._app_page.WaitForJavaScriptCondition2(
+    self._app_page.WaitForJavaScriptCondition(
         '!document.getElementById("pairing-button-title")'
         '.classList.contains("animated-fade-out")', timeout=5)
-    self._app_page.WaitForJavaScriptCondition2(
+    self._app_page.WaitForJavaScriptCondition(
         '!document.getElementById("pairing-button-title")'
         '.classList.contains("animated-fade-in")', timeout=5)
 
@@ -395,13 +395,13 @@
   @property
   def cryptauth_access_token(self):
     try:
-      self._background_page.WaitForJavaScriptCondition2(
+      self._background_page.WaitForJavaScriptCondition(
             'var __token = __token || null; '
             'chrome.identity.getAuthToken(function(token) {'
             '  __token = token;'
             '}); '
             '__token != null', timeout=5)
-      return self._background_page.EvaluateJavaScript2('__token');
+      return self._background_page.EvaluateJavaScript('__token');
     except exceptions.TimeoutException:
       logger.error('Failed to get access token.');
       return ''
@@ -486,11 +486,11 @@
            self.session_state == self.SessionState.SIGNIN_SCREEN)
     oobe = self._browser.oobe
     def IsLockScreenResponsive():
-      return (oobe.EvaluateJavaScript2("typeof Oobe == 'function'") and
-              oobe.EvaluateJavaScript2(
+      return (oobe.EvaluateJavaScript("typeof Oobe == 'function'") and
+              oobe.EvaluateJavaScript(
                   "typeof Oobe.authenticateForTesting == 'function'"))
     util.WaitFor(IsLockScreenResponsive, 10)
-    oobe.WaitForJavaScriptCondition2(
+    oobe.WaitForJavaScriptCondition(
         'document.getElementById("pod-row") && '
         'document.getElementById("pod-row").pods && '
         'document.getElementById("pod-row").pods.length > 0', timeout=10)
@@ -508,12 +508,12 @@
     if not len(self._browser.tabs):
       self._browser.New()
     tab = self._browser.tabs[0]
-    url = tab.EvaluateJavaScript2('document.location.href')
+    url = tab.EvaluateJavaScript('document.location.href')
     if url != self._SMART_LOCK_SETTINGS_URL:
       tab.Navigate(self._SMART_LOCK_SETTINGS_URL)
 
     # Wait for settings page to be responsive.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'document.getElementById("easy-unlock-disabled") && '
         'document.getElementById("easy-unlock-enabled") && '
         '(!document.getElementById("easy-unlock-disabled").hidden || '
@@ -533,7 +533,7 @@
     app_page = self._FindSmartLockAppPage('/pairing.html')
     if app_page is not None:
       # Wait for app window to be responsive.
-      tab.WaitForJavaScriptCondition2(
+      tab.WaitForJavaScriptCondition(
             'document.getElementById("pairing-button") != null', timeout=10)
       return SmartLockApp(app_page, self)
     return None
@@ -541,14 +541,14 @@
   def SetCryptAuthStaging(self, cryptauth_staging_url):
     logger.info('Setting CryptAuth to Staging')
     try:
-      self._background_page.ExecuteJavaScript2("""
+      self._background_page.ExecuteJavaScript("""
           var key = app.CryptAuthClient.GOOGLE_API_URL_OVERRIDE_;
           var __complete = false;
           chrome.storage.local.set({key: {{ url }}}, function() {
               __complete = true;
           });""",
           url=cryptauth_staging_url)
-      self._background_page.WaitForJavaScriptCondition2(
+      self._background_page.WaitForJavaScriptCondition(
           '__complete == true', timeout=10)
     except exceptions.TimeoutException:
       logger.error('Failed to override CryptAuth to staging url.')
@@ -572,7 +572,7 @@
     except KeyError:
       return None
     for extension_page in extensions:
-      pathname = extension_page.EvaluateJavaScript2(
+      pathname = extension_page.EvaluateJavaScript(
           'document.location.pathname')
       if pathname == page_name:
         return extension_page
diff --git a/components/search_engines/template_url_fetcher.cc b/components/search_engines/template_url_fetcher.cc
index bc74b092..0db11843 100644
--- a/components/search_engines/template_url_fetcher.cc
+++ b/components/search_engines/template_url_fetcher.cc
@@ -13,11 +13,39 @@
 #include "components/search_engines/template_url_parser.h"
 #include "components/search_engines/template_url_service.h"
 #include "net/base/load_flags.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
 
+namespace {
+
+// Traffic annotation for RequestDelegate.
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("open_search", R"(
+      semantics {
+        sender: "Omnibox"
+        description:
+          "Web pages can include an OpenSearch description doc in their HTML. "
+          "In this case Chromium downloads and parses the file. The "
+          "corresponding search engine is added to the list in the browser "
+          "settings (chrome://settings/searchEngines)."
+        trigger:
+          "User visits a web page containing a <link rel="search"> tag."
+        data: "None"
+        destination: WEBSITE
+      }
+      policy {
+        cookies_allowed: false
+        setting: "This feature cannot be disabled in settings."
+        policy_exception_justification:
+          "Not implemented, considered not useful as this feature does not "
+          "upload any data."
+      })");
+
+}  // namespace
+
 // RequestDelegate ------------------------------------------------------------
 class TemplateURLFetcher::RequestDelegate : public net::URLFetcherDelegate {
  public:
@@ -61,8 +89,10 @@
     const GURL& osdd_url,
     const GURL& favicon_url,
     const URLFetcherCustomizeCallback& url_fetcher_customize_callback)
-    : url_fetcher_(
-          net::URLFetcher::Create(osdd_url, net::URLFetcher::GET, this)),
+    : url_fetcher_(net::URLFetcher::Create(osdd_url,
+                                           net::URLFetcher::GET,
+                                           this,
+                                           kTrafficAnnotation)),
       fetcher_(fetcher),
       keyword_(keyword),
       osdd_url_(osdd_url),
diff --git a/content/browser/frame_host/navigation_handle_impl_browsertest.cc b/content/browser/frame_host/navigation_handle_impl_browsertest.cc
index bdda508..dd09a06 100644
--- a/content/browser/frame_host/navigation_handle_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_handle_impl_browsertest.cc
@@ -725,9 +725,17 @@
             GURL(embedded_test_server()->GetURL("bar.com", "/title2.html")));
 }
 
+#if defined(OS_WIN)
+#define MAYBE_VerifyRequestContextTypeForFrameTree \
+  DISABLED_VerifyRequestContextTypeForFrameTree
+#else
+#define MAYBE_VerifyRequestContextTypeForFrameTree \
+  VerifyRequestContextTypeForFrameTree
+#endif
+
 // Checks that the RequestContextType value is properly set.
 IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
-                       VerifyRequestContextTypeForFrameTree) {
+                       MAYBE_VerifyRequestContextTypeForFrameTree) {
   GURL main_url(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
   GURL b_url(embedded_test_server()->GetURL(
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
index d920818f..ea75cfde 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
@@ -158,9 +158,16 @@
   ASSERT_FALSE(view_->IsShowing());
 }
 
+// http://crbug.com/696919
+#if defined(OS_WIN)
+#define MAYBE_SwapCompositorFrame DISABLED_SwapCompositorFrame
+#else
+#define MAYBE_SwapCompositorFrame SwapCompositorFrame
+#endif
+
 // Verify that OnSwapCompositorFrame behavior is correct when a delegated
 // frame is received from a renderer process.
-TEST_F(RenderWidgetHostViewChildFrameTest, SwapCompositorFrame) {
+TEST_F(RenderWidgetHostViewChildFrameTest, MAYBE_SwapCompositorFrame) {
   gfx::Size view_size(100, 100);
   gfx::Rect view_rect(view_size);
   float scale_factor = 1.f;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index c2ac56c..c4073ed 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -365,6 +365,9 @@
     WebRuntimeFeatures::enableWebVR(true);
   }
 
+  if (base::FeatureList::IsEnabled(features::kLoadingWithMojo))
+    WebRuntimeFeatures::enableLoadingWithMojo(true);
+
   // Enable explicitly enabled features, and then disable explicitly disabled
   // ones.
   if (command_line.HasSwitch(switches::kEnableBlinkFeatures)) {
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 94b685d..4a5e874 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -102,6 +102,10 @@
 const base::Feature kLazyParseCSS{"LazyParseCSS",
                                   base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Use Mojo IPC for resource loading.
+const base::Feature kLoadingWithMojo{"LoadingWithMojo",
+                                     base::FEATURE_DISABLED_BY_DEFAULT};
+
 // FeatureList definition for trials to enable the download button on
 // MediaDocument.
 const base::Feature kMediaDocumentDownloadButton{
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 5875a89..d2c13ef3 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -36,6 +36,7 @@
 CONTENT_EXPORT extern const base::Feature kGuestViewCrossProcessFrames;
 CONTENT_EXPORT extern const base::Feature kHeapCompaction;
 CONTENT_EXPORT extern const base::Feature kLazyParseCSS;
+CONTENT_EXPORT extern const base::Feature kLoadingWithMojo;
 CONTENT_EXPORT extern const base::Feature kMediaDocumentDownloadButton;
 CONTENT_EXPORT extern const base::Feature kMemoryCoordinator;
 CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
diff --git a/content/test/gpu/gpu_tests/context_lost_integration_test.py b/content/test/gpu/gpu_tests/context_lost_integration_test.py
index 670f850..98dabb1 100644
--- a/content/test/gpu/gpu_tests/context_lost_integration_test.py
+++ b/content/test/gpu/gpu_tests/context_lost_integration_test.py
@@ -106,7 +106,7 @@
 
   def _WaitForPageToFinish(self, tab):
     try:
-      tab.WaitForJavaScriptCondition2(
+      tab.WaitForJavaScriptCondition(
         'window.domAutomationController._finished', timeout=wait_timeout)
       return True
     except exceptions.TimeoutException:
@@ -122,13 +122,13 @@
       expected_kills = x + 1
 
       # Reset the test's state.
-      tab.EvaluateJavaScript2(
+      tab.EvaluateJavaScript(
         'window.domAutomationController.reset()')
 
       # If we're running the GPU process crash test, we need the test
       # to have fully reset before crashing the GPU process.
       if check_crash_count:
-        tab.WaitForJavaScriptCondition2(
+        tab.WaitForJavaScriptCondition(
           'window.domAutomationController._finished', timeout=wait_timeout)
 
       # Crash the GPU process.
@@ -154,7 +154,7 @@
         print 'Tab crashed while closing chrome://gpucrash'
       if not completed:
         self.fail('Test didn\'t complete (no context lost event?)')
-      if not tab.EvaluateJavaScript2(
+      if not tab.EvaluateJavaScript(
         'window.domAutomationController._succeeded'):
         self.fail('Test failed (context not restored properly?)')
 
@@ -162,7 +162,7 @@
     if not tab.browser.supports_system_info:
       self.fail('Browser must support system info')
 
-    if not tab.EvaluateJavaScript2(
+    if not tab.EvaluateJavaScript(
         'window.domAutomationController._succeeded'):
       self.fail('Test failed (didn\'t render content properly?)')
 
@@ -197,7 +197,7 @@
     url = self.UrlOfStaticFilePath(test_path)
     tab = self.tab
     tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
-    tab.action_runner.WaitForJavaScriptCondition2(
+    tab.action_runner.WaitForJavaScriptCondition(
       'window.domAutomationController._loaded')
 
   def _WaitForTabAndCheckCompletion(self):
@@ -205,7 +205,7 @@
     completed = self._WaitForPageToFinish(tab)
     if not completed:
       self.fail('Test didn\'t complete (no context restored event?)')
-    if not tab.EvaluateJavaScript2('window.domAutomationController._succeeded'):
+    if not tab.EvaluateJavaScript('window.domAutomationController._succeeded'):
       self.fail('Test failed (context not restored properly?)')
 
   # The browser test runner synthesizes methods with the exact name
@@ -227,7 +227,7 @@
     url = self.UrlOfStaticFilePath(test_path)
     tab = self.tab
     tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
-    tab.action_runner.WaitForJavaScriptCondition2(
+    tab.action_runner.WaitForJavaScriptCondition(
       'window.domAutomationController._finished')
 
   def _ContextLost_WebGLContextLostFromQuantity(self, test_path):
@@ -248,7 +248,7 @@
     # doesn't crash.
     tab = self.tab
     dummy_tab = tab.browser.tabs.New()
-    tab.EvaluateJavaScript2('loseContextUsingExtension()')
+    tab.EvaluateJavaScript('loseContextUsingExtension()')
     tab.Activate()
     self._WaitForTabAndCheckCompletion()
 
diff --git a/content/test/gpu/gpu_tests/depth_capture_integration_test.py b/content/test/gpu/gpu_tests/depth_capture_integration_test.py
index 9f3b6693..00e9359 100644
--- a/content/test/gpu/gpu_tests/depth_capture_integration_test.py
+++ b/content/test/gpu/gpu_tests/depth_capture_integration_test.py
@@ -77,11 +77,11 @@
     url = self.UrlOfStaticFilePath(test_path)
     tab = self.tab
     tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
-    tab.action_runner.WaitForJavaScriptCondition2(
+    tab.action_runner.WaitForJavaScriptCondition(
       'domAutomationController._finished', timeout=60)
-    if not tab.EvaluateJavaScript2('domAutomationController._succeeded'):
+    if not tab.EvaluateJavaScript('domAutomationController._succeeded'):
       self.fail('page indicated test failure:' +
-                tab.EvaluateJavaScript2('domAutomationController._error_msg'))
+                tab.EvaluateJavaScript('domAutomationController._error_msg'))
 
   @classmethod
   def _CreateExpectations(cls):
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
index 48fca640..39ab8718 100644
--- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py
+++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -142,22 +142,22 @@
 
   def _NavigateAndWait(self, test_path):
     self._Navigate(test_path)
-    self.tab.action_runner.WaitForJavaScriptCondition2(
+    self.tab.action_runner.WaitForJavaScriptCondition(
       'window.domAutomationController._finished', timeout=10)
 
   def _VerifyGpuProcessPresent(self):
     tab = self.tab
-    if not tab.EvaluateJavaScript2('chrome.gpuBenchmarking.hasGpuChannel()'):
+    if not tab.EvaluateJavaScript('chrome.gpuBenchmarking.hasGpuChannel()'):
       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.EvaluateJavaScript2(
+      gpu_driver_bug_workarounds = tab.EvaluateJavaScript(
         'GetDriverBugWorkarounds()')
     elif process_kind == "gpu_process":
-      gpu_driver_bug_workarounds = tab.EvaluateJavaScript2(
+      gpu_driver_bug_workarounds = tab.EvaluateJavaScript(
         'chrome.gpuBenchmarking.getGpuDriverBugWorkarounds()')
 
     is_present = workaround_name in gpu_driver_bug_workarounds
@@ -171,7 +171,7 @@
 
     if failure:
       print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript2('document.body.innerHTML')
+      print tab.EvaluateJavaScript('document.body.innerHTML')
       self.fail('%s %s in %s workarounds: %s'
                 % (workaround_name, error_message, process_kind,
                    gpu_driver_bug_workarounds))
@@ -199,25 +199,25 @@
 
   def _CompareAndCaptureDriverBugWorkarounds(self):
     tab = self.tab
-    if not tab.EvaluateJavaScript2('chrome.gpuBenchmarking.hasGpuProcess()'):
+    if not tab.EvaluateJavaScript('chrome.gpuBenchmarking.hasGpuProcess()'):
       self.fail('No GPU process detected')
 
-    if not tab.EvaluateJavaScript2('chrome.gpuBenchmarking.hasGpuChannel()'):
+    if not tab.EvaluateJavaScript('chrome.gpuBenchmarking.hasGpuChannel()'):
       self.fail('No GPU channel detected')
 
-    browser_list = tab.EvaluateJavaScript2('GetDriverBugWorkarounds()')
-    gpu_list = tab.EvaluateJavaScript2(
+    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.EvaluateJavaScript2('document.body.innerHTML')
+      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.EvaluateJavaScript2('browserBridge.gpuInfo.basic_info')
+    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
     disabled_gl_extensions = None
     for info in basic_infos:
       if info['description'].startswith('Disabled Extensions'):
@@ -229,7 +229,7 @@
   def _VerifyActiveAndInactiveGPUs(
       self, expected_active_gpu, expected_inactive_gpus):
     tab = self.tab
-    basic_infos = tab.EvaluateJavaScript2('browserBridge.gpuInfo.basic_info')
+    basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basic_info')
     active_gpu = []
     inactive_gpus = []
     index = 0
@@ -317,7 +317,7 @@
         '--gpu-testing-vendor-id=0x8086',
         '--gpu-testing-device-id=0x0116'])
     self._Navigate(test_path)
-    if self.tab.EvaluateJavaScript2('chrome.gpuBenchmarking.hasGpuProcess()'):
+    if self.tab.EvaluateJavaScript('chrome.gpuBenchmarking.hasGpuProcess()'):
       self.fail('GPU process detected')
 
   def _GpuProcess_driver_bug_workarounds_in_gpu_process(self, test_path):
@@ -341,7 +341,7 @@
         'on llvmpipe (LLVM 3.4, 256 bits)',
         '--gpu-testing-gl-version="3.0 Mesa 11.2"'])
       self._Navigate(test_path)
-      feature_status_list = self.tab.EvaluateJavaScript2(
+      feature_status_list = self.tab.EvaluateJavaScript(
           'browserBridge.gpuInfo.featureStatus.featureStatus')
       result = True
       for name, status in feature_status_list.items():
@@ -436,14 +436,14 @@
     tab = self.tab
     if len(diff) > 0:
       print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript2('document.body.innerHTML')
+      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.EvaluateJavaScript2('document.body.innerHTML')
+      print tab.EvaluateJavaScript('document.body.innerHTML')
       self.fail(
         'The expected disabled gl extensions are '
         'incorrect: %s != %s:' %
@@ -454,7 +454,7 @@
       '--disable-gpu',
       '--skip-gpu-data-loading'])
     self._Navigate(test_path)
-    if self.tab.EvaluateJavaScript2('chrome.gpuBenchmarking.hasGpuProcess()'):
+    if self.tab.EvaluateJavaScript('chrome.gpuBenchmarking.hasGpuProcess()'):
       self.fail('GPU process detected')
 
   def _GpuProcess_identify_active_gpu1(self, test_path):
diff --git a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py
index 2d192fb8d..2fd35ef 100644
--- a/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py
+++ b/content/test/gpu/gpu_tests/hardware_accelerated_feature_integration_test.py
@@ -68,10 +68,10 @@
     feature = args[0]
     self._Navigate(test_path)
     tab = self.tab
-    if not tab.EvaluateJavaScript2(
+    if not tab.EvaluateJavaScript(
         'VerifyHardwareAccelerated({{ feature }})', feature=feature):
       print 'Test failed. Printing page contents:'
-      print tab.EvaluateJavaScript2('document.body.innerHTML')
+      print tab.EvaluateJavaScript('document.body.innerHTML')
       self.fail('%s not hardware accelerated' % feature)
 
 def load_tests(loader, tests, pattern):
diff --git a/content/test/gpu/gpu_tests/maps_integration_test.py b/content/test/gpu/gpu_tests/maps_integration_test.py
index 8284ffc..7ae3bfc 100644
--- a/content/test/gpu/gpu_tests/maps_integration_test.py
+++ b/content/test/gpu/gpu_tests/maps_integration_test.py
@@ -86,7 +86,7 @@
     return json_contents
 
   def _SpinWaitOnRAF(self, iterations, timeout=60):
-    self.tab.ExecuteJavaScript2("""
+    self.tab.ExecuteJavaScript("""
         window.__spinWaitOnRAFDone = false;
         var iterationsLeft = {{ iterations }};
 
@@ -100,7 +100,7 @@
         }
         window.requestAnimationFrame(spin);
         """, iterations=iterations)
-    self.tab.WaitForJavaScriptCondition2(
+    self.tab.WaitForJavaScriptCondition(
         'window.__spinWaitOnRAFDone', timeout=timeout)
 
   def RunActualGpuTest(self, url, *args):
@@ -108,7 +108,7 @@
     pixel_expectations_file = args[0]
     action_runner = tab.action_runner
     action_runner.Navigate(url)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.testDone', timeout=180)
 
     # TODO(kbr): This should not be necessary, but it's not clear if the test
@@ -122,7 +122,7 @@
     if screenshot is None:
       self.fail('Could not capture screenshot')
 
-    dpr = tab.EvaluateJavaScript2('window.devicePixelRatio')
+    dpr = tab.EvaluateJavaScript('window.devicePixelRatio')
     print 'Maps\' devicePixelRatio is ' + str(dpr)
     # Even though the Maps test uses a fixed devicePixelRatio so that
     # it fetches all of the map tiles at the same resolution, on two
diff --git a/content/test/gpu/gpu_tests/pixel_integration_test.py b/content/test/gpu/gpu_tests/pixel_integration_test.py
index d7b5c66..83da9ab8 100644
--- a/content/test/gpu/gpu_tests/pixel_integration_test.py
+++ b/content/test/gpu/gpu_tests/pixel_integration_test.py
@@ -131,16 +131,16 @@
     # This property actually comes off the class, not 'self'.
     tab = self.tab
     tab.Navigate(url, script_to_evaluate_on_commit=test_harness_script)
-    tab.action_runner.WaitForJavaScriptCondition2(
+    tab.action_runner.WaitForJavaScriptCondition(
       'domAutomationController._finished', timeout=300)
-    if not tab.EvaluateJavaScript2('domAutomationController._succeeded'):
+    if not tab.EvaluateJavaScript('domAutomationController._succeeded'):
       self.fail('page indicated test failure')
     if not tab.screenshot_supported:
       self.fail('Browser does not support screenshot capture')
     screenshot = tab.Screenshot(5)
     if screenshot is None:
       self.fail('Could not capture screenshot')
-    dpr = tab.EvaluateJavaScript2('window.devicePixelRatio')
+    dpr = tab.EvaluateJavaScript('window.devicePixelRatio')
     if page.test_rect:
       screenshot = image_util.Crop(
           screenshot, page.test_rect[0] * dpr, page.test_rect[1] * dpr,
diff --git a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
index ec0efe1..1a22046 100644
--- a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
+++ b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
@@ -115,7 +115,7 @@
                                      random.randint(0, 255),
                                      255)
     tab = self.tab
-    tab.EvaluateJavaScript2(
+    tab.EvaluateJavaScript(
         "window.draw({{ red }}, {{ green }}, {{ blue }});",
         red=canvasRGB.r, green=canvasRGB.g, blue=canvasRGB.b)
     screenshot = tab.Screenshot(5)
diff --git a/content/test/gpu/gpu_tests/trace_integration_test.py b/content/test/gpu/gpu_tests/trace_integration_test.py
index 9f7e44a..71d8f5ae 100644
--- a/content/test/gpu/gpu_tests/trace_integration_test.py
+++ b/content/test/gpu/gpu_tests/trace_integration_test.py
@@ -93,7 +93,7 @@
     # Perform page navigation.
     url = self.UrlOfStaticFilePath(test_path)
     tab.Navigate(url, script_to_evaluate_on_commit=test_harness_script)
-    tab.action_runner.WaitForJavaScriptCondition2(
+    tab.action_runner.WaitForJavaScriptCondition(
       'domAutomationController._finished', timeout=30)
 
     # Stop tracing.
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
index ba31b00..3bb978e0 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -207,7 +207,7 @@
     self.tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
 
   def _CheckTestCompletion(self):
-    self.tab.action_runner.WaitForJavaScriptCondition2(
+    self.tab.action_runner.WaitForJavaScriptCondition(
         'webglTestHarness._finished', timeout=300)
     if not self._DidWebGLTestSucceed(self.tab):
       self.fail(self._WebGLTestMessages(self.tab))
@@ -222,7 +222,7 @@
 
   def _RunExtensionCoverageTest(self, test_path, *args):
     self._NavigateTo(test_path, self._GetExtensionHarnessScript())
-    self.tab.action_runner.WaitForJavaScriptCondition2(
+    self.tab.action_runner.WaitForJavaScriptCondition(
         'window._loaded', timeout=300)
     extension_list = args[0]
     webgl_version = args[1]
@@ -231,19 +231,19 @@
     for extension in extension_list:
       extension_list_string = extension_list_string + extension + ", "
     extension_list_string = extension_list_string + "]"
-    self.tab.action_runner.EvaluateJavaScript2(
+    self.tab.action_runner.EvaluateJavaScript(
         'checkSupportedExtensions({{ extensions_string }}, {{context_type}})',
         extensions_string=extension_list_string, context_type=context_type)
     self._CheckTestCompletion()
 
   def _RunExtensionTest(self, test_path, *args):
     self._NavigateTo(test_path, self._GetExtensionHarnessScript())
-    self.tab.action_runner.WaitForJavaScriptCondition2(
+    self.tab.action_runner.WaitForJavaScriptCondition(
         'window._loaded', timeout=300)
     extension = args[0]
     webgl_version = args[1]
     context_type = "webgl2" if webgl_version == 2 else "webgl"
-    self.tab.action_runner.EvaluateJavaScript2(
+    self.tab.action_runner.EvaluateJavaScript(
       'checkExtension({{ extension }}, {{ context_type }})',
       extension=extension, context_type=context_type)
     self._CheckTestCompletion()
@@ -329,11 +329,11 @@
 
   @staticmethod
   def _DidWebGLTestSucceed(tab):
-    return tab.EvaluateJavaScript2('webglTestHarness._allTestSucceeded')
+    return tab.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
 
   @staticmethod
   def _WebGLTestMessages(tab):
-    return tab.EvaluateJavaScript2('webglTestHarness._messages')
+    return tab.EvaluateJavaScript('webglTestHarness._messages')
 
   @classmethod
   def _ParseTests(cls, path, version, webgl2_only, folder_min_version):
diff --git a/docs/android_studio.md b/docs/android_studio.md
index 511d5e4e..3752122 100644
--- a/docs/android_studio.md
+++ b/docs/android_studio.md
@@ -78,7 +78,7 @@
 * Import Android style settings:
     * Help -&gt; Find Action -&gt; "Code Style" (settings) -&gt; Java -&gt;
       Manage -&gt; Import
-        * Select `third_party/android_platform/development/ide/intellij/codestyles/AndroidStyle.xml`
+        * Select `tools/android/android_studio/ChromiumStyle.xml`
 * Turn on automatic import:
     * Help -&gt; Find Action -&gt; "Auto Import"
         * Tick all the boxes under "Java" and change the dropdown to "All".
diff --git a/ios/web_view/internal/BUILD.gn b/ios/web_view/internal/BUILD.gn
index 86a7b894..4196693 100644
--- a/ios/web_view/internal/BUILD.gn
+++ b/ios/web_view/internal/BUILD.gn
@@ -20,6 +20,8 @@
     "pref_names.h",
     "web_view_browser_state.h",
     "web_view_browser_state.mm",
+    "web_view_java_script_dialog_presenter.h",
+    "web_view_java_script_dialog_presenter.mm",
     "web_view_network_delegate.cc",
     "web_view_network_delegate.h",
     "web_view_url_request_context_getter.h",
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index b23577bd..06a1af9 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -22,6 +22,7 @@
 #import "ios/web_view/internal/cwv_website_data_store_internal.h"
 #import "ios/web_view/internal/translate/web_view_translate_client.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
+#import "ios/web_view/internal/web_view_java_script_dialog_presenter.h"
 #import "ios/web_view/public/cwv_ui_delegate.h"
 #import "ios/web_view/public/cwv_web_view_configuration.h"
 #import "ios/web_view/public/cwv_web_view_delegate.h"
@@ -40,6 +41,9 @@
   std::unique_ptr<web::WebStateDelegateBridge> _webStateDelegate;
   std::unique_ptr<web::WebStateObserverBridge> _webStateObserver;
   CGFloat _loadProgress;
+  // Handles presentation of JavaScript dialogs.
+  std::unique_ptr<ios_web_view::WebViewJavaScriptDialogPresenter>
+      _javaScriptDialogPresenter;
 }
 
 @end
@@ -66,6 +70,10 @@
     _webStateDelegate = base::MakeUnique<web::WebStateDelegateBridge>(self);
     _webState->SetDelegate(_webStateDelegate.get());
 
+    _javaScriptDialogPresenter =
+        base::MakeUnique<ios_web_view::WebViewJavaScriptDialogPresenter>(
+            self, _UIDelegate);
+
     // Initialize Translate.
     ios_web_view::WebViewTranslateClient::CreateForWebState(_webState.get());
   }
@@ -155,6 +163,12 @@
   translateClient->set_translate_delegate(translateDelegate);
 }
 
+- (void)setUIDelegate:(id<CWVUIDelegate>)UIDelegate {
+  _UIDelegate = UIDelegate;
+
+  _javaScriptDialogPresenter->SetUIDelegate(_UIDelegate);
+}
+
 - (void)notifyDidUpdateWithChanges:(CRIWVWebViewUpdateType)changes {
   SEL selector = @selector(webView:didUpdateWithChanges:);
   if ([_delegate respondsToSelector:selector]) {
@@ -210,4 +224,9 @@
   return YES;
 }
 
+- (web::JavaScriptDialogPresenter*)javaScriptDialogPresenterForWebState:
+    (web::WebState*)webState {
+  return _javaScriptDialogPresenter.get();
+}
+
 @end
diff --git a/ios/web_view/internal/web_view_java_script_dialog_presenter.h b/ios/web_view/internal/web_view_java_script_dialog_presenter.h
new file mode 100644
index 0000000..1bc856b6
--- /dev/null
+++ b/ios/web_view/internal/web_view_java_script_dialog_presenter.h
@@ -0,0 +1,62 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_VIEW_INTERNAL_WEB_VIEW_JAVA_SCRIPT_DIALOG_PRESENTER_H_
+#define IOS_WEB_VIEW_INTERNAL_WEB_VIEW_JAVA_SCRIPT_DIALOG_PRESENTER_H_
+
+#import "base/ios/weak_nsobject.h"
+#import "ios/web/public/java_script_dialog_presenter.h"
+
+@class CWVWebView;
+@protocol CWVUIDelegate;
+
+namespace ios_web_view {
+
+// WebView implementation of JavaScriptDialogPresenter. Passes JavaScript alert
+// handling to |ui_delegate_|.
+class WebViewJavaScriptDialogPresenter : public web::JavaScriptDialogPresenter {
+ public:
+  WebViewJavaScriptDialogPresenter(CWVWebView* web_view,
+                                   id<CWVUIDelegate> ui_delegate);
+  ~WebViewJavaScriptDialogPresenter();
+
+  void SetUIDelegate(id<CWVUIDelegate> ui_delegate);
+
+  // web::JavaScriptDialogPresenter overrides:
+  void RunJavaScriptDialog(web::WebState* web_state,
+                           const GURL& origin_url,
+                           web::JavaScriptDialogType dialog_type,
+                           NSString* message_text,
+                           NSString* default_prompt_text,
+                           const web::DialogClosedCallback& callback) override;
+  void CancelDialogs(web::WebState* web_state) override;
+
+ private:
+  // Displays JavaScript alert.
+  void HandleJavaScriptAlert(const GURL& origin_url,
+                             NSString* message_text,
+                             const web::DialogClosedCallback& callback);
+
+  // Displays JavaScript confirm dialog.
+  void HandleJavaScriptConfirmDialog(const GURL& origin_url,
+                                     NSString* message_text,
+                                     const web::DialogClosedCallback& callback);
+
+  // Displays JavaScript text prompt.
+  void HandleJavaScriptTextPrompt(const GURL& origin_url,
+                                  NSString* message_text,
+                                  NSString* default_prompt_text,
+                                  const web::DialogClosedCallback& callback);
+
+  // The underlying delegate handling the dialog UI.
+  base::WeakNSProtocol<id<CWVUIDelegate>> ui_delegate_;
+  // The web view which originated the dialogs.
+  base::WeakNSObject<CWVWebView> web_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebViewJavaScriptDialogPresenter);
+};
+
+}  // namespace ios_web_view
+
+#endif  // IOS_WEB_VIEW_INTERNAL_WEB_VIEW_JAVA_SCRIPT_DIALOG_PRESENTER_H_
diff --git a/ios/web_view/internal/web_view_java_script_dialog_presenter.mm b/ios/web_view/internal/web_view_java_script_dialog_presenter.mm
new file mode 100644
index 0000000..ff87cda
--- /dev/null
+++ b/ios/web_view/internal/web_view_java_script_dialog_presenter.mm
@@ -0,0 +1,117 @@
+// 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 "ios/web_view/internal/web_view_java_script_dialog_presenter.h"
+
+#import "ios/web_view/public/cwv_ui_delegate.h"
+#import "net/base/mac/url_conversions.h"
+
+namespace ios_web_view {
+
+WebViewJavaScriptDialogPresenter::WebViewJavaScriptDialogPresenter(
+    CWVWebView* web_view,
+    id<CWVUIDelegate> ui_delegate)
+    : ui_delegate_(ui_delegate), web_view_(web_view) {}
+
+WebViewJavaScriptDialogPresenter::~WebViewJavaScriptDialogPresenter() = default;
+
+void WebViewJavaScriptDialogPresenter::RunJavaScriptDialog(
+    web::WebState* web_state,
+    const GURL& origin_url,
+    web::JavaScriptDialogType dialog_type,
+    NSString* message_text,
+    NSString* default_prompt_text,
+    const web::DialogClosedCallback& callback) {
+  switch (dialog_type) {
+    case web::JAVASCRIPT_DIALOG_TYPE_ALERT:
+      HandleJavaScriptAlert(origin_url, message_text, callback);
+      break;
+    case web::JAVASCRIPT_DIALOG_TYPE_CONFIRM:
+      HandleJavaScriptConfirmDialog(origin_url, message_text, callback);
+      break;
+    case web::JAVASCRIPT_DIALOG_TYPE_PROMPT:
+      HandleJavaScriptTextPrompt(origin_url, message_text, default_prompt_text,
+                                 callback);
+      break;
+  }
+}
+
+void WebViewJavaScriptDialogPresenter::HandleJavaScriptAlert(
+    const GURL& origin_url,
+    NSString* message_text,
+    const web::DialogClosedCallback& callback) {
+  if (![ui_delegate_ respondsToSelector:@selector
+                     (webView:runJavaScriptAlertPanelWithMessage:pageURL
+                                :completionHandler:)]) {
+    callback.Run(NO, nil);
+    return;
+  }
+  web::DialogClosedCallback scoped_callback = callback;
+  [ui_delegate_ webView:web_view_
+      runJavaScriptAlertPanelWithMessage:message_text
+                                 pageURL:net::NSURLWithGURL(origin_url)
+                       completionHandler:^{
+                         if (!scoped_callback.is_null()) {
+                           scoped_callback.Run(YES, nil);
+                         }
+                       }];
+}
+
+void WebViewJavaScriptDialogPresenter::HandleJavaScriptConfirmDialog(
+    const GURL& origin_url,
+    NSString* message_text,
+    const web::DialogClosedCallback& callback) {
+  if (![ui_delegate_ respondsToSelector:@selector
+                     (webView:runJavaScriptConfirmPanelWithMessage:pageURL
+                                :completionHandler:)]) {
+    callback.Run(NO, nil);
+    return;
+  }
+  web::DialogClosedCallback scoped_callback = callback;
+  [ui_delegate_ webView:web_view_
+      runJavaScriptConfirmPanelWithMessage:message_text
+                                   pageURL:net::NSURLWithGURL(origin_url)
+                         completionHandler:^(BOOL is_confirmed) {
+                           if (!scoped_callback.is_null()) {
+                             scoped_callback.Run(is_confirmed, nil);
+                           }
+                         }];
+}
+
+void WebViewJavaScriptDialogPresenter::HandleJavaScriptTextPrompt(
+    const GURL& origin_url,
+    NSString* message_text,
+    NSString* default_prompt_text,
+    const web::DialogClosedCallback& callback) {
+  if (![ui_delegate_ respondsToSelector:@selector
+                     (webView:runJavaScriptTextInputPanelWithPrompt:defaultText
+                                :pageURL:completionHandler:)]) {
+    callback.Run(NO, nil);
+    return;
+  }
+  web::DialogClosedCallback scoped_callback = callback;
+  [ui_delegate_ webView:web_view_
+      runJavaScriptTextInputPanelWithPrompt:message_text
+                                defaultText:default_prompt_text
+                                    pageURL:net::NSURLWithGURL(origin_url)
+                          completionHandler:^(NSString* text_input) {
+                            if (!scoped_callback.is_null()) {
+                              if (text_input == nil) {
+                                scoped_callback.Run(NO, nil);
+                              } else {
+                                scoped_callback.Run(YES, text_input);
+                              }
+                            }
+                          }];
+}
+
+void WebViewJavaScriptDialogPresenter::CancelDialogs(web::WebState* web_state) {
+}
+
+void WebViewJavaScriptDialogPresenter::SetUIDelegate(
+    id<CWVUIDelegate> ui_delegate) {
+  ui_delegate_.reset(ui_delegate);
+}
+
+}  // namespace ios_web_view
diff --git a/ios/web_view/public/cwv_ui_delegate.h b/ios/web_view/public/cwv_ui_delegate.h
index 6aa3cff..0e3a5b97 100644
--- a/ios/web_view/public/cwv_ui_delegate.h
+++ b/ios/web_view/public/cwv_ui_delegate.h
@@ -25,6 +25,29 @@
                      inView:(UIView*)view
         userGestureLocation:(CGPoint)location;
 
+// Instructs the delegate to show UI in response to window.alert JavaScript
+// call.
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptAlertPanelWithMessage:(NSString*)message
+                               pageURL:(NSURL*)URL
+                     completionHandler:(void (^)(void))completionHandler;
+
+// Instructs the delegate to show UI in response to window.confirm JavaScript
+// call.
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptConfirmPanelWithMessage:(NSString*)message
+                                 pageURL:(NSURL*)URL
+                       completionHandler:(void (^)(BOOL))completionHandler;
+
+// Instructs the delegate to show UI in response to window.prompt JavaScript
+// call.
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
+                              defaultText:(NSString*)defaultText
+                                  pageURL:(NSURL*)URL
+                        completionHandler:
+                            (void (^)(NSString*))completionHandler;
+
 @end
 
 #endif  // IOS_WEB_VIEW_PUBLIC_CWV_UI_DELEGATE_H_
diff --git a/ios/web_view/shell/shell_view_controller.h b/ios/web_view/shell/shell_view_controller.h
index 97bf6276..0d097d7 100644
--- a/ios/web_view/shell/shell_view_controller.h
+++ b/ios/web_view/shell/shell_view_controller.h
@@ -10,6 +10,10 @@
 #import "ios/web_view/public/cwv_ui_delegate.h"
 #import "ios/web_view/public/cwv_web_view_delegate.h"
 
+// Accessibility identifier added to the text field of JavaScript prompts.
+extern NSString* const
+    kWebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier;
+
 // Implements the main UI for web_view_shell, including the toolbar and web
 // view.
 @interface ShellViewController : UIViewController
diff --git a/ios/web_view/shell/shell_view_controller.m b/ios/web_view/shell/shell_view_controller.m
index 89f19d98..18a08c2 100644
--- a/ios/web_view/shell/shell_view_controller.m
+++ b/ios/web_view/shell/shell_view_controller.m
@@ -15,6 +15,10 @@
 #error "This file requires ARC support."
 #endif
 
+// Externed accessibility identifier.
+NSString* const kWebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier =
+    @"WebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier";
+
 @interface ShellViewController ()<CWVUIDelegate,
                                   CWVWebViewDelegate,
                                   UITextFieldDelegate>
@@ -216,6 +220,81 @@
   [self presentViewController:alert animated:YES completion:nil];
 }
 
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptAlertPanelWithMessage:(NSString*)message
+                               pageURL:(NSURL*)URL
+                     completionHandler:(void (^)(void))handler {
+  UIAlertController* alert =
+      [UIAlertController alertControllerWithTitle:nil
+                                          message:message
+                                   preferredStyle:UIAlertControllerStyleAlert];
+
+  [alert addAction:[UIAlertAction actionWithTitle:@"Ok"
+                                            style:UIAlertActionStyleDefault
+                                          handler:^(UIAlertAction* action) {
+                                            handler();
+                                          }]];
+
+  [self presentViewController:alert animated:YES completion:nil];
+}
+
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptConfirmPanelWithMessage:(NSString*)message
+                                 pageURL:(NSURL*)URL
+                       completionHandler:(void (^)(BOOL))handler {
+  UIAlertController* alert =
+      [UIAlertController alertControllerWithTitle:nil
+                                          message:message
+                                   preferredStyle:UIAlertControllerStyleAlert];
+
+  [alert addAction:[UIAlertAction actionWithTitle:@"Ok"
+                                            style:UIAlertActionStyleDefault
+                                          handler:^(UIAlertAction* action) {
+                                            handler(YES);
+                                          }]];
+  [alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
+                                            style:UIAlertActionStyleCancel
+                                          handler:^(UIAlertAction* action) {
+                                            handler(NO);
+                                          }]];
+
+  [self presentViewController:alert animated:YES completion:nil];
+}
+
+- (void)webView:(CWVWebView*)webView
+    runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
+                              defaultText:(NSString*)defaultText
+                                  pageURL:(NSURL*)URL
+                        completionHandler:(void (^)(NSString*))handler {
+  UIAlertController* alert =
+      [UIAlertController alertControllerWithTitle:nil
+                                          message:prompt
+                                   preferredStyle:UIAlertControllerStyleAlert];
+
+  [alert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
+    textField.text = defaultText;
+    textField.accessibilityIdentifier =
+        kWebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier;
+  }];
+
+  __weak UIAlertController* weakAlert = alert;
+  [alert addAction:[UIAlertAction
+                       actionWithTitle:@"Ok"
+                                 style:UIAlertActionStyleDefault
+                               handler:^(UIAlertAction* action) {
+                                 NSString* textInput =
+                                     weakAlert.textFields.firstObject.text;
+                                 handler(textInput);
+                               }]];
+  [alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
+                                            style:UIAlertActionStyleCancel
+                                          handler:^(UIAlertAction* action) {
+                                            handler(nil);
+                                          }]];
+
+  [self presentViewController:alert animated:YES completion:nil];
+}
+
 #pragma mark CWVWebViewDelegate methods
 
 - (void)webView:(CWVWebView*)webView
diff --git a/media/base/demuxer_perftest.cc b/media/base/demuxer_perftest.cc
index b04db50..45b44991 100644
--- a/media/base/demuxer_perftest.cc
+++ b/media/base/demuxer_perftest.cc
@@ -12,7 +12,6 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/scoped_task_scheduler.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -49,19 +48,20 @@
   DISALLOW_COPY_AND_ASSIGN(DemuxerHostImpl);
 };
 
-static void QuitLoopWithStatus(base::Closure quit_cb,
+static void QuitLoopWithStatus(base::MessageLoop* message_loop,
                                media::PipelineStatus status) {
   CHECK_EQ(status, media::PIPELINE_OK);
-  quit_cb.Run();
+  message_loop->task_runner()->PostTask(
+      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
 }
 
 static void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
                                      const std::vector<uint8_t>& init_data) {
-  DVLOG(1) << "File is encrypted.";
+  VLOG(0) << "File is encrypted.";
 }
 
 static void OnMediaTracksUpdated(std::unique_ptr<MediaTracks> tracks) {
-  DVLOG(1) << "Got media tracks info, tracks = " << tracks->tracks().size();
+  VLOG(0) << "Got media tracks info, tracks = " << tracks->tracks().size();
 }
 
 typedef std::vector<media::DemuxerStream* > Streams;
@@ -177,10 +177,10 @@
 
 static void RunDemuxerBenchmark(const std::string& filename) {
   base::FilePath file_path(GetTestDataFilePath(filename));
-  base::TimeDelta total_time;
+  double total_time = 0.0;
   for (int i = 0; i < kBenchmarkIterations; ++i) {
     // Setup.
-    base::test::ScopedTaskScheduler scoped_task_scheduler;
+    base::MessageLoop message_loop;
     DemuxerHostImpl demuxer_host;
     FileDataSource data_source;
     ASSERT_TRUE(data_source.Initialize(file_path));
@@ -189,32 +189,34 @@
         base::Bind(&OnEncryptedMediaInitData);
     Demuxer::MediaTracksUpdatedCB tracks_updated_cb =
         base::Bind(&OnMediaTracksUpdated);
-    FFmpegDemuxer demuxer(base::ThreadTaskRunnerHandle::Get(), &data_source,
+    FFmpegDemuxer demuxer(message_loop.task_runner(), &data_source,
                           encrypted_media_init_data_cb, tracks_updated_cb,
                           new MediaLog());
 
-    {
-      base::RunLoop run_loop;
-      demuxer.Initialize(
-          &demuxer_host,
-          base::Bind(&QuitLoopWithStatus, run_loop.QuitClosure()), false);
-      run_loop.Run();
-    }
-
+    demuxer.Initialize(&demuxer_host,
+                       base::Bind(&QuitLoopWithStatus, &message_loop),
+                       false);
+    base::RunLoop().Run();
     StreamReader stream_reader(&demuxer, false);
 
     // Benchmark.
     base::TimeTicks start = base::TimeTicks::Now();
-    while (!stream_reader.IsDone())
+    while (!stream_reader.IsDone()) {
       stream_reader.Read();
-    total_time += base::TimeTicks::Now() - start;
+    }
+    base::TimeTicks end = base::TimeTicks::Now();
+    total_time += (end - start).InSecondsF();
     demuxer.Stop();
-    base::RunLoop().RunUntilIdle();
+    QuitLoopWithStatus(&message_loop, PIPELINE_OK);
+    base::RunLoop().Run();
   }
 
-  perf_test::PrintResult("demuxer_bench", "", filename,
-                         kBenchmarkIterations / total_time.InSecondsF(),
-                         "runs/s", true);
+  perf_test::PrintResult("demuxer_bench",
+                         "",
+                         filename,
+                         kBenchmarkIterations / total_time,
+                         "runs/s",
+                         true);
 }
 
 #if defined(OS_WIN)
diff --git a/media/filters/blocking_url_protocol.cc b/media/filters/blocking_url_protocol.cc
index 760e4c4e3..9f8e95e 100644
--- a/media/filters/blocking_url_protocol.cc
+++ b/media/filters/blocking_url_protocol.cc
@@ -17,7 +17,6 @@
                                          const base::Closure& error_cb)
     : data_source_(data_source),
       error_cb_(error_cb),
-      is_streaming_(data_source_->IsStreaming()),
       aborted_(base::WaitableEvent::ResetPolicy::MANUAL,
                base::WaitableEvent::InitialState::NOT_SIGNALED),  // We never
                                                                   // want to
@@ -32,32 +31,24 @@
 
 void BlockingUrlProtocol::Abort() {
   aborted_.Signal();
-  base::AutoLock lock(data_source_lock_);
-  data_source_ = nullptr;
 }
 
 int BlockingUrlProtocol::Read(int size, uint8_t* data) {
-  {
-    // Read errors are unrecoverable.
-    base::AutoLock lock(data_source_lock_);
-    if (!data_source_) {
-      DCHECK(aborted_.IsSignaled());
-      return AVERROR(EIO);
-    }
+  // Read errors are unrecoverable.
+  if (aborted_.IsSignaled())
+    return AVERROR(EIO);
 
-    // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O
-    // routines. Instead return 0 for any read at or past EOF.
-    int64_t file_size;
-    if (data_source_->GetSize(&file_size) && read_position_ >= file_size)
-      return 0;
+  // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O
+  // routines. Instead return 0 for any read at or past EOF.
+  int64_t file_size;
+  if (data_source_->GetSize(&file_size) && read_position_ >= file_size)
+    return 0;
 
-    // Blocking read from data source until either:
-    //   1) |last_read_bytes_| is set and |read_complete_| is signalled
-    //   2) |aborted_| is signalled
-    data_source_->Read(read_position_, size, data,
-                       base::Bind(&BlockingUrlProtocol::SignalReadCompleted,
-                                  base::Unretained(this)));
-  }
+  // Blocking read from data source until either:
+  //   1) |last_read_bytes_| is set and |read_complete_| is signalled
+  //   2) |aborted_| is signalled
+  data_source_->Read(read_position_, size, data, base::Bind(
+      &BlockingUrlProtocol::SignalReadCompleted, base::Unretained(this)));
 
   base::WaitableEvent* events[] = { &aborted_, &read_complete_ };
   size_t index = base::WaitableEvent::WaitMany(events, arraysize(events));
@@ -84,10 +75,8 @@
 }
 
 bool BlockingUrlProtocol::SetPosition(int64_t position) {
-  base::AutoLock lock(data_source_lock_);
   int64_t file_size;
-  if (!data_source_ ||
-      (data_source_->GetSize(&file_size) && position > file_size) ||
+  if ((data_source_->GetSize(&file_size) && position > file_size) ||
       position < 0) {
     return false;
   }
@@ -97,12 +86,11 @@
 }
 
 bool BlockingUrlProtocol::GetSize(int64_t* size_out) {
-  base::AutoLock lock(data_source_lock_);
-  return data_source_ ? data_source_->GetSize(size_out) : 0;
+  return data_source_->GetSize(size_out);
 }
 
 bool BlockingUrlProtocol::IsStreaming() {
-  return is_streaming_;
+  return data_source_->IsStreaming();
 }
 
 void BlockingUrlProtocol::SignalReadCompleted(int size) {
diff --git a/media/filters/blocking_url_protocol.h b/media/filters/blocking_url_protocol.h
index 7e6a1eb..4f9ef4f 100644
--- a/media/filters/blocking_url_protocol.h
+++ b/media/filters/blocking_url_protocol.h
@@ -9,7 +9,6 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
 #include "media/filters/ffmpeg_glue.h"
 
@@ -18,19 +17,19 @@
 class DataSource;
 
 // An implementation of FFmpegURLProtocol that blocks until the underlying
-// asynchronous DataSource::Read() operation completes. Generally constructed on
-// the media thread and used by ffmpeg through the AVIO interface from a
-// sequenced blocking pool.
+// asynchronous DataSource::Read() operation completes.
 class MEDIA_EXPORT BlockingUrlProtocol : public FFmpegURLProtocol {
  public:
   // Implements FFmpegURLProtocol using the given |data_source|. |error_cb| is
   // fired any time DataSource::Read() returns an error.
+  //
+  // TODO(scherkus): After all blocking operations are isolated on a separate
+  // thread we should be able to eliminate |error_cb|.
   BlockingUrlProtocol(DataSource* data_source, const base::Closure& error_cb);
   virtual ~BlockingUrlProtocol();
 
   // Aborts any pending reads by returning a read error. After this method
-  // returns all subsequent calls to Read() will immediately fail. May be called
-  // from any thread and upon return ensures no further use of |data_source_|.
+  // returns all subsequent calls to Read() will immediately fail.
   void Abort();
 
   // FFmpegURLProtocol implementation.
@@ -45,14 +44,8 @@
   // has completed.
   void SignalReadCompleted(int size);
 
-  // |data_source_lock_| allows Abort() to be called from any thread and stop
-  // all outstanding access to |data_source_|. Typically Abort() is called from
-  // the media thread while ffmpeg is operating on another thread.
-  base::Lock data_source_lock_;
   DataSource* data_source_;
-
   base::Closure error_cb_;
-  const bool is_streaming_;
 
   // Used to unblock the thread during shutdown and when reads complete.
   base::WaitableEvent aborted_;
diff --git a/media/filters/blocking_url_protocol_unittest.cc b/media/filters/blocking_url_protocol_unittest.cc
index dda4000..266f893 100644
--- a/media/filters/blocking_url_protocol_unittest.cc
+++ b/media/filters/blocking_url_protocol_unittest.cc
@@ -20,10 +20,9 @@
 class BlockingUrlProtocolTest : public testing::Test {
  public:
   BlockingUrlProtocolTest()
-      : url_protocol_(new BlockingUrlProtocol(
-            &data_source_,
-            base::Bind(&BlockingUrlProtocolTest::OnDataSourceError,
-                       base::Unretained(this)))) {
+      : url_protocol_(&data_source_,
+                      base::Bind(&BlockingUrlProtocolTest::OnDataSourceError,
+                                 base::Unretained(this))) {
     CHECK(data_source_.Initialize(GetTestDataFilePath("bear-320x240.webm")));
   }
 
@@ -34,7 +33,7 @@
   MOCK_METHOD0(OnDataSourceError, void());
 
   FileDataSource data_source_;
-  std::unique_ptr<BlockingUrlProtocol> url_protocol_;
+  BlockingUrlProtocol url_protocol_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BlockingUrlProtocolTest);
@@ -44,35 +43,35 @@
 TEST_F(BlockingUrlProtocolTest, Read) {
   // Set read head to zero as Initialize() will have parsed a bit of the file.
   int64_t position = 0;
-  EXPECT_TRUE(url_protocol_->SetPosition(0));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_TRUE(url_protocol_.SetPosition(0));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(0, position);
 
   // Read 32 bytes from offset zero and verify position.
   uint8_t buffer[32];
-  EXPECT_EQ(32, url_protocol_->Read(32, buffer));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_EQ(32, url_protocol_.Read(32, buffer));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(32, position);
 
   // Read an additional 32 bytes and verify position.
-  EXPECT_EQ(32, url_protocol_->Read(32, buffer));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_EQ(32, url_protocol_.Read(32, buffer));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(64, position);
 
   // Seek to end and read until EOF.
   int64_t size = 0;
-  EXPECT_TRUE(url_protocol_->GetSize(&size));
-  EXPECT_TRUE(url_protocol_->SetPosition(size - 48));
-  EXPECT_EQ(32, url_protocol_->Read(32, buffer));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_TRUE(url_protocol_.GetSize(&size));
+  EXPECT_TRUE(url_protocol_.SetPosition(size - 48));
+  EXPECT_EQ(32, url_protocol_.Read(32, buffer));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(size - 16, position);
 
-  EXPECT_EQ(16, url_protocol_->Read(32, buffer));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_EQ(16, url_protocol_.Read(32, buffer));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(size, position);
 
-  EXPECT_EQ(0, url_protocol_->Read(32, buffer));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_EQ(0, url_protocol_.Read(32, buffer));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(size, position);
 }
 
@@ -81,23 +80,23 @@
 
   uint8_t buffer[32];
   EXPECT_CALL(*this, OnDataSourceError());
-  EXPECT_EQ(AVERROR(EIO), url_protocol_->Read(32, buffer));
+  EXPECT_EQ(AVERROR(EIO), url_protocol_.Read(32, buffer));
 }
 
 TEST_F(BlockingUrlProtocolTest, GetSetPosition) {
   int64_t size;
   int64_t position;
-  EXPECT_TRUE(url_protocol_->GetSize(&size));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_TRUE(url_protocol_.GetSize(&size));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
 
-  EXPECT_TRUE(url_protocol_->SetPosition(512));
-  EXPECT_FALSE(url_protocol_->SetPosition(size + 1));
-  EXPECT_FALSE(url_protocol_->SetPosition(-1));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_TRUE(url_protocol_.SetPosition(512));
+  EXPECT_FALSE(url_protocol_.SetPosition(size + 1));
+  EXPECT_FALSE(url_protocol_.SetPosition(-1));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(512, position);
 
-  EXPECT_TRUE(url_protocol_->SetPosition(size));
-  EXPECT_TRUE(url_protocol_->GetPosition(&position));
+  EXPECT_TRUE(url_protocol_.SetPosition(size));
+  EXPECT_TRUE(url_protocol_.GetPosition(&position));
   EXPECT_EQ(size, position);
 }
 
@@ -105,21 +104,18 @@
   int64_t data_source_size = 0;
   int64_t url_protocol_size = 0;
   EXPECT_TRUE(data_source_.GetSize(&data_source_size));
-  EXPECT_TRUE(url_protocol_->GetSize(&url_protocol_size));
+  EXPECT_TRUE(url_protocol_.GetSize(&url_protocol_size));
   EXPECT_NE(0, data_source_size);
   EXPECT_EQ(data_source_size, url_protocol_size);
 }
 
 TEST_F(BlockingUrlProtocolTest, IsStreaming) {
   EXPECT_FALSE(data_source_.IsStreaming());
-  EXPECT_FALSE(url_protocol_->IsStreaming());
+  EXPECT_FALSE(url_protocol_.IsStreaming());
 
   data_source_.force_streaming_for_testing();
-  url_protocol_.reset(new BlockingUrlProtocol(
-      &data_source_, base::Bind(&BlockingUrlProtocolTest::OnDataSourceError,
-                                base::Unretained(this))));
   EXPECT_TRUE(data_source_.IsStreaming());
-  EXPECT_TRUE(url_protocol_->IsStreaming());
+  EXPECT_TRUE(url_protocol_.IsStreaming());
 }
 
 }  // namespace media
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 7919a2e..f7747e6 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -22,8 +22,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/sys_byteorder.h"
 #include "base/task_runner_util.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "media/audio/sample_rates.h"
@@ -847,13 +845,7 @@
     const scoped_refptr<MediaLog>& media_log)
     : host_(NULL),
       task_runner_(task_runner),
-      // FFmpeg has no asynchronous API, so we use base::WaitableEvents inside
-      // the BlockingUrlProtocol to handle hops to the render thread for network
-      // reads and seeks.
-      blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          base::TaskTraits().MayBlock().WithBaseSyncPrimitives().WithPriority(
-              base::TaskPriority::USER_BLOCKING))),
-      stopped_(false),
+      blocking_thread_("FFmpegDemuxer"),
       pending_read_(false),
       data_source_(data_source),
       media_log_(media_log),
@@ -874,12 +866,6 @@
   // NOTE: This class is not destroyed on |task_runner|, so we must ensure that
   // there are no outstanding WeakPtrs by the time we reach here.
   DCHECK(!weak_factory_.HasWeakPtrs());
-
-  // There may be outstanding tasks in the blocking pool which are trying to use
-  // these members, so release them in sequence with any outstanding calls. The
-  // earlier call to Abort() on |data_source_| prevents further access to it.
-  blocking_task_runner_->DeleteSoon(FROM_HERE, url_protocol_.release());
-  blocking_task_runner_->DeleteSoon(FROM_HERE, glue_.release());
 }
 
 std::string FFmpegDemuxer::GetDisplayName() const {
@@ -913,8 +899,9 @@
   format_context->max_analyze_duration = 60 * AV_TIME_BASE;
 
   // Open the AVFormatContext using our glue layer.
+  CHECK(blocking_thread_.Start());
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(), FROM_HERE,
+      blocking_thread_.task_runner().get(), FROM_HERE,
       base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
       base::Bind(&FFmpegDemuxer::OnOpenContextDone, weak_factory_.GetWeakPtr(),
                  status_cb));
@@ -924,7 +911,7 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   // If Stop() has been called, then drop this call.
-  if (stopped_)
+  if (!blocking_thread_.IsRunning())
     return;
 
   // This should only be called after the demuxer has been initialized.
@@ -942,7 +929,7 @@
   data_source_->Abort();
 
   // Aborting the read may cause EOF to be marked, undo this.
-  blocking_task_runner_->PostTask(
+  blocking_thread_.task_runner()->PostTask(
       FROM_HERE, base::Bind(&UnmarkEndOfStream, glue_->format_context()));
   pending_read_ = false;
 
@@ -962,6 +949,12 @@
   data_source_->Stop();
   url_protocol_->Abort();
 
+  // This will block until all tasks complete. Note that after this returns it's
+  // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
+  // thread. Each of the reply task methods must check whether we've stopped the
+  // thread and drop their results on the floor.
+  blocking_thread_.Stop();
+
   for (const auto& stream : streams_) {
     if (stream)
       stream->Stop();
@@ -970,9 +963,7 @@
   data_source_ = NULL;
 
   // Invalidate WeakPtrs on |task_runner_|, destruction may happen on another
-  // thread. We don't need to wait for any outstanding tasks since they will all
-  // fail to return after invalidating WeakPtrs.
-  stopped_ = true;
+  // thread.
   weak_factory_.InvalidateWeakPtrs();
   cancel_pending_seek_factory_.InvalidateWeakPtrs();
 }
@@ -1031,7 +1022,7 @@
 
   pending_seek_cb_ = cb;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(), FROM_HERE,
+      blocking_thread_.task_runner().get(), FROM_HERE,
       base::Bind(&av_seek_frame, glue_->format_context(), seeking_stream->index,
                  ConvertToTimeBase(seeking_stream->time_base, seek_time),
                  // Always seek to a timestamp <= to the desired timestamp.
@@ -1168,7 +1159,7 @@
 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
                                       bool result) {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  if (stopped_) {
+  if (!blocking_thread_.IsRunning()) {
     MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
     status_cb.Run(PIPELINE_ERROR_ABORT);
     return;
@@ -1182,17 +1173,20 @@
 
   // Fully initialize AVFormatContext by parsing the stream a little.
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(), FROM_HERE,
-      base::Bind(&avformat_find_stream_info, glue_->format_context(),
+      blocking_thread_.task_runner().get(),
+      FROM_HERE,
+      base::Bind(&avformat_find_stream_info,
+                 glue_->format_context(),
                  static_cast<AVDictionary**>(NULL)),
       base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
-                 weak_factory_.GetWeakPtr(), status_cb));
+                 weak_factory_.GetWeakPtr(),
+                 status_cb));
 }
 
 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
                                          int result) {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  if (stopped_ || !data_source_) {
+  if (!blocking_thread_.IsRunning() || !data_source_) {
     MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
     status_cb.Run(PIPELINE_ERROR_ABORT);
     return;
@@ -1612,7 +1606,7 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
   CHECK(!pending_seek_cb_.is_null());
 
-  if (stopped_) {
+  if (!blocking_thread_.IsRunning()) {
     MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
     base::ResetAndReturn(&pending_seek_cb_).Run(PIPELINE_ERROR_ABORT);
     return;
@@ -1698,8 +1692,8 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   // Make sure we have work to do before reading.
-  if (stopped_ || !StreamsHaveAvailableCapacity() || pending_read_ ||
-      !pending_seek_cb_.is_null()) {
+  if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
+      pending_read_ || !pending_seek_cb_.is_null()) {
     return;
   }
 
@@ -1711,9 +1705,11 @@
 
   pending_read_ = true;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(), FROM_HERE,
+      blocking_thread_.task_runner().get(),
+      FROM_HERE,
       base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
-      base::Bind(&FFmpegDemuxer::OnReadFrameDone, weak_factory_.GetWeakPtr(),
+      base::Bind(&FFmpegDemuxer::OnReadFrameDone,
+                 weak_factory_.GetWeakPtr(),
                  base::Passed(&packet)));
 }
 
@@ -1722,7 +1718,7 @@
   DCHECK(pending_read_);
   pending_read_ = false;
 
-  if (stopped_ || !pending_seek_cb_.is_null())
+  if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null())
     return;
 
   // Consider the stream as ended if:
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index 4c06c4c..a5b15bc6 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -32,9 +32,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
+#include "base/threading/thread.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/decoder_buffer_queue.h"
@@ -297,12 +295,8 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
-  // Task runner on which all blocking FFmpeg operations are executed; retrieved
-  // from base::TaskScheduler.
-  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-
-  // Indicates if Stop() has been called.
-  bool stopped_;
+  // Thread on which all blocking FFmpeg operations are executed.
+  base::Thread blocking_thread_;
 
   // Tracks if there's an outstanding av_read_frame() operation.
   //
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index d0a7d1a2..92766f1 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -18,7 +18,6 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/test/mock_callback.h"
-#include "base/test/scoped_task_scheduler.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/base/decrypt_config.h"
@@ -86,8 +85,6 @@
   virtual ~FFmpegDemuxerTest() {
     if (demuxer_)
       demuxer_->Stop();
-    demuxer_.reset();
-    base::RunLoop().RunUntilIdle();
   }
 
   void CreateDemuxer(const std::string& name) {
@@ -104,7 +101,7 @@
         &FFmpegDemuxerTest::OnMediaTracksUpdated, base::Unretained(this));
 
     demuxer_.reset(new FFmpegDemuxer(
-        base::ThreadTaskRunnerHandle::Get(), data_source_.get(),
+        message_loop_.task_runner(), data_source_.get(),
         encrypted_media_init_data_cb, tracks_updated_cb, new MediaLog()));
   }
 
@@ -191,8 +188,9 @@
                 buffer->discard_padding().first);
       EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame());
     }
+    DCHECK_EQ(&message_loop_, base::MessageLoop::current());
     OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us);
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
+    message_loop_.task_runner()->PostTask(
         FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
   }
 
@@ -241,12 +239,11 @@
   }
 
   // Fixture members.
-
-  base::test::ScopedTaskScheduler task_scheduler_;
   std::unique_ptr<FileDataSource> data_source_;
   std::unique_ptr<FFmpegDemuxer> demuxer_;
   StrictMock<MockDemuxerHost> host_;
   std::unique_ptr<MediaTracks> media_tracks_;
+  base::MessageLoop message_loop_;
 
   AVFormatContext* format_context() {
     return demuxer_->glue_->format_context();
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn
index 1d426da..595da4c 100644
--- a/media/test/BUILD.gn
+++ b/media/test/BUILD.gn
@@ -39,7 +39,6 @@
 
     deps = [
       "//base",
-      "//base/test:test_support",
       "//media:test_support",
       "//media/audio:test_support",
       "//media/base:test_support",
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index da174a1..15e6e868 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -1723,12 +1723,16 @@
   EXPECT_HASH_EQ(config.hash, GetAudioHash());
 }
 
+// TODO(CHCUNNINGHAM): Re-enable for OSX once 1% flakiness is root caused.
+// See http://crbug.com/571898
+#if !defined(OS_MACOSX)
 // CBR seeks should always be fast and accurate.
 INSTANTIATE_TEST_CASE_P(
     CBRSeek_HasTOC,
     Mp3FastSeekIntegrationTest,
     ::testing::Values(Mp3FastSeekParams("bear-audio-10s-CBR-has-TOC.mp3",
-                                        "-0.71,0.36,2.96,2.68,2.11,-1.08,")));
+                                        "-0.71,0.36,2.96,2.68,2.10,-1.08,")));
+#endif
 
 INSTANTIATE_TEST_CASE_P(
     CBRSeeks_NoTOC,
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index 3902b1f2..6115e472 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -59,7 +59,6 @@
   if (pipeline_->IsRunning())
     Stop();
 
-  demuxer_.reset();
   pipeline_.reset();
   base::RunLoop().RunUntilIdle();
 }
@@ -311,7 +310,6 @@
   data_source_ = std::move(data_source);
 
 #if !defined(MEDIA_DISABLE_FFMPEG)
-  task_scheduler_.reset(new base::test::ScopedTaskScheduler(&message_loop_));
   demuxer_ = std::unique_ptr<Demuxer>(new FFmpegDemuxer(
       message_loop_.task_runner(), data_source_.get(),
       base::Bind(&PipelineIntegrationTestBase::DemuxerEncryptedMediaInitDataCB,
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index 580e963c..192d6f8 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -11,7 +11,6 @@
 #include "base/md5.h"
 #include "base/memory/scoped_vector.h"
 #include "base/message_loop/message_loop.h"
-#include "base/test/scoped_task_scheduler.h"
 #include "media/audio/clockless_audio_sink.h"
 #include "media/audio/null_audio_sink.h"
 #include "media/base/demuxer.h"
@@ -134,9 +133,6 @@
   base::MD5Context md5_context_;
   bool hashing_enabled_;
   bool clockless_playback_;
-
-  // TaskScheduler is used only for FFmpegDemuxer.
-  std::unique_ptr<base::test::ScopedTaskScheduler> task_scheduler_;
   std::unique_ptr<Demuxer> demuxer_;
   std::unique_ptr<DataSource> data_source_;
   std::unique_ptr<PipelineImpl> pipeline_;
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn
index b15cd66..7e3d3f2 100644
--- a/testing/libfuzzer/fuzzers/BUILD.gn
+++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -249,6 +249,14 @@
   libfuzzer_options = [ "max_len=500" ]
 }
 
+fuzzer_test("v8_wasm_compile_fuzzer") {
+  sources = []
+  deps = [
+    "//v8:wasm_compile_fuzzer",
+  ]
+  libfuzzer_options = [ "max_len=500" ]
+}
+
 fuzzer_test("v8_wasm_call_fuzzer") {
   sources = []
   deps = [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 35f1f01..1b338e05 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2560,3 +2560,7 @@
 crbug.com/696407 [ Linux ] external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-with-colon.sub.html [ Failure Pass ]
 crbug.com/694338 [ Mac10.9 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Failure ]
 crbug.com/694338 [ Mac10.9 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ Failure ]
+
+# Sheriff failures 2017-02-28
+crbug.com/696903 [ Mac ] custom-properties/register-property-syntax-parsing.html [ Crash ]
+crbug.com/696903 [ Mac ] custom-properties/register-property.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/csspaint/paint-arguments-expected.html b/third_party/WebKit/LayoutTests/csspaint/paint-arguments-expected.html
new file mode 100644
index 0000000..3352acf6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/csspaint/paint-arguments-expected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#background {
+  background-color: yellow;
+  display: inline-block;
+}
+
+.container {
+  font-size: 0px;
+}
+</style>
+</head>
+<body>
+
+<div id="background">
+  <div class="container">
+    <canvas id ="box-green" width="100" height="100"></canvas>
+  </div>
+  <div class="container">
+    <canvas id ="box-red" width="100" height="100"></canvas>
+  </div>
+</div>
+
+<script>
+function drawCanvas(canvasID, color) {
+  var canvas = document.getElementById(canvasID);
+  var context = canvas.getContext("2d", {alpha: true});
+  context.clearRect(0, 0, canvas.width, canvas.height);
+  context.strokeStyle = color;
+  context.lineWidth = 4;
+  context.strokeRect(20, 20, 60, 60);
+};
+
+drawCanvas('box-green', 'green');
+drawCanvas('box-red', 'red');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/csspaint/paint-arguments.html b/third_party/WebKit/LayoutTests/csspaint/paint-arguments.html
new file mode 100644
index 0000000..6374131
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/csspaint/paint-arguments.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/run-after-layout-and-paint.js"></script>
+<script src="resources/test-runner-paint-worklet.js"></script>
+<style>
+.container {
+  width: 100px;
+  height: 100px;
+}
+
+#canvas-box-green {
+  background-image: paint(box, green);
+}
+
+#canvas-box-red {
+  background-image: paint(box, red);
+}
+
+#background {
+  background-color: yellow;
+  display: inline-block;
+}
+</style>
+</head>
+<body>
+
+<div id="background">
+  <div id="canvas-box-green" class="container"></div>
+  <div id="canvas-box-red" class="container"></div>
+</div>
+
+<script id="code" type="text/worklet">
+registerPaint('box', class {
+    static get alpha() { return true; }
+    static get inputArguments() { return ['<color>']; }
+    paint(ctx, geom, properties, args) {
+        ctx.strokeStyle = args[0].cssText;
+        ctx.lineWidth = 4;
+        ctx.strokeRect(20, 20, 60, 60);
+    }
+});
+
+</script>
+
+<script>
+  importPaintWorkletAndTerminateTestAfterAsyncPaint(document.getElementById('code').textContent);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/editing/selection/selection-update-range-after-addrange.html b/third_party/WebKit/LayoutTests/editing/selection/selection-update-range-after-addrange.html
index c85b1493..973864c 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/selection-update-range-after-addrange.html
+++ b/third_party/WebKit/LayoutTests/editing/selection/selection-update-range-after-addrange.html
@@ -25,6 +25,26 @@
   let selection = getSelection();
   selection.removeAllRanges();
   let range = document.createRange();
+  let text = document.querySelector('p').firstChild;
+  range.setStart(text, 1);
+  range.setEnd(text, 2);
+
+  selection.addRange(range);
+  assert_equals(selection.anchorNode, text);
+  assert_equals(selection.anchorOffset, 1);
+  assert_equals(selection.focusNode, text);
+  assert_equals(selection.focusOffset, 2);
+
+  text.parentNode.contentEditable = true;
+  range.setStart(text, 0);
+  assert_equals(selection.anchorOffset, 0);
+  assert_not_equals(document.activeElement, text.parentNode);
+}, 'Mutation of Range after adding it to Selection should not focus on editable anchor.');
+
+test(() => {
+  let selection = getSelection();
+  selection.removeAllRanges();
+  let range = document.createRange();
   range.selectNode(document.body);
   selection.addRange(range);
   assert_equals(selection.rangeCount, 1);
diff --git a/third_party/WebKit/LayoutTests/html/dialog/shadowdom-in-dialog.html b/third_party/WebKit/LayoutTests/html/dialog/shadowdom-in-dialog.html
new file mode 100644
index 0000000..8fab4905
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/html/dialog/shadowdom-in-dialog.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<!-- This test is testing unspecified behavior of using Shadow DOM in <dialog>.
+See crbug/383230 and https://github.com/whatwg/html/issue/2393 . -->
+<input id="outer">
+
+<dialog id="dlg">
+  <div id="host"></div>
+  <button id="btn"></button>
+</dialog>
+
+<dialog id="dlg2">
+  <div id="host2"><input id="inner2"></div>
+  <button id="btn2"></button>
+</dialog>
+<script>
+'use strict';
+
+host.attachShadow({mode: 'open'}).innerHTML = '<input id="inner">';
+let inner = host.shadowRoot.querySelector('#inner');
+
+test(() => {
+  outer.focus();
+  assert_equals(document.activeElement, outer);
+
+  dlg.show();
+  assert_equals(document.activeElement, host);
+  assert_equals(host.shadowRoot.activeElement, inner);
+  dlg.close();
+
+  outer.focus();
+  assert_equals(document.activeElement, outer);
+
+  dlg.showModal();
+  assert_equals(document.activeElement, host);
+  assert_equals(host.shadowRoot.activeElement, inner);
+  dlg.close();
+}, "Dialog focusing steps should be applied to elements inside ShadowRoot.");
+
+
+host2.attachShadow({mode: 'open'}).innerHTML = '<slot></slot>';
+
+test(() => {
+  outer.focus();
+  assert_equals(document.activeElement, outer);
+
+  dlg2.show();
+  assert_equals(document.activeElement, inner2);
+  dlg2.close();
+
+  outer.focus();
+  assert_equals(document.activeElement, outer);
+
+  dlg2.showModal();
+  assert_equals(document.activeElement, inner2);
+  dlg2.close();
+}, "Dialog focusing steps should be applied to slotted elements in Shadow DOM.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-initiator.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-initiator.html
index b8f2a88..a59bb8c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-initiator.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-initiator.html
@@ -4,18 +4,6 @@
 <script src="../network-test.js"></script>
 <script>
 
-/*function addClassToDiv()
-{
-    // We need to setTimeout, to make sure that style recalculation scheduling
-    // is really triggered by adding a class to the div.
-    window.setTimeout(addClassToDivStep2, 0);
-}
-
-function addClassToDivStep2()
-{
-    document.getElementById("div-without-class").className = "image-background-2";
-}*/
-
 function loadData()
 {
     var iframe = document.createElement("iframe");
@@ -27,24 +15,8 @@
 {
     step2();
 
-    /*function step1()
-    {
-        InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, onRequest);
-        InspectorTest.evaluateInPage("addClassToDiv()", step2);
-    }
-
-    function onRequest(event)
-    {
-        var request = event.data;
-        if (/size=300/.test(request.url))
-            step2();
-    }*/
-
     function step2()
     {
-        //if (InspectorTest.findRequestsByURLPattern(/size=300/).length === 0)
-        //    return;
-
         InspectorTest.addConsoleSniffer(step3);
         InspectorTest.evaluateInPage("loadData()");
     }
@@ -77,8 +49,6 @@
 
         dumpInitiator("initiator.css");
         dumpInitiator("size=100");
-        //dumpInitiator("size=200");
-        //dumpInitiator("size=300");
         dumpInitiator("size=400");
         dumpInitiator("style.css");
         dumpInitiator("empty.html");
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py
index 58151a9..1b50fee8e9 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -605,17 +605,16 @@
     if (native_array_element_type.is_interface_type and
         native_array_element_type.name != 'Dictionary'):
         this_cpp_type = None
-        ref_ptr_type = 'Member'
         expression_format = 'toMemberNativeArray<{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionState)'
     else:
-        ref_ptr_type = None
         this_cpp_type = native_array_element_type.cpp_type
         if native_array_element_type.is_dictionary or native_array_element_type.is_union_type:
             vector_type = 'HeapVector'
         else:
             vector_type = 'Vector'
         expression_format = 'toImplArray<%s<{cpp_type}>>({v8_value}, {index}, {isolate}, exceptionState)' % vector_type
-    expression = expression_format.format(native_array_element_type=native_array_element_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_type, v8_value=v8_value, isolate=isolate)
+    expression = expression_format.format(native_array_element_type=native_array_element_type.name, cpp_type=this_cpp_type,
+                                          index=index, v8_value=v8_value, isolate=isolate)
     return expression
 
 
diff --git a/third_party/WebKit/Source/core/css/CSSPaintImageGenerator.h b/third_party/WebKit/Source/core/css/CSSPaintImageGenerator.h
index 9569f34..97a37e9e 100644
--- a/third_party/WebKit/Source/core/css/CSSPaintImageGenerator.h
+++ b/third_party/WebKit/Source/core/css/CSSPaintImageGenerator.h
@@ -7,11 +7,13 @@
 
 #include "core/CSSPropertyNames.h"
 #include "core/CoreExport.h"
+#include "core/css/cssom/CSSStyleValue.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
+class CSSSyntaxDescriptor;
 class Document;
 class Image;
 class LayoutObject;
@@ -47,11 +49,14 @@
   // representing an invalid image if an error occurred.
   virtual PassRefPtr<Image> paint(const LayoutObject&,
                                   const IntSize&,
-                                  float zoom) = 0;
+                                  float zoom,
+                                  const CSSStyleValueVector*) = 0;
 
   virtual const Vector<CSSPropertyID>& nativeInvalidationProperties() const = 0;
   virtual const Vector<AtomicString>& customInvalidationProperties() const = 0;
   virtual bool hasAlpha() const = 0;
+  virtual const Vector<CSSSyntaxDescriptor>& inputArgumentTypes() const = 0;
+  virtual bool isImageGeneratorReady() const = 0;
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
 };
diff --git a/third_party/WebKit/Source/core/css/CSSPaintValue.cpp b/third_party/WebKit/Source/core/css/CSSPaintValue.cpp
index d93ed24..82ccd3f 100644
--- a/third_party/WebKit/Source/core/css/CSSPaintValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSPaintValue.cpp
@@ -5,6 +5,8 @@
 #include "core/css/CSSPaintValue.h"
 
 #include "core/css/CSSCustomIdentValue.h"
+#include "core/css/CSSSyntaxDescriptor.h"
+#include "core/css/cssom/StyleValueFactory.h"
 #include "core/layout/LayoutObject.h"
 #include "platform/graphics/Image.h"
 #include "wtf/text/StringBuilder.h"
@@ -47,7 +49,44 @@
     m_generator = CSSPaintImageGenerator::create(
         name(), layoutObject.document(), m_paintImageGeneratorObserver);
 
-  return m_generator->paint(layoutObject, size, zoom);
+  if (!parseInputArguments())
+    return nullptr;
+
+  return m_generator->paint(layoutObject, size, zoom, m_parsedInputArguments);
+}
+
+bool CSSPaintValue::parseInputArguments() {
+  if (m_inputArgumentsInvalid)
+    return false;
+
+  if (m_parsedInputArguments ||
+      !RuntimeEnabledFeatures::cssPaintAPIArgumentsEnabled())
+    return true;
+
+  if (!m_generator->isImageGeneratorReady())
+    return false;
+
+  const Vector<CSSSyntaxDescriptor>& inputArgumentTypes =
+      m_generator->inputArgumentTypes();
+  if (m_argumentVariableData.size() != inputArgumentTypes.size()) {
+    m_inputArgumentsInvalid = true;
+    return false;
+  }
+
+  m_parsedInputArguments = new CSSStyleValueVector();
+
+  for (size_t i = 0; i < m_argumentVariableData.size(); ++i) {
+    const CSSValue* parsedValue =
+        m_argumentVariableData[i]->parseForSyntax(inputArgumentTypes[i]);
+    if (!parsedValue) {
+      m_inputArgumentsInvalid = true;
+      m_parsedInputArguments = nullptr;
+      return false;
+    }
+    m_parsedInputArguments->appendVector(
+        StyleValueFactory::cssValueToStyleValueVector(*parsedValue));
+  }
+  return true;
 }
 
 void CSSPaintValue::Observer::paintImageGeneratorReady() {
@@ -73,6 +112,7 @@
   visitor->trace(m_name);
   visitor->trace(m_generator);
   visitor->trace(m_paintImageGeneratorObserver);
+  visitor->trace(m_parsedInputArguments);
   CSSImageGeneratorValue::traceAfterDispatch(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/css/CSSPaintValue.h b/third_party/WebKit/Source/core/css/CSSPaintValue.h
index 09aeece..ea552af 100644
--- a/third_party/WebKit/Source/core/css/CSSPaintValue.h
+++ b/third_party/WebKit/Source/core/css/CSSPaintValue.h
@@ -76,9 +76,14 @@
 
   void paintImageGeneratorReady();
 
+  bool parseInputArguments();
+
+  bool m_inputArgumentsInvalid = false;
+
   Member<CSSCustomIdentValue> m_name;
   Member<CSSPaintImageGenerator> m_generator;
   Member<Observer> m_paintImageGeneratorObserver;
+  Member<CSSStyleValueVector> m_parsedInputArguments;
   Vector<RefPtr<CSSVariableData>> m_argumentVariableData;
 };
 
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index acf197b..3ae557b 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -3012,6 +3012,11 @@
       alias_for: "justify-content",
     },
     {
+      name: "line-break",
+      alias_for: "-webkit-line-break",
+      runtime_flag: "CSSLineBreak",
+    },
+    {
       name: "-webkit-opacity",
       alias_for: "opacity",
     },
diff --git a/third_party/WebKit/Source/core/css/CSSVariableData.h b/third_party/WebKit/Source/core/css/CSSVariableData.h
index 697c2da..41020f1 100644
--- a/third_party/WebKit/Source/core/css/CSSVariableData.h
+++ b/third_party/WebKit/Source/core/css/CSSVariableData.h
@@ -17,7 +17,7 @@
 class CSSParserTokenRange;
 class CSSSyntaxDescriptor;
 
-class CSSVariableData : public RefCounted<CSSVariableData> {
+class CORE_EXPORT CSSVariableData : public RefCounted<CSSVariableData> {
   WTF_MAKE_NONCOPYABLE(CSSVariableData);
   USING_FAST_MALLOC(CSSVariableData);
 
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
index 331ea22..8c924dc 100644
--- a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
+++ b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
@@ -13,7 +13,7 @@
 
 class CSSValue;
 
-class StyleValueFactory {
+class CORE_EXPORT StyleValueFactory {
   STATIC_ONLY(StyleValueFactory);
 
  public:
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index a2427de..09445ca 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -1739,8 +1739,6 @@
   TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
                        "ScheduleStyleRecalculation", TRACE_EVENT_SCOPE_THREAD,
                        "data", InspectorRecalculateStylesEvent::data(frame()));
-  InspectorInstrumentation::didScheduleStyleRecalculation(this);
-
   ++m_styleVersion;
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Range.cpp b/third_party/WebKit/Source/core/dom/Range.cpp
index 4e1d44a..6dcbf0c1 100644
--- a/third_party/WebKit/Source/core/dom/Range.cpp
+++ b/third_party/WebKit/Source/core/dom/Range.cpp
@@ -48,6 +48,7 @@
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutText.h"
 #include "core/svg/SVGSVGElement.h"
+#include "platform/EventDispatchForbiddenScope.h"
 #include "platform/geometry/FloatQuad.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/StringBuilder.h"
@@ -1782,13 +1783,15 @@
   DCHECK(startContainer()->document() == ownerDocument());
   DCHECK(endContainer()->isConnected());
   DCHECK(endContainer()->document() == ownerDocument());
-  bool didSet = selection.setSelectionDeprecated(SelectionInDOMTree::Builder()
-                                                     .collapse(startPosition())
-                                                     .extend(endPosition())
-                                                     .build());
+  EventDispatchForbiddenScope noEvents;
+  selection.setSelection(SelectionInDOMTree::Builder()
+                             .collapse(startPosition())
+                             .extend(endPosition())
+                             .build(),
+                         FrameSelection::CloseTyping |
+                             FrameSelection::ClearTypingStyle |
+                             FrameSelection::DoNotSetFocus);
   selection.cacheRangeOfDocument(this);
-  if (didSet)
-    selection.didSetSelectionDeprecated();
 }
 
 void Range::removeFromSelectionIfInDifferentRoot(Document& oldDocument) {
diff --git a/third_party/WebKit/Source/core/editing/DOMSelection.cpp b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
index b19285eb..2ad77da 100644
--- a/third_party/WebKit/Source/core/editing/DOMSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
@@ -82,8 +82,13 @@
   // TODO(tkent): Specify FrameSelection::DoNotSetFocus. crbug.com/690272
   bool didSet = frameSelection.setSelectionDeprecated(selection);
   cacheRangeIfSelectionOfDocument(newCachedRange);
-  if (didSet)
-    frameSelection.didSetSelectionDeprecated();
+  if (!didSet)
+    return;
+  Element* focusedElement = frame()->document()->focusedElement();
+  frameSelection.didSetSelectionDeprecated();
+  if (frame() && frame()->document() &&
+      focusedElement != frame()->document()->focusedElement())
+    UseCounter::count(frame(), UseCounter::SelectionFuncionsChangeFocus);
 }
 
 const VisibleSelection& DOMSelection::visibleSelection() const {
@@ -98,11 +103,6 @@
   return selection.base() <= selection.extent();
 }
 
-const Position& DOMSelection::anchorPosition() const {
-  DCHECK(frame());
-  return frame()->selection().selectionInDOMTree().base();
-}
-
 // TODO(tkent): Following four functions based on VisibleSelection should be
 // removed.
 static Position anchorPosition(const VisibleSelection& selection) {
@@ -466,22 +466,7 @@
 
   // 3. Let oldAnchor and oldFocus be the context object's anchor and focus, and
   // let newFocus be the boundary point (node, offset).
-  const Position& oldAnchor = anchorPosition();
-  // TODO(tkent): Diagnostic checks for crbug.com/693578.  They should be
-  // removed before M58 branch.
-  if (oldAnchor.isNull()) {
-    if (Range* range = documentCachedRange()) {
-      LOG(FATAL)
-          << "Selection has a cached Range, but anchorPosition is null. start="
-          << range->startContainer() << " end=" << range->endContainer();
-    } else if (frame() &&
-               !frame()
-                    ->selection()
-                    .computeVisibleSelectionInDOMTreeDeprecated()
-                    .isNone()) {
-      LOG(FATAL) << "FrameSelection is not none, but anchorPosition is null.";
-    }
-  }
+  const Position oldAnchor(anchorNode(), anchorOffset());
   DCHECK(!oldAnchor.isNull());
   const Position newFocus(node, offset);
 
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index de34916..effb5fa 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -255,15 +255,19 @@
   // Always clear the x position used for vertical arrow navigation.
   // It will be restored by the vertical arrow navigation code if necessary.
   m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
+
   // TODO(yosin): Can we move this to at end of this function?
   // This may dispatch a synchronous focus-related events.
-  selectFrameElementInParentIfFullySelected();
-  if (!isAvailable() || document() != currentDocument) {
-    // editing/selection/selectallchildren-crash.html and
-    // editing/selection/longpress-selection-in-iframe-removed-crash.html
-    // reach here.
-    return;
+  if (!(options & DoNotSetFocus)) {
+    selectFrameElementInParentIfFullySelected();
+    if (!isAvailable() || document() != currentDocument) {
+      // editing/selection/selectallchildren-crash.html and
+      // editing/selection/longpress-selection-in-iframe-removed-crash.html
+      // reach here.
+      return;
+    }
   }
+
   EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
   notifyLayoutObjectOfSelectionChange(userTriggered);
   if (userTriggered == UserTriggered) {
diff --git a/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
index 0647e19..7c8eac1 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodController.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -148,6 +148,11 @@
   switch (compositionType) {
     case TypingCommand::TextCompositionType::TextCompositionUpdate:
     case TypingCommand::TextCompositionType::TextCompositionConfirm:
+      // Calling |TypingCommand::insertText()| with empty text will result in an
+      // incorrect ending selection. We need to delete selection first.
+      // https://crbug.com/693481
+      if (text.isEmpty())
+        TypingCommand::deleteSelection(*frame.document(), 0);
       TypingCommand::insertText(*frame.document(), text, options,
                                 compositionType, isIncrementalInsertion);
       break;
diff --git a/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp b/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
index 03f0071..2234601 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
@@ -4,6 +4,7 @@
 
 #include "core/editing/InputMethodController.h"
 
+#include <memory>
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/Range.h"
@@ -15,9 +16,9 @@
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLTextAreaElement.h"
 #include "core/testing/DummyPageHolder.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include <memory>
 
 namespace blink {
 
@@ -1169,7 +1170,7 @@
   // Delete the existing composition.
   document().setTitle(emptyString);
   controller().setComposition("", underlines, 0, 0);
-  EXPECT_STREQ("beforeinput.data:;input.data:;compositionend.data:;",
+  EXPECT_STREQ("beforeinput.data:;input.data:null;compositionend.data:;",
                document().title().utf8().data());
 }
 
@@ -1223,7 +1224,7 @@
   document().setTitle(emptyString);
   document().updateStyleAndLayout();
   controller().commitText("", underlines, 1);
-  EXPECT_STREQ("beforeinput.data:;input.data:;compositionend.data:;",
+  EXPECT_STREQ("beforeinput.data:;input.data:null;compositionend.data:;",
                document().title().utf8().data());
 }
 
@@ -1409,4 +1410,21 @@
                    .computeOffsetInContainerNode());
 }
 
+TEST_F(InputMethodControllerTest, SetEmptyCompositionShouldNotMoveCaret) {
+  HTMLTextAreaElement* textarea =
+      toHTMLTextAreaElement(insertHTMLElement("<textarea id='txt'>", "txt"));
+
+  textarea->setValue("abc\n");
+  document().updateStyleAndLayout();
+  controller().setEditableSelectionOffsets(PlainTextRange(4, 4));
+
+  Vector<CompositionUnderline> underlines;
+  underlines.push_back(CompositionUnderline(0, 3, Color(255, 0, 0), false, 0));
+  controller().setComposition(String("def"), underlines, 0, 3);
+  controller().setComposition(String(""), underlines, 0, 3);
+  controller().commitText(String("def"), underlines, 0);
+
+  EXPECT_STREQ("abc\ndef", textarea->value().utf8().data());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
index 9858b90..4d83f7fa 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -74,32 +74,10 @@
   return isHTMLTextAreaElement(textControl);
 }
 
-static bool isSpellCheckingEnabledFor(const Position& position) {
-  if (position.isNull())
-    return false;
-  if (TextControlElement* textControl = enclosingTextControl(position)) {
-    if (isHTMLInputElement(textControl)) {
-      HTMLInputElement& input = toHTMLInputElement(*textControl);
-      // TODO(tkent): The following password type check should be done in
-      // HTMLElement::spellcheck(). crbug.com/371567
-      if (input.type() == InputTypeNames::password)
-        return false;
-      if (!input.isFocusedElementInDocument())
-        return false;
-    }
-  }
-  if (HTMLElement* element =
-          Traversal<HTMLElement>::firstAncestorOrSelf(*position.anchorNode())) {
-    if (element->isSpellCheckingEnabled())
-      return true;
-  }
-  return false;
-}
-
 static bool isSpellCheckingEnabledFor(const VisibleSelection& selection) {
   if (selection.isNone())
     return false;
-  return isSpellCheckingEnabledFor(selection.start());
+  return SpellChecker::isSpellCheckingEnabledAt(selection.start());
 }
 
 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) {
@@ -601,9 +579,9 @@
   DCHECK_GE(location, 0);
   const EphemeralRange& rangeToMark =
       calculateCharacterSubrange(checkingRange, location, length);
-  if (!isSpellCheckingEnabledFor(rangeToMark.startPosition()))
+  if (!SpellChecker::isSpellCheckingEnabledAt(rangeToMark.startPosition()))
     return;
-  if (!isSpellCheckingEnabledFor(rangeToMark.endPosition()))
+  if (!SpellChecker::isSpellCheckingEnabledAt(rangeToMark.endPosition()))
     return;
   document->markers().addMarker(rangeToMark.startPosition(),
                                 rangeToMark.endPosition(), type, description);
@@ -929,7 +907,7 @@
   }
 
   TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection");
-  if (!isSpellCheckingEnabledFor(oldSelectionStart))
+  if (!isSpellCheckingEnabledAt(oldSelectionStart))
     return;
 
   // When spell checking is off, existing markers disappear after the selection
@@ -1243,4 +1221,24 @@
   return std::make_pair(firstFoundItem, firstFoundOffset);
 }
 
+// static
+bool SpellChecker::isSpellCheckingEnabledAt(const Position& position) {
+  if (position.isNull())
+    return false;
+  if (TextControlElement* textControl = enclosingTextControl(position)) {
+    if (isHTMLInputElement(textControl)) {
+      HTMLInputElement& input = toHTMLInputElement(*textControl);
+      // TODO(tkent): The following password type check should be done in
+      // HTMLElement::spellcheck(). crbug.com/371567
+      if (input.type() == InputTypeNames::password)
+        return false;
+      if (!input.isFocusedElementInDocument())
+        return false;
+    }
+  }
+  HTMLElement* element =
+      Traversal<HTMLElement>::firstAncestorOrSelf(*position.anchorNode());
+  return element && element->isSpellCheckingEnabled();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
index ee43c79..d5b9ca5f 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
@@ -58,6 +58,7 @@
   SpellCheckerClient& spellCheckerClient() const;
   TextCheckerClient& textChecker() const;
 
+  static bool isSpellCheckingEnabledAt(const Position&);
   bool isSpellCheckingEnabled() const;
   void toggleSpellCheckingEnabled();
   void ignoreSpelling();
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp
index fe6fdb5..e7361a7 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.cpp
+++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -46,7 +46,7 @@
 }
 
 // Make sure update_use_counter_css.py was run which updates histograms.xml.
-constexpr int kMaximumCSSSampleId = 555;
+constexpr int kMaximumCSSSampleId = 556;
 
 }  // namespace
 
@@ -1079,6 +1079,8 @@
       return 554;
     case CSSPropertyMaxBlockSize:
       return 555;
+    case CSSPropertyAliasLineBreak:
+      return 556;
     // 1. Add new features above this line (don't change the assigned numbers of
     // the existing items).
     // 2. Update kMaximumCSSSampleId with the new maximum value.
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 6b3753d..0a799a8 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1465,6 +1465,7 @@
     OffscreenCanvasConvertToBlob = 1834,
     SVGInCanvas2D = 1835,
     SVGInWebGL = 1836,
+    SelectionFuncionsChangeFocus = 1837,
 
     // 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/html/HTMLDialogElement.cpp b/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
index 9edc5883..14b1332 100644
--- a/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
@@ -28,7 +28,7 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/dom/AXObjectCache.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/dom/shadow/FlatTreeTraversal.h"
 #include "core/events/Event.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/UseCounter.h"
@@ -42,13 +42,16 @@
 // This function chooses the focused element when show() or showModal() is
 // invoked, as described in their spec.
 static void setFocusForDialog(HTMLDialogElement* dialog) {
-  Element* focusableDescendant = 0;
-  Node* next = 0;
-  for (Node* node = dialog->firstChild(); node; node = next) {
-    if (isHTMLDialogElement(*node))
-      next = NodeTraversal::nextSkippingChildren(*node, dialog);
-    else
-      next = NodeTraversal::next(*node, dialog);
+  Element* focusableDescendant = nullptr;
+  Node* next = nullptr;
+
+  // TODO(kochi): How to find focusable element inside Shadow DOM is not
+  // currently specified.  This may change at any time.
+  // See crbug/383230 and https://github.com/whatwg/html/issue/2393 .
+  for (Node* node = FlatTreeTraversal::firstChild(*dialog); node; node = next) {
+    next = isHTMLDialogElement(*node)
+               ? FlatTreeTraversal::nextSkippingChildren(*node, dialog)
+               : FlatTreeTraversal::next(*node, dialog);
 
     if (!node->isElementNode())
       continue;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
index 84d9898d..b5e7250 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
@@ -150,9 +150,6 @@
     void didPaint(LocalFrame*, const GraphicsLayer*, GraphicsContext&, const LayoutRect&);
 
     [Network]
-    void didScheduleStyleRecalculation([Keep] Document*);
-
-    [Network]
     void applyUserAgentOverride(LocalFrame*, String* userAgent);
 
     [Network]
@@ -321,10 +318,10 @@
     [Log]
     void consoleMessageAdded(ExecutionContext*, ConsoleMessage*);
 
-    [Network, Performance]
+    [Performance]
     void willRecalculateStyle([Keep] Document*);
 
-    [Page, Network, Performance]
+    [Page, Performance]
     void didRecalculateStyle(Document*);
 
     [Page]
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
index 5ec8ef4e..3432d073 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -1046,22 +1046,6 @@
     *userAgent = userAgentOverride;
 }
 
-void InspectorNetworkAgent::willRecalculateStyle(Document*) {
-  DCHECK(!m_isRecalculatingStyle);
-  m_isRecalculatingStyle = true;
-}
-
-void InspectorNetworkAgent::didRecalculateStyle() {
-  m_isRecalculatingStyle = false;
-  m_styleRecalculationInitiator = nullptr;
-}
-
-void InspectorNetworkAgent::didScheduleStyleRecalculation(Document* document) {
-  if (!m_styleRecalculationInitiator)
-    m_styleRecalculationInitiator =
-        buildInitiatorObject(document, FetchInitiatorInfo());
-}
-
 std::unique_ptr<protocol::Network::Initiator>
 InspectorNetworkAgent::buildInitiatorObject(
     Document* document,
@@ -1096,9 +1080,6 @@
     return initiatorObject;
   }
 
-  if (m_isRecalculatingStyle && m_styleRecalculationInitiator)
-    return m_styleRecalculationInitiator->clone();
-
   return protocol::Network::Initiator::create()
       .setType(protocol::Network::Initiator::TypeEnum::Other)
       .build();
@@ -1565,7 +1546,6 @@
       m_resourcesData(NetworkResourcesData::create(maximumTotalBufferSize,
                                                    maximumResourceBufferSize)),
       m_pendingRequest(nullptr),
-      m_isRecalculatingStyle(false),
       m_removeFinishedReplayXHRTimer(
           TaskRunnerHelper::get(TaskType::UnspecedLoading,
                                 inspectedFrames->root()),
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
index b01d9fe..71f498e 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
@@ -158,12 +158,6 @@
   void willDestroyResource(Resource*);
 
   void applyUserAgentOverride(String* userAgent);
-
-  // FIXME: InspectorNetworkAgent should not be aware of style recalculation.
-  void willRecalculateStyle(Document*);
-  void didRecalculateStyle();
-  void didScheduleStyleRecalculation(Document*);
-
   void frameScheduledNavigation(LocalFrame*, double);
   void frameClearedScheduledNavigation(LocalFrame*);
   void frameScheduledClientNavigation(LocalFrame*);
@@ -279,10 +273,6 @@
   HashSet<String> m_framesWithScheduledNavigation;
   HashSet<String> m_framesWithScheduledClientNavigation;
 
-  // FIXME: InspectorNetworkAgent should now be aware of style recalculation.
-  std::unique_ptr<protocol::Network::Initiator> m_styleRecalculationInitiator;
-  bool m_isRecalculatingStyle;
-
   HeapHashSet<Member<XMLHttpRequest>> m_replayXHRs;
   HeapHashSet<Member<XMLHttpRequest>> m_replayXHRsToBeDeleted;
   TaskRunnerTimer<InspectorNetworkAgent> m_removeFinishedReplayXHRTimer;
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
index fa1660f..719487ad0 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
@@ -31,12 +31,13 @@
  * @implements {SDK.TargetManager.Observer}
  * @unrestricted
  */
-Bindings.NetworkProjectManager = class {
+Bindings.NetworkProjectManager = class extends Common.Object {
   /**
    * @param {!SDK.TargetManager} targetManager
    * @param {!Workspace.Workspace} workspace
    */
   constructor(targetManager, workspace) {
+    super();
     this._workspace = workspace;
     targetManager.observeTargets(this);
   }
@@ -58,6 +59,17 @@
   }
 };
 
+/** @implements {Common.Emittable} */
+Bindings.NetworkProjectManager.FrameAttributionChangedEvent = class {
+  /**
+   * @param {!Workspace.UISourceCode} uiSourceCode
+   */
+  constructor(uiSourceCode) {
+    this.uiSourceCode = uiSourceCode;
+  }
+};
+
+
 /**
  * @unrestricted
  */
@@ -70,10 +82,9 @@
   constructor(target, workspace, resourceTreeModel) {
     super(target);
     this._workspace = workspace;
-    /** @type {!Map<string, !Bindings.ContentProviderBasedProject>} */
-    this._workspaceProjects = new Map();
     this._resourceTreeModel = resourceTreeModel;
     target[Bindings.NetworkProject._networkProjectSymbol] = this;
+    this._createProjects();
 
     this._eventListeners = [];
 
@@ -105,12 +116,11 @@
 
   /**
    * @param {!SDK.Target} target
-   * @param {?SDK.ResourceTreeFrame} frame
    * @param {boolean} isContentScripts
    * @return {string}
    */
-  static projectId(target, frame, isContentScripts) {
-    return target.id() + ':' + (frame ? frame.id : '') + ':' + (isContentScripts ? 'contentscripts' : '');
+  static projectId(target, isContentScripts) {
+    return (isContentScripts ? 'contentscripts' : 'networkproject') + ':' + target.id();
   }
 
   /**
@@ -122,19 +132,11 @@
   }
 
   /**
-   * @param {!Workspace.Project} project
-   * @return {?SDK.Target} target
+   * @param {!Workspace.UISourceCode} uiSourceCode
+   * @return {?Set<!SDK.ResourceTreeFrame>}
    */
-  static targetForProject(project) {
-    return project[Bindings.NetworkProject._targetSymbol] || null;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  static frameForProject(project) {
-    return project[Bindings.NetworkProject._frameSymbol] || null;
+  static framesForUISourceCode(uiSourceCode) {
+    return uiSourceCode[Bindings.NetworkProject._frameSymbol] || null;
   }
 
   /**
@@ -142,7 +144,7 @@
    * @return {?SDK.Target} target
    */
   static targetForUISourceCode(uiSourceCode) {
-    return uiSourceCode[Bindings.NetworkProject._targetSymbol] || null;
+    return uiSourceCode.project()[Bindings.NetworkProject._targetSymbol] || null;
   }
 
   /**
@@ -150,7 +152,7 @@
    * @return {string}
    */
   static uiSourceCodeMimeType(uiSourceCode) {
-    if (uiSourceCode[Bindings.NetworkProject._scriptSymbol] || uiSourceCode[Bindings.NetworkProject._styleSheetSymbol])
+    if (uiSourceCode[Bindings.NetworkProject._useCanonicalMimeType])
       return uiSourceCode.contentType().canonicalMimeType();
 
     var resource = uiSourceCode[Bindings.NetworkProject._resourceSymbol];
@@ -161,24 +163,36 @@
   }
 
   /**
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @param {boolean} isContentScripts
-   * @return {!Bindings.ContentProviderBasedProject}
+   * @param {!Workspace.UISourceCode} uiSourceCode
+   * @param {!SDK.ResourceTreeFrame} frame
    */
-  _workspaceProject(frame, isContentScripts) {
-    var projectId = Bindings.NetworkProject.projectId(this.target(), frame, isContentScripts);
-    var projectType = isContentScripts ? Workspace.projectTypes.ContentScripts : Workspace.projectTypes.Network;
+  _addFrameToUISourceCode(uiSourceCode, frame) {
+    var frames = uiSourceCode[Bindings.NetworkProject._frameSymbol];
+    if (!frames) {
+      frames = /** @type {!Set<!SDK.ResourceTreeFrame>} */ (new Set());
+      uiSourceCode[Bindings.NetworkProject._frameSymbol] = frames;
+    }
+    frames.add(frame);
+  }
 
-    var project = this._workspaceProjects.get(projectId);
-    if (project)
-      return project;
+  /**
+   * @param {!Workspace.UISourceCode} uiSourceCode
+   * @param {!SDK.ResourceTreeFrame} frame
+   */
+  _removeFrameFromUISourceCode(uiSourceCode, frame) {
+    var frames = uiSourceCode[Bindings.NetworkProject._frameSymbol];
+    frames.delete(frame);
+  }
 
-    project = new Bindings.ContentProviderBasedProject(
-        this._workspace, projectId, projectType, '', false /* isServiceProject */);
-    project[Bindings.NetworkProject._targetSymbol] = this.target();
-    project[Bindings.NetworkProject._frameSymbol] = frame;
-    this._workspaceProjects.set(projectId, project);
-    return project;
+  _createProjects() {
+    this._regularProject = new Bindings.ContentProviderBasedProject(
+        this._workspace, Bindings.NetworkProject.projectId(this.target(), false), Workspace.projectTypes.Network, '',
+        false /* isServiceProject */);
+    this._regularProject[Bindings.NetworkProject._targetSymbol] = this.target();
+    this._contentScriptsProject = new Bindings.ContentProviderBasedProject(
+        this._workspace, Bindings.NetworkProject.projectId(this.target(), true), Workspace.projectTypes.ContentScripts,
+        '', false /* isServiceProject */);
+    this._contentScriptsProject[Bindings.NetworkProject._targetSymbol] = this.target();
   }
 
   /**
@@ -195,17 +209,6 @@
     return uiSourceCode;
   }
 
-  /**
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @param {string} url
-   */
-  _removeFileForURL(frame, url) {
-    var project = this._workspaceProjects.get(Bindings.NetworkProject.projectId(this.target(), frame, false));
-    if (!project)
-      return;
-    project.removeFile(url);
-  }
-
   _populate() {
     /**
      * @param {!SDK.ResourceTreeFrame} frame
@@ -249,10 +252,19 @@
       if (!parsedURL.isValid)
         return;
     }
-    var uiSourceCode = this._createFile(script, SDK.ResourceTreeFrame.fromScript(script), script.isContentScript());
-    uiSourceCode[Bindings.NetworkProject._scriptSymbol] = script;
-    var resource = SDK.ResourceTreeModel.resourceForURL(uiSourceCode.url());
-    this._addUISourceCodeWithProvider(uiSourceCode, script, this._resourceMetadata(resource));
+    var frame = SDK.ResourceTreeFrame.fromScript(script);
+    var url = script.sourceURL;
+    var project = script.isContentScript() ? this._contentScriptsProject : this._regularProject;
+    var oldSourceCode = project.uiSourceCodeForURL(url);
+    var oldFrames = oldSourceCode ? Bindings.NetworkProject.framesForUISourceCode(oldSourceCode) : null;
+    var newSourceCode = this._createFile(script, frame, script.isContentScript());
+    newSourceCode[Bindings.NetworkProject._useCanonicalMimeType] = true;
+    if (oldFrames) {
+      for (var oldFrame of oldFrames)
+        this._addFrameToUISourceCode(newSourceCode, oldFrame);
+    }
+    var metadata = frame ? Bindings.resourceMetadata(frame.resourceForURL(newSourceCode.url())) : null;
+    this._addUISourceCodeWithProvider(newSourceCode, script, metadata);
   }
 
   /**
@@ -262,14 +274,23 @@
     var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
     if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector')
       return;
-    if (!header.resourceURL())
+    var url = header.resourceURL();
+    if (!url)
       return;
 
+    var frame = SDK.ResourceTreeFrame.fromStyleSheet(header);
+    var uiSourceCode = this._regularProject.uiSourceCodeForURL(url);
+    if (uiSourceCode) {
+      this._addFrameToUISourceCode(uiSourceCode, frame);
+      Bindings.networkProjectManager.emit(
+          new Bindings.NetworkProjectManager.FrameAttributionChangedEvent(uiSourceCode));
+      return;
+    }
     var originalContentProvider = header.originalContentProvider();
-    var uiSourceCode = this._createFile(originalContentProvider, SDK.ResourceTreeFrame.fromStyleSheet(header), false);
-    uiSourceCode[Bindings.NetworkProject._styleSheetSymbol] = header;
-    var resource = SDK.ResourceTreeModel.resourceForURL(uiSourceCode.url());
-    this._addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, this._resourceMetadata(resource));
+    uiSourceCode = this._createFile(originalContentProvider, frame, false);
+    uiSourceCode[Bindings.NetworkProject._useCanonicalMimeType] = true;
+    var metadata = frame ? Bindings.resourceMetadata(frame.resourceForURL(uiSourceCode.url())) : null;
+    this._addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, metadata);
   }
 
   /**
@@ -280,7 +301,16 @@
     if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector')
       return;
 
-    this._removeFileForURL(SDK.ResourceTreeFrame.fromStyleSheet(header), header.resourceURL());
+    var url = header.resourceURL();
+    var uiSourceCode = this._regularProject.uiSourceCodeForURL(url);
+    if (!uiSourceCode)
+      return;
+    var frame = SDK.ResourceTreeFrame.fromStyleSheet(header);
+    this._removeFrameFromUISourceCode(uiSourceCode, frame);
+    var frames =
+        /** @type {!Set<!SDK.ResourceTreeFrame>} */ (Bindings.NetworkProject.framesForUISourceCode(uiSourceCode));
+    if (!frames.size)
+      this._regularProject.removeFile(url);
   }
 
   /**
@@ -317,7 +347,7 @@
 
     var uiSourceCode = this._createFile(resource, SDK.ResourceTreeFrame.fromResource(resource), false);
     uiSourceCode[Bindings.NetworkProject._resourceSymbol] = resource;
-    this._addUISourceCodeWithProvider(uiSourceCode, resource, this._resourceMetadata(resource));
+    this._addUISourceCodeWithProvider(uiSourceCode, resource, Bindings.resourceMetadata(resource));
   }
 
   /**
@@ -325,12 +355,10 @@
    */
   _frameWillNavigate(event) {
     var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    var project = this._workspaceProject(frame, false);
-    for (var resource of frame.resources())
-      project.removeUISourceCode(resource.url);
-    project = this._workspaceProject(frame, true);
-    for (var resource of frame.resources())
-      project.removeUISourceCode(resource.url);
+    for (var resource of frame.resources()) {
+      this._regularProject.removeUISourceCode(resource.url);
+      this._contentScriptsProject.removeUISourceCode(resource.url);
+    }
   }
 
   /**
@@ -356,32 +384,24 @@
    */
   _createFile(contentProvider, frame, isContentScript) {
     var url = contentProvider.contentURL();
-    var project = this._workspaceProject(frame, isContentScript);
+    var project = isContentScript ? this._contentScriptsProject : this._regularProject;
     var uiSourceCode = project.createUISourceCode(url, contentProvider.contentType());
-    uiSourceCode[Bindings.NetworkProject._targetSymbol] = this.target();
+    if (frame)
+      this._addFrameToUISourceCode(uiSourceCode, frame);
     return uiSourceCode;
   }
 
-  /**
-   * @param {?SDK.Resource} resource
-   * @return {?Workspace.UISourceCodeMetadata}
-   */
-  _resourceMetadata(resource) {
-    if (!resource || (typeof resource.contentSize() !== 'number' && !resource.lastModified()))
-      return null;
-    return new Workspace.UISourceCodeMetadata(resource.lastModified(), resource.contentSize());
-  }
-
   _dispose() {
-    this._reset();
+    this._regularProject.removeProject();
+    this._contentScriptsProject.removeProject();
     Common.EventTarget.removeEventListeners(this._eventListeners);
     delete this.target()[Bindings.NetworkProject._networkProjectSymbol];
   }
 
   _reset() {
-    for (var project of this._workspaceProjects.values())
-      project.removeProject();
-    this._workspaceProjects.clear();
+    this._regularProject.removeProject();
+    this._contentScriptsProject.removeProject();
+    this._createProjects();
   }
 
   /**
@@ -392,9 +412,8 @@
    */
   static uiSourceCodeForScriptURL(workspace, url, script) {
     var target = script.debuggerModel.target();
-    var frame = SDK.ResourceTreeFrame.fromScript(script);
-    return workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, frame, false), url) ||
-        workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, frame, true), url);
+    return workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, false), url) ||
+        workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, true), url);
   }
 
   /**
@@ -404,14 +423,12 @@
    * @return {?Workspace.UISourceCode}
    */
   static uiSourceCodeForStyleURL(workspace, url, header) {
-    var frame = SDK.ResourceTreeFrame.fromStyleSheet(header);
-    return workspace.uiSourceCode(Bindings.NetworkProject.projectId(header.target(), frame, false), url);
+    return workspace.uiSourceCode(Bindings.NetworkProject.projectId(header.target(), false), url);
   }
 };
 
 Bindings.NetworkProject._networkProjectSymbol = Symbol('networkProject');
 Bindings.NetworkProject._resourceSymbol = Symbol('resource');
-Bindings.NetworkProject._scriptSymbol = Symbol('script');
-Bindings.NetworkProject._styleSheetSymbol = Symbol('styleSheet');
+Bindings.NetworkProject._useCanonicalMimeType = Symbol('useCanonicalMimeType');
 Bindings.NetworkProject._targetSymbol = Symbol('target');
 Bindings.NetworkProject._frameSymbol = Symbol('frame');
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceUtils.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceUtils.js
index d586241f..8ddd2c9 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceUtils.js
@@ -86,3 +86,13 @@
   var displayName = url.trimURL(parsedURL.host);
   return displayName === '/' ? parsedURL.host + '/' : displayName;
 };
+
+/**
+ * @param {?SDK.Resource} resource
+ * @return {?Workspace.UISourceCodeMetadata}
+ */
+Bindings.resourceMetadata = function(resource) {
+  if (!resource || (typeof resource.contentSize() !== 'number' && !resource.lastModified()))
+    return null;
+  return new Workspace.UISourceCodeMetadata(resource.lastModified(), resource.contentSize());
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index 12c82662e..574e6df3 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -181,7 +181,7 @@
     Common.formatterWorkerPool = new Common.FormatterWorkerPool();
     Workspace.fileSystemMapping = new Workspace.FileSystemMapping(Workspace.isolatedFileSystemManager);
 
-    Main.networkProjectManager = new Bindings.NetworkProjectManager(SDK.targetManager, Workspace.workspace);
+    Bindings.networkProjectManager = new Bindings.NetworkProjectManager(SDK.targetManager, Workspace.workspace);
     Bindings.presentationConsoleMessageHelper = new Bindings.PresentationConsoleMessageHelper(Workspace.workspace);
     Bindings.cssWorkspaceBinding = new Bindings.CSSWorkspaceBinding(SDK.targetManager, Workspace.workspace);
     Bindings.debuggerWorkspaceBinding = new Bindings.DebuggerWorkspaceBinding(SDK.targetManager, Workspace.workspace);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
index bf98089..b2b3384 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -532,10 +532,12 @@
 
   /**
    * @param {!SDK.CSSStyleSheetHeader} header
-   * @return {?SDK.ResourceTreeFrame}
+   * @return {!SDK.ResourceTreeFrame}
    */
   static fromStyleSheet(header) {
-    return SDK.ResourceTreeFrame._fromObject(header);
+    var frame = SDK.ResourceTreeFrame._fromObject(header);
+    console.assert(frame, 'Failed to find frame for header ', header.id);
+    return /** @type {!SDK.ResourceTreeFrame} */ (frame);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
index fc433ab..8948d300 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -78,6 +78,9 @@
     SDK.targetManager.observeTargets(this);
     this._resetWorkspace(Workspace.workspace);
     this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
+
+    Bindings.networkProjectManager.on(
+        Bindings.NetworkProjectManager.FrameAttributionChangedEvent, this._frameAttributionChanged, this);
   }
 
   /**
@@ -176,7 +179,8 @@
    */
   _onBindingRemoved(event) {
     var binding = /** @type {!Persistence.PersistenceBinding} */ (event.data);
-    this._addUISourceCode(binding.network);
+    if (this._addUISourceCode(binding.network))
+      this.uiSourceCodeAdded(binding.network);
   }
 
   /**
@@ -247,16 +251,27 @@
 
   /**
    * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?SDK.ResourceTreeFrame}
+   * @return {?Set<!SDK.ResourceTreeFrame>}
    */
-  _uiSourceCodeFrame(uiSourceCode) {
-    var frame = Bindings.NetworkProject.frameForProject(uiSourceCode.project());
-    if (!frame) {
-      var target = Bindings.NetworkProject.targetForProject(uiSourceCode.project());
+  _uiSourceCodeFrames(uiSourceCode) {
+    var frames = Bindings.NetworkProject.framesForUISourceCode(uiSourceCode);
+    if (!frames || !frames.size) {
+      // This is to overcome compilation cache which doesn't get reset.
+      var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
       var resourceTreeModel = target && SDK.ResourceTreeModel.fromTarget(target);
-      frame = resourceTreeModel && resourceTreeModel.mainFrame;
+      var frame = resourceTreeModel ? resourceTreeModel.mainFrame : null;
+      if (frame)
+        frames = new Set([frame]);
     }
-    return frame;
+    return frames;
+  }
+
+  /**
+   * @param {!Bindings.NetworkProjectManager.FrameAttributionChangedEvent} event
+   */
+  _frameAttributionChanged(event) {
+    this._removeUISourceCode(event.uiSourceCode);
+    this._addUISourceCode(event.uiSourceCode);
   }
 
   /**
@@ -264,11 +279,11 @@
    */
   _addUISourceCode(uiSourceCode) {
     if (!this.accept(uiSourceCode))
-      return;
+      return false;
 
     var binding = Persistence.persistence.binding(uiSourceCode);
     if (!Runtime.experiments.isEnabled('persistence2') && binding && binding.network === uiSourceCode)
-      return;
+      return false;
 
     var isFromSourceMap = uiSourceCode.contentType().isFromSourceMap();
     var path;
@@ -279,14 +294,26 @@
 
     var project = uiSourceCode.project();
     var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    var frame = this._uiSourceCodeFrame(uiSourceCode);
+    var frames = this._uiSourceCodeFrames(uiSourceCode);
+    var uiSourceCodeNodes = [];
+    if (frames && frames.size) {
+      for (var frame of frames) {
+        var folderNode =
+            this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap);
+        var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode, frame);
+        folderNode.appendChild(uiSourceCodeNode);
+        uiSourceCodeNodes.push(uiSourceCodeNode);
+      }
+    } else {
+      var folderNode =
+          this._folderNode(uiSourceCode, project, target, null, uiSourceCode.origin(), path, isFromSourceMap);
+      var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode, null);
+      folderNode.appendChild(uiSourceCodeNode);
+      uiSourceCodeNodes.push(uiSourceCodeNode);
+    }
 
-    var folderNode =
-        this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap);
-    var uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode);
-    this._uiSourceCodeNodes.set(uiSourceCode, [uiSourceCodeNode]);
-    folderNode.appendChild(uiSourceCodeNode);
-    this.uiSourceCodeAdded(uiSourceCode);
+    this._uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNodes);
+    return true;
   }
 
   /**
@@ -300,7 +327,8 @@
    */
   _uiSourceCodeAdded(event) {
     var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._addUISourceCode(uiSourceCode);
+    if (this._addUISourceCode(uiSourceCode))
+      this.uiSourceCodeAdded(uiSourceCode);
   }
 
   /**
@@ -532,7 +560,7 @@
 
       var project = uiSourceCode.project();
       var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-      var frame = this._uiSourceCodeFrame(uiSourceCode);
+      var frame = node.frame();
 
       var parentNode = node.parent;
       parentNode.removeChild(node);
@@ -1238,13 +1266,22 @@
   /**
    * @param {!Sources.NavigatorView} navigatorView
    * @param {!Workspace.UISourceCode} uiSourceCode
+   * @param {?SDK.ResourceTreeFrame} frame
    */
-  constructor(navigatorView, uiSourceCode) {
+  constructor(navigatorView, uiSourceCode, frame) {
     super(uiSourceCode.project().id() + ':' + uiSourceCode.url(), Sources.NavigatorView.Types.File);
     this._navigatorView = navigatorView;
     this._uiSourceCode = uiSourceCode;
     this._treeElement = null;
     this._eventListeners = [];
+    this._frame = frame;
+  }
+
+  /**
+   * @return {?SDK.ResourceTreeFrame}
+   */
+  frame() {
+    return this._frame;
   }
 
   /**
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index 06100e3..25c2a68 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -896,8 +896,12 @@
   if (!imageBitmap)
     return String();
 
+  StaticBitmapImage* bitmapImage = imageBitmap->bitmapImage();
+  if (!bitmapImage)
+    return String();
+
   // TODO(ccameron): AXLayoutObject::imageDataUrl should create sRGB images.
-  sk_sp<SkImage> image = imageBitmap->bitmapImage()->imageForCurrentFrame(
+  sk_sp<SkImage> image = bitmapImage->imageForCurrentFrame(
       ColorBehavior::transformToGlobalTarget());
   if (!image || image->width() <= 0 || image->height() <= 0)
     return String();
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp
index 5a37f56c..a3b9493 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp
@@ -66,9 +66,13 @@
 
 CSSPaintDefinition::~CSSPaintDefinition() {}
 
-PassRefPtr<Image> CSSPaintDefinition::paint(const LayoutObject& layoutObject,
-                                            const IntSize& size,
-                                            float zoom) {
+PassRefPtr<Image> CSSPaintDefinition::paint(
+    const LayoutObject& layoutObject,
+    const IntSize& size,
+    float zoom,
+    const CSSStyleValueVector* paintArguments) {
+  DCHECK(paintArguments);
+
   const IntSize specifiedSize = getSpecifiedSize(size, zoom);
 
   ScriptState::Scope scope(m_scriptState.get());
@@ -99,7 +103,8 @@
   v8::Local<v8::Value> argv[] = {
       ToV8(renderingContext, m_scriptState->context()->Global(), isolate),
       ToV8(paintSize, m_scriptState->context()->Global(), isolate),
-      ToV8(styleMap, m_scriptState->context()->Global(), isolate)};
+      ToV8(styleMap, m_scriptState->context()->Global(), isolate),
+      ToV8(*paintArguments, m_scriptState->context()->Global(), isolate)};
 
   v8::Local<v8::Function> paint = m_paint.newLocal(isolate);
 
@@ -107,7 +112,7 @@
   block.SetVerbose(true);
 
   V8ScriptRunner::callFunction(paint, m_scriptState->getExecutionContext(),
-                               instance, 3, argv, isolate);
+                               instance, WTF_ARRAY_LENGTH(argv), argv, isolate);
 
   // The paint function may have produced an error, in which case produce an
   // invalid image.
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.h b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.h
index 636b821f..86b9762 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.h
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.h
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/ScopedPersistent.h"
 #include "core/CSSPropertyNames.h"
 #include "core/css/CSSSyntaxDescriptor.h"
+#include "core/css/cssom/CSSStyleValue.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/heap/Handle.h"
 #include "v8/include/v8.h"
@@ -40,7 +41,10 @@
   //
   // This may return a nullptr (representing an invalid image) if javascript
   // throws an error.
-  PassRefPtr<Image> paint(const LayoutObject&, const IntSize&, float zoom);
+  PassRefPtr<Image> paint(const LayoutObject&,
+                          const IntSize&,
+                          float zoom,
+                          const CSSStyleValueVector*);
   const Vector<CSSPropertyID>& nativeInvalidationProperties() const {
     return m_nativeInvalidationProperties;
   }
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
index 6b488a1..546b68d 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
@@ -52,8 +52,10 @@
 PassRefPtr<Image> CSSPaintImageGeneratorImpl::paint(
     const LayoutObject& layoutObject,
     const IntSize& size,
-    float zoom) {
-  return m_definition ? m_definition->paint(layoutObject, size, zoom) : nullptr;
+    float zoom,
+    const CSSStyleValueVector* data) {
+  return m_definition ? m_definition->paint(layoutObject, size, zoom, data)
+                      : nullptr;
 }
 
 const Vector<CSSPropertyID>&
@@ -74,6 +76,16 @@
   return m_definition && m_definition->hasAlpha();
 }
 
+const Vector<CSSSyntaxDescriptor>&
+CSSPaintImageGeneratorImpl::inputArgumentTypes() const {
+  DEFINE_STATIC_LOCAL(Vector<CSSSyntaxDescriptor>, emptyVector, ());
+  return m_definition ? m_definition->inputArgumentTypes() : emptyVector;
+}
+
+bool CSSPaintImageGeneratorImpl::isImageGeneratorReady() const {
+  return m_definition;
+}
+
 DEFINE_TRACE(CSSPaintImageGeneratorImpl) {
   visitor->trace(m_definition);
   visitor->trace(m_observer);
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
index 0fff240..a6c1b02 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
@@ -7,6 +7,7 @@
 
 #include "bindings/core/v8/ScopedPersistent.h"
 #include "core/css/CSSPaintImageGenerator.h"
+#include "core/css/cssom/CSSStyleValue.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/heap/Handle.h"
 #include "v8/include/v8.h"
@@ -14,6 +15,7 @@
 namespace blink {
 
 class CSSPaintDefinition;
+class CSSSyntaxDescriptor;
 class Document;
 class Image;
 
@@ -26,10 +28,13 @@
 
   PassRefPtr<Image> paint(const LayoutObject&,
                           const IntSize&,
-                          float zoom) final;
+                          float zoom,
+                          const CSSStyleValueVector*) final;
   const Vector<CSSPropertyID>& nativeInvalidationProperties() const final;
   const Vector<AtomicString>& customInvalidationProperties() const final;
   bool hasAlpha() const final;
+  const Vector<CSSSyntaxDescriptor>& inputArgumentTypes() const final;
+  bool isImageGeneratorReady() const final;
 
   // Should be called from the PaintWorkletGlobalScope when a javascript class
   // is registered with the same name.
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index b5f4d84..41000ca 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -217,6 +217,10 @@
       status: "experimental",
     },
     {
+      name: "CSSLineBreak",
+      status: "test",
+    },
+    {
       name: "CSSMaskSourceType",
       status: "experimental",
     },
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 12986c06..8fc301e 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -162,6 +162,10 @@
   RuntimeEnabledFeatures::setLazyParseCSSEnabled(enable);
 }
 
+void WebRuntimeFeatures::enableLoadingWithMojo(bool enable) {
+  RuntimeEnabledFeatures::setLoadingWithMojoEnabled(enable);
+}
+
 void WebRuntimeFeatures::enableMediaCapture(bool enable) {
   RuntimeEnabledFeatures::setMediaCaptureEnabled(enable);
 }
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index 1428a480..c1188d3b 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -87,6 +87,7 @@
   BLINK_EXPORT static void enableHeapCompaction(bool);
   BLINK_EXPORT static void enableInputMultipleFieldsUI(bool);
   BLINK_EXPORT static void enableLazyParseCSS(bool);
+  BLINK_EXPORT static void enableLoadingWithMojo(bool);
   BLINK_EXPORT static void enableMediaCapture(bool);
   BLINK_EXPORT static void enableMediaDocumentDownloadButton(bool);
   BLINK_EXPORT static void enableMediaSession(bool);
diff --git a/tools/android/android_studio/ChromiumStyle.xml b/tools/android/android_studio/ChromiumStyle.xml
new file mode 100644
index 0000000..76be454
--- /dev/null
+++ b/tools/android/android_studio/ChromiumStyle.xml
@@ -0,0 +1,312 @@
+<code_scheme name="ChromiumStyle">
+  <option name="JAVA_INDENT_OPTIONS">
+    <value>
+      <option name="INDENT_SIZE" value="4" />
+      <option name="CONTINUATION_INDENT_SIZE" value="8" />
+      <option name="TAB_SIZE" value="8" />
+      <option name="USE_TAB_CHARACTER" value="false" />
+      <option name="SMART_TABS" value="false" />
+      <option name="LABEL_INDENT_SIZE" value="0" />
+      <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+      <option name="USE_RELATIVE_INDENTS" value="false" />
+    </value>
+  </option>
+  <option name="FIELD_NAME_PREFIX" value="m" />
+  <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
+  <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
+  <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
+  <option name="IMPORT_LAYOUT_TABLE">
+    <value>
+      <package name="android" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="com" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="dalvik" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="junit" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="org" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="com.google.android.apps.chrome" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="org.chromium" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="java" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="javax" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="android" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="com" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="dalvik" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="junit" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="org" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="com.google.android.apps.chrome" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="org.chromium" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="java" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="javax" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="" withSubpackages="true" static="false" />
+    </value>
+  </option>
+  <option name="RIGHT_MARGIN" value="100" />
+  <option name="JD_P_AT_EMPTY_LINES" value="false" />
+  <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
+  <option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
+  <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
+  <option name="JD_KEEP_EMPTY_RETURN" value="false" />
+  <option name="JD_PRESERVE_LINE_FEEDS" value="true" />
+  <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+  <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+  <option name="BLANK_LINES_AROUND_FIELD" value="1" />
+  <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+  <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+  <option name="ALIGN_MULTILINE_FOR" value="false" />
+  <option name="CALL_PARAMETERS_WRAP" value="1" />
+  <option name="METHOD_PARAMETERS_WRAP" value="1" />
+  <option name="EXTENDS_LIST_WRAP" value="1" />
+  <option name="THROWS_LIST_WRAP" value="1" />
+  <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+  <option name="THROWS_KEYWORD_WRAP" value="1" />
+  <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+  <option name="BINARY_OPERATION_WRAP" value="1" />
+  <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+  <option name="TERNARY_OPERATION_WRAP" value="1" />
+  <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+  <option name="FOR_STATEMENT_WRAP" value="1" />
+  <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+  <option name="ASSIGNMENT_WRAP" value="1" />
+  <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+  <option name="WRAP_COMMENTS" value="true" />
+  <option name="IF_BRACE_FORCE" value="3" />
+  <option name="DOWHILE_BRACE_FORCE" value="3" />
+  <option name="WHILE_BRACE_FORCE" value="3" />
+  <option name="FOR_BRACE_FORCE" value="3" />
+  <XML>
+    <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+  </XML>
+  <ADDITIONAL_INDENT_OPTIONS fileType="java">
+    <option name="TAB_SIZE" value="8" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <ADDITIONAL_INDENT_OPTIONS fileType="js">
+    <option name="CONTINUATION_INDENT_SIZE" value="4" />
+  </ADDITIONAL_INDENT_OPTIONS>
+  <codeStyleSettings language="JAVA">
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+    <option name="ALIGN_MULTILINE_FOR" value="false" />
+    <option name="CALL_PARAMETERS_WRAP" value="1" />
+    <option name="PREFER_PARAMETERS_WRAP" value="true" />
+    <option name="METHOD_PARAMETERS_WRAP" value="1" />
+    <option name="RESOURCE_LIST_WRAP" value="1" />
+    <option name="EXTENDS_LIST_WRAP" value="1" />
+    <option name="THROWS_LIST_WRAP" value="1" />
+    <option name="THROWS_KEYWORD_WRAP" value="1" />
+    <option name="BINARY_OPERATION_WRAP" value="1" />
+    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="TERNARY_OPERATION_WRAP" value="1" />
+    <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+    <option name="FOR_STATEMENT_WRAP" value="1" />
+    <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+    <option name="ASSIGNMENT_WRAP" value="1" />
+    <option name="IF_BRACE_FORCE" value="1" />
+    <option name="DOWHILE_BRACE_FORCE" value="1" />
+    <option name="WHILE_BRACE_FORCE" value="1" />
+    <option name="FOR_BRACE_FORCE" value="1" />
+    <option name="WRAP_LONG_LINES" value="true" />
+  </codeStyleSettings>
+  <codeStyleSettings language="JavaScript">
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+    <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+    <option name="BLANK_LINES_AROUND_FIELD" value="1" />
+    <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+    <option name="ALIGN_MULTILINE_FOR" value="false" />
+    <option name="CALL_PARAMETERS_WRAP" value="1" />
+    <option name="METHOD_PARAMETERS_WRAP" value="1" />
+    <option name="EXTENDS_LIST_WRAP" value="1" />
+    <option name="THROWS_LIST_WRAP" value="1" />
+    <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+    <option name="THROWS_KEYWORD_WRAP" value="1" />
+    <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+    <option name="BINARY_OPERATION_WRAP" value="1" />
+    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="TERNARY_OPERATION_WRAP" value="1" />
+    <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+    <option name="FOR_STATEMENT_WRAP" value="1" />
+    <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+    <option name="ASSIGNMENT_WRAP" value="1" />
+    <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="WRAP_COMMENTS" value="true" />
+    <option name="IF_BRACE_FORCE" value="3" />
+    <option name="DOWHILE_BRACE_FORCE" value="3" />
+    <option name="WHILE_BRACE_FORCE" value="3" />
+    <option name="FOR_BRACE_FORCE" value="3" />
+    <option name="PARENT_SETTINGS_INSTALLED" value="true" />
+  </codeStyleSettings>
+  <codeStyleSettings language="XML">
+    <option name="FORCE_REARRANGE_MODE" value="1" />
+    <indentOptions>
+      <option name="CONTINUATION_INDENT_SIZE" value="4" />
+    </indentOptions>
+    <arrangement>
+      <rules>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>xmlns:android</NAME>
+                <XML_NAMESPACE>^$</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>xmlns:.*</NAME>
+                <XML_NAMESPACE>^$</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:id</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:name</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>name</NAME>
+                <XML_NAMESPACE>^$</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>style</NAME>
+                <XML_NAMESPACE>^$</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*</NAME>
+                <XML_NAMESPACE>^$</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:layout_width</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:layout_height</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:layout_.*</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:width</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*:height</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*</NAME>
+                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+        <section>
+          <rule>
+            <match>
+              <AND>
+                <NAME>.*</NAME>
+                <XML_NAMESPACE>.*</XML_NAMESPACE>
+              </AND>
+            </match>
+            <order>BY_NAME</order>
+          </rule>
+        </section>
+      </rules>
+    </arrangement>
+  </codeStyleSettings>
+</code_scheme>
diff --git a/tools/android/android_studio/OWNERS b/tools/android/android_studio/OWNERS
new file mode 100644
index 0000000..4ec4b30
--- /dev/null
+++ b/tools/android/android_studio/OWNERS
@@ -0,0 +1 @@
+per-file ChromiumStyle.xml=file://styleguide/java/OWNERS
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index f4b57dc6..1af7385e 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -166,7 +166,7 @@
     </module>
     <module name="ImportOrder">
       <property name="severity" value="error"/>
-      <message key="import.ordering" value="Wrong order for {0} import. Use :JavaImportOrganize (ECLIM) or Ctrl+Shift+O (Eclipse) to sort imports. An importorder file for configuring Eclipse can be found at //tools/android/eclipse/android.importorder."/>
+      <message key="import.ordering" value="Wrong order for {0} import. Use :JavaImportOrganize (ECLIM), Ctrl+Shift+O (Eclipse), or Ctrl+Alt+O (Android Studio) to sort imports. An importorder file for configuring Eclipse can be found at //tools/android/eclipse/android.importorder. A style configuration file for Android Studio can be found at //tools/android/android_studio/ChromiumStyle.xml."/>
       <property name="groups" value="android, com, dalvik, junit, org, com.google.android.apps.chrome, org.chromium, java, javax"/>
       <property name="ordered" value="true"/>
       <property name="option" value="top"/>
diff --git a/tools/chrome_proxy/common/chrome_proxy_measurements.py b/tools/chrome_proxy/common/chrome_proxy_measurements.py
index ad41be7..b629208 100644
--- a/tools/chrome_proxy/common/chrome_proxy_measurements.py
+++ b/tools/chrome_proxy/common/chrome_proxy_measurements.py
@@ -51,13 +51,13 @@
     '</body></html>'))
 
   # Ensure the page has finished loading before attempting the DRP check.
-  tab.WaitForJavaScriptCondition2('performance.timing.loadEventEnd', timeout=60)
+  tab.WaitForJavaScriptCondition('performance.timing.loadEventEnd', timeout=60)
 
   expected_via_header = metrics.CHROME_PROXY_VIA_HEADER
   if ChromeProxyValidation.extra_via_header:
     expected_via_header = ChromeProxyValidation.extra_via_header
 
-  tab.WaitForJavaScriptCondition2(
+  tab.WaitForJavaScriptCondition(
       'PollDRPCheck({{ url }}, {{ via_header }})',
       url=url, via_header=expected_via_header,
       timeout=60)
@@ -102,7 +102,7 @@
   def ValidateAndMeasurePage(self, page, tab, results):
     self._page = page
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     assert self._metrics
     self._metrics.Stop(page, tab)
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py b/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py
index 55d1a3d..7b07d76 100644
--- a/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py
+++ b/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py
@@ -47,7 +47,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     self._metrics.Stop(page, tab)
     self._metrics.AddResultsForDataSaving(tab, results)
@@ -124,7 +124,7 @@
   def ValidateAndMeasurePage(self, page, tab, results):
     # The test page sets window.xhrRequestCompleted to true when the XHR fetch
     # finishes.
-    tab.WaitForJavaScriptCondition2('window.xhrRequestCompleted', timeout=300)
+    tab.WaitForJavaScriptCondition('window.xhrRequestCompleted', timeout=300)
     super(ChromeProxyCorsBypass,
           self).ValidateAndMeasurePage(page, tab, results)
 
@@ -366,7 +366,7 @@
 
   def DidNavigateToPage(self, page, tab):
     if not self._is_lo_fi_enabled:
-      tab.ExecuteJavaScript2('window.location.reload()')
+      tab.ExecuteJavaScript('window.location.reload()')
       util.WaitFor(tab.HasReachedQuiescence, 3)
 
 class ChromeProxyCacheProxyDisabled(ChromeProxyValidation):
@@ -413,7 +413,7 @@
 
   def DidNavigateToPage(self, page, tab):
     if not self._is_chrome_proxy_enabled:
-      tab.ExecuteJavaScript2('window.location.reload()')
+      tab.ExecuteJavaScript('window.location.reload()')
       util.WaitFor(tab.HasReachedQuiescence, 3)
 
 class ChromeProxyLitePage(ChromeProxyValidation):
@@ -502,7 +502,7 @@
     # cause a proxy fallback, and have this test run starting from the HTTP
     # fallback proxy.
     tab.Navigate(_TEST_SERVER_DEFAULT_URL)
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
 
   def AddResults(self, tab, results):
@@ -604,7 +604,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     self._metrics.Stop(page, tab)
     page_to_metrics = {
@@ -803,7 +803,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     self._metrics.Stop(page, tab)
     self._metrics.AddResultsForQuicTransaction(tab, results)
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py
index 988140d..004b228 100644
--- a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py
+++ b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py
@@ -82,27 +82,27 @@
     # TODO(bustamante): This is a hack to workaround crbug.com/467174,
     #   once fixed just pull down window.performance.timing object and
     #   reference that everywhere.
-    load_event_start = tab.EvaluateJavaScript2(
+    load_event_start = tab.EvaluateJavaScript(
         'window.performance.timing.loadEventStart')
-    navigation_start = tab.EvaluateJavaScript2(
+    navigation_start = tab.EvaluateJavaScript(
         'window.performance.timing.navigationStart')
-    dom_content_loaded_event_start = tab.EvaluateJavaScript2(
+    dom_content_loaded_event_start = tab.EvaluateJavaScript(
         'window.performance.timing.domContentLoadedEventStart')
-    fetch_start = tab.EvaluateJavaScript2(
+    fetch_start = tab.EvaluateJavaScript(
         'window.performance.timing.fetchStart')
-    request_start = tab.EvaluateJavaScript2(
+    request_start = tab.EvaluateJavaScript(
         'window.performance.timing.requestStart')
-    domain_lookup_end = tab.EvaluateJavaScript2(
+    domain_lookup_end = tab.EvaluateJavaScript(
         'window.performance.timing.domainLookupEnd')
-    domain_lookup_start = tab.EvaluateJavaScript2(
+    domain_lookup_start = tab.EvaluateJavaScript(
         'window.performance.timing.domainLookupStart')
-    connect_end = tab.EvaluateJavaScript2(
+    connect_end = tab.EvaluateJavaScript(
         'window.performance.timing.connectEnd')
-    connect_start = tab.EvaluateJavaScript2(
+    connect_start = tab.EvaluateJavaScript(
         'window.performance.timing.connectStart')
-    response_end = tab.EvaluateJavaScript2(
+    response_end = tab.EvaluateJavaScript(
         'window.performance.timing.responseEnd')
-    response_start = tab.EvaluateJavaScript2(
+    response_start = tab.EvaluateJavaScript(
         'window.performance.timing.responseStart')
 
     # NavigationStart relative markers in milliseconds.
@@ -431,12 +431,12 @@
   def AddResultsForHTML5Test(self, tab, results):
     # Wait for the number of "points" of HTML5 compatibility to appear to verify
     # the HTML5 elements have loaded successfully.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'document.getElementsByClassName("pointsPanel")', timeout=15)
 
   def AddResultsForYouTube(self, tab, results):
     # Wait for the video to begin playing.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.playerState == YT.PlayerState.PLAYING', timeout=30)
 
   def AddResultsForBypass(self, tab, results, url_pattern=""):
@@ -671,7 +671,7 @@
     before_metrics = ChromeProxyMetric()
     before_metrics.Start(results.current_page, tab)
     tab.Navigate('http://chromeproxy-test.appspot.com/default')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=10)
     before_metrics.Stop(results.current_page, tab)
 
@@ -697,7 +697,7 @@
     after_metrics = ChromeProxyMetric()
     after_metrics.Start(results.current_page, tab)
     tab.Navigate('http://chromeproxy-test.appspot.com/default')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=10)
     after_metrics.Stop(results.current_page, tab)
 
@@ -748,7 +748,7 @@
     before_metrics = ChromeProxyMetric()
     before_metrics.Start(results.current_page, tab)
     tab.Navigate('http://chromeproxy-test.appspot.com/default')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=10)
     before_metrics.Stop(results.current_page, tab)
 
@@ -776,7 +776,7 @@
     after_metrics = ChromeProxyMetric()
     after_metrics.Start(results.current_page, tab)
     tab.Navigate('http://chromeproxy-test.appspot.com/default')
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=10)
     after_metrics.Stop(results.current_page, tab)
 
@@ -980,26 +980,26 @@
     super(ChromeProxyVideoMetric, self).__init__()
     with open(os.path.join(os.path.dirname(__file__), 'videowrapper.js')) as f:
       js = f.read()
-      tab.ExecuteJavaScript2(js)
+      tab.ExecuteJavaScript(js)
 
   def Start(self, page, tab):
-    tab.ExecuteJavaScript2('window.__chromeProxyCreateVideoWrappers()')
+    tab.ExecuteJavaScript('window.__chromeProxyCreateVideoWrappers()')
     self.videoMetrics = None
     super(ChromeProxyVideoMetric, self).Start(page, tab)
 
   def Stop(self, page, tab):
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.__chromeProxyVideoLoaded', timeout=30)
-    m = tab.EvaluateJavaScript2('window.__chromeProxyVideoMetrics')
+    m = tab.EvaluateJavaScript('window.__chromeProxyVideoMetrics')
 
     # Now wait for the video to stop playing.
     # Give it 2x the total duration to account for buffering.
     waitTime = 2 * m['video_duration']
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.__chromeProxyVideoEnded', timeout=waitTime)
 
     # Load the final metrics.
-    m = tab.EvaluateJavaScript2('window.__chromeProxyVideoMetrics')
+    m = tab.EvaluateJavaScript('window.__chromeProxyVideoMetrics')
     self.videoMetrics = m
     # Cast this to an integer as it is often approximate (for an unknown reason)
     m['video_duration'] = int(m['video_duration'])
@@ -1073,12 +1073,12 @@
     super(ChromeProxyInstrumentedVideoMetric, self).__init__()
 
   def Stop(self, page, tab):
-    waitTime = tab.EvaluateJavaScript2('test.waitTime')
-    tab.WaitForJavaScriptCondition2('test.metrics.complete', timeout=waitTime)
+    waitTime = tab.EvaluateJavaScript('test.waitTime')
+    tab.WaitForJavaScriptCondition('test.metrics.complete', timeout=waitTime)
     super(ChromeProxyInstrumentedVideoMetric, self).Stop(page, tab)
 
   def AddResults(self, tab, results):
-    metrics = tab.EvaluateJavaScript2('test.metrics')
+    metrics = tab.EvaluateJavaScript('test.metrics')
     for (k, v) in metrics.iteritems():
       results.AddValue(scalar.ScalarValue(results.current_page, k, '', v))
     try:
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/block_once.py b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/block_once.py
index 977b08f0..395ca19d 100644
--- a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/block_once.py
+++ b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/block_once.py
@@ -17,7 +17,7 @@
     super(BlockOncePage, self).RunNavigateSteps(action_runner)
     # Test block-once on a POST request.
     # Ensure that a subsequent request uses the data reduction proxy.
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
       (function() {
         window.post_request_completed = false;
         var request = new XMLHttpRequest();
@@ -35,7 +35,7 @@
         request.send();
       })();
     ''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         "window.post_request_completed == true", timeout=30)
 
 class BlockOnceStorySet(story.StorySet):
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/pass_through.py b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/pass_through.py
index cecba704..cc1d267 100644
--- a/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/pass_through.py
+++ b/tools/chrome_proxy/integration_tests/chrome_proxy_pagesets/pass_through.py
@@ -17,7 +17,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(PassThroughPage, self).RunNavigateSteps(action_runner)
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         (function() {
           var request = new XMLHttpRequest();
           request.open("GET", {{ url }});
diff --git a/tools/chrome_proxy/live_tests/chrome_proxy_measurements.py b/tools/chrome_proxy/live_tests/chrome_proxy_measurements.py
index a317404..126eb89 100644
--- a/tools/chrome_proxy/live_tests/chrome_proxy_measurements.py
+++ b/tools/chrome_proxy/live_tests/chrome_proxy_measurements.py
@@ -22,7 +22,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     self._metrics.Stop(page, tab)
     self._metrics.AddResultsForLatency(tab, results)
@@ -62,7 +62,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     # Wait for the load event.
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'performance.timing.loadEventStart', timeout=300)
     self._metrics.Stop(page, tab)
     self._metrics.AddResultsForDataSaving(tab, results)
diff --git a/tools/chrome_proxy/live_tests/chrome_proxy_metrics.py b/tools/chrome_proxy/live_tests/chrome_proxy_metrics.py
index 54d66d36..171e565 100644
--- a/tools/chrome_proxy/live_tests/chrome_proxy_metrics.py
+++ b/tools/chrome_proxy/live_tests/chrome_proxy_metrics.py
@@ -60,27 +60,27 @@
     # TODO(bustamante): This is a hack to workaround crbug.com/467174,
     #   once fixed just pull down window.performance.timing object and
     #   reference that everywhere.
-    load_event_start = tab.EvaluateJavaScript2(
+    load_event_start = tab.EvaluateJavaScript(
         'window.performance.timing.loadEventStart')
-    navigation_start = tab.EvaluateJavaScript2(
+    navigation_start = tab.EvaluateJavaScript(
         'window.performance.timing.navigationStart')
-    dom_content_loaded_event_start = tab.EvaluateJavaScript2(
+    dom_content_loaded_event_start = tab.EvaluateJavaScript(
         'window.performance.timing.domContentLoadedEventStart')
-    fetch_start = tab.EvaluateJavaScript2(
+    fetch_start = tab.EvaluateJavaScript(
         'window.performance.timing.fetchStart')
-    request_start = tab.EvaluateJavaScript2(
+    request_start = tab.EvaluateJavaScript(
         'window.performance.timing.requestStart')
-    domain_lookup_end = tab.EvaluateJavaScript2(
+    domain_lookup_end = tab.EvaluateJavaScript(
         'window.performance.timing.domainLookupEnd')
-    domain_lookup_start = tab.EvaluateJavaScript2(
+    domain_lookup_start = tab.EvaluateJavaScript(
         'window.performance.timing.domainLookupStart')
-    connect_end = tab.EvaluateJavaScript2(
+    connect_end = tab.EvaluateJavaScript(
         'window.performance.timing.connectEnd')
-    connect_start = tab.EvaluateJavaScript2(
+    connect_start = tab.EvaluateJavaScript(
         'window.performance.timing.connectStart')
-    response_end = tab.EvaluateJavaScript2(
+    response_end = tab.EvaluateJavaScript(
         'window.performance.timing.responseEnd')
-    response_start = tab.EvaluateJavaScript2(
+    response_start = tab.EvaluateJavaScript(
         'window.performance.timing.responseStart')
 
     # NavigationStart relative markers in milliseconds.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 008fe0f..17197fe9 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -94745,6 +94745,7 @@
   <int value="-2005270483" label="DXGI_ERROR_SDK_COMPONENT_MISSING"/>
   <int value="-2004287480" label="AUDCLNT_E_UNSUPPORTED_FORMAT"/>
   <int value="-2004287478" label="AUDCLNT_E_DEVICE_IN_USE"/>
+  <int value="-2004287465" label="AUDCLNT_E_CPUUSAGE_EXCEEDED"/>
   <int value="-1606219753" label="GOOPDATE_E_NON_BLOCKING_CALL_PENDING"/>
   <int value="-1606219747" label="GOOPDATE_E_APP_USING_EXTERNAL_UPDATER"/>
 </enum>
@@ -99344,6 +99345,7 @@
   <int value="553" label="min-block-size"/>
   <int value="554" label="max-inline-size"/>
   <int value="555" label="max-block-size"/>
+  <int value="556" label="line-break"/>
 </enum>
 
 <enum name="MappedEditingCommands" type="int">
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 743656c..7b43df32 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -97,9 +97,9 @@
       options.AppendExtraBrowserArgs('--expose-internals-for-testing')
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2('testRunner.isDone', timeout=600)
+    tab.WaitForJavaScriptCondition('testRunner.isDone', timeout=600)
 
-    log = tab.EvaluateJavaScript2('document.getElementById("log").innerHTML')
+    log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')
 
     for line in log.splitlines():
       if line.startswith("FATAL: "):
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py
index 22289d0..2eaaca3 100644
--- a/tools/perf/benchmarks/dromaeo.py
+++ b/tools/perf/benchmarks/dromaeo.py
@@ -33,14 +33,14 @@
     self._power_metric.Start(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.document.getElementById("pause") &&' +
         'window.document.getElementById("pause").value == "Run"',
         timeout=120)
 
     # Start spying on POST request that will report benchmark results, and
     # intercept result data.
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         (function() {
           var real_jquery_ajax_ = window.jQuery;
           window.results_ = "";
@@ -55,14 +55,14 @@
           };
         })();""")
     # Starts benchmark.
-    tab.ExecuteJavaScript2('window.document.getElementById("pause").click();')
+    tab.ExecuteJavaScript('window.document.getElementById("pause").click();')
 
-    tab.WaitForJavaScriptCondition2('!!window.results_', timeout=600)
+    tab.WaitForJavaScriptCondition('!!window.results_', timeout=600)
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
 
-    score = json.loads(tab.EvaluateJavaScript2('window.results_ || "[]"'))
+    score = json.loads(tab.EvaluateJavaScript('window.results_ || "[]"'))
 
     def Escape(k):
       chars = [' ', '.', '-', '/', '(', ')', '*']
diff --git a/tools/perf/benchmarks/indexeddb_perf.py b/tools/perf/benchmarks/indexeddb_perf.py
index 41847ca..4955798 100644
--- a/tools/perf/benchmarks/indexeddb_perf.py
+++ b/tools/perf/benchmarks/indexeddb_perf.py
@@ -65,7 +65,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     tab.WaitForDocumentReadyStateToBeComplete()
-    tab.WaitForJavaScriptCondition2('window.done', timeout=600)
+    tab.WaitForJavaScriptCondition('window.done', timeout=600)
 
     self._power_metric.Stop(page, tab)
     self._memory_metric.Stop(page, tab)
@@ -73,7 +73,7 @@
     self._memory_metric.AddResults(tab, results)
     self._power_metric.AddResults(tab, results)
 
-    result_dict = json.loads(tab.EvaluateJavaScript2(
+    result_dict = json.loads(tab.EvaluateJavaScript(
         'JSON.stringify(automation.getResults());'))
     total = 0.0
     for key in result_dict:
diff --git a/tools/perf/benchmarks/jetstream.py b/tools/perf/benchmarks/jetstream.py
index ec1be5f..1231481 100644
--- a/tools/perf/benchmarks/jetstream.py
+++ b/tools/perf/benchmarks/jetstream.py
@@ -48,8 +48,8 @@
   def ValidateAndMeasurePage(self, page, tab, results):
     del page  # unused
     tab.WaitForDocumentReadyStateToBeComplete()
-    tab.EvaluateJavaScript2('JetStream.start()')
-    result = tab.WaitForJavaScriptCondition2("""
+    tab.EvaluateJavaScript('JetStream.start()')
+    result = tab.WaitForJavaScriptCondition("""
         (function() {
           for (var i = 0; i < __results.length; i++) {
             if (!__results[i].indexOf('Raw results: ')) return __results[i];
diff --git a/tools/perf/benchmarks/kraken.py b/tools/perf/benchmarks/kraken.py
index d2834b5c6..3d90902 100644
--- a/tools/perf/benchmarks/kraken.py
+++ b/tools/perf/benchmarks/kraken.py
@@ -86,14 +86,14 @@
     self._power_metric.Start(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'document.title.indexOf("Results") != -1', timeout=700)
     tab.WaitForDocumentReadyStateToBeComplete()
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
 
-    result_dict = json.loads(tab.EvaluateJavaScript2("""
+    result_dict = json.loads(tab.EvaluateJavaScript("""
         var formElement = document.getElementsByTagName("input")[0];
         decodeURIComponent(formElement.value.split("?")[1]);
         """))
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py
index 02ae46d..4ba2e0a1e 100644
--- a/tools/perf/benchmarks/media.py
+++ b/tools/perf/benchmarks/media.py
@@ -20,7 +20,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     del page  # unused
-    media_metric = tab.EvaluateJavaScript2('window.__testMetrics')
+    media_metric = tab.EvaluateJavaScript('window.__testMetrics')
     trace = media_metric['id'] if 'id' in media_metric else None
     metrics = media_metric['metrics'] if 'metrics' in media_metric else []
     for m in metrics:
diff --git a/tools/perf/benchmarks/octane.py b/tools/perf/benchmarks/octane.py
index 98ec3da7..95b6894 100644
--- a/tools/perf/benchmarks/octane.py
+++ b/tools/perf/benchmarks/octane.py
@@ -99,14 +99,14 @@
     self._power_metric.Start(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2('window.completed', timeout=10)
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition('window.completed', timeout=10)
+    tab.WaitForJavaScriptCondition(
         '!document.getElementById("progress-bar-container")', timeout=1200)
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
 
-    results_log = tab.EvaluateJavaScript2('__results')
+    results_log = tab.EvaluateJavaScript('__results')
     all_scores = []
     for output in results_log:
       # Split the results into score and test name.
diff --git a/tools/perf/benchmarks/oortonline.py b/tools/perf/benchmarks/oortonline.py
index 13fc7f9e..2453b80 100644
--- a/tools/perf/benchmarks/oortonline.py
+++ b/tools/perf/benchmarks/oortonline.py
@@ -23,8 +23,8 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     del page  # unused
-    tab.WaitForJavaScriptCondition2('window.benchmarkFinished', timeout=1000)
-    scores = tab.EvaluateJavaScript2('window.benchmarkScore')
+    tab.WaitForJavaScriptCondition('window.benchmarkFinished', timeout=1000)
+    scores = tab.EvaluateJavaScript('window.benchmarkScore')
     for score in scores:
       valid = score['valid']
       if valid:
diff --git a/tools/perf/benchmarks/robohornet_pro.py b/tools/perf/benchmarks/robohornet_pro.py
index dfa54b2..25e5c8b 100644
--- a/tools/perf/benchmarks/robohornet_pro.py
+++ b/tools/perf/benchmarks/robohornet_pro.py
@@ -33,15 +33,15 @@
     self._power_metric.Start(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.ExecuteJavaScript2('ToggleRoboHornet()')
-    tab.WaitForJavaScriptCondition2(
+    tab.ExecuteJavaScript('ToggleRoboHornet()')
+    tab.WaitForJavaScriptCondition(
         'document.getElementById("results").innerHTML.indexOf("Total") != -1',
         timeout=600)
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
 
-    result = int(tab.EvaluateJavaScript2('stopTime - startTime'))
+    result = int(tab.EvaluateJavaScript('stopTime - startTime'))
     results.AddValue(
         scalar.ScalarValue(results.current_page, 'Total', 'ms', result))
 
diff --git a/tools/perf/benchmarks/service_worker.py b/tools/perf/benchmarks/service_worker.py
index f9f12502..390bab57 100644
--- a/tools/perf/benchmarks/service_worker.py
+++ b/tools/perf/benchmarks/service_worker.py
@@ -151,8 +151,8 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     del page  # unused
-    tab.WaitForJavaScriptCondition2('window.done', timeout=40)
-    json = tab.EvaluateJavaScript2('window.results || {}')
+    tab.WaitForJavaScriptCondition('window.done', timeout=40)
+    json = tab.EvaluateJavaScript('window.results || {}')
     for key, value in json.iteritems():
       results.AddValue(scalar.ScalarValue(
           results.current_page, key, value['units'], value['value']))
diff --git a/tools/perf/benchmarks/spaceport.py b/tools/perf/benchmarks/spaceport.py
index 5d13cb9..46f3b39 100644
--- a/tools/perf/benchmarks/spaceport.py
+++ b/tools/perf/benchmarks/spaceport.py
@@ -60,11 +60,11 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     del page  # unused
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         '!document.getElementById("start-performance-tests").disabled',
         timeout=60)
 
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         window.__results = {};
         window.console.log = function(str) {
             if (!str) return;
@@ -78,16 +78,16 @@
     num_results = 0
     num_tests_in_spaceport = 24
     while num_results < num_tests_in_spaceport:
-      tab.WaitForJavaScriptCondition2(
+      tab.WaitForJavaScriptCondition(
           'Object.keys(window.__results).length > {{ num_results }}',
           num_results=num_results,
           timeout=180)
-      num_results = tab.EvaluateJavaScript2(
+      num_results = tab.EvaluateJavaScript(
           'Object.keys(window.__results).length')
       logging.info('Completed test %d of %d',
                    num_results, num_tests_in_spaceport)
 
-    result_dict = json.loads(tab.EvaluateJavaScript2(
+    result_dict = json.loads(tab.EvaluateJavaScript(
         'JSON.stringify(window.__results)'))
     for key in result_dict:
       chart, trace = key.split('.', 1)
diff --git a/tools/perf/benchmarks/speedometer.py b/tools/perf/benchmarks/speedometer.py
index 8af1db1..b4b12bf 100644
--- a/tools/perf/benchmarks/speedometer.py
+++ b/tools/perf/benchmarks/speedometer.py
@@ -56,7 +56,7 @@
     if tab.browser.platform.GetOSName() == 'android':
       iterationCount = 3
 
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         // Store all the results in the benchmarkClient
         benchmarkClient._measuredValues = []
         benchmarkClient.didRunSuites = function(measuredValues) {
@@ -67,19 +67,19 @@
         startTest();
         """,
         count=iterationCount)
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'benchmarkClient._finishedTestCount == benchmarkClient.testsCount',
         timeout=600)
     results.AddValue(list_of_scalar_values.ListOfScalarValues(
         page, 'Total', 'ms',
-        tab.EvaluateJavaScript2('benchmarkClient._timeValues'),
+        tab.EvaluateJavaScript('benchmarkClient._timeValues'),
         important=True))
 
     # Extract the timings for each suite
     for suite_name in self.enabled_suites:
       results.AddValue(list_of_scalar_values.ListOfScalarValues(
           page, suite_name, 'ms',
-          tab.EvaluateJavaScript2("""
+          tab.EvaluateJavaScript("""
               var suite_times = [];
               for(var i = 0; i < benchmarkClient.iterationCount; i++) {
                 suite_times.push(
diff --git a/tools/perf/benchmarks/sunspider.py b/tools/perf/benchmarks/sunspider.py
index a504426d..888e194 100644
--- a/tools/perf/benchmarks/sunspider.py
+++ b/tools/perf/benchmarks/sunspider.py
@@ -91,14 +91,14 @@
     self._power_metric.Start(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.location.pathname.indexOf("results.html") >= 0'
         '&& typeof(output) != "undefined"', timeout=300)
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
 
-    js_results = json.loads(tab.EvaluateJavaScript2('JSON.stringify(output);'))
+    js_results = json.loads(tab.EvaluateJavaScript('JSON.stringify(output);'))
 
     # Below, r is a map of benchmark names to lists of result numbers,
     # and totals is a list of totals of result numbers.
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py
index 3ad67e4..bfff2cb 100644
--- a/tools/perf/benchmarks/system_health_smoke_test.py
+++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -48,6 +48,9 @@
 
   # crbug.com/
   'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:news:nytimes',  # pylint: disable=line-too-long
+
+  # crbug.com/696824
+  'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.load:news:qq',  # pylint: disable=line-too-long
 })
 
 
diff --git a/tools/perf/measurements/blink_style.py b/tools/perf/measurements/blink_style.py
index 4e31a9ed..dae97c7 100644
--- a/tools/perf/measurements/blink_style.py
+++ b/tools/perf/measurements/blink_style.py
@@ -30,7 +30,7 @@
 
   def ValidateAndMeasurePage(self, page, tab, results):
     with tab.action_runner.CreateInteraction('wait-for-quiescence'):
-      tab.ExecuteJavaScript2('console.time("");')
+      tab.ExecuteJavaScript('console.time("");')
       try:
         util.WaitFor(tab.HasReachedQuiescence, 15)
       except py_utils.TimeoutException:
@@ -39,7 +39,7 @@
         # state on every run.
         pass
 
-    tab.ExecuteJavaScript2('''
+    tab.ExecuteJavaScript('''
         for (var i = 0; i < 11; i++) {
           var cold = i % 2 == 0;
           var name = "update_style";
diff --git a/tools/perf/measurements/image_decoding.py b/tools/perf/measurements/image_decoding.py
index bde481cd..cf6e5a68 100644
--- a/tools/perf/measurements/image_decoding.py
+++ b/tools/perf/measurements/image_decoding.py
@@ -24,7 +24,7 @@
     self._power_metric = power.PowerMetric(platform)
 
   def WillNavigateToPage(self, page, tab):
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         if (window.chrome &&
             chrome.gpuBenchmarking &&
             chrome.gpuBenchmarking.clearImageCache) {
@@ -49,7 +49,7 @@
 
   def StopBrowserAfterPage(self, browser, page):
     del page  # unused
-    return not browser.tabs[0].ExecuteJavaScript2("""
+    return not browser.tabs[0].ExecuteJavaScript("""
         window.chrome &&
             chrome.gpuBenchmarking &&
             chrome.gpuBenchmarking.clearImageCache;
@@ -62,7 +62,7 @@
     self._power_metric.AddResults(tab, results)
 
     def _IsDone():
-      return tab.EvaluateJavaScript2('isDone')
+      return tab.EvaluateJavaScript('isDone')
 
     decode_image_events = timeline_model.GetAllEventsOfName(
         'ImageFrameGenerator::decode')
@@ -77,7 +77,7 @@
             'image_decoding_measurement_limit_results_to_min_iterations') and
         page.image_decoding_measurement_limit_results_to_min_iterations):
       assert _IsDone()
-      min_iterations = tab.EvaluateJavaScript2('minIterations')
+      min_iterations = tab.EvaluateJavaScript('minIterations')
       decode_image_events = decode_image_events[-min_iterations:]
 
     durations = [d.duration for d in decode_image_events]
@@ -91,7 +91,7 @@
                     'located at chrome/test/data/image_decoding.'))
     results.AddValue(scalar.ScalarValue(
         results.current_page, 'ImageLoading_avg', 'ms',
-        tab.EvaluateJavaScript2('averageLoadingTimeMs()')))
+        tab.EvaluateJavaScript('averageLoadingTimeMs()')))
 
   def DidRunPage(self, platform):
     self._power_metric.Close()
diff --git a/tools/perf/measurements/multipage_skpicture_printer.py b/tools/perf/measurements/multipage_skpicture_printer.py
index c92d836..aa03c08 100644
--- a/tools/perf/measurements/multipage_skpicture_printer.py
+++ b/tools/perf/measurements/multipage_skpicture_printer.py
@@ -26,6 +26,6 @@
         os.path.join(self._mskp_outdir, page.file_safe_name + '.mskp'))
     # Replace win32 path separator char '\' with '\\'.
     outpath = outpath.replace('\\', '\\\\')
-    tab.EvaluateJavaScript2(
+    tab.EvaluateJavaScript(
         'chrome.gpuBenchmarking.printPagesToSkPictures({{ outpath }});',
         outpath=outpath)
diff --git a/tools/perf/measurements/oilpan_gc_times.py b/tools/perf/measurements/oilpan_gc_times.py
index 7ab0de24..832e357 100644
--- a/tools/perf/measurements/oilpan_gc_times.py
+++ b/tools/perf/measurements/oilpan_gc_times.py
@@ -188,7 +188,7 @@
     super(OilpanGCTimesForBlinkPerf, self).WillNavigateToPage(page, tab)
 
   def ValidateAndMeasurePage(self, page, tab, results):
-    tab.WaitForJavaScriptCondition2('testRunner.isDone', timeout=600)
+    tab.WaitForJavaScriptCondition('testRunner.isDone', timeout=600)
     super(OilpanGCTimesForBlinkPerf, self).ValidateAndMeasurePage(
         page, tab, results)
 
diff --git a/tools/perf/measurements/rasterize_and_record_micro.py b/tools/perf/measurements/rasterize_and_record_micro.py
index 3d3aaa87..1eb6426 100644
--- a/tools/perf/measurements/rasterize_and_record_micro.py
+++ b/tools/perf/measurements/rasterize_and_record_micro.py
@@ -35,7 +35,7 @@
     time.sleep(self._start_wait_time)
 
     # Enqueue benchmark
-    tab.ExecuteJavaScript2("""
+    tab.ExecuteJavaScript("""
         window.benchmark_results = {};
         window.benchmark_results.done = false;
         window.benchmark_results.id =
@@ -53,16 +53,16 @@
         rasterize_repeat_count=self._rasterize_repeat)
 
     # Evaluating this expression usually takes between 60 and 90 seconds.
-    benchmark_id = tab.EvaluateJavaScript2(
+    benchmark_id = tab.EvaluateJavaScript(
         'window.benchmark_results.id', timeout=self._timeout)
     if not benchmark_id:
       raise legacy_page_test.MeasurementFailure(
           'Failed to schedule rasterize_and_record_micro')
 
-    tab.WaitForJavaScriptCondition2(
+    tab.WaitForJavaScriptCondition(
         'window.benchmark_results.done', timeout=self._timeout)
 
-    data = tab.EvaluateJavaScript2('window.benchmark_results.results')
+    data = tab.EvaluateJavaScript('window.benchmark_results.results')
 
     pixels_recorded = data['pixels_recorded']
     record_time = data['record_time_ms']
diff --git a/tools/perf/measurements/skpicture_printer.py b/tools/perf/measurements/skpicture_printer.py
index f85562a..87355b3 100644
--- a/tools/perf/measurements/skpicture_printer.py
+++ b/tools/perf/measurements/skpicture_printer.py
@@ -28,7 +28,7 @@
         os.path.join(self._skp_outdir, page.file_safe_name))
     # Replace win32 path separator char '\' with '\\'.
     outpath = outpath.replace('\\', '\\\\')
-    tab.EvaluateJavaScript2(
+    tab.EvaluateJavaScript(
         'chrome.gpuBenchmarking.printToSkPicture({{ outpath }});',
         outpath=outpath)
     pictures = glob.glob(os.path.join(outpath, '*.skp'))
diff --git a/tools/perf/metrics/loading.py b/tools/perf/metrics/loading.py
index ac9b51f..fa1ee3b 100644
--- a/tools/perf/metrics/loading.py
+++ b/tools/perf/metrics/loading.py
@@ -18,7 +18,7 @@
     raise NotImplementedError()
 
   def AddResults(self, tab, results):
-    load_timings = tab.EvaluateJavaScript2('window.performance.timing')
+    load_timings = tab.EvaluateJavaScript('window.performance.timing')
 
     # NavigationStart relative markers in milliseconds.
     load_start = (
diff --git a/tools/perf/metrics/media.py b/tools/perf/metrics/media.py
index 4e0519f..78411351 100644
--- a/tools/perf/metrics/media.py
+++ b/tools/perf/metrics/media.py
@@ -23,7 +23,7 @@
     super(MediaMetric, self).__init__()
     with open(os.path.join(os.path.dirname(__file__), 'media.js')) as f:
       js = f.read()
-      tab.ExecuteJavaScript2(js)
+      tab.ExecuteJavaScript(js)
     self._results = None
     self._skip_basic_metrics = False
 
@@ -31,10 +31,10 @@
     """Create the media metrics for all media elements in the document."""
     if hasattr(page, 'skip_basic_metrics'):
       self._skip_basic_metrics = page.skip_basic_metrics
-    tab.ExecuteJavaScript2('window.__createMediaMetricsForDocument()')
+    tab.ExecuteJavaScript('window.__createMediaMetricsForDocument()')
 
   def Stop(self, page, tab):
-    self._results = tab.EvaluateJavaScript2('window.__getAllMetrics()')
+    self._results = tab.EvaluateJavaScript('window.__getAllMetrics()')
 
   # Optional |exclude_metrics| args are not in base class Metric.
   # pylint: disable=arguments-differ
diff --git a/tools/perf/metrics/startup_metric.py b/tools/perf/metrics/startup_metric.py
index ff07b8b..463cb30 100644
--- a/tools/perf/metrics/startup_metric.py
+++ b/tools/perf/metrics/startup_metric.py
@@ -57,14 +57,14 @@
 
     def RecordOneTab(t):
       def EvaluateInt(exp):
-        val = t.EvaluateJavaScript2(exp)
+        val = t.EvaluateJavaScript(exp)
         if not val:
           logging.warn('%s undefined', exp)
           return 0
         return int(val)
 
       try:
-        t.WaitForJavaScriptCondition2(
+        t.WaitForJavaScriptCondition(
             'window.performance.timing["loadEventEnd"] > 0',
             timeout=self.DEFAULT_LOADING_TIMEOUT)
 
@@ -105,7 +105,7 @@
 
   def AddResults(self, tab, results):
     for display_name, histogram_name in self.HISTOGRAMS_TO_RECORD.iteritems():
-      result = tab.EvaluateJavaScript2(
+      result = tab.EvaluateJavaScript(
           'statsCollectionController.getBrowserHistogram({{ name }})',
           name=histogram_name)
       result = json.loads(result)
diff --git a/tools/perf/metrics/webrtc_stats.py b/tools/perf/metrics/webrtc_stats.py
index 6b64f5a4..8c35703 100644
--- a/tools/perf/metrics/webrtc_stats.py
+++ b/tools/perf/metrics/webrtc_stats.py
@@ -140,7 +140,7 @@
 
   def Stop(self, page, tab):
     """Digs out stats from data populated by the javascript in webrtc_cases."""
-    self._all_reports = tab.EvaluateJavaScript2(
+    self._all_reports = tab.EvaluateJavaScript(
         'JSON.stringify(window.peerConnectionReports)')
 
   def AddResults(self, tab, results):
diff --git a/tools/perf/metrics/webrtc_stats_unittest.py b/tools/perf/metrics/webrtc_stats_unittest.py
index 79943c8..b6f3488 100644
--- a/tools/perf/metrics/webrtc_stats_unittest.py
+++ b/tools/perf/metrics/webrtc_stats_unittest.py
@@ -113,7 +113,7 @@
 
     stats_metric.Start(page, tab)
 
-    tab.ExpectCall('EvaluateJavaScript2',
+    tab.ExpectCall('EvaluateJavaScript',
                    simple_mock.DONT_CARE).WillReturn(json_to_return)
     stats_metric.Stop(page, tab)
 
diff --git a/tools/perf/page_sets/blank_page.py b/tools/perf/page_sets/blank_page.py
index 6719096..1858cfa 100644
--- a/tools/perf/page_sets/blank_page.py
+++ b/tools/perf/page_sets/blank_page.py
@@ -13,7 +13,7 @@
   def RunPageInteractions(self, action_runner):
     # Request a RAF and wait for it to be processed to ensure that the metric
     # Startup.FirstWebContents.NonEmptyPaint2 is recorded.
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         """
         this.hasRunRAF = 0;
         requestAnimationFrame(function() {
@@ -21,7 +21,7 @@
         });
         """
     )
-    action_runner.WaitForJavaScriptCondition2("this.hasRunRAF == 1")
+    action_runner.WaitForJavaScriptCondition("this.hasRunRAF == 1")
 
 class BlankPageSet(story.StorySet):
   """A single blank page."""
@@ -39,7 +39,7 @@
         shared_page_state_class=BrowserStartupSharedState)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         """
         this.hasRunRAF = 0;
         requestAnimationFrame(function() {
@@ -47,7 +47,7 @@
         });
         """
     )
-    action_runner.WaitForJavaScriptCondition2("this.hasRunRAF == 1")
+    action_runner.WaitForJavaScriptCondition("this.hasRunRAF == 1")
 
 
 class BlankPageSetTBM(story.StorySet):
diff --git a/tools/perf/page_sets/blink_memory_mobile.py b/tools/perf/page_sets/blink_memory_mobile.py
index 1e0ad6c..e6c53c94 100644
--- a/tools/perf/page_sets/blink_memory_mobile.py
+++ b/tools/perf/page_sets/blink_memory_mobile.py
@@ -47,11 +47,11 @@
 
   def RunPageInteractions(self, action_runner):
     action_runner.WaitForElement(selector=TheVergePage.COMMENT_LINK_SELECTOR)
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         'window.location.hash = "comments"')
     action_runner.TapElement(
         selector=TheVergePage.COMMENT_LINK_SELECTOR)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.Chorus.Comments.collection.length > 0')
     super(TheVergePage, self).RunPageInteractions(action_runner)
 
@@ -65,7 +65,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(FacebookPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("u_0_c") !== null &&'
         'document.body.scrollHeight > window.innerHeight')
 
@@ -82,7 +82,7 @@
                                     self.credentials_path)
     super(GmailPage, self).RunNavigateSteps(action_runner)
     action_runner.WaitForElement(selector='#apploadingdiv')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.querySelector("#apploadingdiv").style.opacity == "0"')
 
 
diff --git a/tools/perf/page_sets/blob_workshop.py b/tools/perf/page_sets/blob_workshop.py
index a79dacd..049983f 100644
--- a/tools/perf/page_sets/blob_workshop.py
+++ b/tools/perf/page_sets/blob_workshop.py
@@ -20,17 +20,17 @@
     self._blob_sizes = blob_sizes
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('disableUI = true;')
+    action_runner.ExecuteJavaScript('disableUI = true;')
 
     for size_bytes in self._blob_sizes:
       with action_runner.CreateInteraction('Action_CreateAndReadBlob',
                                            repeatable=True):
-        action_runner.ExecuteJavaScript2(
+        action_runner.ExecuteJavaScript(
             'createAndRead({{ size }});', size=size_bytes)
-        action_runner.WaitForJavaScriptCondition2(
+        action_runner.WaitForJavaScriptCondition(
             'doneReading === true || errors', timeout=60)
 
-    errors = action_runner.EvaluateJavaScript2('errors')
+    errors = action_runner.EvaluateJavaScript('errors')
     if errors:
       raise legacy_page_test.Failure('Errors on page: ' + ', '.join(errors))
 
@@ -44,27 +44,27 @@
     self._blob_sizes = blob_sizes
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('disableUI = true;')
+    action_runner.ExecuteJavaScript('disableUI = true;')
 
     # Add blobs
     for size_bytes in self._blob_sizes:
       with action_runner.CreateInteraction('Action_CreateBlob',
                                            repeatable=True):
-        action_runner.ExecuteJavaScript2(
+        action_runner.ExecuteJavaScript(
             'createBlob({{ size }});', size=size_bytes)
 
     # Read blobs
     for _ in range(0, NUM_BLOB_MASS_CREATE_READS):
       with action_runner.CreateInteraction('Action_ReadBlobs',
                                            repeatable=True):
-        action_runner.ExecuteJavaScript2('readBlobsSerially();')
-        action_runner.WaitForJavaScriptCondition2(
+        action_runner.ExecuteJavaScript('readBlobsSerially();')
+        action_runner.WaitForJavaScriptCondition(
             'doneReading === true || errors', timeout=60)
     # Clean up blobs. Make sure this flag is turned on:
     # --enable-experimental-web-platform-features
-    action_runner.ExecuteJavaScript2('garbageCollect();')
+    action_runner.ExecuteJavaScript('garbageCollect();')
 
-    errors = action_runner.EvaluateJavaScript2('errors')
+    errors = action_runner.EvaluateJavaScript('errors')
     if errors:
       raise legacy_page_test.Failure('Errors on page: ' + ', '.join(errors))
 
diff --git a/tools/perf/page_sets/dummy_story_set.py b/tools/perf/page_sets/dummy_story_set.py
index 15ce788..c3fe05c 100644
--- a/tools/perf/page_sets/dummy_story_set.py
+++ b/tools/perf/page_sets/dummy_story_set.py
@@ -13,7 +13,7 @@
       page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    assert action_runner.EvaluateJavaScript2('1 + window.__dummy_value') == 2
+    assert action_runner.EvaluateJavaScript('1 + window.__dummy_value') == 2
 
 
 class BrokenDummyPage(page_module.Page):
@@ -26,7 +26,7 @@
 
   def RunPageInteractions(self, action_runner):
     # The call below should raise an AssertionError
-    assert action_runner.EvaluateJavaScript2('1 + window.__dummy_value') == 3
+    assert action_runner.EvaluateJavaScript('1 + window.__dummy_value') == 3
 
 
 class DummyStorySet(story.StorySet):
diff --git a/tools/perf/page_sets/google_pages.py b/tools/perf/page_sets/google_pages.py
index 21aaddca..abdb76a 100644
--- a/tools/perf/page_sets/google_pages.py
+++ b/tools/perf/page_sets/google_pages.py
@@ -38,7 +38,7 @@
     google_login.LoginGoogleAccount(action_runner, 'google',
                                     self.credentials_path)
     super(GmailPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
@@ -56,7 +56,7 @@
                                     self.credentials_path)
     super(GoogleDocPage, self).RunNavigateSteps(action_runner)
     action_runner.Wait(2)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("kix-appview-editor").length')
 
 
@@ -78,5 +78,5 @@
 
   def RunPageInteractions(self, action_runner):
     action_runner.WaitForElement(text='Welcome to AdWords!')
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         'console.timeEnd({{ label }});', label=INTERACTION_NAME)
diff --git a/tools/perf/page_sets/image_decoding_measurement.py b/tools/perf/page_sets/image_decoding_measurement.py
index fed80cc..e101fff9 100644
--- a/tools/perf/page_sets/image_decoding_measurement.py
+++ b/tools/perf/page_sets/image_decoding_measurement.py
@@ -14,8 +14,8 @@
 
   def RunNavigateSteps(self, action_runner):
     super(ImageDecodingMeasurementPage, self).RunNavigateSteps(action_runner)
-    action_runner.ExecuteJavaScript2('runBenchmark();')
-    action_runner.WaitForJavaScriptCondition2('isDone')
+    action_runner.ExecuteJavaScript('runBenchmark();')
+    action_runner.WaitForJavaScriptCondition('isDone')
 
 
 class ImageDecodingMeasurementPageSet(story.StorySet):
diff --git a/tools/perf/page_sets/indexeddb_endure_page.py b/tools/perf/page_sets/indexeddb_endure_page.py
index fdee22c..80feb6e 100644
--- a/tools/perf/page_sets/indexeddb_endure_page.py
+++ b/tools/perf/page_sets/indexeddb_endure_page.py
@@ -15,11 +15,11 @@
     self._subtest = subtest
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         'window.testFilter = {{ subtest }};', subtest=self._subtest)
     with action_runner.CreateInteraction('Action_Test'):
-      action_runner.ExecuteJavaScript2('window.test();')
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.ExecuteJavaScript('window.test();')
+      action_runner.WaitForJavaScriptCondition(
           'window.done', timeout=600)
 
 class IndexedDBEndurePageSet(story.StorySet):
diff --git a/tools/perf/page_sets/infinite_scroll_cases.py b/tools/perf/page_sets/infinite_scroll_cases.py
index 6c3de0fc..7930a6e 100644
--- a/tools/perf/page_sets/infinite_scroll_cases.py
+++ b/tools/perf/page_sets/infinite_scroll_cases.py
@@ -47,7 +47,7 @@
 
   def _WaitAction(self, action_runner):
     with action_runner.CreateInteraction('Load'):
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.WaitForJavaScriptCondition(
         'document.body != null && '
         'document.body.scrollHeight > window.innerHeight && '
         '!document.body.addEventListener("touchstart", function() {})')
diff --git a/tools/perf/page_sets/key_desktop_move_cases.py b/tools/perf/page_sets/key_desktop_move_cases.py
index d2e1ad82..a226a62 100644
--- a/tools/perf/page_sets/key_desktop_move_cases.py
+++ b/tools/perf/page_sets/key_desktop_move_cases.py
@@ -36,19 +36,19 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GmailMouseScrollPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
     # This check is needed for gmonkey to load completely.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.readyState == "complete"')
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         gmonkey.load('2.0', function(api) {
           window.__scrollableElementForTelemetry = api.getScrollableElement();
         });''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__scrollableElementForTelemetry != null')
     scrollbar_x, start_y, end_y = self._CalculateScrollBarRatios(action_runner)
 
@@ -59,13 +59,13 @@
           element_function='window.__scrollableElementForTelemetry')
 
   def _CalculateScrollBarRatios(self, action_runner):
-    viewport_height = float(action_runner.EvaluateJavaScript2(
+    viewport_height = float(action_runner.EvaluateJavaScript(
         'window.__scrollableElementForTelemetry.clientHeight'))
-    content_height = float(action_runner.EvaluateJavaScript2(
+    content_height = float(action_runner.EvaluateJavaScript(
         'window.__scrollableElementForTelemetry.scrollHeight'))
-    viewport_width = float(action_runner.EvaluateJavaScript2(
+    viewport_width = float(action_runner.EvaluateJavaScript(
         'window.__scrollableElementForTelemetry.offsetWidth'))
-    scrollbar_width = float(action_runner.EvaluateJavaScript2('''
+    scrollbar_width = float(action_runner.EvaluateJavaScript('''
         window.__scrollableElementForTelemetry.offsetWidth -
         window.__scrollableElementForTelemetry.scrollWidth'''))
 
diff --git a/tools/perf/page_sets/key_desktop_sites.py b/tools/perf/page_sets/key_desktop_sites.py
index ff930d5d..8fca86e3 100644
--- a/tools/perf/page_sets/key_desktop_sites.py
+++ b/tools/perf/page_sets/key_desktop_sites.py
@@ -45,7 +45,7 @@
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined && '
         'document.getElementById("gb") !== null')
 
@@ -80,7 +80,7 @@
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("doclistview-list").length')
 
 
@@ -101,7 +101,7 @@
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("kix-appview-editor").length')
 
 
diff --git a/tools/perf/page_sets/key_hit_test_cases.py b/tools/perf/page_sets/key_hit_test_cases.py
index 955e219b9..d9dd86c 100644
--- a/tools/perf/page_sets/key_hit_test_cases.py
+++ b/tools/perf/page_sets/key_hit_test_cases.py
@@ -18,7 +18,7 @@
 
   def PerformPageInteractions(self, action_runner):
     # pay cost of selecting tap target only once
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         window.__tapTarget = document.querySelector(
             'body /deep/ #outerPanels'
         ).querySelector(
@@ -26,7 +26,7 @@
         ).shadowRoot.querySelector(
             'paper-calculator-key[label="5"]'
         )''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__tapTarget != null')
 
     for _ in xrange(100):
diff --git a/tools/perf/page_sets/key_mobile_sites_pages.py b/tools/perf/page_sets/key_mobile_sites_pages.py
index f8db9140..cf79415 100644
--- a/tools/perf/page_sets/key_mobile_sites_pages.py
+++ b/tools/perf/page_sets/key_mobile_sites_pages.py
@@ -28,7 +28,7 @@
   def RunNavigateSteps(self, action_runner):
     super(CapitolVolkswagenPage, self).RunNavigateSteps(action_runner)
     action_runner.WaitForElement(text='Next 35')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.body.scrollHeight > 2560')
 
 
@@ -45,7 +45,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(TheVergeArticlePage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.Chorus !== undefined &&'
         'window.Chorus.Comments !== undefined &&'
         'window.Chorus.Comments.Json !== undefined &&'
@@ -80,7 +80,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(FacebookPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("u_0_c") !== null &&'
         'document.body.scrollHeight > window.innerHeight')
 
@@ -96,7 +96,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(YoutubeMobilePage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("paginatortarget") !== null')
 
 
@@ -112,7 +112,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(LinkedInPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("profile-view-scroller") !== null')
 
 
@@ -146,9 +146,9 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GmailPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("og_user_warning") !== null')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("og_user_warning") === null')
 
 
@@ -165,7 +165,7 @@
   def RunNavigateSteps(self, action_runner):
     super(GroupClonedPage, self).RunNavigateSteps(action_runner)
     action_runner.Wait(5)
-    action_runner.WaitForJavaScriptCondition2('''
+    action_runner.WaitForJavaScriptCondition('''
         document.getElementById("element-19") !== null &&
         document.getElementById("element-19").contentDocument
           .getElementById("element-22") !== null &&
@@ -185,7 +185,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GroupClonedListImagesPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("element-5") !== null')
 
 
@@ -200,7 +200,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GoogleNewsMobilePage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'typeof NEWS_telemetryReady !== "undefined" && '
         'NEWS_telemetryReady == true')
 
@@ -218,7 +218,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GoogleNewsMobile2Page, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById(":h") != null')
     action_runner.Wait(1)
 
diff --git a/tools/perf/page_sets/key_mobile_sites_smooth.py b/tools/perf/page_sets/key_mobile_sites_smooth.py
index 5600f86..2ba7134 100644
--- a/tools/perf/page_sets/key_mobile_sites_smooth.py
+++ b/tools/perf/page_sets/key_mobile_sites_smooth.py
@@ -34,7 +34,7 @@
 
   def RunPageInteractions(self, action_runner):
     if self.action_on_load_complete:
-        action_runner.WaitForJavaScriptCondition2(
+        action_runner.WaitForJavaScriptCondition(
             'document.readyState == "complete"', timeout=30)
     _IssueMarkerAndScroll(action_runner)
 
diff --git a/tools/perf/page_sets/key_silk_cases.py b/tools/perf/page_sets/key_silk_cases.py
index 9e7789f..ee9395f 100644
--- a/tools/perf/page_sets/key_silk_cases.py
+++ b/tools/perf/page_sets/key_silk_cases.py
@@ -364,7 +364,7 @@
       action_runner.TapElement('#menu-button')
 
     with action_runner.CreateInteraction('Wait'):
-      action_runner.WaitForJavaScriptCondition2('''
+      action_runner.WaitForJavaScriptCondition('''
           document.getElementById("nav-drawer").active &&
           document.getElementById("nav-drawer").children[0]
               .getBoundingClientRect().left == 0''')
@@ -383,7 +383,7 @@
           left_start_ratio=0.8, top_start_ratio=0.2,
           direction='left', distance=200,
           element_function='document.getElementById("nav-drawer").children[0]')
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.WaitForJavaScriptCondition(
           '!document.getElementById("nav-drawer").active')
 
 
@@ -418,7 +418,7 @@
 
   def ScrollKnowledgeCardToTop(self, action_runner, card_id):
     # scroll until the knowledge card is at the top
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         "document.getElementById({{ card_id }}).scrollIntoView()",
         card_id=card_id)
 
@@ -465,7 +465,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(Page22, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("fHa").length > 0')
     action_runner.Wait(2)
 
@@ -511,7 +511,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(Page24, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById(":h") != null')
     action_runner.Wait(1)
 
@@ -532,7 +532,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(Page25, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById(":h") != null')
     action_runner.Wait(1)
 
@@ -556,14 +556,14 @@
 
   def RunNavigateSteps(self, action_runner):
     super(Page26, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("tweet").length > 0')
     action_runner.Wait(1)
 
   def PerformPageInteractions(self, action_runner):
     # Add a touch-action: none because this page prevent defaults all
     # touch moves.
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         var style = document.createElement("style");
         document.head.appendChild(style);
         style.sheet.insertRule("body { touch-action: none }", 0);
@@ -583,7 +583,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(SVGIconRaster, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'loaded = true')
     action_runner.Wait(1)
 
@@ -607,12 +607,12 @@
 
   def RunNavigateSteps(self, action_runner):
     super(UpdateHistoryState, self).RunNavigateSteps(action_runner)
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         window.requestAnimationFrame(function() {
             window.__history_state_loaded = true;
           });
         ''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__history_state_loaded == true;')
 
   def PerformPageInteractions(self, action_runner):
@@ -648,20 +648,20 @@
     first_name = profile + 'paper-input#first /deep/ input'
     action_runner.WaitForElement(selector=first_name)
     # Input First Name:
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         var fn = document.querySelector({{ first_name }});
         fn.value = 'Chrome';
         fn.fire('input');''',
         first_name=first_name)
     # Input Last Initial:
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         var li = document.querySelector({{ selector }});
         li.value = 'E';
         li.fire('input');''',
         selector='%s paper-input#last /deep/ input' % profile)
     with action_runner.CreateInteraction('animation_interaction'):
       # Click the check-mark to login:
-      action_runner.ExecuteJavaScript2('''
+      action_runner.ExecuteJavaScript('''
           window.topeka_page_transitions = 0;
           [].forEach.call(document.querySelectorAll(
               'html /deep/ core-animated-pages'), function(p){
@@ -673,32 +673,32 @@
           document.querySelector({{ selector }}).fire('tap')''',
           selector='%s paper-fab' % profile)
       # Wait for category list to animate in:
-      action_runner.WaitForJavaScriptCondition2('''
+      action_runner.WaitForJavaScriptCondition('''
           window.topeka_page_transitions === 1''')
       # Click a category to start a quiz:
-      action_runner.ExecuteJavaScript2('''
+      action_runner.ExecuteJavaScript('''
           document.querySelector('\
               html /deep/ core-selector.category-list').fire(
               'tap',1,document.querySelector('html /deep/ \
                       div.category-item.red-theme'));''')
       # Wait for the category splash to animate in:
-      action_runner.WaitForJavaScriptCondition2('''
+      action_runner.WaitForJavaScriptCondition('''
           window.topeka_page_transitions === 2''')
       # Click to start the quiz:
-      action_runner.ExecuteJavaScript2('''
+      action_runner.ExecuteJavaScript('''
           document.querySelector('html /deep/ topeka-category-front-page /deep/\
               paper-fab').fire('tap');''')
-      action_runner.WaitForJavaScriptCondition2('''
+      action_runner.WaitForJavaScriptCondition('''
           window.topeka_page_transitions === 4''')
       # Input a mostly correct answer:
-      action_runner.ExecuteJavaScript2('''
+      action_runner.ExecuteJavaScript('''
           document.querySelector('html /deep/ topeka-quiz-fill-blank /deep/\
               input').value = 'arkinsaw';
           document.querySelector('html /deep/ topeka-quiz-fill-blank /deep/\
               input').fire('input');
           document.querySelector('html /deep/ topeka-quizzes /deep/ \
               paper-fab').fire('tap');''')
-      action_runner.WaitForJavaScriptCondition2('''
+      action_runner.WaitForJavaScriptCondition('''
           window.topeka_page_transitions === 6''')
 
 class Masonry(KeySilkCasesPage):
@@ -712,8 +712,8 @@
 
   def PerformPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('animation_interaction'):
-      action_runner.ExecuteJavaScript2('window.brick()')
-      action_runner.WaitForJavaScriptCondition2('window.done')
+      action_runner.ExecuteJavaScript('window.brick()')
+      action_runner.WaitForJavaScriptCondition('window.done')
 
 
 class KeySilkCasesPageSet(story.StorySet):
diff --git a/tools/perf/page_sets/login_helpers/chrome_login.py b/tools/perf/page_sets/login_helpers/chrome_login.py
index 1be4ee2..33dad0fc 100644
--- a/tools/perf/page_sets/login_helpers/chrome_login.py
+++ b/tools/perf/page_sets/login_helpers/chrome_login.py
@@ -44,7 +44,7 @@
     raise RuntimeError('Can not find GAIA webview context for sign in.')
   gaia_action_runner = action_runner_module.ActionRunner(gaia_context)
 
-  new_flow = gaia_action_runner.EvaluateJavaScript2(
+  new_flow = gaia_action_runner.EvaluateJavaScript(
       'document.querySelector("#gaia_firsform") != null')
   gaia_form_id = 'gaia_firstform' if new_flow else 'gaia_loginform'
   login_utils.InputForm(gaia_action_runner, account_name, input_id='Email',
diff --git a/tools/perf/page_sets/login_helpers/dropbox_login.py b/tools/perf/page_sets/login_helpers/dropbox_login.py
index a2aef275..c4f81c4 100644
--- a/tools/perf/page_sets/login_helpers/dropbox_login.py
+++ b/tools/perf/page_sets/login_helpers/dropbox_login.py
@@ -32,7 +32,7 @@
 
   # Wait until the "Sign in" button is enabled and then click it.
   login_button_selector = '.login-form .login-button'
-  action_runner.WaitForJavaScriptCondition2('''
+  action_runner.WaitForJavaScriptCondition('''
       (function() {
         var loginButton = document.querySelector({{ selector }});
         if (!loginButton)
diff --git a/tools/perf/page_sets/login_helpers/google_login.py b/tools/perf/page_sets/login_helpers/google_login.py
index e41bb07a3..a1108e4 100644
--- a/tools/perf/page_sets/login_helpers/google_login.py
+++ b/tools/perf/page_sets/login_helpers/google_login.py
@@ -43,13 +43,13 @@
        'https%3A%2F%2Faccounts.google.com%2FManageAccount')
 
   # Wait until either the email or password input is visible.
-  action_runner.WaitForJavaScriptCondition2('{{ @a }} || {{ @b }}',
+  action_runner.WaitForJavaScriptCondition('{{ @a }} || {{ @b }}',
       a=_EMAIL_INPUT_VISIBLE_CONDITION, b=_PASSWORD_INPUT_VISIBLE_CONDITION)
 
   # If the email input is visible, this is the first Google login within the
   # browser session, so we must enter both email and password. Otherwise, only
   # password is required.
-  if action_runner.EvaluateJavaScript2(_EMAIL_INPUT_VISIBLE_CONDITION):
+  if action_runner.EvaluateJavaScript(_EMAIL_INPUT_VISIBLE_CONDITION):
     login_utils.InputForm(action_runner, account_name, input_id='Email',
                           form_id='gaia_firstform')
     action_runner.ClickElement(selector='#gaia_firstform #next')
diff --git a/tools/perf/page_sets/login_helpers/login_utils.py b/tools/perf/page_sets/login_helpers/login_utils.py
index 6e313f7..710c415 100644
--- a/tools/perf/page_sets/login_helpers/login_utils.py
+++ b/tools/perf/page_sets/login_helpers/login_utils.py
@@ -45,7 +45,7 @@
       possible exceptions.
   """
   action_runner.WaitForElement(selector=input_selector)
-  action_runner.ExecuteJavaScript2(
+  action_runner.ExecuteJavaScript(
       'document.querySelector({{ selector }}).value = {{ value }};',
       selector=input_selector, value=input_text)
 
diff --git a/tools/perf/page_sets/maps.py b/tools/perf/page_sets/maps.py
index 4d5ec2c..9cd1897 100644
--- a/tools/perf/page_sets/maps.py
+++ b/tools/perf/page_sets/maps.py
@@ -29,7 +29,7 @@
 
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('MapAnimation'):
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.WaitForJavaScriptCondition(
         'window.testMetrics != undefined', timeout=120)
 
 
diff --git a/tools/perf/page_sets/mobile_infinite_scroll_cases.py b/tools/perf/page_sets/mobile_infinite_scroll_cases.py
index 5cf6d2ca..adf4271 100644
--- a/tools/perf/page_sets/mobile_infinite_scroll_cases.py
+++ b/tools/perf/page_sets/mobile_infinite_scroll_cases.py
@@ -29,7 +29,7 @@
 
 def _WaitAction(action_runner):
   with action_runner.CreateInteraction('Load'):
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
       'document.body != null && '
       'document.body.scrollHeight > window.innerHeight && '
       '!document.body.addEventListener("touchstart", function() {})')
diff --git a/tools/perf/page_sets/mobile_memory.py b/tools/perf/page_sets/mobile_memory.py
index 268a848..4357d10f 100644
--- a/tools/perf/page_sets/mobile_memory.py
+++ b/tools/perf/page_sets/mobile_memory.py
@@ -59,7 +59,7 @@
     action_runner.Wait(3)
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("rg_s").childElementCount > 300')
 
 
diff --git a/tools/perf/page_sets/mse_cases.py b/tools/perf/page_sets/mse_cases.py
index 3cd41b70..d87964a 100644
--- a/tools/perf/page_sets/mse_cases.py
+++ b/tools/perf/page_sets/mse_cases.py
@@ -12,7 +12,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(MseCasesPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2('window.__testDone == true')
+    action_runner.WaitForJavaScriptCondition('window.__testDone == true')
 
 
 class MseCasesPageSet(story.StorySet):
diff --git a/tools/perf/page_sets/oortonline.py b/tools/perf/page_sets/oortonline.py
index 55655d79..6e1f6e8 100644
--- a/tools/perf/page_sets/oortonline.py
+++ b/tools/perf/page_sets/oortonline.py
@@ -52,7 +52,7 @@
   def RunPageInteractions(self, action_runner):
     WAIT_TIME_IN_SECONDS = 2
     RUN_TIME_IN_SECONDS = 20
-    action_runner.WaitForJavaScriptCondition2('window.benchmarkStarted')
+    action_runner.WaitForJavaScriptCondition('window.benchmarkStarted')
     # Perform GC to get rid of start-up garbage.
     action_runner.ForceGarbageCollection()
     with action_runner.CreateInteraction('Begin'):
diff --git a/tools/perf/page_sets/polymer.py b/tools/perf/page_sets/polymer.py
index 7a9c26b9..47665aa 100644
--- a/tools/perf/page_sets/polymer.py
+++ b/tools/perf/page_sets/polymer.py
@@ -40,7 +40,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(PolymerPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__polymer_ready')
 
 
@@ -70,7 +70,7 @@
 
   def SlidePanel(self, action_runner):
     # only bother with this interaction if the drawer is hidden
-    opened = action_runner.EvaluateJavaScript2('''
+    opened = action_runner.EvaluateJavaScript('''
         (function() {
           var outer = document.querySelector("body /deep/ #outerPanels");
           return outer.opened || outer.wideMode;
@@ -88,7 +88,7 @@
                 ).shadowRoot.querySelector(
                   '.handle-bar'
                 )''')
-        action_runner.WaitForJavaScriptCondition2('''
+        action_runner.WaitForJavaScriptCondition('''
             var outer = document.querySelector("body /deep/ #outerPanels");
             outer.opened || outer.wideMode;''')
 
@@ -102,7 +102,7 @@
 
   def PerformPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('ScrollAndShadowAnimation'):
-      action_runner.ExecuteJavaScript2(
+      action_runner.ExecuteJavaScript(
           "document.getElementById('fab').scrollIntoView()")
       action_runner.Wait(5)
       self.AnimateShadow(action_runner, 'card')
@@ -112,7 +112,7 @@
 
   def AnimateShadow(self, action_runner, eid):
     for i in range(1, 6):
-      action_runner.ExecuteJavaScript2(
+      action_runner.ExecuteJavaScript(
           'document.getElementById({{ eid }}).z = {{ i }}', eid=eid, i=i)
       action_runner.Wait(1)
 
@@ -138,14 +138,14 @@
 
   def RunNavigateSteps(self, action_runner):
     super(PolymerSampler, self).RunNavigateSteps(action_runner)
-    action_runner.ExecuteJavaScript2("""
+    action_runner.ExecuteJavaScript("""
         window.Polymer.whenPolymerReady(function() {
           {{ @iframe }}.contentWindow.Polymer.whenPolymerReady(function() {
             window.__polymer_ready = true;
           })
         });
         """, iframe=self.iframe_js)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__polymer_ready')
 
   def PerformPageInteractions(self, action_runner):
@@ -196,13 +196,13 @@
         selector='body %s:not([disabled]):not([active])' % widget_type)
 
     roles_count_query = element_list_query + '.length'
-    for i in range(action_runner.EvaluateJavaScript2(roles_count_query)):
+    for i in range(action_runner.EvaluateJavaScript(roles_count_query)):
       element_query = js_template.Render(
         '{{ @query }}[{{ i }}]', query=element_list_query, i=i)
-      if action_runner.EvaluateJavaScript2(
+      if action_runner.EvaluateJavaScript(
           element_query + '.offsetParent != null'):
         # Only try to tap on visible elements (offsetParent != null)
-        action_runner.ExecuteJavaScript2(element_query + '.scrollIntoView()')
+        action_runner.ExecuteJavaScript(element_query + '.scrollIntoView()')
         action_runner.Wait(1) # wait for page to settle after scrolling
         action_function(action_runner, element_query)
 
diff --git a/tools/perf/page_sets/repaint_helpers.py b/tools/perf/page_sets/repaint_helpers.py
index 45486d2a..b6b9472 100644
--- a/tools/perf/page_sets/repaint_helpers.py
+++ b/tools/perf/page_sets/repaint_helpers.py
@@ -6,10 +6,10 @@
 
 
 def Repaint(action_runner, mode='viewport', width=None, height=None):
-  action_runner.WaitForJavaScriptCondition2(
+  action_runner.WaitForJavaScriptCondition(
     'document.readyState == "complete"', timeout=90)
   # Rasterize only what's visible.
-  action_runner.ExecuteJavaScript2(
+  action_runner.ExecuteJavaScript(
       'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();')
 
   args = {}
@@ -20,7 +20,7 @@
     args['height'] = height
 
   # Enqueue benchmark
-  action_runner.ExecuteJavaScript2("""
+  action_runner.ExecuteJavaScript("""
       window.benchmark_results = {};
       window.benchmark_results.id =
           chrome.gpuBenchmarking.runMicroBenchmark(
@@ -31,7 +31,7 @@
       """,
       args=args)
 
-  micro_benchmark_id = action_runner.EvaluateJavaScript2(
+  micro_benchmark_id = action_runner.EvaluateJavaScript(
       'window.benchmark_results.id')
   if not micro_benchmark_id:
     raise legacy_page_test.MeasurementFailure(
@@ -40,7 +40,7 @@
   with action_runner.CreateInteraction('Repaint'):
     action_runner.RepaintContinuously(seconds=5)
 
-  action_runner.ExecuteJavaScript2("""
+  action_runner.ExecuteJavaScript("""
       window.benchmark_results.message_handled =
           chrome.gpuBenchmarking.sendMessageToMicroBenchmark(
                 {{ micro_benchmark_id }}, {
diff --git a/tools/perf/page_sets/service_worker_micro_benchmark.py b/tools/perf/page_sets/service_worker_micro_benchmark.py
index 87fe435..21f1c8e 100644
--- a/tools/perf/page_sets/service_worker_micro_benchmark.py
+++ b/tools/perf/page_sets/service_worker_micro_benchmark.py
@@ -11,7 +11,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(ServiceWorkerBenchmarkPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2('window.done')
+    action_runner.WaitForJavaScriptCondition('window.done')
 
 
 class ServiceWorkerMicroBenchmarkPageSet(story.StorySet):
diff --git a/tools/perf/page_sets/system_health/background_stories.py b/tools/perf/page_sets/system_health/background_stories.py
index b55eb70..59b4c13 100644
--- a/tools/perf/page_sets/system_health/background_stories.py
+++ b/tools/perf/page_sets/system_health/background_stories.py
@@ -58,7 +58,7 @@
     action_runner.WaitForElement(selector='#additional-content button')
     action_runner.ScrollPageToElement(selector='#additional-content button')
     # TapElement seems flaky here so use JavaScript instead.
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         'document.querySelector("#additional-content button").click()')
 
     # Scroll to video, start it and then wait for a few seconds.
diff --git a/tools/perf/page_sets/system_health/blank_stories.py b/tools/perf/page_sets/system_health/blank_stories.py
index 24866b0..ffe0ecc 100644
--- a/tools/perf/page_sets/system_health/blank_stories.py
+++ b/tools/perf/page_sets/system_health/blank_stories.py
@@ -14,7 +14,7 @@
   def _DidLoadDocument(self, action_runner):
     # Request a RAF and wait for it to be processed to ensure that the metric
     # Startup.FirstWebContents.NonEmptyPaint2 is recorded.
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         """
         window.__hasRunRAF = false;
         requestAnimationFrame(function() {
@@ -22,4 +22,4 @@
         });
         """
     )
-    action_runner.WaitForJavaScriptCondition2("window.__hasRunRAF")
+    action_runner.WaitForJavaScriptCondition("window.__hasRunRAF")
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index 51858ef..0769b2e 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -229,7 +229,7 @@
     # window does not have a "Close" button, instead it has only a "Send link
     # to phone" button. So on tablets we run with the popup window open. The
     # popup is transparent, so this is mostly an aesthetical issue.
-    has_button = action_runner.EvaluateJavaScript2(
+    has_button = action_runner.EvaluateJavaScript(
         '!!document.querySelector({{ selector }})',
         selector=self._CLOSE_BUTTON_SELECTOR)
     if has_button:
@@ -324,7 +324,7 @@
     # Refine search query in the search box.
     # TODO(nednguyen): replace this with input text gesture to make it more
     # realistic.
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         js_template.Render(
             'document.querySelector({{ selector }}).value += "वितरण";',
             selector=self._SEARCH_BOX_SELECTOR))
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py
index 14196c9..f3ab950 100644
--- a/tools/perf/page_sets/system_health/loading_stories.py
+++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -198,7 +198,7 @@
     # window does not have a "Close" button, instead it has only a "Send link
     # to phone" button. So on tablets we run with the popup window open. The
     # popup is transparent, so this is mostly an aesthetical issue.
-    has_button = action_runner.EvaluateJavaScript2(
+    has_button = action_runner.EvaluateJavaScript(
         '!!document.querySelector({{ selector }})',
         selector=self._CLOSE_BUTTON_SELECTOR)
     if has_button:
@@ -253,7 +253,7 @@
 
   def _DidLoadDocument(self, action_runner):
     # Wait until the 'Recently tagged' view loads.
-    action_runner.WaitForJavaScriptCondition2('''
+    action_runner.WaitForJavaScriptCondition('''
         document.querySelector(
             '.search-photos-everyone-trending-view .photo-list-view')
                 !== null''')
@@ -317,7 +317,7 @@
 
   def _DidLoadDocument(self, action_runner):
     # Wait until the UI loads.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("loading").style.display === "none"')
 
 
@@ -328,7 +328,7 @@
   def _DidLoadDocument(self, action_runner):
     # Wait until the UI loads.
     action_runner.WaitForElement('#apploadingdiv')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("apploadingdiv").style.height === "0px"')
 
 class LoadMapsStory(_LoadingStory):
@@ -378,7 +378,7 @@
 
   def _DidLoadDocument(self, action_runner):
     # The #logo element is removed right before the main menu is displayed.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("logo") === null')
 
 
@@ -396,7 +396,7 @@
   def _DidLoadDocument(self, action_runner):
     # The background of the game canvas is set when the "Tap screen to play"
     # caption is displayed.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.querySelector("#game canvas").style.background !== ""')
 
 
diff --git a/tools/perf/page_sets/system_health/long_running_stories.py b/tools/perf/page_sets/system_health/long_running_stories.py
index 809971d8..a32ea45 100644
--- a/tools/perf/page_sets/system_health/long_running_stories.py
+++ b/tools/perf/page_sets/system_health/long_running_stories.py
@@ -65,12 +65,12 @@
 
   def _DidLoadDocument(self, action_runner):
     # Close the "Get Inbox by Gmail" interstitial.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.querySelector("#isppromo a") !== null')
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         'document.querySelector("#isppromo a").click()')
     # Wait until the UI loads.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("apploadingdiv").style.height === "0px"')
 
 
@@ -79,7 +79,7 @@
 
   def _DidLoadDocument(self, action_runner):
     # Wait until the UI loads.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("loading").style.display === "none"')
 
 
diff --git a/tools/perf/page_sets/system_health/media_stories.py b/tools/perf/page_sets/system_health/media_stories.py
index c8a68ae..ad079e8d 100644
--- a/tools/perf/page_sets/system_health/media_stories.py
+++ b/tools/perf/page_sets/system_health/media_stories.py
@@ -45,7 +45,7 @@
           self.PLAY_DURATION - self._GetTimeInSeconds(action_runner))
 
   def _GetTimeInSeconds(self, action_runner):
-    minutes, seconds = action_runner.EvaluateJavaScript2(
+    minutes, seconds = action_runner.EvaluateJavaScript(
         'document.querySelector({{ selector }}).textContent',
         selector=self.TIME_SELECTOR).split(':')
     return int(minutes * 60 + seconds)
diff --git a/tools/perf/page_sets/text_selection_sites.py b/tools/perf/page_sets/text_selection_sites.py
index 0fa2aa63..435379cbc 100644
--- a/tools/perf/page_sets/text_selection_sites.py
+++ b/tools/perf/page_sets/text_selection_sites.py
@@ -18,7 +18,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(SimplePage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.readyState == "complete"')
 
 
@@ -31,7 +31,7 @@
     # Create a fixed position div in the top left corner of the page, and
     # another one in the bottom right corner of the page.
     # Select the text within the first div.
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         (function() {
           var text_div = document.createElement('div');
           var text_div_2 = document.createElement('div');
@@ -65,32 +65,32 @@
 
     # Wait two frames so that the selection information is sent to chromium
     # and it is able to process input events interacting with selection.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("text-for-perf-test").style.color == "green"')
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
           window.requestAnimationFrame(function() {
             document.getElementById("text-for-perf-test").style.color="red";
           });
         ''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementById("text-for-perf-test").style.color == "red"')
 
     # Confirm that the selection is set correctly.
-    text = action_runner.EvaluateJavaScript2('window.getSelection().toString()')
+    text = action_runner.EvaluateJavaScript('window.getSelection().toString()')
     assert text == "Hello"
 
     # Tap on the selected text to make the handles show up.
     with action_runner.CreateGestureInteraction('TapAction'):
       action_runner.TapElement('#text-for-perf-test')
 
-    text_div_bottom = float(action_runner.EvaluateJavaScript2('''
+    text_div_bottom = float(action_runner.EvaluateJavaScript('''
         document.getElementById("text-for-perf-test").getClientRects()[0].bottom
         '''))
-    text_div_2_bottom = float(action_runner.EvaluateJavaScript2('''
+    text_div_2_bottom = float(action_runner.EvaluateJavaScript('''
         document.getElementById(
             "text-for-perf-test-2").getClientRects()[0].bottom
         '''))
-    body_rect_str = action_runner.EvaluateJavaScript2('''
+    body_rect_str = action_runner.EvaluateJavaScript('''
         var r = window.__GestureCommon_GetBoundingVisibleRect(document.body);
         r.left + " " + r.top + " " + r.height + " " + r.width;
         ''')
@@ -116,11 +116,11 @@
           use_touch=1)
 
     # Confirm that the selection has changed.
-    text = action_runner.EvaluateJavaScript2('window.getSelection().toString()')
+    text = action_runner.EvaluateJavaScript('window.getSelection().toString()')
     assert text != "Hello"
 
     # Determine the coordinates of the end of the selection
-    sel_end_str = action_runner.EvaluateJavaScript2('''
+    sel_end_str = action_runner.EvaluateJavaScript('''
           var rects = window.getSelection().getRangeAt(0).getClientRects();
           var last_rect = rects[rects.length - 1];
           last_rect.right + " " + last_rect.bottom;
@@ -139,7 +139,7 @@
           use_touch=1)
 
     # Confirm that the selection is back to the text in the first div.
-    text = action_runner.EvaluateJavaScript2('window.getSelection().toString()')
+    text = action_runner.EvaluateJavaScript('window.getSelection().toString()')
     assert text == "Hello"
 
 
diff --git a/tools/perf/page_sets/todomvc.py b/tools/perf/page_sets/todomvc.py
index a03ebab1..43ce61e 100644
--- a/tools/perf/page_sets/todomvc.py
+++ b/tools/perf/page_sets/todomvc.py
@@ -36,7 +36,7 @@
         'console.time({{ label }});', label=INTERACTION_NAME)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2(
+    action_runner.ExecuteJavaScript(
         """
         this.becameIdle = false;
         this.idleCallback = function(deadline) {
@@ -48,8 +48,8 @@
         requestIdleCallback(this.idleCallback);
         """
     )
-    action_runner.WaitForJavaScriptCondition2('this.becameIdle === true')
-    action_runner.ExecuteJavaScript2(
+    action_runner.WaitForJavaScriptCondition('this.becameIdle === true')
+    action_runner.ExecuteJavaScript(
         'console.timeEnd({{ label }});', label=INTERACTION_NAME)
 
 
diff --git a/tools/perf/page_sets/top_10.py b/tools/perf/page_sets/top_10.py
index 4d9b5eb..7c9045f 100644
--- a/tools/perf/page_sets/top_10.py
+++ b/tools/perf/page_sets/top_10.py
@@ -37,7 +37,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(Gmail, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
@@ -51,7 +51,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GoogleCalendar, self).RunNavigateSteps(action_runner)
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         (function() { var elem = document.createElement("meta");
           elem.name="viewport";
           elem.content="initial-scale=1";
diff --git a/tools/perf/page_sets/top_25_smooth.py b/tools/perf/page_sets/top_25_smooth.py
index 9267c522..f327ff1 100644
--- a/tools/perf/page_sets/top_25_smooth.py
+++ b/tools/perf/page_sets/top_25_smooth.py
@@ -57,17 +57,17 @@
     google_login.LoginGoogleAccount(action_runner, 'google3',
                                     self.credentials_path)
     super(GmailSmoothPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null',
         timeout=120)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         gmonkey.load('2.0', function(api) {
           window.__scrollableElementForTelemetry = api.getScrollableElement();
         });''')
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.__scrollableElementForTelemetry != null')
     action_runner.Wait(1)
     with action_runner.CreateGestureInteraction('ScrollAction'):
diff --git a/tools/perf/page_sets/top_7_stress.py b/tools/perf/page_sets/top_7_stress.py
index c3494a60..c46eb79 100644
--- a/tools/perf/page_sets/top_7_stress.py
+++ b/tools/perf/page_sets/top_7_stress.py
@@ -7,11 +7,11 @@
 
 
 def _GetCurrentLocation(action_runner):
-  return action_runner.EvaluateJavaScript2('document.location.href')
+  return action_runner.EvaluateJavaScript('document.location.href')
 
 
 def _WaitForLocationChange(action_runner, old_href):
-  action_runner.WaitForJavaScriptCondition2(
+  action_runner.WaitForJavaScriptCondition(
       'document.location.href != {{ old_href }}', old_href=old_href)
 
 
@@ -99,7 +99,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GmailPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
@@ -129,7 +129,7 @@
     super(GoogleCalendarPage, self).RunNavigateSteps(action_runner)
     action_runner.Wait(2)
     action_runner.WaitForElement('div[class~="navForward"]')
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         (function() {
           var elem = document.createElement('meta');
           elem.name='viewport';
@@ -295,14 +295,14 @@
     # Scroll and wait for the next page to be loaded.
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.documentElement.scrollHeight - window.innerHeight - '
         'window.pageYOffset > 0')
 
     # Scroll and wait again.
     with action_runner.CreateGestureInteraction('ScrollAction'):
       action_runner.ScrollPage()
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.documentElement.scrollHeight - window.innerHeight - '
         'window.pageYOffset > 0')
 
diff --git a/tools/perf/page_sets/top_pages.py b/tools/perf/page_sets/top_pages.py
index bb758447..7f0d187 100644
--- a/tools/perf/page_sets/top_pages.py
+++ b/tools/perf/page_sets/top_pages.py
@@ -59,7 +59,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GmailPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
@@ -80,7 +80,7 @@
     super(GoogleCalendarPage, self).RunNavigateSteps(action_runner)
     action_runner.Wait(2)
     action_runner.WaitForElement('div[class~="navForward"]')
-    action_runner.ExecuteJavaScript2('''
+    action_runner.ExecuteJavaScript('''
         (function() {
           var elem = document.createElement('meta');
           elem.name='viewport';
@@ -107,7 +107,7 @@
   def RunNavigateSteps(self, action_runner):
     super(GoogleDocPage, self).RunNavigateSteps(action_runner)
     action_runner.Wait(2)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.getElementsByClassName("kix-appview-editor").length')
 
 
diff --git a/tools/perf/page_sets/tough_ad_cases.py b/tools/perf/page_sets/tough_ad_cases.py
index 6ab88fc0..cf96357 100644
--- a/tools/perf/page_sets/tough_ad_cases.py
+++ b/tools/perf/page_sets/tough_ad_cases.py
@@ -21,10 +21,10 @@
     util.WaitFor(action_runner.tab.HasReachedQuiescence, 60)
     # Swiffy overwrites toString() to return a constant string, so "undo" that
     # here so that we don't think it has stomped over console.time.
-    action_runner.EvaluateJavaScript2(
+    action_runner.EvaluateJavaScript(
         'Function.prototype.toString = function() { return "[native code]"; }')
     # Make sure we have a reasonable viewport for mobile.
-    action_runner.EvaluateJavaScript2("""
+    action_runner.EvaluateJavaScript("""
         var meta = document.createElement("meta");
         meta.name = "viewport";
         meta.content = "width=device-width";
@@ -68,14 +68,14 @@
     # Most ads have touch handlers and we want to simulate the worst case of the
     # user trying to scroll the page by grabbing an ad.
     if self._wait_for_interactive_or_better:
-        action_runner.WaitForJavaScriptCondition2(
+        action_runner.WaitForJavaScriptCondition(
             '(document.readyState == "interactive" || '
             'document.readyState == "complete") &&'
             'document.body != null && '
             'document.body.scrollHeight > window.innerHeight && '
             '!document.body.addEventListener("touchstart", function() {})')
     else:
-        action_runner.WaitForJavaScriptCondition2(
+        action_runner.WaitForJavaScriptCondition(
             'document.body != null && '
             'document.body.scrollHeight > window.innerHeight && '
             '!document.body.addEventListener("touchstart", function() {})')
@@ -104,7 +104,7 @@
   def RunNavigateSteps(self, action_runner):
     super(ForbesAdPage, self).RunNavigateSteps(action_runner)
     # Wait until the interstitial banner goes away.
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.location.pathname.indexOf("welcome") == -1')
 
 
diff --git a/tools/perf/page_sets/tough_animation_cases.py b/tools/perf/page_sets/tough_animation_cases.py
index a817ad69..6e831b2 100644
--- a/tools/perf/page_sets/tough_animation_cases.py
+++ b/tools/perf/page_sets/tough_animation_cases.py
@@ -15,7 +15,7 @@
   def RunNavigateSteps(self, action_runner):
     super(ToughAnimationCasesPage, self).RunNavigateSteps(action_runner)
     if self._need_measurement_ready:
-      action_runner.WaitForJavaScriptCondition2('window.measurementReady')
+      action_runner.WaitForJavaScriptCondition('window.measurementReady')
 
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('ToughAnimation'):
diff --git a/tools/perf/page_sets/tough_canvas_cases.py b/tools/perf/page_sets/tough_canvas_cases.py
index 1a9d729..28ce0bb 100644
--- a/tools/perf/page_sets/tough_canvas_cases.py
+++ b/tools/perf/page_sets/tough_canvas_cases.py
@@ -13,7 +13,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(ToughCanvasCasesPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         "document.readyState == 'complete'")
 
   def RunPageInteractions(self, action_runner):
diff --git a/tools/perf/page_sets/tough_energy_cases.py b/tools/perf/page_sets/tough_energy_cases.py
index 94043fd5..215435c 100644
--- a/tools/perf/page_sets/tough_energy_cases.py
+++ b/tools/perf/page_sets/tough_energy_cases.py
@@ -28,7 +28,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GooglePage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
diff --git a/tools/perf/page_sets/tough_filters_cases.py b/tools/perf/page_sets/tough_filters_cases.py
index 2c7bc8d5..36b41276 100644
--- a/tools/perf/page_sets/tough_filters_cases.py
+++ b/tools/perf/page_sets/tough_filters_cases.py
@@ -23,7 +23,7 @@
   def RunPageInteractions(self, action_runner):
     action_runner.WaitForNetworkQuiescence()
     with action_runner.CreateInteraction('Filter'):
-      action_runner.EvaluateJavaScript2(
+      action_runner.EvaluateJavaScript(
           'document.getElementById("benchmarkButtonText").click()')
       action_runner.Wait(10)
 
diff --git a/tools/perf/page_sets/tough_image_decode_cases.py b/tools/perf/page_sets/tough_image_decode_cases.py
index 40b95b7..fd20064 100644
--- a/tools/perf/page_sets/tough_image_decode_cases.py
+++ b/tools/perf/page_sets/tough_image_decode_cases.py
@@ -16,7 +16,7 @@
     self.archive_data_file = 'data/tough_image_decode_cases.json'
 
   def RunPageInteractions(self, action_runner):
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
       'document.readyState === "complete"')
     action_runner.ScrollPage(direction='down', speed_in_pixels_per_second=5000)
     with action_runner.CreateGestureInteraction('ScrollAction'):
diff --git a/tools/perf/page_sets/tough_path_rendering_cases.py b/tools/perf/page_sets/tough_path_rendering_cases.py
index 626b545..b8b4dd91 100644
--- a/tools/perf/page_sets/tough_path_rendering_cases.py
+++ b/tools/perf/page_sets/tough_path_rendering_cases.py
@@ -15,7 +15,7 @@
 
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('ClickStart'):
-      action_runner.EvaluateJavaScript2(
+      action_runner.EvaluateJavaScript(
           'document.getElementById("StartButton").click()')
       action_runner.Wait(20)
 
diff --git a/tools/perf/page_sets/tough_pinch_zoom_cases.py b/tools/perf/page_sets/tough_pinch_zoom_cases.py
index 8b672e35..2aa0151 100644
--- a/tools/perf/page_sets/tough_pinch_zoom_cases.py
+++ b/tools/perf/page_sets/tough_pinch_zoom_cases.py
@@ -62,7 +62,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(GmailPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'window.gmonkey !== undefined &&'
         'document.getElementById("gb") !== null')
 
diff --git a/tools/perf/page_sets/tough_scheduling_cases.py b/tools/perf/page_sets/tough_scheduling_cases.py
index ac0de95..1a817a1 100644
--- a/tools/perf/page_sets/tough_scheduling_cases.py
+++ b/tools/perf/page_sets/tough_scheduling_cases.py
@@ -377,16 +377,16 @@
     action_runner.TapElement(selector='div[id="spinner"]')
     # Begin the action immediately because we want the page to update smoothly
     # even while resources are being loaded.
-    action_runner.WaitForJavaScriptCondition2('window.__ready !== undefined')
+    action_runner.WaitForJavaScriptCondition('window.__ready !== undefined')
 
     with action_runner.CreateGestureInteraction('LoadAction'):
-      action_runner.ExecuteJavaScript2('kickOffLoading()')
-      action_runner.WaitForJavaScriptCondition2('window.__ready')
+      action_runner.ExecuteJavaScript('kickOffLoading()')
+      action_runner.WaitForJavaScriptCondition('window.__ready')
       # Click one second after the resources have finished loading.
       action_runner.Wait(1)
       action_runner.TapElement(selector='input[id="run"]')
       # Wait for the test to complete.
-      action_runner.WaitForJavaScriptCondition2('window.__finished')
+      action_runner.WaitForJavaScriptCondition('window.__finished')
 
 
 class ToughSchedulingCasesPageSet(story.StorySet):
diff --git a/tools/perf/page_sets/tough_webgl_cases.py b/tools/perf/page_sets/tough_webgl_cases.py
index 54677df..49a0be2c 100644
--- a/tools/perf/page_sets/tough_webgl_cases.py
+++ b/tools/perf/page_sets/tough_webgl_cases.py
@@ -27,7 +27,7 @@
 
   def RunNavigateSteps(self, action_runner):
     super(ToughWebglCasesPage, self).RunNavigateSteps(action_runner)
-    action_runner.WaitForJavaScriptCondition2(
+    action_runner.WaitForJavaScriptCondition(
         'document.readyState == "complete"')
     action_runner.Wait(2)
 
diff --git a/tools/perf/page_sets/typical_10_mobile.py b/tools/perf/page_sets/typical_10_mobile.py
index 9c8951d..5b03a73 100644
--- a/tools/perf/page_sets/typical_10_mobile.py
+++ b/tools/perf/page_sets/typical_10_mobile.py
@@ -29,7 +29,7 @@
   def RunPageInteractions(self, action_runner):
     for _ in range(0, 5):
       action_runner.ReloadPage()
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.WaitForJavaScriptCondition(
           'document.readyState === "complete"')
 
 
diff --git a/tools/perf/page_sets/typical_25.py b/tools/perf/page_sets/typical_25.py
index 085f356..a1700d1 100644
--- a/tools/perf/page_sets/typical_25.py
+++ b/tools/perf/page_sets/typical_25.py
@@ -50,7 +50,7 @@
 
   def RunPageInteractions(self, action_runner):
     if self._run_no_page_interactions:
-      action_runner.WaitForJavaScriptCondition2(
+      action_runner.WaitForJavaScriptCondition(
           'performance.timing.loadEventStart > 0')
       return
     with action_runner.CreateGestureInteraction('ScrollAction'):
diff --git a/tools/perf/page_sets/webrtc_cases.py b/tools/perf/page_sets/webrtc_cases.py
index af0c9ead..41427d81 100644
--- a/tools/perf/page_sets/webrtc_cases.py
+++ b/tools/perf/page_sets/webrtc_cases.py
@@ -49,10 +49,10 @@
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('Action_Create_PeerConnection',
                                          repeatable=False):
-      action_runner.ExecuteJavaScript2('minWidthInput.value = 1280')
-      action_runner.ExecuteJavaScript2('maxWidthInput.value = 1280')
-      action_runner.ExecuteJavaScript2('minHeightInput.value = 720')
-      action_runner.ExecuteJavaScript2('maxHeightInput.value = 720')
+      action_runner.ExecuteJavaScript('minWidthInput.value = 1280')
+      action_runner.ExecuteJavaScript('maxWidthInput.value = 1280')
+      action_runner.ExecuteJavaScript('minHeightInput.value = 720')
+      action_runner.ExecuteJavaScript('maxHeightInput.value = 720')
       action_runner.ClickElement('button[id="getMedia"]')
       action_runner.Wait(2)
       action_runner.ClickElement('button[id="connect"]')
@@ -71,7 +71,7 @@
   def RunPageInteractions(self, action_runner):
     # It won't have time to finish the 512 MB, but we're only interested in
     # cpu + memory anyway rather than how much data we manage to transfer.
-    action_runner.ExecuteJavaScript2('megsToSend.value = 512;')
+    action_runner.ExecuteJavaScript('megsToSend.value = 512;')
     action_runner.ClickElement('button[id="sendTheData"]')
     action_runner.Wait(30)
 
@@ -86,7 +86,7 @@
         page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('codecSelector.value="OPUS";')
+    action_runner.ExecuteJavaScript('codecSelector.value="OPUS";')
     action_runner.ClickElement('button[id="callButton"]')
     action_runner.Wait(10)
 
@@ -101,7 +101,7 @@
         page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('codecSelector.value="G722";')
+    action_runner.ExecuteJavaScript('codecSelector.value="G722";')
     action_runner.ClickElement('button[id="callButton"]')
     action_runner.Wait(10)
 
@@ -116,7 +116,7 @@
         page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('codecSelector.value="PCMU";')
+    action_runner.ExecuteJavaScript('codecSelector.value="PCMU";')
     action_runner.ClickElement('button[id="callButton"]')
     action_runner.Wait(10)
 
@@ -131,7 +131,7 @@
         page_set=page_set)
 
   def RunPageInteractions(self, action_runner):
-    action_runner.ExecuteJavaScript2('codecSelector.value="ISAC/16000";')
+    action_runner.ExecuteJavaScript('codecSelector.value="ISAC/16000";')
     action_runner.ClickElement('button[id="callButton"]')
     action_runner.Wait(10)
 
@@ -149,8 +149,8 @@
   def RunPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('Action_Canvas_PeerConnection',
                                          repeatable=False):
-      action_runner.ExecuteJavaScript2('draw();')
-      action_runner.ExecuteJavaScript2('doCanvasCaptureAndPeerConnection();')
+      action_runner.ExecuteJavaScript('draw();')
+      action_runner.ExecuteJavaScript('doCanvasCaptureAndPeerConnection();')
       action_runner.Wait(10)
 
 
@@ -167,9 +167,9 @@
     with action_runner.CreateInteraction('Action_Create_PeerConnection',
                                          repeatable=False):
       # Set the number of peer connections to create to 15.
-      action_runner.ExecuteJavaScript2(
+      action_runner.ExecuteJavaScript(
           'document.getElementById("num-peerconnections").value=15')
-      action_runner.ExecuteJavaScript2(
+      action_runner.ExecuteJavaScript(
           'document.getElementById("cpuoveruse-detection").checked=false')
       action_runner.ClickElement('button[id="start-test"]')
       action_runner.Wait(45)
diff --git a/tools/perf/profile_creators/fast_navigation_profile_extender.py b/tools/perf/profile_creators/fast_navigation_profile_extender.py
index 318198d..f2003d4 100644
--- a/tools/perf/profile_creators/fast_navigation_profile_extender.py
+++ b/tools/perf/profile_creators/fast_navigation_profile_extender.py
@@ -120,7 +120,7 @@
     """Retrives the URL of the tab."""
     # TODO(erikchen): Use tab.url instead, which talks to the browser process
     # instead of the renderer process. http://crbug.com/486119
-    return tab.EvaluateJavaScript2('document.URL', timeout=timeout)
+    return tab.EvaluateJavaScript('document.URL', timeout=timeout)
 
   def _WaitForUrlToChange(self, tab, initial_url, end_time):
     """Waits for the tab to navigate away from its initial url.
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc
index 1846796..b622f42 100644
--- a/ui/arc/notification/arc_custom_notification_view.cc
+++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -20,6 +20,7 @@
 #include "ui/gfx/transform.h"
 #include "ui/message_center/message_center_style.h"
 #include "ui/message_center/views/custom_notification_view.h"
+#include "ui/message_center/views/padded_button.h"
 #include "ui/resources/grit/ui_resources.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/background.h"
@@ -179,33 +180,19 @@
   DISALLOW_COPY_AND_ASSIGN(ContentViewDelegate);
 };
 
-class ArcCustomNotificationView::ControlButton : public views::ImageButton {
+class ArcCustomNotificationView::ControlButton
+    : public message_center::PaddedButton {
  public:
   explicit ControlButton(ArcCustomNotificationView* owner)
-      : views::ImageButton(owner), owner_(owner) {
-    set_background(
-        views::Background::CreateSolidBackground(SK_ColorTRANSPARENT));
-    SetFocusForPlatform();
-    SetFocusPainter(views::Painter::CreateSolidFocusPainter(
-        message_center::kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
-
-    // The sizes below are in DIPs.
-    SetBorder(views::CreateEmptyBorder(
-        message_center::kControlButtonPaddingFromBorder,
-        message_center::kControlButtonPaddingFromBorder,
-        message_center::kControlButtonPaddingFromBorder,
-        message_center::kControlButtonPaddingFromBorder));
-
-    set_animate_on_state_change(false);
-  }
+      : message_center::PaddedButton(owner), owner_(owner) {}
 
   void OnFocus() override {
-    views::ImageButton::OnFocus();
+    message_center::PaddedButton::OnFocus();
     owner_->UpdateControlButtonsVisiblity();
   }
 
   void OnBlur() override {
-    views::ImageButton::OnBlur();
+    message_center::PaddedButton::OnBlur();
     owner_->UpdateControlButtonsVisiblity();
   }
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
index 75e146b..54cf35f 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -34,6 +34,16 @@
   this.dialogType_ = launchParam.type;
 
   /**
+   * <hr> elements in cr.ui.Menu.
+   * This is a workaround for crbug.com/689255. This member variable is just for
+   * keeping explicit reference to decorated <hr>s to prevent GC from collecting
+   * <hr> wrappers, and not used anywhere.
+   * TODO(fukino): Remove this member variable once the root cause is fixed.
+   * @private {!Array<!Element>}
+   */
+  this.separators_ = [].slice.call(document.querySelectorAll('cr-menu > hr'));
+
+  /**
    * Error dialog.
    * @type {!ErrorDialog}
    * @const
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index 841e074..966fe19f 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -294,11 +294,14 @@
   int bottom_height = bottom_view_->GetHeightForWidth(content_width);
 
   if (settings_button_view_) {
-    gfx::Size settings_size(settings_button_view_->GetPreferredSize());
-    settings_button_view_->SetBounds(content_width - settings_size.width(),
-                                     bottom_y - settings_size.height(),
-                                     settings_size.width(),
-                                     settings_size.height());
+    const gfx::Size settings_size(settings_button_view_->GetPreferredSize());
+    const int marginFromRight =
+        settings_size.width() +
+        (close_button_ ? close_button_->GetPreferredSize().width() : 0);
+    gfx::Rect settings_rect(insets.left() + content_width - marginFromRight,
+                            GetContentsBounds().y(), settings_size.width(),
+                            settings_size.height());
+    settings_button_view_->SetBoundsRect(settings_rect);
   }
 
   // Close button.
@@ -514,18 +517,11 @@
   if (!settings_button_view_ && notification.delegate() &&
       notification.delegate()->ShouldDisplaySettingsButton()) {
     PaddedButton* settings = new PaddedButton(this);
-    settings->SetPadding(-kNotificationSettingsPadding,
-                         kNotificationSettingsPadding);
-    settings->SetNormalImage(IDR_NOTIFICATION_SETTINGS_BUTTON_ICON);
-    settings->SetHoveredImage(IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_HOVER);
-    settings->SetPressedImage(IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_PRESSED);
-    settings->set_animate_on_state_change(false);
+    settings->SetImage(views::Button::STATE_NORMAL, GetSettingsIcon());
     settings->SetAccessibleName(l10n_util::GetStringUTF16(
         IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
     settings->SetTooltipText(l10n_util::GetStringUTF16(
         IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
-    settings->SetFocusPainter(views::Painter::CreateSolidFocusPainter(
-        kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
     settings_button_view_ = settings;
     AddChildView(settings_button_view_);
   }
@@ -685,17 +681,8 @@
 void NotificationView::CreateOrUpdateCloseButtonView(
     const Notification& notification) {
   if (!notification.pinned() && !close_button_) {
-    // TODO(yhanada): Make PaddedButton class support new type of icons after
-    // changing the icon of the settings button.
-    close_button_ = base::MakeUnique<views::ImageButton>(this);
-    close_button_->SetFocusForPlatform();
-    close_button_->SetFocusPainter(views::Painter::CreateSolidFocusPainter(
-        kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
+    close_button_ = base::MakeUnique<PaddedButton>(this);
     close_button_->SetImage(views::Button::STATE_NORMAL, GetCloseIcon());
-    close_button_->SetBorder(views::CreateEmptyBorder(
-        kControlButtonPaddingFromBorder, kControlButtonPaddingFromBorder,
-        kControlButtonPaddingFromBorder, kControlButtonPaddingFromBorder));
-    close_button_->set_animate_on_state_change(false);
     close_button_->SetAccessibleName(l10n_util::GetStringUTF16(
         IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME));
     close_button_->SetTooltipText(l10n_util::GetStringUTF16(
diff --git a/ui/message_center/views/padded_button.cc b/ui/message_center/views/padded_button.cc
index 3977bc84..a0c6a44 100644
--- a/ui/message_center/views/padded_button.cc
+++ b/ui/message_center/views/padded_button.cc
@@ -7,6 +7,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/message_center/message_center_style.h"
+#include "ui/views/border.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/painter.h"
 
@@ -18,78 +19,12 @@
   SetFocusPainter(views::Painter::CreateSolidFocusPainter(
       kFocusBorderColor,
       gfx::Insets(1, 2, 2, 2)));
+  SetBorder(
+      views::CreateEmptyBorder(gfx::Insets(kControlButtonPaddingFromBorder)));
+  set_animate_on_state_change(false);
 }
 
 PaddedButton::~PaddedButton() {
 }
 
-void PaddedButton::SetPadding(int horizontal_padding, int vertical_padding) {
-  padding_.Set(std::max(vertical_padding, 0),
-               std::max(horizontal_padding, 0),
-               std::max(-vertical_padding, 0),
-               std::max(-horizontal_padding, 0));
-}
-
-void PaddedButton::SetNormalImage(int resource_id) {
-  SetImage(views::CustomButton::STATE_NORMAL,
-           ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-               resource_id));
-}
-
-void PaddedButton::SetHoveredImage(int resource_id) {
-  SetImage(views::CustomButton::STATE_HOVERED,
-           ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-               resource_id));
-}
-
-void PaddedButton::SetPressedImage(int resource_id) {
-  SetImage(views::CustomButton::STATE_PRESSED,
-           ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-               resource_id));
-}
-
-gfx::Size PaddedButton::GetPreferredSize() const {
-  return gfx::Size(message_center::kControlButtonSize,
-                   message_center::kControlButtonSize);
-}
-
-void PaddedButton::OnPaint(gfx::Canvas* canvas) {
-  // This is the same implementation as ImageButton::OnPaint except
-  // that it calls ComputePaddedImagePaintPosition() instead of
-  // ComputeImagePaintPosition(), in effect overriding that private method.
-  View::OnPaint(canvas);
-  gfx::ImageSkia image = GetImageToPaint();
-  if (!image.isNull()) {
-    gfx::Point position = ComputePaddedImagePaintPosition(image);
-    if (!background_image_.isNull())
-      canvas->DrawImageInt(background_image_, position.x(), position.y());
-    canvas->DrawImageInt(image, position.x(), position.y());
-  }
-  views::Painter::PaintFocusPainter(this, canvas, focus_painter());
-}
-
-void PaddedButton::OnFocus() {
-  views::ImageButton::OnFocus();
-  ScrollRectToVisible(GetLocalBounds());
-}
-
-gfx::Point PaddedButton::ComputePaddedImagePaintPosition(
-    const gfx::ImageSkia& image) {
-  gfx::Vector2d offset;
-  gfx::Rect bounds = GetContentsBounds();
-  bounds.Inset(padding_);
-
-  if (padding_.left() == 0 && padding_.right() == 0)
-    offset.set_x((bounds.width() - image.width()) / 2);  // Center align.
-  else if (padding_.right() > 0)
-    offset.set_x(bounds.width() - image.width());  // Right align.
-
-  if (padding_.top() == 0 && padding_.bottom() == 0)
-    offset.set_y((bounds.height() - image.height()) / 2);  // Middle align.
-  else if (padding_.bottom() > 0)
-    offset.set_y(bounds.height() - image.height());  // Bottom align.
-
-  return bounds.origin() + offset;
-}
-
 }  // namespace message_center
diff --git a/ui/message_center/views/padded_button.h b/ui/message_center/views/padded_button.h
index fc7df83..1624579 100644
--- a/ui/message_center/views/padded_button.h
+++ b/ui/message_center/views/padded_button.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "ui/message_center/message_center_export.h"
 #include "ui/views/controls/button/image_button.h"
 
 namespace message_center {
@@ -18,32 +19,12 @@
 // corresponding resource images with alpha padding. In the future, this class
 // will also allow for buttons whose touch areas extend beyond their clickable
 // area (<http://crbug.com/168856>).
-class PaddedButton : public views::ImageButton {
+class MESSAGE_CENTER_EXPORT PaddedButton : public views::ImageButton {
  public:
   PaddedButton(views::ButtonListener* listener);
   ~PaddedButton() override;
 
-  // Overridden from views::ImageButton:
-  gfx::Size GetPreferredSize() const override;
-  void OnPaint(gfx::Canvas* canvas) override;
-  void OnFocus() override;
-
-  // The SetPadding() method also sets the button's image alignment (positive
-  // values yield left/top alignments, negative values yield right/bottom ones,
-  // and zero values center/middle ones). ImageButton::SetImageAlignment() calls
-  // will not affect PaddedButton image alignments.
-  void SetPadding(int horizontal_padding, int vertical_padding);
-
-  void SetNormalImage(int resource_id);
-  void SetHoveredImage(int resource_id);
-  void SetPressedImage(int resource_id);
-
- protected:
-  gfx::Point ComputePaddedImagePaintPosition(const gfx::ImageSkia& image);
-
  private:
-  gfx::Insets padding_;
-
   DISALLOW_COPY_AND_ASSIGN(PaddedButton);
 };