diff --git a/.gn b/.gn
index f86b832a..8975f99b 100644
--- a/.gn
+++ b/.gn
@@ -174,6 +174,7 @@
   "//third_party/harfbuzz-ng/BUILD.gn",
   "//third_party/libaddressinput/BUILD.gn",
   "//third_party/opus/BUILD.gn",
+  "//third_party/openh264/BUILD.gn",
   "//third_party/WebKit/Source/bindings/bindings.gni",
   "//third_party/WebKit/Source/bindings/scripts/scripts.gni",
   "//third_party/WebKit/Source/config.gni",
diff --git a/BUILD.gn b/BUILD.gn
index f160eb2..60a313e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -13,6 +13,7 @@
 import("//build/config/ui.gni")
 import("//build_overrides/v8.gni")
 import("//media/media_options.gni")
+import("//third_party/openh264/openh264_args.gni")
 
 if (is_android) {
   import("//build/config/android/config.gni")
@@ -587,6 +588,14 @@
   if (is_ios || is_mac) {
     deps += [ "//media/cast:cast_h264_vt_encoder_unittests" ]
   }
+
+  if (use_openh264) {
+    deps += [
+      "//third_party/openh264:common",
+      "//third_party/openh264:encoder",
+      "//third_party/openh264:processing",
+    ]
+  }
 }
 
 group("gn_only") {
diff --git a/DEPS b/DEPS
index 8c4f64f..0f30fc2 100644
--- a/DEPS
+++ b/DEPS
@@ -190,7 +190,7 @@
    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'b5b1d0e988d68b2bba2eb2deeacf77079f70ddfa',
 
   'src/third_party/libjingle/source/talk':
-    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'b92be1202589b4530e348aca9cf2a0dcd1263c6a', # commit position 10864
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '917ba7e47b92bea2e157c4a42f091bfa44b0836f', # commit position 10903
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
@@ -214,7 +214,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' + '@' + 'ebe6f8ed69e4853a78c8c095a0e49ff36bfb54b1', # commit position 10865
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '118aa04bb20ec8ddaee87f1487324d12cca853d1', # commit position 10903
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/build/all.gyp b/build/all.gyp
index 48e4482b..63e7178 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -10,6 +10,9 @@
     # For Android-specific targets.
     'android_app_targets%': [],
   },
+  'includes': [
+    '../third_party/openh264/openh264_args.gypi',
+  ],
   'targets': [
     {
       'target_name': 'All',
@@ -286,6 +289,11 @@
             '../envoy/envoy.gyp:*',
           ],
         }],
+        ['use_openh264==1', {
+          'dependencies': [
+            '../third_party/openh264/openh264.gyp:*',
+          ],
+        }],
       ],
     }, # target_name: All
     {
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 3861cef9..4cffcbc 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -528,8 +528,15 @@
         ['chromecast==1', {
           'dependencies': [
             '../chromecast/chromecast.gyp:cast_shell',
-          ]
-        }]
+          ],
+        }],
+        ['use_openh264==1', {
+          'dependencies': [
+            '../third_party/openh264/openh264.gyp:openh264_common',
+            '../third_party/openh264/openh264.gyp:openh264_processing',
+            '../third_party/openh264/openh264.gyp:openh264_encoder',
+          ],
+        }],
       ],
     },
     {
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index 80ab9eb..10399eee 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -686,8 +686,11 @@
     if (controller_impl->GetAnimationById(animations_[i]->id()))
       continue;
 
-    // Scroll animations always start at the current scroll offset.
-    if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
+    if (animations_[i]->target_property() == Animation::SCROLL_OFFSET &&
+        !animations_[i]
+             ->curve()
+             ->ToScrollOffsetAnimationCurve()
+             ->HasSetInitialValue()) {
       gfx::ScrollOffset current_scroll_offset;
       if (controller_impl->value_provider_) {
         current_scroll_offset =
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index 2128f27..75c61e8 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -67,6 +67,62 @@
             controller_impl->GetAnimationById(animation_id)->run_state());
 }
 
+TEST(LayerAnimationControllerTest,
+     SyncScrollOffsetAnimationRespectsHasSetInitialValue) {
+  FakeLayerAnimationValueObserver dummy_impl;
+  FakeLayerAnimationValueProvider dummy_provider_impl;
+  scoped_refptr<LayerAnimationController> controller_impl(
+      LayerAnimationController::Create(0));
+  controller_impl->AddValueObserver(&dummy_impl);
+  controller_impl->set_value_provider(&dummy_provider_impl);
+  FakeLayerAnimationValueObserver dummy;
+  FakeLayerAnimationValueProvider dummy_provider;
+  scoped_refptr<LayerAnimationController> controller(
+      LayerAnimationController::Create(0));
+  controller->AddValueObserver(&dummy);
+  controller->set_value_provider(&dummy_provider);
+
+  EXPECT_FALSE(controller_impl->GetAnimation(Animation::SCROLL_OFFSET));
+
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
+  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
+
+  gfx::ScrollOffset initial_value(100.f, 300.f);
+  gfx::ScrollOffset provider_initial_value(150.f, 300.f);
+  gfx::ScrollOffset target_value(300.f, 200.f);
+
+  dummy_provider_impl.set_scroll_offset(provider_initial_value);
+
+  // Animation with initial value set.
+  scoped_ptr<ScrollOffsetAnimationCurve> curve_fixed(
+      ScrollOffsetAnimationCurve::Create(target_value,
+                                         EaseInOutTimingFunction::Create()));
+  curve_fixed->SetInitialValue(initial_value);
+  scoped_ptr<Animation> animation_fixed(
+      Animation::Create(std::move(curve_fixed), 1 /* animation_id */, 0,
+                        Animation::SCROLL_OFFSET));
+  controller->AddAnimation(std::move(animation_fixed));
+  controller->PushAnimationUpdatesTo(controller_impl.get());
+  EXPECT_VECTOR2DF_EQ(initial_value, controller_impl->GetAnimationById(1)
+                                         ->curve()
+                                         ->ToScrollOffsetAnimationCurve()
+                                         ->GetValue(base::TimeDelta()));
+
+  // Animation without initial value set.
+  scoped_ptr<ScrollOffsetAnimationCurve> curve(
+      ScrollOffsetAnimationCurve::Create(target_value,
+                                         EaseInOutTimingFunction::Create()));
+  scoped_ptr<Animation> animation(Animation::Create(
+      std::move(curve), 2 /* animation id */, 0, Animation::SCROLL_OFFSET));
+  controller->AddAnimation(std::move(animation));
+  controller->PushAnimationUpdatesTo(controller_impl.get());
+  EXPECT_VECTOR2DF_EQ(provider_initial_value,
+                      controller_impl->GetAnimationById(2)
+                          ->curve()
+                          ->ToScrollOffsetAnimationCurve()
+                          ->GetValue(base::TimeDelta()));
+}
+
 // If an animation is started on the impl thread before it is ticked on the main
 // thread, we must be sure to respect the synchronized start time.
 TEST(LayerAnimationControllerTest, DoNotClobberStartTimes) {
diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc
index bb8d712..6cd823f 100644
--- a/cc/animation/scroll_offset_animation_curve.cc
+++ b/cc/animation/scroll_offset_animation_curve.cc
@@ -69,17 +69,23 @@
     DurationBehavior duration_behavior)
     : target_value_(target_value),
       timing_function_(std::move(timing_function)),
-      duration_behavior_(duration_behavior) {}
+      duration_behavior_(duration_behavior),
+      has_set_initial_value_(false) {}
 
 ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() {}
 
 void ScrollOffsetAnimationCurve::SetInitialValue(
     const gfx::ScrollOffset& initial_value) {
   initial_value_ = initial_value;
+  has_set_initial_value_ = true;
   total_animation_duration_ = SegmentDuration(
       target_value_.DeltaFrom(initial_value_), duration_behavior_);
 }
 
+bool ScrollOffsetAnimationCurve::HasSetInitialValue() const {
+  return has_set_initial_value_;
+}
+
 gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
     base::TimeDelta t) const {
   base::TimeDelta duration = total_animation_duration_ - last_retarget_;
@@ -115,6 +121,7 @@
   curve_clone->initial_value_ = initial_value_;
   curve_clone->total_animation_duration_ = total_animation_duration_;
   curve_clone->last_retarget_ = last_retarget_;
+  curve_clone->has_set_initial_value_ = has_set_initial_value_;
   return std::move(curve_clone);
 }
 
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h
index 4c43a20..95f3d9f5 100644
--- a/cc/animation/scroll_offset_animation_curve.h
+++ b/cc/animation/scroll_offset_animation_curve.h
@@ -26,6 +26,7 @@
   ~ScrollOffsetAnimationCurve() override;
 
   void SetInitialValue(const gfx::ScrollOffset& initial_value);
+  bool HasSetInitialValue() const;
   gfx::ScrollOffset GetValue(base::TimeDelta t) const;
   gfx::ScrollOffset target_value() const { return target_value_; }
   void UpdateTarget(double t, const gfx::ScrollOffset& new_target);
@@ -50,6 +51,8 @@
   scoped_ptr<TimingFunction> timing_function_;
   DurationBehavior duration_behavior_;
 
+  bool has_set_initial_value_;
+
   DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimationCurve);
 };
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 38e2fd6..ff8ffc08 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=49
 MINOR=0
-BUILD=2584
+BUILD=2585
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java
index 4f4cbc24..98c4d2c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java
@@ -39,6 +39,7 @@
 
     @Override
     public View getView() {
+        assert false;
         return null;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 84c53ae..10097b49 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -182,8 +182,8 @@
     /** Listens to gesture events fired by the ContentViewCore. */
     private GestureStateListener mGestureStateListener;
 
-    /** The parent view of the ContentView, NativePage's view and the InfoBarContainer. */
-    private FrameLayout mTabView;
+    /** The parent view of the ContentView and the InfoBarContainer. */
+    private FrameLayout mContentViewParent;
 
     /** A list of Tab observers.  These are used to broadcast Tab events to listeners. */
     private final ObserverList<TabObserver> mObservers = new ObserverList<TabObserver>();
@@ -780,7 +780,7 @@
      *         This can be {@code null}, if the tab is frozen or being initialized or destroyed.
      */
     public View getView() {
-        return mTabView;
+        return mNativePage != null ? mNativePage.getView() : mContentViewParent;
     }
 
     /**
@@ -1200,13 +1200,8 @@
      */
     private void showNativePage(NativePage nativePage) {
         if (mNativePage == nativePage) return;
-        destroyNativePage();
+        NativePage previousNativePage = mNativePage;
         mNativePage = nativePage;
-
-        mTabView.addView(nativePage.getView(),
-                mTabView.indexOfChild(mContentViewCore.getContainerView()) + 1,
-                new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-
         pushNativePageStateToNavigationEntry();
         // Notifying of theme color change before content change because some of
         // the observers depend on the theme information being correct in
@@ -1217,6 +1212,7 @@
         for (TabObserver observer : mObservers) {
             observer.onContentChanged(this);
         }
+        destroyNativePageInternal(previousNativePage);
     }
 
     /**
@@ -1225,8 +1221,7 @@
      */
     public void freezeNativePage() {
         if (mNativePage == null || mNativePage instanceof FrozenNativePage) return;
-        assert mNativePage.getView().getWindowToken() == null : "Cannot freeze visible native page";
-        mTabView.removeView(mNativePage.getView());
+        assert mNativePage.getView().getParent() == null : "Cannot freeze visible native page";
         mNativePage = FrozenNativePage.freeze(mNativePage);
     }
 
@@ -1237,9 +1232,10 @@
         updateTitle();
 
         if (mNativePage == null) return;
-        destroyNativePage();
+        NativePage previousNativePage = mNativePage;
+        mNativePage = null;
         for (TabObserver observer : mObservers) observer.onContentChanged(this);
-
+        destroyNativePageInternal(previousNativePage);
     }
 
     /**
@@ -1507,7 +1503,9 @@
     private void setContentViewCore(ContentViewCore cvc) {
         try {
             TraceEvent.begin("ChromeTab.setContentViewCore");
-            destroyNativePage();
+            NativePage previousNativePage = mNativePage;
+            mNativePage = null;
+            destroyNativePageInternal(previousNativePage);
 
             mContentViewCore = cvc;
             cvc.getContainerView().setOnHierarchyChangeListener(this);
@@ -1518,12 +1516,12 @@
             // ContentView -- causes problems since then the ContentView would contain both real
             // views (the infobars) and virtual views (the web page elements), which breaks Android
             // accessibility. http://crbug.com/416663
-            if (mTabView != null) {
+            if (mContentViewParent != null) {
                 assert false;
-                mTabView.removeAllViews();
+                mContentViewParent.removeAllViews();
             }
-            mTabView = new FrameLayout(mThemedApplicationContext);
-            mTabView.addView(cvc.getContainerView(),
+            mContentViewParent = new FrameLayout(mThemedApplicationContext);
+            mContentViewParent.addView(cvc.getContainerView(),
                     new FrameLayout.LayoutParams(
                             LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 
@@ -1547,9 +1545,9 @@
                 // The InfoBarContainer needs to be created after the ContentView has been natively
                 // initialized.
                 mInfoBarContainer =  new InfoBarContainer(
-                        mThemedApplicationContext, getId(), mTabView, this);
+                        mThemedApplicationContext, getId(), mContentViewParent, this);
             } else {
-                mInfoBarContainer.onParentViewChanged(getId(), mTabView);
+                mInfoBarContainer.onParentViewChanged(getId(), mContentViewParent);
             }
             mInfoBarContainer.setContentViewCore(mContentViewCore);
 
@@ -1694,7 +1692,9 @@
         for (TabObserver observer : mObservers) observer.onDestroyed(this);
         mObservers.clear();
 
-        destroyNativePage();
+        NativePage currentNativePage = mNativePage;
+        mNativePage = null;
+        destroyNativePageInternal(currentNativePage);
         destroyContentViewCore(true);
 
         // Destroys the native tab after destroying the ContentView but before destroying the
@@ -2013,12 +2013,11 @@
         mGroupedWithParent = groupedWithParent;
     }
 
-    private void destroyNativePage() {
-        if (mNativePage == null) return;
-        if (mTabView != null) mTabView.removeView(mNativePage.getView());
+    private void destroyNativePageInternal(NativePage nativePage) {
+        if (nativePage == null) return;
+        assert nativePage != mNativePage : "Attempting to destroy active page.";
 
-        mNativePage.destroy();
-        mNativePage = null;
+        nativePage.destroy();
     }
 
     /**
@@ -2050,7 +2049,7 @@
             mSwipeRefreshHandler.setContentViewCore(null);
             mSwipeRefreshHandler = null;
         }
-        mTabView = null;
+        mContentViewParent = null;
         mContentViewCore.destroy();
         mContentViewCore = null;
 
@@ -2163,6 +2162,8 @@
             mContentViewCore.onHide();
         }
         destroyContentViewCore(deleteOldNativeWebContents);
+        NativePage previousNativePage = mNativePage;
+        mNativePage = null;
         setContentViewCore(newContentViewCore);
         // Size of the new ContentViewCore is zero at this point. If we don't call onSizeChanged(),
         // next onShow() call would send a resize message with the current ContentViewCore size
@@ -2172,6 +2173,7 @@
         mContentViewCore.onSizeChanged(originalWidth, originalHeight, 0, 0);
         mContentViewCore.onShow();
         mContentViewCore.attachImeAdapter();
+        destroyNativePageInternal(previousNativePage);
         mWebContentsObserver.didChangeThemeColor(
                 getWebContents().getThemeColor(mDefaultThemeColor));
         for (TabObserver observer : mObservers) {
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index d595568..0432431 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -224,8 +224,16 @@
       <message name="IDS_ABOUT_TERMS_OF_SERVICE" desc="The terms of service label in the About box.">
         Not used in Chromium. Placeholder to keep resource maps in sync. It expects one argument: $1.
       </message>
+      <if expr="is_linux and not chromeos">
+        <!-- These messages are not actually used, but they are here as placeholders to match the Chrome messages. -->
+        <message name="IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is about to become unsupported.">
+          Future versions of Chromium will no longer support this Linux system.
+        </message>
+        <message name="IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
+          Chromium may not function correctly because it is no longer supported on this Linux system.
+        </message>
+      </if>
       <if expr="is_macosx">
-        <!-- Mac 32-bit deprecation -->
         <message name="IDS_MAC_10_678_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is about to become unsupported.">
           Future versions of Chromium will no longer support Mac OS X 10.6, 10.7, or 10.8.
         </message>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 1bce2212..5fe43fd 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -226,8 +226,15 @@
       <message name="IDS_ABOUT_TERMS_OF_SERVICE" desc="The terms of service label in the About box.">
         Google Chrome <ph name="TERMS_OF_SERVICE_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Terms of Service<ph name="END_TERMS_OF_SERVICE_LINK">&lt;/a&gt;</ph>
       </message>
+      <if expr="is_linux and not chromeos">
+        <message name="IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is about to become unsupported.">
+          This computer will soon stop receiving Google Chrome updates because this Linux system will no longer be supported.
+        </message>
+        <message name="IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
+          This computer will no longer receive Google Chrome updates because this Linux system is no longer supported.
+        </message>
+      </if>
       <if expr="is_macosx">
-        <!-- Mac 32-bit deprecation -->
         <message name="IDS_MAC_10_678_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is about to become unsupported.">
           This computer will soon stop receiving Google Chrome updates because Mac OS X 10.6, 10.7, and 10.8 will no longer be supported.
         </message>
diff --git a/chrome/browser/chromeos/system_logs/debug_log_writer.cc b/chrome/browser/chromeos/system_logs/debug_log_writer.cc
index 1c2b089..032b1ebf 100644
--- a/chrome/browser/chromeos/system_logs/debug_log_writer.cc
+++ b/chrome/browser/chromeos/system_logs/debug_log_writer.cc
@@ -122,8 +122,8 @@
         content::BrowserThread::UI,
         FROM_HERE,
         base::Bind(callback, base::FilePath(), false));
-    base::DeleteFile(tar_file_path, true);
-    base::DeleteFile(compressed_output_path, true);
+    base::DeleteFile(tar_file_path, false);
+    base::DeleteFile(compressed_output_path, false);
     return;
   }
 
@@ -144,7 +144,7 @@
         content::BrowserThread::UI,
         FROM_HERE,
         base::Bind(callback, base::FilePath(), false));
-    base::DeleteFile(tar_file_path, true);
+    base::DeleteFile(tar_file_path, false);
     return;
   }
 
diff --git a/chrome/browser/devtools/devtools_network_transaction.cc b/chrome/browser/devtools/devtools_network_transaction.cc
index a2e6b78f..655248f6 100644
--- a/chrome/browser/devtools/devtools_network_transaction.cc
+++ b/chrome/browser/devtools/devtools_network_transaction.cc
@@ -256,6 +256,11 @@
   return network_transaction_->GetRemoteEndpoint(endpoint);
 }
 
+void DevToolsNetworkTransaction::PopulateNetErrorDetails(
+    net::NetErrorDetails* details) const {
+  return network_transaction_->PopulateNetErrorDetails(details);
+}
+
 void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) {
   network_transaction_->SetPriority(priority);
 }
diff --git a/chrome/browser/devtools/devtools_network_transaction.h b/chrome/browser/devtools/devtools_network_transaction.h
index bb83ce0..6bd3a15 100644
--- a/chrome/browser/devtools/devtools_network_transaction.h
+++ b/chrome/browser/devtools/devtools_network_transaction.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/devtools/devtools_network_interceptor.h"
 #include "net/base/completion_callback.h"
 #include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_transaction.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
@@ -79,6 +80,7 @@
   void SetQuicServerInfo(net::QuicServerInfo* quic_server_info) override;
   bool GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
   bool GetRemoteEndpoint(net::IPEndPoint* endpoint) const override;
+  void PopulateNetErrorDetails(net::NetErrorDetails* details) const override;
   void SetPriority(net::RequestPriority priority) override;
   void SetWebSocketHandshakeStreamCreateHelper(
       net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 4d48d78..7b0e9be 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -793,7 +793,7 @@
     EXPECT_TRUE(VerifyFile(download_path, expected_contents, file_size));
 
     // Delete the file we just downloaded.
-    EXPECT_TRUE(base::DieFileDie(download_path, true));
+    EXPECT_TRUE(base::DieFileDie(download_path, false));
     EXPECT_FALSE(base::PathExists(download_path));
 
     return true;
diff --git a/chrome/browser/obsolete_system/obsolete_system_linux.cc b/chrome/browser/obsolete_system/obsolete_system_linux.cc
index 10d94a57..9d56d40 100644
--- a/chrome/browser/obsolete_system/obsolete_system_linux.cc
+++ b/chrome/browser/obsolete_system/obsolete_system_linux.cc
@@ -4,14 +4,48 @@
 
 #include "chrome/browser/obsolete_system/obsolete_system.h"
 
+#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
+#include <gnu/libc-version.h>
+
+#include "base/version.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#endif
+
 // static
 bool ObsoleteSystem::IsObsoleteNowOrSoon() {
+#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
+#if defined(ARCH_CPU_32_BITS)
+  return true;
+#else
+  // Ubuntu 14.04 will be used as the next build platform, and it ships with
+  // glibc 2.19, so check for that as the minimum requirement.
+  Version version(gnu_get_libc_version());
+  if (!version.IsValid() || version.components().size() != 2)
+    return false;
+
+  uint32_t glibc_major_version = version.components()[0];
+  uint32_t glibc_minor_version = version.components()[1];
+  if (glibc_major_version < 2)
+    return true;
+
+  return glibc_major_version == 2 && glibc_minor_version < 19;
+#endif  // defined(ARCH_CPU_32_BITS)
+#else
   return false;
+#endif  // defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
 }
 
 // static
 base::string16 ObsoleteSystem::LocalizedObsoleteString() {
+#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
+  return l10n_util::GetStringUTF16(
+      IsEndOfTheLine() ? IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_NOW
+                       : IDS_LINUX_WHEEZY_PRECISE_OBSOLETE_SOON);
+#else
   return base::string16();
+#endif
 }
 
 // static
@@ -21,5 +55,9 @@
 
 // static
 const char* ObsoleteSystem::GetLinkURL() {
+#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
+  return chrome::kLinuxWheezyPreciseDeprecationURL;
+#else
   return "";
+#endif
 }
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index cd1f8689..eb1aa448 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -609,7 +609,7 @@
   // Clean up.
   EXPECT_NE(std::string::npos, icon_path.MaybeAsASCII().find(file_name));
   EXPECT_TRUE(base::PathExists(icon_path));
-  EXPECT_TRUE(base::DeleteFile(icon_path, true));
+  EXPECT_TRUE(base::DeleteFile(icon_path, false));
   EXPECT_FALSE(base::PathExists(icon_path));
 }
 
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index e334815..6f16ae9 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -4,7 +4,8 @@
 
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 
-#include "base/command_line.h"
+#include <utility>
+
 #include "base/memory/singleton.h"
 #include "base/time/time.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
-#include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/signin/about_signin_internals_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
@@ -134,7 +134,7 @@
 
 KeyedService* ProfileSyncServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
-  Profile* profile = static_cast<Profile*>(context);
+  Profile* profile = Profile::FromBrowserContext(context);
 
   SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
 
@@ -162,10 +162,12 @@
   browser_sync::ProfileSyncServiceStartBehavior behavior =
       browser_defaults::kSyncAutoStarts ? browser_sync::AUTO_START
                                         : browser_sync::MANUAL_START;
-  browser_sync::ChromeSyncClient* chrome_sync_client =
-      new browser_sync::ChromeSyncClient(profile);
-  ProfileSyncService* pss = new ProfileSyncService(
-      make_scoped_ptr(chrome_sync_client), signin_wrapper.Pass(), token_service,
+
+  auto chrome_sync_client =
+      make_scoped_ptr(new browser_sync::ChromeSyncClient(profile));
+
+  auto pss = make_scoped_ptr(new ProfileSyncService(
+      std::move(chrome_sync_client), std::move(signin_wrapper), token_service,
       behavior, base::Bind(&UpdateNetworkTime), profile->GetPath(),
       profile->GetRequestContext(), profile->GetDebugName(),
       chrome::GetChannel(),
@@ -173,11 +175,11 @@
           content::BrowserThread::DB),
       content::BrowserThread::GetMessageLoopProxyForThread(
           content::BrowserThread::FILE),
-      content::BrowserThread::GetBlockingPool());
+      content::BrowserThread::GetBlockingPool()));
 
   // Will also initialize the sync client.
   pss->Initialize();
-  return pss;
+  return pss.release();
 }
 
 // static
diff --git a/chrome/browser/sync/profile_sync_service_factory.h b/chrome/browser/sync/profile_sync_service_factory.h
index 4fec18d..31d0c4d 100644
--- a/chrome/browser/sync/profile_sync_service_factory.h
+++ b/chrome/browser/sync/profile_sync_service_factory.h
@@ -5,10 +5,14 @@
 #ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
 #define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
 
-#include "base/compiler_specific.h"
-#include "base/memory/singleton.h"
+#include "base/macros.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
 namespace sync_driver {
 class SyncService;
 }
@@ -37,6 +41,8 @@
   // BrowserContextKeyedServiceFactory:
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceFactory);
 };
 
 #endif  // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 99a662e..384fc7c 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -747,6 +747,11 @@
     "https://support.google.com/chrome/topic/1678461";
 #endif
 
+#if defined(GOOGLE_CHROME_BUILD) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
+const char kLinuxWheezyPreciseDeprecationURL[] =
+    "https://support.google.com/chrome/answer/95346";
+#endif
+
 #if defined(OS_MACOSX)
 // TODO(mark): Change to a Help Center URL when one is available.
 // https://crbug.com/555044
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 7f471c8..f9e9184d5 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -556,6 +556,10 @@
 // The URL for the "Learn more" link in the language settings.
 extern const char kLanguageSettingsLearnMoreUrl[];
 
+#if defined(GOOGLE_CHROME_BUILD) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
+extern const char kLinuxWheezyPreciseDeprecationURL[];
+#endif
+
 #if defined(OS_MACOSX)
 // The URL for the Mac OS X 10.6/10.7/10.8 deprecation help center article.
 extern const char kMac10_678_DeprecationURL[];
diff --git a/chrome/installer/util/copy_tree_work_item_unittest.cc b/chrome/installer/util/copy_tree_work_item_unittest.cc
index 35cc3af..5d7a5e0 100644
--- a/chrome/installer/util/copy_tree_work_item_unittest.cc
+++ b/chrome/installer/util/copy_tree_work_item_unittest.cc
@@ -560,7 +560,7 @@
   EXPECT_FALSE(base::PathExists(backup_file));
 
   // Now delete the destination and try copying the file again.
-  base::DeleteFile(file_name_to, true);
+  base::DeleteFile(file_name_to, false);
   work_item.reset(WorkItem::CreateCopyTreeWorkItem(
       file_name_from, file_name_to,
       temp_dir_.path(), WorkItem::IF_NOT_PRESENT,
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.cc b/chrome/test/chromedriver/chrome/stub_web_view.cc
index 57df23f..0af2fab 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.cc
+++ b/chrome/test/chromedriver/chrome/stub_web_view.cc
@@ -28,6 +28,10 @@
   return Status(kOk);
 }
 
+Status StubWebView::GetUrl(std::string* url) {
+  return Status(kOk);
+}
+
 Status StubWebView::Load(const std::string& url) {
   return Status(kOk);
 }
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.h b/chrome/test/chromedriver/chrome/stub_web_view.h
index 1d85eb6..5b52c0b 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.h
+++ b/chrome/test/chromedriver/chrome/stub_web_view.h
@@ -22,6 +22,7 @@
   bool WasCrashed() override;
   Status ConnectIfNecessary() override;
   Status HandleReceivedEvents() override;
+  Status GetUrl(std::string* url) override;
   Status Load(const std::string& url) override;
   Status Reload() override;
   Status TraverseHistory(int delta) override;
diff --git a/chrome/test/chromedriver/chrome/web_view.h b/chrome/test/chromedriver/chrome/web_view.h
index f184e92..e9a78ee 100644
--- a/chrome/test/chromedriver/chrome/web_view.h
+++ b/chrome/test/chromedriver/chrome/web_view.h
@@ -44,6 +44,9 @@
   // Handles events that have been received but not yet handled.
   virtual Status HandleReceivedEvents() = 0;
 
+  // Get the current URL of the main frame.
+  virtual Status GetUrl(std::string* url) = 0;
+
   // Load a given URL in the main frame.
   virtual Status Load(const std::string& url) = 0;
 
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index 0c37a571..8f2aaf3 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -152,6 +152,27 @@
   return client_->HandleReceivedEvents();
 }
 
+Status WebViewImpl::GetUrl(std::string* url) {
+  base::DictionaryValue params;
+  scoped_ptr<base::DictionaryValue> result;
+  Status status = client_->SendCommandAndGetResult(
+      "Page.getNavigationHistory", params, &result);
+  if (status.IsError())
+    return status;
+  int current_index = 0;
+  if (!result->GetInteger("currentIndex", &current_index))
+    return Status(kUnknownError, "navigation history missing currentIndex");
+  base::ListValue* entries = nullptr;
+  if (!result->GetList("entries", &entries))
+    return Status(kUnknownError, "navigation history missing entries");
+  base::DictionaryValue* entry = nullptr;
+  if (!entries->GetDictionary(current_index, &entry))
+    return Status(kUnknownError, "navigation history missing entry");
+  if (!entry->GetString("url", url))
+    return Status(kUnknownError, "navigation history entry is missing url");
+  return Status(kOk);
+}
+
 Status WebViewImpl::Load(const std::string& url) {
   // Javascript URLs will cause a hang while waiting for the page to stop
   // loading, so just disallow.
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h
index dd04538..ba639b7 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.h
+++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -50,6 +50,7 @@
   bool WasCrashed() override;
   Status ConnectIfNecessary() override;
   Status HandleReceivedEvents() override;
+  Status GetUrl(std::string* url) override;
   Status Load(const std::string& url) override;
   Status Reload() override;
   Status TraverseHistory(int delta) override;
diff --git a/chrome/test/chromedriver/js/call_function.js b/chrome/test/chromedriver/js/call_function.js
index ab1551b..17a0ae5 100644
--- a/chrome/test/chromedriver/js/call_function.js
+++ b/chrome/test/chromedriver/js/call_function.js
@@ -149,7 +149,7 @@
  * @return {*} The wrapped value.
  */
 function wrap(value) {
-  if (typeof(value) == 'object' && value != null) {
+  if (value instanceof Object && value != null) {
     var nodeType = value['nodeType'];
     if (nodeType == NodeType.ELEMENT || nodeType == NodeType.DOCUMENT
         || (SHADOW_DOM_ENABLED && value instanceof ShadowRoot)) {
@@ -176,7 +176,7 @@
  * @return {*} The unwrapped value.
  */
 function unwrap(value, cache) {
-  if (typeof(value) == 'object' && value != null) {
+  if (value instanceof Object && value != null) {
     if (ELEMENT_KEY in value)
       return cache.retrieveItem(value[ELEMENT_KEY]);
 
diff --git a/chrome/test/chromedriver/net/websocket.cc b/chrome/test/chromedriver/net/websocket.cc
index d62f7fb..9b1ed93 100644
--- a/chrome/test/chromedriver/net/websocket.cc
+++ b/chrome/test/chromedriver/net/websocket.cc
@@ -5,11 +5,12 @@
 #include "chrome/test/chromedriver/net/websocket.h"
 
 #include <string.h>
+#include <vector>
 
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/rand_util.h"
 #include "base/sha1.h"
 #include "base/strings/string_number_conversions.h"
@@ -232,7 +233,7 @@
 }
 
 void WebSocket::OnReadDuringOpen(const char* data, int len) {
-  ScopedVector<net::WebSocketFrameChunk> frame_chunks;
+  std::vector<scoped_ptr<net::WebSocketFrameChunk>> frame_chunks;
   CHECK(parser_.Decode(data, len, &frame_chunks));
   for (size_t i = 0; i < frame_chunks.size(); ++i) {
     scoped_refptr<net::IOBufferWithSize> buffer = frame_chunks[i]->data;
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 924b12f5..277395c 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -60,6 +60,8 @@
 _VERSION_SPECIFIC_FILTER['HEAD'] = [
     # https://code.google.com/p/chromedriver/issues/detail?id=992
     'ChromeDownloadDirTest.testDownloadDirectoryOverridesExistingPreferences',
+    # https://code.google.com/p/chromedriver/issues/detail?id=1278
+    #'ChromeDownloadDirTest.testFileDownloadWithGet',
 ]
 _VERSION_SPECIFIC_FILTER['44'] = [
     # https://code.google.com/p/chromedriver/issues/detail?id=1202
@@ -1190,6 +1192,14 @@
       else:
         self.fail('unexpected cookie: %s' % json.dumps(cookie))
 
+  def testGetUrlOnInvalidUrl(self):
+    # Make sure we don't return 'data:text/html,chromewebdata' (see
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1272). RFC 6761
+    # requires domain registrars to keep 'invalid.' unregistered (see
+    # https://tools.ietf.org/html/rfc6761#section-6.4).
+    self._driver.Load('http://invalid./')
+    self.assertEquals('http://invalid./', self._driver.GetCurrentUrl())
+
 
 class ChromeDriverAndroidTest(ChromeDriverBaseTest):
   """End to end tests for Android-specific tests."""
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 493cc48..55e3839 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -32,6 +32,8 @@
 
 namespace {
 
+const std::string kUnreachableWebDataURL = "data:text/html,chromewebdata";
+
 Status GetMouseButton(const base::DictionaryValue& params,
                       MouseButton* button) {
   int button_num;
@@ -449,12 +451,27 @@
   Status status = GetUrl(web_view, std::string(), &url);
   if (status.IsError())
     return status;
+  if (url == kUnreachableWebDataURL) {
+    // https://bugs.chromium.org/p/chromedriver/issues/detail?id=1272
+    const BrowserInfo* browser_info = session->chrome->GetBrowserInfo();
+    bool is_kitkat_webview = browser_info->browser_name == "webview" &&
+                             browser_info->major_version <= 30 &&
+                             browser_info->is_android;
+    if (!is_kitkat_webview) {
+      // Page.getNavigationHistory isn't implemented in WebView for KitKat and
+      // older Android releases.
+      status = web_view->GetUrl(&url);
+      if (status.IsError())
+        return status;
+    }
+  }
   if (!session->GetCurrentFrameId().empty()) {
     // TODO(samuong): remove this after we release ChromeDriver 2.21.
-    LOG(WARNING) << "As of ChromeDriver 2.21, GetCurrentUrl now returns the "
-                    "URL of the top-level browsing, not the current frame. See "
-                    "https://code.google.com/p/chromedriver/issues/"
-                    "detail?id=1249 for details and workarounds.";
+    LOG(WARNING)
+        << "As of ChromeDriver 2.21, GetCurrentUrl now returns the "
+           "URL of the top-level browsing context, not the current frame. "
+           "See https://code.google.com/p/chromedriver/issues/detail?id=1249 "
+           "for details and workarounds.";
   }
   value->reset(new base::StringValue(url));
   return Status(kOk);
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 8d7cfda..5a48217e 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-7703.0.0
\ No newline at end of file
+7710.0.0
\ No newline at end of file
diff --git a/components/mus/gles2/command_buffer_driver.cc b/components/mus/gles2/command_buffer_driver.cc
index 2157ef790..2ef83e1 100644
--- a/components/mus/gles2/command_buffer_driver.cc
+++ b/components/mus/gles2/command_buffer_driver.cc
@@ -9,7 +9,6 @@
 #include "base/macros.h"
 #include "base/memory/shared_memory.h"
 #include "base/process/process_handle.h"
-#include "components/mus/gles2/command_buffer_type_conversions.h"
 #include "components/mus/gles2/gpu_memory_tracker.h"
 #include "components/mus/gles2/gpu_state.h"
 #include "components/mus/gles2/mojo_buffer_backing.h"
@@ -54,22 +53,13 @@
   DestroyDecoder();
 }
 
-void CommandBufferDriver::Initialize(
-    mojo::InterfacePtrInfo<mojom::CommandBufferSyncClient> sync_client,
+bool CommandBufferDriver::Initialize(
     mojo::InterfacePtrInfo<mojom::CommandBufferLostContextObserver>
         loss_observer,
     mojo::ScopedSharedBufferHandle shared_state,
     mojo::Array<int32_t> attribs) {
-  sync_client_ = mojo::MakeProxy(sync_client.Pass());
   loss_observer_ = mojo::MakeProxy(loss_observer.Pass());
-  bool success = DoInitialize(shared_state.Pass(), attribs.Pass());
-  mojom::GpuCapabilitiesPtr capabilities =
-      success ? mojom::GpuCapabilities::From(decoder_->GetCapabilities())
-              : nullptr;
-  sync_client_->DidInitialize(success,
-                              gpu::CommandBufferNamespace::MOJO,
-                              command_buffer_id_,
-                              capabilities.Pass());
+  return DoInitialize(shared_state.Pass(), attribs.Pass());
 }
 
 bool CommandBufferDriver::MakeCurrent() {
@@ -128,8 +118,7 @@
                                          decoder_.get()));
   sync_point_order_data_ = gpu::SyncPointOrderData::Create();
   sync_point_client_ = gpu_state_->sync_point_manager()->CreateSyncPointClient(
-      sync_point_order_data_, gpu::CommandBufferNamespace::MOJO,
-      command_buffer_id_);
+      sync_point_order_data_, GetNamespaceID(), command_buffer_id_);
   decoder_->set_engine(scheduler_.get());
   decoder_->SetWaitSyncPointCallback(base::Bind(
       &CommandBufferDriver::OnWaitSyncPoint, base::Unretained(this)));
@@ -181,12 +170,6 @@
   command_buffer_->Flush(put_offset);
 }
 
-void CommandBufferDriver::MakeProgress(int32_t last_get_offset) {
-  // TODO(piman): handle out-of-order.
-  sync_client_->DidMakeProgress(
-      mojom::CommandBufferState::From(command_buffer_->GetLastState()));
-}
-
 void CommandBufferDriver::RegisterTransferBuffer(
     int32_t id,
     mojo::ScopedSharedBufferHandle transfer_buffer,
@@ -298,6 +281,14 @@
   return false;
 }
 
+gpu::Capabilities CommandBufferDriver::GetCapabilities() {
+  return decoder_->GetCapabilities();
+}
+
+gpu::CommandBuffer::State CommandBufferDriver::GetLastState() {
+  return command_buffer_->GetLastState();
+}
+
 void CommandBufferDriver::OnParseError() {
   gpu::CommandBuffer::State state = command_buffer_->GetLastState();
   OnContextLost(state.context_lost_reason);
diff --git a/components/mus/gles2/command_buffer_driver.h b/components/mus/gles2/command_buffer_driver.h
index e0e5a7fa..2ac36e5a 100644
--- a/components/mus/gles2/command_buffer_driver.h
+++ b/components/mus/gles2/command_buffer_driver.h
@@ -10,8 +10,9 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
-#include "base/timer/timer.h"
 #include "components/mus/public/interfaces/command_buffer.mojom.h"
+#include "gpu/command_buffer/common/capabilities.h"
+#include "gpu/command_buffer/common/command_buffer.h"
 #include "gpu/command_buffer/common/constants.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -50,15 +51,12 @@
 
   void set_client(scoped_ptr<Client> client) { client_ = client.Pass(); }
 
-  void Initialize(
-      mojo::InterfacePtrInfo<mojom::CommandBufferSyncClient> sync_client,
-      mojo::InterfacePtrInfo<mojom::CommandBufferLostContextObserver>
-          loss_observer,
-      mojo::ScopedSharedBufferHandle shared_state,
-      mojo::Array<int32_t> attribs);
+  bool Initialize(mojo::InterfacePtrInfo<
+                      mojom::CommandBufferLostContextObserver> loss_observer,
+                  mojo::ScopedSharedBufferHandle shared_state,
+                  mojo::Array<int32_t> attribs);
   void SetGetBuffer(int32_t buffer);
   void Flush(int32_t put_offset);
-  void MakeProgress(int32_t last_get_offset);
   void RegisterTransferBuffer(int32_t id,
                               mojo::ScopedSharedBufferHandle transfer_buffer,
                               uint32_t size);
@@ -72,6 +70,12 @@
   void DestroyImage(int32_t id);
   bool IsScheduled() const;
   bool HasUnprocessedCommands() const;
+  gpu::Capabilities GetCapabilities();
+  gpu::CommandBuffer::State GetLastState();
+  gpu::CommandBufferNamespace GetNamespaceID() const {
+    return gpu::CommandBufferNamespace::MOJO;
+  }
+  uint64_t GetCommandBufferID() const { return command_buffer_id_; }
   gpu::SyncPointOrderData* sync_point_order_data() {
     return sync_point_order_data_.get();
   }
@@ -92,7 +96,6 @@
 
   const uint64_t command_buffer_id_;
   scoped_ptr<Client> client_;
-  mojom::CommandBufferSyncClientPtr sync_client_;
   mojom::CommandBufferLostContextObserverPtr loss_observer_;
   scoped_ptr<gpu::CommandBufferService> command_buffer_;
   scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
diff --git a/components/mus/gles2/command_buffer_impl.cc b/components/mus/gles2/command_buffer_impl.cc
index fb64244..d33be7d6 100644
--- a/components/mus/gles2/command_buffer_impl.cc
+++ b/components/mus/gles2/command_buffer_impl.cc
@@ -8,6 +8,7 @@
 #include "base/message_loop/message_loop.h"
 #include "components/mus/gles2/command_buffer_driver.h"
 #include "components/mus/gles2/command_buffer_impl_observer.h"
+#include "components/mus/gles2/command_buffer_type_conversions.h"
 #include "components/mus/gles2/gpu_state.h"
 #include "gpu/command_buffer/service/sync_point_manager.h"
 
@@ -15,8 +16,16 @@
 
 namespace {
 
-void RunCallback(const mojo::Callback<void()>& callback) {
-  callback.Run();
+void RunInitializeCallback(
+    const mojom::CommandBuffer::InitializeCallback& callback,
+    mojom::CommandBufferInfoPtr info) {
+  callback.Run(std::move(info));
+}
+
+void RunMakeProgressCallback(
+    const mojom::CommandBuffer::MakeProgressCallback& callback,
+    mojom::CommandBufferStatePtr state) {
+  callback.Run(std::move(state));
 }
 
 }  // namespace
@@ -40,7 +49,7 @@
     scoped_refptr<GpuState> gpu_state,
     scoped_ptr<CommandBufferDriver> driver)
     : gpu_state_(gpu_state),
-      driver_(driver.Pass()),
+      driver_(std::move(driver)),
       observer_(nullptr),
       weak_ptr_factory_(this) {
   driver_->set_client(make_scoped_ptr(new CommandBufferDriverClientImpl(this)));
@@ -61,19 +70,16 @@
 }
 
 void CommandBufferImpl::Initialize(
-    mus::mojom::CommandBufferSyncClientPtr sync_client,
-    mus::mojom::CommandBufferSyncPointClientPtr sync_point_client,
     mus::mojom::CommandBufferLostContextObserverPtr loss_observer,
     mojo::ScopedSharedBufferHandle shared_state,
-    mojo::Array<int32_t> attribs) {
-  sync_point_client_ = sync_point_client.Pass();
+    mojo::Array<int32_t> attribs,
+    const mojom::CommandBuffer::InitializeCallback& callback) {
   gpu_state_->command_buffer_task_runner()->PostTask(
       driver_.get(),
-      base::Bind(&CommandBufferImpl::InitializeHelper,
-                 base::Unretained(this),
-                 base::Passed(&sync_client),
-                 base::Passed(&loss_observer),
-                 base::Passed(&shared_state), base::Passed(&attribs)));
+      base::Bind(&CommandBufferImpl::InitializeHelper, base::Unretained(this),
+                 base::Passed(&loss_observer), base::Passed(&shared_state),
+                 base::Passed(&attribs),
+                 base::Bind(&RunInitializeCallback, callback)));
 }
 
 void CommandBufferImpl::SetGetBuffer(int32_t buffer) {
@@ -93,11 +99,13 @@
                  base::Unretained(this), put_offset, order_num));
 }
 
-void CommandBufferImpl::MakeProgress(int32_t last_get_offset) {
+void CommandBufferImpl::MakeProgress(
+    int32_t last_get_offset,
+    const mojom::CommandBuffer::MakeProgressCallback& callback) {
   gpu_state_->command_buffer_task_runner()->PostTask(
-      driver_.get(),
-      base::Bind(&CommandBufferImpl::MakeProgressHelper,
-                 base::Unretained(this), last_get_offset));
+      driver_.get(), base::Bind(&CommandBufferImpl::MakeProgressHelper,
+                                base::Unretained(this), last_get_offset,
+                                base::Bind(RunMakeProgressCallback, callback)));
 }
 
 void CommandBufferImpl::RegisterTransferBuffer(
@@ -118,9 +126,11 @@
                  base::Unretained(this), id));
 }
 
-void CommandBufferImpl::InsertSyncPoint(bool retire) {
+void CommandBufferImpl::InsertSyncPoint(
+    bool retire,
+    const mojom::CommandBuffer::InsertSyncPointCallback& callback) {
   uint32_t sync_point = gpu_state_->sync_point_manager()->GenerateSyncPoint();
-  sync_point_client_->DidInsertSyncPoint(sync_point);
+  callback.Run(sync_point);
   if (retire) {
     gpu_state_->command_buffer_task_runner()->PostTask(
         driver_.get(),
@@ -138,15 +148,6 @@
                  sync_point));
 }
 
-void CommandBufferImpl::Echo(const mojo::Callback<void()>& callback) {
-  gpu_state_->command_buffer_task_runner()->PostTask(
-      driver_.get(),
-      base::Bind(&CommandBufferImpl::EchoHelper, base::Unretained(this),
-          FROM_HERE,
-          gpu_state_->control_task_runner(),
-          base::Bind(&RunCallback, callback)));
-}
-
 void CommandBufferImpl::CreateImage(int32_t id,
                                     mojo::ScopedHandle memory_handle,
                                     int32 type,
@@ -171,20 +172,29 @@
 void CommandBufferImpl::BindToRequest(
     mojo::InterfaceRequest<mus::mojom::CommandBuffer> request) {
   binding_.reset(
-      new mojo::Binding<mus::mojom::CommandBuffer>(this, request.Pass()));
+      new mojo::Binding<mus::mojom::CommandBuffer>(this, std::move(request)));
   binding_->set_connection_error_handler([this]() { OnConnectionError(); });
 }
 
 bool CommandBufferImpl::InitializeHelper(
-    mojom::CommandBufferSyncClientPtr sync_client,
     mojom::CommandBufferLostContextObserverPtr loss_observer,
     mojo::ScopedSharedBufferHandle shared_state,
-    mojo::Array<int32_t> attribs) {
+    mojo::Array<int32_t> attribs,
+    const base::Callback<void(mojom::CommandBufferInfoPtr)>& callback) {
   DCHECK(driver_->IsScheduled());
-  driver_->Initialize(sync_client.PassInterface(),
-                      loss_observer.PassInterface(),
-                      shared_state.Pass(),
-                      attribs.Pass());
+  bool result =
+      driver_->Initialize(loss_observer.PassInterface(),
+                          std::move(shared_state), std::move(attribs));
+  mojom::CommandBufferInfoPtr info;
+  if (result) {
+    info = mojom::CommandBufferInfo::New();
+    info->command_buffer_namespace = driver_->GetNamespaceID();
+    info->command_buffer_id = driver_->GetCommandBufferID();
+    info->capabilities =
+        mojom::GpuCapabilities::From(driver_->GetCapabilities());
+  }
+  gpu_state_->control_task_runner()->PostTask(
+      FROM_HERE, base::Bind(callback, base::Passed(&info)));
   return true;
 }
 
@@ -208,9 +218,14 @@
   return complete;
 }
 
-bool CommandBufferImpl::MakeProgressHelper(int32_t last_get_offset) {
+bool CommandBufferImpl::MakeProgressHelper(
+    int32_t last_get_offset,
+    const base::Callback<void(mojom::CommandBufferStatePtr)>& callback) {
   DCHECK(driver_->IsScheduled());
-  driver_->MakeProgress(last_get_offset);
+  mojom::CommandBufferStatePtr state =
+      mojom::CommandBufferState::From(driver_->GetLastState());
+  gpu_state_->control_task_runner()->PostTask(
+      FROM_HERE, base::Bind(callback, base::Passed(&state)));
   return true;
 }
 
@@ -219,7 +234,7 @@
     mojo::ScopedSharedBufferHandle transfer_buffer,
     uint32_t size) {
   DCHECK(driver_->IsScheduled());
-  driver_->RegisterTransferBuffer(id, transfer_buffer.Pass(), size);
+  driver_->RegisterTransferBuffer(id, std::move(transfer_buffer), size);
   return true;
 }
 
@@ -235,14 +250,6 @@
   return true;
 }
 
-bool CommandBufferImpl::EchoHelper(
-    const tracked_objects::Location& from_here,
-    scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner,
-    const base::Closure& reply) {
-  origin_task_runner->PostTask(from_here, reply);
-  return true;
-}
-
 bool CommandBufferImpl::CreateImageHelper(
     int32_t id,
     mojo::ScopedHandle memory_handle,
@@ -251,8 +258,8 @@
     int32_t format,
     int32_t internal_format) {
   DCHECK(driver_->IsScheduled());
-  driver_->CreateImage(id, memory_handle.Pass(), type, size.Pass(), format,
-      internal_format);
+  driver_->CreateImage(id, std::move(memory_handle), type, std::move(size),
+                       format, internal_format);
   return true;
 }
 
@@ -264,10 +271,6 @@
 
 void CommandBufferImpl::OnConnectionError() {
   // OnConnectionError() is called on the control thread |control_task_runner|.
-  // sync_point_client_ is assigned and accessed on the control thread and so it
-  // should also be destroyed on the control because InterfacePtrs are thread-
-  // hostile.
-  sync_point_client_.reset();
 
   // Before deleting, we need to delete |binding_| because it is bound to the
   // current thread (|control_task_runner|).
diff --git a/components/mus/gles2/command_buffer_impl.h b/components/mus/gles2/command_buffer_impl.h
index c0f920d..67a8181 100644
--- a/components/mus/gles2/command_buffer_impl.h
+++ b/components/mus/gles2/command_buffer_impl.h
@@ -37,21 +37,24 @@
   ~CommandBufferImpl() override;
 
   // mojom::CommandBuffer:
-  void Initialize(mojom::CommandBufferSyncClientPtr sync_client,
-                  mojom::CommandBufferSyncPointClientPtr sync_point_client,
-                  mojom::CommandBufferLostContextObserverPtr loss_observer,
-                  mojo::ScopedSharedBufferHandle shared_state,
-                  mojo::Array<int32_t> attribs) override;
+  void Initialize(
+      mojom::CommandBufferLostContextObserverPtr loss_observer,
+      mojo::ScopedSharedBufferHandle shared_state,
+      mojo::Array<int32_t> attribs,
+      const mojom::CommandBuffer::InitializeCallback& callback) override;
   void SetGetBuffer(int32_t buffer) override;
   void Flush(int32_t put_offset) override;
-  void MakeProgress(int32_t last_get_offset) override;
+  void MakeProgress(
+      int32_t last_get_offset,
+      const mojom::CommandBuffer::MakeProgressCallback& callback) override;
   void RegisterTransferBuffer(int32_t id,
                               mojo::ScopedSharedBufferHandle transfer_buffer,
                               uint32_t size) override;
   void DestroyTransferBuffer(int32_t id) override;
-  void InsertSyncPoint(bool retire) override;
+  void InsertSyncPoint(
+      bool retire,
+      const mojom::CommandBuffer::InsertSyncPointCallback& callback) override;
   void RetireSyncPoint(uint32_t sync_point) override;
-  void Echo(const mojo::Callback<void()>& callback) override;
   void CreateImage(int32_t id,
                    mojo::ScopedHandle memory_handle,
                    int32_t type,
@@ -61,23 +64,21 @@
   void DestroyImage(int32_t id) override;
 
   bool InitializeHelper(
-      mojom::CommandBufferSyncClientPtr sync_client,
       mojom::CommandBufferLostContextObserverPtr loss_observer,
       mojo::ScopedSharedBufferHandle shared_state,
-      mojo::Array<int32_t> attribs);
+      mojo::Array<int32_t> attribs,
+      const base::Callback<void(mojom::CommandBufferInfoPtr)>& callback);
   bool SetGetBufferHelper(int32_t buffer);
   bool FlushHelper(int32_t put_offset, uint32_t order_num);
-  bool MakeProgressHelper(int32_t last_get_offset);
+  bool MakeProgressHelper(
+      int32_t last_get_offset,
+      const base::Callback<void(mojom::CommandBufferStatePtr)>& callback);
   bool RegisterTransferBufferHelper(
       int32_t id,
       mojo::ScopedSharedBufferHandle transfer_buffer,
       uint32_t size);
   bool DestroyTransferBufferHelper(int32_t id);
   bool RetireSyncPointHelper(uint32_t sync_point);
-  bool EchoHelper(
-      const tracked_objects::Location& from_here,
-      scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner,
-      const base::Closure& reply);
   bool CreateImageHelper(
       int32_t id,
       mojo::ScopedHandle memory_handle,
@@ -94,7 +95,6 @@
 
   scoped_refptr<GpuState> gpu_state_;
   scoped_ptr<CommandBufferDriver> driver_;
-  mojom::CommandBufferSyncPointClientPtr sync_point_client_;
   scoped_ptr<mojo::Binding<CommandBuffer>> binding_;
   CommandBufferImplObserver* observer_;
   base::WeakPtrFactory<CommandBufferImpl> weak_ptr_factory_;
diff --git a/components/mus/public/interfaces/command_buffer.mojom b/components/mus/public/interfaces/command_buffer.mojom
index db035c3..e61882f 100644
--- a/components/mus/public/interfaces/command_buffer.mojom
+++ b/components/mus/public/interfaces/command_buffer.mojom
@@ -7,6 +7,12 @@
 import "components/mus/public/interfaces/gpu_capabilities.mojom";
 import "ui/mojo/geometry/geometry.mojom";
 
+struct CommandBufferInfo {
+    int32 command_buffer_namespace;
+    uint64 command_buffer_id;
+    GpuCapabilities capabilities;
+};
+
 struct CommandBufferState {
   int32 num_entries;
   int32 get_offset;
@@ -17,47 +23,30 @@
   uint32 generation;
 };
 
-interface CommandBufferSyncClient {
-  // |capabilities| is null if |success| is false.
-  DidInitialize(bool success,
-                int32 command_buffer_namespace,
-                uint64 command_buffer_id,
-                GpuCapabilities? capabilities);
-  DidMakeProgress(CommandBufferState state);
-};
-
-interface CommandBufferSyncPointClient {
-  DidInsertSyncPoint(uint32 sync_point);
-};
-
 interface CommandBufferLostContextObserver {
   DidLoseContext(int32 context_lost_reason);
 };
 
+
 interface CommandBuffer {
-  // Initialize attempts to initialize the command buffer. Success or failure
-  // will be communicated via the CommandBufferSyncClient DidInitialize() call.
+  // Initialize attempts to initialize the command buffer.
   // If the context is lost after creation the LostContext method on the
   // CommandBufferLostContextObserver's will be called then this pipe will be
   // closed.
-  Initialize(CommandBufferSyncClient sync_client,
-             CommandBufferSyncPointClient sync_point_client,
-             CommandBufferLostContextObserver lost_observer,
+  Initialize(CommandBufferLostContextObserver lost_observer,
              handle<shared_buffer> shared_state,
-             array<int32> attribs);
+             array<int32> attribs) => (CommandBufferInfo? info);
   SetGetBuffer(int32 buffer);
   Flush(int32 put_offset);
-  MakeProgress(int32 last_get_offset);
+  MakeProgress(int32 last_get_offset) => (CommandBufferState state);
   RegisterTransferBuffer(
       int32 id, handle<shared_buffer> transfer_buffer, uint32 size);
   DestroyTransferBuffer(int32 id);
 
-  // InsertSyncPoint returns the sync point returned via DidInsertSyncPoint.
   // If |retire| is true, the sync point is retired on insertion. Otherwise,
   // explicitly call RetireSyncPoint to retire it.
-  InsertSyncPoint(bool retire);
+  InsertSyncPoint(bool retire) => (uint32 sync_point);
   RetireSyncPoint(uint32 sync_point);
-  Echo() => ();
 
   CreateImage(int32 id,
               handle memory_handle,
diff --git a/content/browser/devtools/shared_worker_devtools_manager.cc b/content/browser/devtools/shared_worker_devtools_manager.cc
index 3289604..31569a51 100644
--- a/content/browser/devtools/shared_worker_devtools_manager.cc
+++ b/content/browser/devtools/shared_worker_devtools_manager.cc
@@ -51,7 +51,7 @@
   agent_host->WorkerRestarted(id);
   workers_.erase(it);
   workers_[id] = agent_host;
-  return true;
+  return agent_host->IsAttached();
 }
 
 void SharedWorkerDevToolsManager::WorkerReadyForInspection(
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index b8a3be9e..d6db909 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -584,6 +584,10 @@
 
   for (const auto& video_capture_device_info : video_capture_device_infos) {
     base::ListValue* format_list = new base::ListValue();
+    // TODO(nisse): Representing format information as a string, to be
+    // parsed by the javascript handler, is brittle. Consider passing
+    // a list of mappings instead.
+
     for (const auto& format : video_capture_device_info.supported_formats)
       format_list->AppendString(media::VideoCaptureFormat::ToString(format));
 
diff --git a/content/browser/media/media_internals_unittest.cc b/content/browser/media/media_internals_unittest.cc
index 37ac3e05..6b026e0 100644
--- a/content/browser/media/media_internals_unittest.cc
+++ b/content/browser/media/media_internals_unittest.cc
@@ -157,7 +157,7 @@
   const media::VideoCaptureFormat capture_format(kFrameSize, kFrameRate,
                                                  kPixelFormat, kPixelStorage);
   const std::string expected_string = base::StringPrintf(
-      "(%s)@%.3ffps, pixel format: %s storage: %s.",
+      "(%s)@%.3ffps, pixel format: %s, storage: %s",
       kFrameSize.ToString().c_str(), kFrameRate,
       media::VideoPixelFormatToString(kPixelFormat).c_str(),
       media::VideoCaptureFormat::PixelStorageToString(kPixelStorage).c_str());
diff --git a/content/browser/media/webrtc_media_recorder_browsertest.cc b/content/browser/media/webrtc_media_recorder_browsertest.cc
index 3cf09dd..434f381 100644
--- a/content/browser/media/webrtc_media_recorder_browsertest.cc
+++ b/content/browser/media/webrtc_media_recorder_browsertest.cc
@@ -64,14 +64,8 @@
   MakeTypicalCall("testStartAndDataAvailable();", kMediaRecorderHtmlFile);
 }
 
-// Fails flakily under ThreadSanitizer, http://crbug.com/562406.
-#if defined(THREAD_SANITIZER)
-#define MAYBE_MediaRecorderStartWithTimeSlice DISABLED_MediaRecorderStartWithTimeSlice
-#else
-#define MAYBE_MediaRecorderStartWithTimeSlice MediaRecorderStartWithTimeSlice
-#endif
 IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcMediaRecorderTest,
-                       MAYBE_MediaRecorderStartWithTimeSlice) {
+                       MediaRecorderStartWithTimeSlice) {
   MakeTypicalCall("testStartWithTimeSlice();", kMediaRecorderHtmlFile);
 }
 
diff --git a/content/browser/power_save_blocker_impl.h b/content/browser/power_save_blocker_impl.h
index 76af7253..a304226 100644
--- a/content/browser/power_save_blocker_impl.h
+++ b/content/browser/power_save_blocker_impl.h
@@ -43,13 +43,6 @@
   // };
   scoped_refptr<Delegate> delegate_;
 
-#if defined(USE_X11)
-  // Since display sleep prevention also implies system suspend prevention, for
-  // the Linux FreeDesktop API case, there needs to be a second delegate to
-  // block system suspend when screen saver / display sleep is blocked.
-  scoped_refptr<Delegate> freedesktop_suspend_delegate_;
-#endif
-
   DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerImpl);
 };
 
diff --git a/content/browser/power_save_blocker_x11.cc b/content/browser/power_save_blocker_x11.cc
index d5c79f43..4783063 100644
--- a/content/browser/power_save_blocker_x11.cc
+++ b/content/browser/power_save_blocker_x11.cc
@@ -52,17 +52,12 @@
 const char kGnomeAPIInterfaceName[] = "org.gnome.SessionManager";
 const char kGnomeAPIObjectPath[] = "/org/gnome/SessionManager";
 
-const char kFreeDesktopAPIPowerServiceName[] =
-    "org.freedesktop.PowerManagement";
-const char kFreeDesktopAPIPowerInterfaceName[] =
+const char kFreeDesktopAPIServiceName[] = "org.freedesktop.PowerManagement";
+const char kFreeDesktopAPIInterfaceName[] =
     "org.freedesktop.PowerManagement.Inhibit";
-const char kFreeDesktopAPIPowerObjectPath[] =
+const char kFreeDesktopAPIObjectPath[] =
     "/org/freedesktop/PowerManagement/Inhibit";
 
-const char kFreeDesktopAPIScreenServiceName[] = "org.freedesktop.ScreenSaver";
-const char kFreeDesktopAPIScreenInterfaceName[] = "org.freedesktop.ScreenSaver";
-const char kFreeDesktopAPIScreenObjectPath[] = "/org/freedesktop/ScreenSaver";
-
 }  // namespace
 
 namespace content {
@@ -71,9 +66,7 @@
     : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> {
  public:
   // Picks an appropriate D-Bus API to use based on the desktop environment.
-  Delegate(PowerSaveBlockerType type,
-           const std::string& description,
-           bool freedesktop_only);
+  Delegate(PowerSaveBlockerType type, const std::string& description);
 
   // Post a task to initialize the delegate on the UI thread, which will itself
   // then post a task to apply the power save block on the FILE thread.
@@ -116,7 +109,6 @@
 
   const PowerSaveBlockerType type_;
   const std::string description_;
-  const bool freedesktop_only_;
 
   // Initially, we post a message to the UI thread to select an API. When it
   // finishes, it will post a message to the FILE thread to perform the actual
@@ -146,11 +138,9 @@
 };
 
 PowerSaveBlockerImpl::Delegate::Delegate(PowerSaveBlockerType type,
-                                         const std::string& description,
-                                         bool freedesktop_only)
+                                         const std::string& description)
     : type_(type),
       description_(description),
-      freedesktop_only_(freedesktop_only),
       api_(NO_API),
       enqueue_apply_(false),
       inhibit_cookie_(0) {
@@ -186,9 +176,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::AutoLock lock(lock_);
   api_ = SelectAPI();
-  bool api_matches =
-      freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API;
-  if (enqueue_apply_ && api_matches) {
+  if (enqueue_apply_ && api_ != NO_API) {
     // The thread we use here becomes the origin and D-Bus thread for the D-Bus
     // library, so we need to use the same thread above for RemoveBlock(). It
     // must be a thread that allows I/O operations, so we use the FILE thread.
@@ -247,22 +235,11 @@
       }
       break;
     case FREEDESKTOP_API:
-      switch (type_) {
-        case kPowerSaveBlockPreventDisplaySleep:
-          object_proxy = bus_->GetObjectProxy(
-              kFreeDesktopAPIScreenServiceName,
-              dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
-          method_call.reset(new dbus::MethodCall(
-              kFreeDesktopAPIScreenInterfaceName, "Inhibit"));
-          break;
-        case kPowerSaveBlockPreventAppSuspension:
-          object_proxy = bus_->GetObjectProxy(
-              kFreeDesktopAPIPowerServiceName,
-              dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
-          method_call.reset(new dbus::MethodCall(
-              kFreeDesktopAPIPowerInterfaceName, "Inhibit"));
-          break;
-      }
+      object_proxy = bus_->GetObjectProxy(
+          kFreeDesktopAPIServiceName,
+          dbus::ObjectPath(kFreeDesktopAPIObjectPath));
+      method_call.reset(
+          new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "Inhibit"));
       message_writer.reset(new dbus::MessageWriter(method_call.get()));
       // The arguments of the method are:
       //     app_id:        The application identifier
@@ -334,22 +311,11 @@
           new dbus::MethodCall(kGnomeAPIInterfaceName, "Uninhibit"));
       break;
     case FREEDESKTOP_API:
-      switch (type_) {
-        case kPowerSaveBlockPreventDisplaySleep:
-          object_proxy = bus_->GetObjectProxy(
-              kFreeDesktopAPIScreenServiceName,
-              dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
-          method_call.reset(new dbus::MethodCall(
-              kFreeDesktopAPIScreenInterfaceName, "UnInhibit"));
-          break;
-        case kPowerSaveBlockPreventAppSuspension:
-          object_proxy = bus_->GetObjectProxy(
-              kFreeDesktopAPIPowerServiceName,
-              dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
-          method_call.reset(new dbus::MethodCall(
-              kFreeDesktopAPIPowerInterfaceName, "UnInhibit"));
-          break;
-      }
+      object_proxy = bus_->GetObjectProxy(
+          kFreeDesktopAPIServiceName,
+          dbus::ObjectPath(kFreeDesktopAPIObjectPath));
+      method_call.reset(
+          new dbus::MethodCall(kFreeDesktopAPIInterfaceName, "UnInhibit"));
       break;
   }
 
@@ -417,21 +383,12 @@
 PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type,
                                            Reason reason,
                                            const std::string& description)
-    : delegate_(new Delegate(type, description, false /* freedesktop_only */)) {
+    : delegate_(new Delegate(type, description)) {
   delegate_->Init();
-
-  if (type == kPowerSaveBlockPreventDisplaySleep) {
-    freedesktop_suspend_delegate_ =
-        new Delegate(kPowerSaveBlockPreventAppSuspension, description,
-                     true /* freedesktop_only */);
-    freedesktop_suspend_delegate_->Init();
-  }
 }
 
 PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
   delegate_->CleanUp();
-  if (freedesktop_suspend_delegate_)
-    freedesktop_suspend_delegate_->CleanUp();
 }
 
 }  // namespace content
diff --git a/content/browser/resources/media/manager.js b/content/browser/resources/media/manager.js
index b335349f..27f6b99 100644
--- a/content/browser/resources/media/manager.js
+++ b/content/browser/resources/media/manager.js
@@ -117,24 +117,33 @@
        * Example:
        *
        * format:
-       *   "resolution: 1280x720, fps: 30.000000, pixel format: I420"
+       *   "(160x120)@30.000fps, pixel format: PIXEL_FORMAT_I420, storage: CPU"
        *
        * formatDict:
-       *   {'resolution':'1280x720', 'fps': '30.00'}
+       *   {'resolution':'1280x720', 'fps': '30.00', "storage: "CPU" }
        */
       var parts = format.split(', ');
       var formatDict = {};
       for (var i in parts) {
         var kv = parts[i].split(': ');
-        formatDict[kv[0]] = kv[1];
+        if (kv.length == 2) {
+          if (kv[0] == 'pixel format') {
+            // The camera does not actually output I420,
+            // so this info is misleading.
+            continue;
+          }
+          formatDict[kv[0]] = kv[1];
+        } else {
+          kv = parts[i].split("@");
+          if (kv.length == 2) {
+            formatDict['resolution'] = kv[0].replace(/[)(]/g, '');
+            // Round down the FPS to 2 decimals.
+            formatDict['fps'] =
+                parseFloat(kv[1].replace(/fps$/, '')).toFixed(2);
+          }
+        }
       }
 
-      // Round down the FPS to 2 decimals.
-      formatDict['fps'] = parseFloat(formatDict['fps']).toFixed(2);
-
-      // The camera does not actually output I420 so this info is misleading.
-      delete formatDict['pixel format'];
-
       return formatDict;
     },
 
diff --git a/content/browser/service_worker/service_worker_process_manager.cc b/content/browser/service_worker/service_worker_process_manager.cc
index fbeaead..d0c3a5d 100644
--- a/content/browser/service_worker/service_worker_process_manager.cc
+++ b/content/browser/service_worker/service_worker_process_manager.cc
@@ -4,6 +4,9 @@
 
 #include "content/browser/service_worker/service_worker_process_manager.h"
 
+#include <algorithm>
+#include <utility>
+
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/public/browser/browser_thread.h"
@@ -51,14 +54,16 @@
     : browser_context_(browser_context),
       process_id_for_test_(-1),
       weak_this_factory_(this) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   weak_this_ = weak_this_factory_.GetWeakPtr();
 }
 
 ServiceWorkerProcessManager::~ServiceWorkerProcessManager() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(browser_context_ == NULL)
+  DCHECK(IsShutdown())
       << "Call Shutdown() before destroying |this|, so that racing method "
       << "invocations don't use a destroyed BrowserContext.";
+  DCHECK(instance_info_.empty());
 }
 
 void ServiceWorkerProcessManager::Shutdown() {
@@ -107,7 +112,7 @@
 
   PatternProcessRefMap::iterator it = pattern_processes_.find(pattern);
   if (it == pattern_processes_.end()) {
-    NOTREACHED() << "process refrences not found for pattern: " << pattern;
+    NOTREACHED() << "process references not found for pattern: " << pattern;
     return;
   }
   ProcessRefMap& process_refs = it->second;
@@ -161,30 +166,28 @@
     return;
   }
 
-  DCHECK(!ContainsKey(instance_info_, embedded_worker_id))
-      << embedded_worker_id << " already has a process allocated";
-
-  std::vector<int> sorted_candidates = SortProcessesForPattern(pattern);
-  for (std::vector<int>::const_iterator it = sorted_candidates.begin();
-       it != sorted_candidates.end();
-       ++it) {
-    if (!IncrementWorkerRefCountByPid(*it))
-      continue;
-    instance_info_.insert(
-        std::make_pair(embedded_worker_id, ProcessInfo(*it)));
-    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                            base::Bind(callback, SERVICE_WORKER_OK, *it,
-                                       false /* is_new_process */));
-    return;
-  }
-
-  if (!browser_context_) {
-    // Shutdown has started.
+  if (IsShutdown()) {
     BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                             base::Bind(callback, SERVICE_WORKER_ERROR_ABORT, -1,
                                        false /* is_new_process */));
     return;
   }
+
+  DCHECK(!ContainsKey(instance_info_, embedded_worker_id))
+      << embedded_worker_id << " already has a process allocated";
+
+  std::vector<int> sorted_candidates = SortProcessesForPattern(pattern);
+  for (int process_id : sorted_candidates) {
+    if (!IncrementWorkerRefCountByPid(process_id))
+      continue;
+    instance_info_.insert(
+        std::make_pair(embedded_worker_id, ProcessInfo(process_id)));
+    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+                            base::Bind(callback, SERVICE_WORKER_OK, process_id,
+                                       false /* is_new_process */));
+    return;
+  }
+
   // No existing processes available; start a new one.
   scoped_refptr<SiteInstance> site_instance =
       SiteInstance::CreateForURL(browser_context_, script_url);
@@ -220,16 +223,19 @@
                    embedded_worker_id));
     return;
   }
+
   if (process_id_for_test_ != -1) {
     // Unittests don't increment or decrement the worker refcount of a
     // RenderProcessHost.
     return;
   }
-  if (browser_context_ == NULL) {
+
+  if (IsShutdown()) {
     // Shutdown already released all instances.
     DCHECK(instance_info_.empty());
     return;
   }
+
   std::map<int, ProcessInfo>::iterator info =
       instance_info_.find(embedded_worker_id);
   DCHECK(info != instance_info_.end());
diff --git a/content/browser/service_worker/service_worker_process_manager.h b/content/browser/service_worker/service_worker_process_manager.h
index 0cb370b1..cc368b5 100644
--- a/content/browser/service_worker/service_worker_process_manager.h
+++ b/content/browser/service_worker/service_worker_process_manager.h
@@ -76,6 +76,8 @@
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest, SortProcess);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProcessManagerTest,
+                           AllocateWorkerProcess_InShutdown);
 
   // Information about the process for an EmbeddedWorkerInstance.
   struct ProcessInfo {
@@ -95,6 +97,9 @@
     int process_id;
   };
 
+  // Returns true if Shutdown() has been called.
+  bool IsShutdown() const { return !browser_context_; }
+
   // Maps the process ID to its reference count.
   typedef std::map<int, int> ProcessRefMap;
 
diff --git a/content/browser/service_worker/service_worker_process_manager_unittest.cc b/content/browser/service_worker/service_worker_process_manager_unittest.cc
index 3b53740..37c0d8d9 100644
--- a/content/browser/service_worker/service_worker_process_manager_unittest.cc
+++ b/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/run_loop.h"
 #include "content/browser/service_worker/service_worker_process_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -11,6 +13,23 @@
 
 namespace content {
 
+namespace {
+
+void DidAllocateWorkerProcess(const base::Closure& quit_closure,
+                              ServiceWorkerStatusCode* status_out,
+                              int* process_id_out,
+                              bool* is_new_process_out,
+                              ServiceWorkerStatusCode status,
+                              int process_id,
+                              bool is_new_process) {
+  *status_out = status;
+  *process_id_out = process_id;
+  *is_new_process_out = is_new_process;
+  quit_closure.Run();
+}
+
+}  // namespace
+
 class ServiceWorkerProcessManagerTest : public testing::Test {
  public:
   ServiceWorkerProcessManagerTest() {}
@@ -18,6 +37,7 @@
   void SetUp() override {
     process_manager_.reset(new ServiceWorkerProcessManager(NULL));
     pattern_ = GURL("http://www.example.com/");
+    script_url_ = GURL("http://www.example.com/sw.js");
   }
 
   void TearDown() override { process_manager_.reset(); }
@@ -25,6 +45,7 @@
  protected:
   scoped_ptr<ServiceWorkerProcessManager> process_manager_;
   GURL pattern_;
+  GURL script_url_;
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
@@ -51,4 +72,24 @@
               testing::ElementsAre(2, 3));
 }
 
+TEST_F(ServiceWorkerProcessManagerTest, AllocateWorkerProcess_InShutdown) {
+  ASSERT_TRUE(process_manager_->IsShutdown());
+
+  base::RunLoop run_loop;
+  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+  int process_id = -10;
+  bool is_new_process = true;
+  process_manager_->AllocateWorkerProcess(
+      1, pattern_, script_url_,
+      base::Bind(&DidAllocateWorkerProcess, run_loop.QuitClosure(), &status,
+                 &process_id, &is_new_process));
+  run_loop.Run();
+
+  // Allocating a process in shutdown should abort.
+  EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
+  EXPECT_EQ(-1, process_id);
+  EXPECT_FALSE(is_new_process);
+  EXPECT_TRUE(process_manager_->instance_info_.empty());
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 6c0d21a..4fd441b 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -1771,7 +1771,7 @@
                                              int render_frame_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  if (running_status() != RUNNING)
+  if (!context_ || running_status() != RUNNING)
     return;
 
   if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
@@ -1963,7 +1963,7 @@
   if (!options.include_uncontrolled) {
     for (auto& controllee : controllee_map_)
       AddWindowClient(controllee.second, &clients_info);
-  } else {
+  } else if (context_) {
     for (auto it =
              context_->GetClientProviderHostIterator(script_url_.GetOrigin());
          !it->IsAtEnd(); it->Advance()) {
@@ -2002,7 +2002,7 @@
     for (auto& controllee : controllee_map_) {
       AddNonWindowClient(controllee.second, options, clients);
     }
-  } else {
+  } else if (context_) {
     for (auto it =
              context_->GetClientProviderHostIterator(script_url_.GetOrigin());
          !it->IsAtEnd(); it->Advance()) {
@@ -2067,6 +2067,9 @@
          running_status() == STOPPING)
       << running_status();
 
+  if (!context_)
+    return;
+
   MarkIfStale();
 
   // Stopping the worker hasn't finished within a certain period.
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 2da6a3a..244378b 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -361,7 +361,6 @@
                            TimeoutStartingWorker);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionBrowserTest,
                            TimeoutWorkerInEvent);
-  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, StayAliveAfterPush);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest, DetachThenStart);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStallInStoppingTest, DetachThenRestart);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest,
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index e527f56..ba984bff 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -572,24 +572,6 @@
   EXPECT_LT(idle_time, version_->idle_time_);
 }
 
-// Test that the worker stays alive for some time after
-// receiving a push event.
-// TODO(falken): Remove this test once Facebook doesn't rely on the behavior:
-// crbug.com/519993
-TEST_F(ServiceWorkerVersionTest, StayAliveAfterPush) {
-  const base::TimeDelta kTenSeconds = base::TimeDelta::FromSeconds(10);
-  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->DispatchPushEvent(CreateReceiverOnCurrentThread(&status),
-                              std::string());
-  base::RunLoop().RunUntilIdle();
-
-  // Pretend we've been idle for 10 seconds and fire the timeout code.
-  version_->idle_time_ = base::TimeTicks::Now() - kTenSeconds;
-  version_->OnTimeoutTimer();
-  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
-}
-
 TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
   version_->StartWorker(CreateReceiverOnCurrentThread(&status));
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc
index 99c369d..8aefff1 100644
--- a/content/browser/shared_worker/shared_worker_host.cc
+++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -58,6 +58,7 @@
       container_render_filter_(filter),
       worker_process_id_(filter->render_process_id()),
       worker_route_id_(worker_route_id),
+      termination_message_sent_(false),
       closed_(false),
       creation_time_(base::TimeTicks::Now()),
       weak_factory_(this) {
@@ -68,7 +69,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   UMA_HISTOGRAM_LONG_TIMES("SharedWorker.TimeToDeleted",
                            base::TimeTicks::Now() - creation_time_);
-  if (!closed_)
+  if (!closed_ && !termination_message_sent_)
     NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
   SharedWorkerServiceImpl::GetInstance()->NotifyWorkerDestroyed(
       worker_process_id_, worker_route_id_);
@@ -100,15 +101,11 @@
 
 bool SharedWorkerHost::FilterMessage(const IPC::Message& message,
                                      SharedWorkerMessageFilter* filter) {
-  if (!instance_)
+  if (!IsAvailable() || !HasFilter(filter, message.routing_id()))
     return false;
 
-  if (!closed_ && HasFilter(filter, message.routing_id())) {
-    RelayMessage(message, filter);
-    return true;
-  }
-
-  return false;
+  RelayMessage(message, filter);
+  return true;
 }
 
 void SharedWorkerHost::FilterShutdown(SharedWorkerMessageFilter* filter) {
@@ -118,7 +115,7 @@
   worker_document_set_->RemoveAll(filter);
   if (worker_document_set_->IsEmpty()) {
     // This worker has no more associated documents - shut it down.
-    Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
+    TerminateWorker();
   }
 }
 
@@ -130,7 +127,7 @@
   worker_document_set_->Remove(filter, document_id);
   if (worker_document_set_->IsEmpty()) {
     // This worker has no more associated documents - shut it down.
-    Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
+    TerminateWorker();
   }
 }
 
@@ -141,7 +138,8 @@
   // being sent to the worker (messages can still be sent from the worker,
   // for exception reporting, etc).
   closed_ = true;
-  NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
+  if (!termination_message_sent_)
+    NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
 }
 
 void SharedWorkerHost::WorkerContextDestroyed() {
@@ -267,6 +265,9 @@
 }
 
 void SharedWorkerHost::TerminateWorker() {
+  termination_message_sent_ = true;
+  if (!closed_)
+    NotifyWorkerDestroyed(worker_process_id_, worker_route_id_);
   Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
 }
 
@@ -287,6 +288,10 @@
   return result;
 }
 
+bool SharedWorkerHost::IsAvailable() const {
+  return instance_ && !termination_message_sent_ && !closed_;
+}
+
 void SharedWorkerHost::AddFilter(SharedWorkerMessageFilter* filter,
                                  int route_id) {
   CHECK(filter);
diff --git a/content/browser/shared_worker/shared_worker_host.h b/content/browser/shared_worker/shared_worker_host.h
index 1a32d128..a73cb183 100644
--- a/content/browser/shared_worker/shared_worker_host.h
+++ b/content/browser/shared_worker/shared_worker_host.h
@@ -85,7 +85,7 @@
   }
   int process_id() const { return worker_process_id_; }
   int worker_route_id() const { return worker_route_id_; }
-  bool closed() const { return closed_; }
+  bool IsAvailable() const;
 
  private:
   // Unique identifier for a worker client.
@@ -127,6 +127,7 @@
   SharedWorkerMessageFilter* container_render_filter_;
   int worker_process_id_;
   int worker_route_id_;
+  bool termination_message_sent_;
   bool closed_;
   const base::TimeTicks creation_time_;
 
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc
index ad4e433..4e71bde 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -604,10 +604,8 @@
        iter != worker_hosts_.end();
        ++iter) {
     SharedWorkerHost* host = iter->second;
-    if (host->instance() && !host->closed() &&
-        host->instance()->Matches(instance)) {
+    if (host->IsAvailable() && host->instance()->Matches(instance))
       return iter->second;
-    }
   }
   return NULL;
 }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 7556ae8..18589f1 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1934,10 +1934,13 @@
                                       bool is_fullscreen,
                                       blink::WebPopupType popup_type) {
   RenderProcessHost* process = GetRenderProcessHost();
-  // A message to create a new widget can only come from the active process for
+  // A message to create a new widget can only come from an active process for
   // this WebContentsImpl instance. If any other process sends the request,
   // it is invalid and the process must be terminated.
-  if (process->GetID() != render_process_id) {
+  bool did_match_process = false;
+  frame_tree_.ForEach(
+      base::Bind(&FindMatchingProcess, render_process_id, &did_match_process));
+  if (!did_match_process) {
     RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
     base::ProcessHandle process_handle = rph->GetHandle();
     if (process_handle != base::kNullProcessHandle) {
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc
index 954f447..73d984a 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -105,7 +105,7 @@
     output_params = params;
 
   media::AudioRendererMixer* mixer =
-      new media::AudioRendererMixer(params, output_params, sink);
+      new media::AudioRendererMixer(output_params, sink);
   AudioRendererMixerReference mixer_reference = { mixer, 1 };
   mixers_[key] = mixer_reference;
   return mixer;
diff --git a/content/renderer/media/audio_renderer_mixer_manager.h b/content/renderer/media/audio_renderer_mixer_manager.h
index e06ff0c..9256013 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.h
+++ b/content/renderer/media/audio_renderer_mixer_manager.h
@@ -91,8 +91,6 @@
     bool operator()(const MixerKey& a, const MixerKey& b) const {
       if (a.source_render_frame_id != b.source_render_frame_id)
         return a.source_render_frame_id < b.source_render_frame_id;
-      if (a.params.sample_rate() != b.params.sample_rate())
-        return a.params.sample_rate() < b.params.sample_rate();
       if (a.params.channels() != b.params.channels())
         return a.params.channels() < b.params.channels();
 
diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
index fd776bde..bfc0f9f 100644
--- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -22,6 +22,8 @@
 static const int kSampleRate = 48000;
 static const int kBufferSize = 8192;
 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
+static const media::ChannelLayout kAnotherChannelLayout =
+    media::CHANNEL_LAYOUT_2_1;
 static const std::string kDefaultDeviceId;
 static const url::Origin kSecurityOrigin;
 
@@ -108,7 +110,7 @@
   EXPECT_EQ(mixer_count(), 1);
 
   media::AudioParameters params2(
-      AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate * 2,
+      AudioParameters::AUDIO_PCM_LINEAR, kAnotherChannelLayout, kSampleRate * 2,
       kBitsPerChannel, kBufferSize * 2);
   media::AudioRendererMixer* mixer2 = GetMixer(
       kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin, nullptr);
@@ -142,21 +144,25 @@
   ASSERT_TRUE(mixer1);
   EXPECT_EQ(mixer_count(), 1);
 
-  // Different formats, bit depths, and buffer sizes should not result in a
-  // different mixer.
+  // Different sample rates, formats, bit depths, and buffer sizes should not
+  // result in a different mixer.
   media::AudioParameters params2(AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                 kChannelLayout, kSampleRate,
-                                 kBitsPerChannel * 2, kBufferSize * 2);
+                                 kChannelLayout,
+                                 kSampleRate * 2,
+                                 kBitsPerChannel * 2,
+                                 kBufferSize * 2);
   EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId,
                              kSecurityOrigin, nullptr));
   EXPECT_EQ(mixer_count(), 1);
   RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
   EXPECT_EQ(mixer_count(), 1);
 
-  // Modify some parameters that do matter.
+  // Modify some parameters that do matter: channel layout
   media::AudioParameters params3(AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                 media::CHANNEL_LAYOUT_MONO, kSampleRate * 2,
-                                 kBitsPerChannel, kBufferSize);
+                                 kAnotherChannelLayout,
+                                 kSampleRate,
+                                 kBitsPerChannel,
+                                 kBufferSize);
   ASSERT_NE(params3.channel_layout(), params1.channel_layout());
 
   EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId,
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index 7a5e37e..62bfb85 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -866,7 +866,7 @@
     return;
   }
   callbacks->onError(blink::WebServiceWorkerError(
-      blink::WebServiceWorkerError::ErrorTypeUnknown,
+      blink::WebServiceWorkerError::ErrorTypeNavigation,
       blink::WebString::fromUTF8(message)));
   context_->client_callbacks.Remove(request_id);
 }
@@ -929,7 +929,7 @@
   }
   std::string message = "Cannot navigate to URL: " + url.spec();
   callbacks->onError(blink::WebServiceWorkerError(
-      blink::WebServiceWorkerError::ErrorTypeUnknown,
+      blink::WebServiceWorkerError::ErrorTypeNavigation,
       blink::WebString::fromUTF8(message)));
   context_->client_callbacks.Remove(request_id);
 }
diff --git a/docs/chromium_browser_vs_google_chrome.md b/docs/chromium_browser_vs_google_chrome.md
index 5896302..b0c6238 100644
--- a/docs/chromium_browser_vs_google_chrome.md
+++ b/docs/chromium_browser_vs_google_chrome.md
@@ -44,7 +44,7 @@
 *   Cache is kept in `~/.cache/chromium`
 *   New release testing depends on the distribution
     *   Distributions are encouraged to track stable channel releases: see
-        http://googlechromereleases.blogspot.com/, http://omahaproxy.pspot.com/
+        http://googlechromereleases.blogspot.com/, http://omahaproxy.appspot.com/
         and http://gsdview.appspot.com/chromium-browser-official/
 *   Google API keys depend on the distribution
     *   See http://www.chromium.org/developers/how-tos/api-keys
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index 117f63d3..247486f 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -102,6 +102,12 @@
     "crash_report/crash_report_user_application_state.mm",
     "crash_report/crash_upload_list.cc",
     "crash_report/crash_upload_list.h",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.cc",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.cc",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.cc",
+    "data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h",
     "dom_distiller/distiller_viewer.cc",
     "dom_distiller/distiller_viewer.h",
     "dom_distiller/dom_distiller_service_factory.cc",
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
index 39514ce..d447a09 100644
--- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
+++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -12,6 +12,7 @@
 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "ios/chrome/browser/bookmarks/startup_task_runner_service_factory.h"
 #include "ios/chrome/browser/content_settings/cookie_settings_factory.h"
+#include "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h"
 #include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h"
 #include "ios/chrome/browser/enhanced_bookmarks/bookmark_server_cluster_service_factory.h"
 #include "ios/chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
@@ -82,6 +83,7 @@
   ios::TopSitesFactory::GetInstance();
   ios::WebDataServiceFactory::GetInstance();
   ios::WebHistoryServiceFactory::GetInstance();
+  IOSChromeDataReductionProxySettingsFactory::GetInstance();
   IOSChromeGCMProfileServiceFactory::GetInstance();
   IOSChromeLargeIconCacheFactory::GetInstance();
   IOSChromeLargeIconServiceFactory::GetInstance();
diff --git a/ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.cc b/ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.cc
index 3140ee2..150d33b 100644
--- a/ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.cc
+++ b/ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.cc
@@ -28,6 +28,8 @@
 #include "components/sessions/core/tab_restore_service.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
+#include "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h"
+#include "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
 #include "ios/chrome/browser/history/web_history_service_factory.h"
 #include "ios/chrome/browser/ios_chrome_io_thread.h"
@@ -39,7 +41,6 @@
 #include "ios/net/http_cache_helper.h"
 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#include "ios/public/provider/chrome/browser/keyed_service_provider.h"
 #include "ios/web/public/user_metrics.h"
 #include "ios/web/public/web_thread.h"
 #include "net/base/net_errors.h"
@@ -247,8 +248,8 @@
 
     data_reduction_proxy::DataReductionProxySettings*
         data_reduction_proxy_settings =
-            ios::GetKeyedServiceProvider()
-                ->GetDataReductionProxySettingsForBrowserState(browser_state_);
+            IOSChromeDataReductionProxySettingsFactory::GetForBrowserState(
+                browser_state_);
 
     // |data_reduction_proxy_settings| is null if |browser_state_| is off the
     // record.
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.cc b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.cc
new file mode 100644
index 0000000..1acaa69e
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 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 "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h"
+
+#include "base/prefs/pref_service.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_retrieval_params.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
+#include "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h"
+#include "ios/web/public/web_client.h"
+
+using data_reduction_proxy::DataReductionProxyParams;
+
+scoped_ptr<data_reduction_proxy::DataReductionProxyIOData>
+CreateIOSChromeDataReductionProxyIOData(
+    net::NetLog* net_log,
+    PrefService* prefs,
+    const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
+    bool enable_quic) {
+  DCHECK(net_log);
+  DCHECK(prefs);
+
+  int flags = DataReductionProxyParams::kAllowed |
+              DataReductionProxyParams::kFallbackAllowed;
+  if (data_reduction_proxy::params::IsIncludedInPromoFieldTrial())
+    flags |= DataReductionProxyParams::kPromoAllowed;
+  if (data_reduction_proxy::params::IsIncludedInHoldbackFieldTrial())
+    flags |= DataReductionProxyParams::kHoldback;
+
+  bool enabled =
+      prefs->GetBoolean(
+          data_reduction_proxy::prefs::kDataReductionProxyEnabled) ||
+      data_reduction_proxy::params::ShouldForceEnableDataReductionProxy();
+  scoped_ptr<data_reduction_proxy::DataReductionProxyIOData>
+      data_reduction_proxy_io_data(
+          new data_reduction_proxy::DataReductionProxyIOData(
+              IOSChromeDataReductionProxySettings::GetClient(), flags, net_log,
+              io_task_runner, ui_task_runner, enabled, enable_quic,
+              web::GetWebClient()->GetUserAgent(false)));
+  data_reduction_proxy_io_data->experiments_stats()->InitializeOnUIThread(
+      data_reduction_proxy::DataReductionProxyConfigRetrievalParams::Create(
+          prefs));
+
+  return data_reduction_proxy_io_data.Pass();
+}
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h
new file mode 100644
index 0000000..2007a0b
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h
@@ -0,0 +1,34 @@
+// Copyright 2015 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_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_IO_DATA_H_
+#define IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_IO_DATA_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+class PrefService;
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace data_reduction_proxy {
+class DataReductionProxyIOData;
+}
+
+namespace net {
+class NetLog;
+}
+
+// Constructs DataReductionProxyIOData suitable for use by Chrome on iOS.
+scoped_ptr<data_reduction_proxy::DataReductionProxyIOData>
+CreateIOSChromeDataReductionProxyIOData(
+    net::NetLog* net_log,
+    PrefService* prefs,
+    const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner,
+    const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread_runner,
+    bool enable_quic);
+
+#endif  // IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_IO_DATA_H_
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.cc b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.cc
new file mode 100644
index 0000000..0d2a64a
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.cc
@@ -0,0 +1,210 @@
+// Copyright 2015 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 "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h"
+
+#include <string>
+
+#include "base/base64.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "base/strings/string_util.h"
+#include "base/time/time.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/core/browser/data_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
+#include "components/proxy_config/proxy_prefs.h"
+#include "ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h"
+#include "net/base/host_port_pair.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_list.h"
+#include "net/proxy/proxy_server.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace {
+
+// Assume that any proxy host ending with this suffix is a Data Reduction Proxy.
+const char kDataReductionProxyDefaultHostSuffix[] = ".googlezip.net";
+
+// Searches |proxy_list| for any Data Reduction Proxies, even if they don't
+// match a currently configured Data Reduction Proxy.
+bool ContainsDataReductionProxyDefaultHostSuffix(
+    const net::ProxyList& proxy_list) {
+  for (const net::ProxyServer& proxy : proxy_list.GetAll()) {
+    if (proxy.is_valid() && !proxy.is_direct() &&
+        base::EndsWith(proxy.host_port_pair().host(),
+                       kDataReductionProxyDefaultHostSuffix,
+                       base::CompareCase::SENSITIVE)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Searches |proxy_rules| for any Data Reduction Proxies, even if they don't
+// match a currently configured Data Reduction Proxy.
+bool ContainsDataReductionProxyDefaultHostSuffix(
+    const net::ProxyConfig::ProxyRules& proxy_rules) {
+  return ContainsDataReductionProxyDefaultHostSuffix(
+             proxy_rules.proxies_for_http) ||
+         ContainsDataReductionProxyDefaultHostSuffix(
+             proxy_rules.proxies_for_https);
+}
+
+// Extract the embedded PAC script from the given |pac_url|, and store the
+// extracted script in |pac_script|. Returns true if extraction was successful,
+// otherwise returns false. |pac_script| must not be NULL.
+bool GetEmbeddedPacScript(const std::string& pac_url, std::string* pac_script) {
+  DCHECK(pac_script);
+  const std::string kPacURLPrefix =
+      "data:application/x-ns-proxy-autoconfig;base64,";
+  return base::StartsWith(pac_url, kPacURLPrefix,
+                          base::CompareCase::SENSITIVE) &&
+         base::Base64Decode(pac_url.substr(kPacURLPrefix.size()), pac_script);
+}
+
+}  // namespace
+
+// The Data Reduction Proxy has been turned into a "best effort" proxy,
+// meaning it is used only if the effective proxy configuration resolves to
+// DIRECT for a URL. It no longer can be a ProxyConfig in the proxy preference
+// hierarchy. This method removes the Data Reduction Proxy configuration from
+// prefs, if present. |proxy_pref_name| is the name of the proxy pref.
+void IOSChromeDataReductionProxySettings::
+    MigrateDataReductionProxyOffProxyPrefs(PrefService* prefs) {
+  ProxyPrefMigrationResult proxy_pref_status =
+      MigrateDataReductionProxyOffProxyPrefsHelper(prefs);
+  UMA_HISTOGRAM_ENUMERATION(
+      "DataReductionProxy.ProxyPrefMigrationResult", proxy_pref_status,
+      IOSChromeDataReductionProxySettings::PROXY_PREF_MAX);
+}
+
+IOSChromeDataReductionProxySettings::ProxyPrefMigrationResult
+IOSChromeDataReductionProxySettings::
+    MigrateDataReductionProxyOffProxyPrefsHelper(PrefService* prefs) {
+  base::DictionaryValue* dict = (base::DictionaryValue*)prefs->GetUserPrefValue(
+      proxy_config::prefs::kProxy);
+  if (!dict)
+    return PROXY_PREF_NOT_CLEARED;
+
+  // Clear empty "proxy" dictionary created by a bug. See http://crbug/448172.
+  if (dict->empty()) {
+    prefs->ClearPref(proxy_config::prefs::kProxy);
+    return PROXY_PREF_CLEARED_EMPTY;
+  }
+
+  std::string mode;
+  if (!dict->GetString("mode", &mode))
+    return PROXY_PREF_NOT_CLEARED;
+  // Clear "system" proxy entry since this is the default. This entry was
+  // created by bug (http://crbug/448172).
+  if (ProxyModeToString(ProxyPrefs::MODE_SYSTEM) == mode) {
+    prefs->ClearPref(proxy_config::prefs::kProxy);
+    return PROXY_PREF_CLEARED_MODE_SYSTEM;
+  }
+
+  // From M36 to M40, the DRP was configured using MODE_FIXED_SERVERS in the
+  // proxy pref.
+  if (ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS) == mode) {
+    std::string proxy_server;
+    if (!dict->GetString("server", &proxy_server))
+      return PROXY_PREF_NOT_CLEARED;
+    net::ProxyConfig::ProxyRules proxy_rules;
+    proxy_rules.ParseFromString(proxy_server);
+    // Clear the proxy pref if it matches a currently configured Data Reduction
+    // Proxy, or if the proxy host ends with ".googlezip.net", in order to
+    // ensure that any DRP in the pref is cleared even if the DRP configuration
+    // was changed. See http://crbug.com/476610.
+    ProxyPrefMigrationResult rv;
+    if (Config()->ContainsDataReductionProxy(proxy_rules))
+      rv = PROXY_PREF_CLEARED_DRP;
+    else if (ContainsDataReductionProxyDefaultHostSuffix(proxy_rules))
+      rv = PROXY_PREF_CLEARED_GOOGLEZIP;
+    else
+      return PROXY_PREF_NOT_CLEARED;
+
+    prefs->ClearPref(proxy_config::prefs::kProxy);
+    return rv;
+  }
+
+  // Before M35, the DRP was configured using a PAC script base64 encoded into a
+  // PAC url.
+  if (ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT) == mode) {
+    std::string pac_url;
+    std::string pac_script;
+    if (!dict->GetString("pac_url", &pac_url) ||
+        !GetEmbeddedPacScript(pac_url, &pac_script)) {
+      return PROXY_PREF_NOT_CLEARED;
+    }
+
+    // In M35 and earlier, the way of specifying the DRP in a PAC script would
+    // always include the port number after the host even if the port number
+    // could be implied, so searching for ".googlezip.net:" in the PAC script
+    // indicates whether there's a proxy in that PAC script with a host of the
+    // form "*.googlezip.net".
+    if (pac_script.find(".googlezip.net:") == std::string::npos)
+      return PROXY_PREF_NOT_CLEARED;
+
+    prefs->ClearPref(proxy_config::prefs::kProxy);
+    return PROXY_PREF_CLEARED_PAC_GOOGLEZIP;
+  }
+
+  return PROXY_PREF_NOT_CLEARED;
+}
+
+IOSChromeDataReductionProxySettings::IOSChromeDataReductionProxySettings()
+    : data_reduction_proxy::DataReductionProxySettings() {}
+
+IOSChromeDataReductionProxySettings::~IOSChromeDataReductionProxySettings() {}
+
+void IOSChromeDataReductionProxySettings::Shutdown() {
+  data_reduction_proxy::DataReductionProxyService* service =
+      data_reduction_proxy_service();
+  if (service)
+    service->Shutdown();
+}
+
+void IOSChromeDataReductionProxySettings::InitDataReductionProxySettings(
+    data_reduction_proxy::DataReductionProxyIOData* io_data,
+    PrefService* profile_prefs,
+    net::URLRequestContextGetter* request_context_getter,
+    scoped_ptr<data_reduction_proxy::DataStore> store,
+    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& db_task_runner) {
+  // On mobile we write Data Reduction Proxy prefs directly to the pref service.
+  // On desktop we store Data Reduction Proxy prefs in memory, writing to disk
+  // every 60 minutes and on termination. Shutdown hooks must be added for
+  // Android and iOS in order for non-zero delays to be supported.
+  // (http://crbug.com/408264)
+  base::TimeDelta commit_delay = base::TimeDelta();
+
+  scoped_ptr<data_reduction_proxy::DataReductionProxyService> service =
+      make_scoped_ptr(new data_reduction_proxy::DataReductionProxyService(
+          this, profile_prefs, request_context_getter, store.Pass(),
+          ui_task_runner, io_data->io_task_runner(), db_task_runner,
+          commit_delay));
+  data_reduction_proxy::DataReductionProxySettings::
+      InitDataReductionProxySettings(profile_prefs, io_data, service.Pass());
+  io_data->SetDataReductionProxyService(
+      data_reduction_proxy_service()->GetWeakPtr());
+
+  data_reduction_proxy::DataReductionProxySettings::
+      SetCallbackToRegisterSyntheticFieldTrial(base::Bind(
+          &IOSChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial));
+  // TODO(bengr): Remove after M46. See http://crbug.com/445599.
+  MigrateDataReductionProxyOffProxyPrefs(profile_prefs);
+}
+
+// static
+data_reduction_proxy::Client IOSChromeDataReductionProxySettings::GetClient() {
+  return data_reduction_proxy::Client::CHROME_IOS;
+}
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h
new file mode 100644
index 0000000..29303b5f
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h
@@ -0,0 +1,87 @@
+// Copyright 2015 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_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_H_
+#define IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_H_
+
+#include "base/macros.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class PrefService;
+
+namespace base {
+class SequencedTaskRunner;
+class SingleThreadTaskRunner;
+}
+
+namespace data_reduction_proxy {
+class DataReductionProxyIOData;
+class DataStore;
+}
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+class PrefService;
+
+// Data reduction proxy settings class suitable for use with a Chrome browser.
+// It is keyed to a browser context.
+class IOSChromeDataReductionProxySettings
+    : public data_reduction_proxy::DataReductionProxySettings,
+      public KeyedService {
+ public:
+  // Enum values that can be reported for the
+  // DataReductionProxy.ProxyPrefMigrationResult histogram. These values must be
+  // kept in sync with their counterparts in histograms.xml. Visible here for
+  // testing purposes.
+  enum ProxyPrefMigrationResult {
+    PROXY_PREF_NOT_CLEARED = 0,
+    PROXY_PREF_CLEARED_EMPTY,
+    PROXY_PREF_CLEARED_MODE_SYSTEM,
+    PROXY_PREF_CLEARED_DRP,
+    PROXY_PREF_CLEARED_GOOGLEZIP,
+    PROXY_PREF_CLEARED_PAC_GOOGLEZIP,
+    PROXY_PREF_MAX
+  };
+
+  // Constructs a settings object. Construction and destruction must happen on
+  // the UI thread.
+  IOSChromeDataReductionProxySettings();
+
+  // Destructs the settings object.
+  ~IOSChromeDataReductionProxySettings() override;
+
+  // Overrides KeyedService::Shutdown:
+  void Shutdown() override;
+
+  // Initialize the settings object with the given io_data, prefs services,
+  // request context getter, data store, ui task runner, and db task runner.
+  void InitDataReductionProxySettings(
+      data_reduction_proxy::DataReductionProxyIOData* io_data,
+      PrefService* profile_prefs,
+      net::URLRequestContextGetter* request_context_getter,
+      scoped_ptr<data_reduction_proxy::DataStore> store,
+      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& db_task_runner);
+
+  // Gets the client type for the data reduction proxy.
+  static data_reduction_proxy::Client GetClient();
+
+  // Public for testing.
+  void MigrateDataReductionProxyOffProxyPrefs(PrefService* prefs);
+
+ private:
+  // Helper method for migrating the Data Reduction Proxy away from using the
+  // proxy pref. Returns the ProxyPrefMigrationResult value indicating the
+  // migration action taken.
+  ProxyPrefMigrationResult MigrateDataReductionProxyOffProxyPrefsHelper(
+      PrefService* prefs);
+
+  DISALLOW_COPY_AND_ASSIGN(IOSChromeDataReductionProxySettings);
+};
+
+#endif  // IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_H_
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.cc b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.cc
new file mode 100644
index 0000000..c4f13e7
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.cc
@@ -0,0 +1,40 @@
+// Copyright 2015 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 "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h"
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+#include "ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h"
+#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
+
+// static
+IOSChromeDataReductionProxySettings*
+IOSChromeDataReductionProxySettingsFactory::GetForBrowserState(
+    ios::ChromeBrowserState* browser_state) {
+  return static_cast<IOSChromeDataReductionProxySettings*>(
+      GetInstance()->GetServiceForBrowserState(browser_state, true));
+}
+
+// static
+IOSChromeDataReductionProxySettingsFactory*
+IOSChromeDataReductionProxySettingsFactory::GetInstance() {
+  return base::Singleton<IOSChromeDataReductionProxySettingsFactory>::get();
+}
+
+IOSChromeDataReductionProxySettingsFactory::
+    IOSChromeDataReductionProxySettingsFactory()
+    : BrowserStateKeyedServiceFactory(
+          "DataReductionProxySettings",
+          BrowserStateDependencyManager::GetInstance()) {}
+
+IOSChromeDataReductionProxySettingsFactory::
+    ~IOSChromeDataReductionProxySettingsFactory() {}
+
+scoped_ptr<KeyedService>
+IOSChromeDataReductionProxySettingsFactory::BuildServiceInstanceFor(
+    web::BrowserState* context) const {
+  return make_scoped_ptr(new IOSChromeDataReductionProxySettings);
+}
diff --git a/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h
new file mode 100644
index 0000000..53dba9c
--- /dev/null
+++ b/ios/chrome/browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h
@@ -0,0 +1,48 @@
+// Copyright 2015 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_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_FACTORY_H_
+#define IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_FACTORY_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+
+class IOSChromeDataReductionProxySettings;
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace ios {
+class ChromeBrowserState;
+}
+
+// Constucts a DataReductionProxySettings object suitable for use with a
+// Chrome browser.
+class IOSChromeDataReductionProxySettingsFactory
+    : public BrowserStateKeyedServiceFactory {
+ public:
+  // Returns a settings object for the given |browser_state|.
+  static IOSChromeDataReductionProxySettings* GetForBrowserState(
+      ios::ChromeBrowserState* browser_state);
+
+  // Returns an instance of this factory.
+  static IOSChromeDataReductionProxySettingsFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<
+      IOSChromeDataReductionProxySettingsFactory>;
+
+  IOSChromeDataReductionProxySettingsFactory();
+  ~IOSChromeDataReductionProxySettingsFactory() override;
+
+  // BrowserStateKeyedServiceFactory:
+  scoped_ptr<KeyedService> BuildServiceInstanceFor(
+      web::BrowserState* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(IOSChromeDataReductionProxySettingsFactory);
+};
+
+#endif  // IOS_CHROME_BROWSER_DATA_REDUCTION_PROXY_IOS_CHROME_DATA_REDUCTION_PROXY_SETTINGS_FACTORY_H_
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h
index 467612a..f996378 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h
@@ -12,6 +12,8 @@
 #include "base/macros.h"
 #include "components/metrics/metrics_service_accessor.h"
 
+class IOSChromeDataReductionProxySettings;
+
 namespace {
 class CrashesDOMHandler;
 }
@@ -23,10 +25,8 @@
  private:
   friend class IOSChromeMetricsServicesManagerClient;
 
-  // TODO(blundell): Remove these //chrome classes as friends once they're no
-  // longer used by the iOS port.
-  friend class ::CrashesDOMHandler;
-  friend class DataReductionProxyChromeSettings;
+  friend class CrashesDOMHandler;
+  friend class IOSChromeDataReductionProxySettings;
 
   FRIEND_TEST_ALL_PREFIXES(IOSChromeMetricsServiceAccessorTest,
                            MetricsReportingEnabled);
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index d0c3f31..daec3ab 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -224,6 +224,12 @@
         'browser/crash_report/crash_report_user_application_state.mm',
         'browser/crash_report/crash_upload_list.cc',
         'browser/crash_report/crash_upload_list.h',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.cc',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_io_data.h',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.cc',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings.h',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.cc',
+        'browser/data_reduction_proxy/ios_chrome_data_reduction_proxy_settings_factory.h',
         'browser/dom_distiller/distiller_viewer.cc',
         'browser/dom_distiller/distiller_viewer.h',
         'browser/dom_distiller/dom_distiller_service_factory.cc',
diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc
index e586ac88..6f35bec 100644
--- a/media/audio/virtual_audio_input_stream.cc
+++ b/media/audio/virtual_audio_input_stream.cc
@@ -10,43 +10,10 @@
 #include "base/bind.h"
 #include "base/single_thread_task_runner.h"
 #include "media/audio/virtual_audio_output_stream.h"
+#include "media/base/loopback_audio_converter.h"
 
 namespace media {
 
-// LoopbackAudioConverter works similar to AudioConverter and converts input
-// streams to different audio parameters. Then, the LoopbackAudioConverter can
-// be used as an input to another AudioConverter. This allows us to
-// use converted audio from AudioOutputStreams as input to an AudioConverter.
-// For example, this allows converting multiple streams into a common format and
-// using the converted audio as input to another AudioConverter (i.e. a mixer).
-class LoopbackAudioConverter : public AudioConverter::InputCallback {
- public:
-  LoopbackAudioConverter(const AudioParameters& input_params,
-                         const AudioParameters& output_params)
-      : audio_converter_(input_params, output_params, false) {}
-
-  ~LoopbackAudioConverter() override {}
-
-  void AddInput(AudioConverter::InputCallback* input) {
-    audio_converter_.AddInput(input);
-  }
-
-  void RemoveInput(AudioConverter::InputCallback* input) {
-    audio_converter_.RemoveInput(input);
-  }
-
- private:
-  double ProvideInput(AudioBus* audio_bus,
-                      base::TimeDelta buffer_delay) override {
-    audio_converter_.ConvertWithDelay(buffer_delay, audio_bus);
-    return 1.0;
-  }
-
-  AudioConverter audio_converter_;
-
-  DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter);
-};
-
 VirtualAudioInputStream::VirtualAudioInputStream(
     const AudioParameters& params,
     const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
@@ -109,8 +76,8 @@
   AudioConvertersMap::iterator converter = converters_.find(output_params);
   if (converter == converters_.end()) {
     std::pair<AudioConvertersMap::iterator, bool> result = converters_.insert(
-        std::make_pair(output_params,
-                       new LoopbackAudioConverter(output_params, params_)));
+        std::make_pair(output_params, new LoopbackAudioConverter(
+                                          output_params, params_, false)));
     converter = result.first;
 
     // Add to main mixer if we just added a new AudioTransform.
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index ee7c518a..041708f2 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -108,6 +108,8 @@
     "key_systems.h",
     "key_systems_support_uma.cc",
     "key_systems_support_uma.h",
+    "loopback_audio_converter.cc",
+    "loopback_audio_converter.h",
     "media.cc",
     "media.h",
     "media_client.cc",
diff --git a/media/base/audio_renderer_mixer.cc b/media/base/audio_renderer_mixer.cc
index 984798d..26171f9 100644
--- a/media/base/audio_renderer_mixer.cc
+++ b/media/base/audio_renderer_mixer.cc
@@ -13,10 +13,11 @@
 enum { kPauseDelaySeconds = 10 };
 
 AudioRendererMixer::AudioRendererMixer(
-    const AudioParameters& input_params, const AudioParameters& output_params,
+    const AudioParameters& output_params,
     const scoped_refptr<AudioRendererSink>& sink)
     : audio_sink_(sink),
-      audio_converter_(input_params, output_params, true),
+      output_params_(output_params),
+      master_converter_(output_params, output_params, true),
       pause_delay_(base::TimeDelta::FromSeconds(kPauseDelaySeconds)),
       last_play_time_(base::TimeTicks::Now()),
       // Initialize |playing_| to true since Start() results in an auto-play.
@@ -30,11 +31,13 @@
   audio_sink_->Stop();
 
   // Ensure that all mixer inputs have removed themselves prior to destruction.
-  DCHECK(audio_converter_.empty());
+  DCHECK(master_converter_.empty());
+  DCHECK(converters_.empty());
   DCHECK_EQ(error_callbacks_.size(), 0U);
 }
 
-void AudioRendererMixer::AddMixerInput(AudioConverter::InputCallback* input) {
+void AudioRendererMixer::AddMixerInput(const AudioParameters& input_params,
+                                       AudioConverter::InputCallback* input) {
   base::AutoLock auto_lock(lock_);
   if (!playing_) {
     playing_ = true;
@@ -42,13 +45,49 @@
     audio_sink_->Play();
   }
 
-  audio_converter_.AddInput(input);
+  int input_sample_rate = input_params.sample_rate();
+  if (is_master_sample_rate(input_sample_rate)) {
+    master_converter_.AddInput(input);
+  } else {
+    AudioConvertersMap::iterator converter =
+        converters_.find(input_sample_rate);
+    if (converter == converters_.end()) {
+      std::pair<AudioConvertersMap::iterator, bool> result =
+          converters_.insert(std::make_pair(
+              input_sample_rate, make_scoped_ptr(
+                                     // We expect all InputCallbacks to be
+                                     // capable of handling arbitrary buffer
+                                     // size requests, disabling FIFO.
+                                     new LoopbackAudioConverter(
+                                         input_params, output_params_, true))));
+      converter = result.first;
+
+      // Add newly-created resampler as an input to the master mixer.
+      master_converter_.AddInput(converter->second.get());
+    }
+    converter->second->AddInput(input);
+  }
 }
 
 void AudioRendererMixer::RemoveMixerInput(
+    const AudioParameters& input_params,
     AudioConverter::InputCallback* input) {
   base::AutoLock auto_lock(lock_);
-  audio_converter_.RemoveInput(input);
+
+  int input_sample_rate = input_params.sample_rate();
+  if (is_master_sample_rate(input_sample_rate)) {
+    master_converter_.RemoveInput(input);
+  } else {
+    AudioConvertersMap::iterator converter =
+        converters_.find(input_sample_rate);
+    DCHECK(converter != converters_.end());
+    converter->second->RemoveInput(input);
+    if (converter->second->empty()) {
+      // Remove converter when it's empty.
+      master_converter_.RemoveInput(converter->second.get());
+      converters_.erase(converter);
+    }
+  }
 }
 
 void AudioRendererMixer::AddErrorCallback(const base::Closure& error_cb) {
@@ -85,14 +124,14 @@
   // sink to avoid wasting resources when media elements are present but remain
   // in the pause state.
   const base::TimeTicks now = base::TimeTicks::Now();
-  if (!audio_converter_.empty()) {
+  if (!master_converter_.empty()) {
     last_play_time_ = now;
   } else if (now - last_play_time_ >= pause_delay_ && playing_) {
     audio_sink_->Pause();
     playing_ = false;
   }
 
-  audio_converter_.ConvertWithDelay(
+  master_converter_.ConvertWithDelay(
       base::TimeDelta::FromMilliseconds(audio_delay_milliseconds), audio_bus);
   return audio_bus->frames();
 }
diff --git a/media/base/audio_renderer_mixer.h b/media/base/audio_renderer_mixer.h
index 9bc3839..e8a0f8d 100644
--- a/media/base/audio_renderer_mixer.h
+++ b/media/base/audio_renderer_mixer.h
@@ -8,10 +8,12 @@
 #include <map>
 #include <string>
 
+#include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "media/base/audio_converter.h"
 #include "media/base/audio_renderer_sink.h"
+#include "media/base/loopback_audio_converter.h"
 
 namespace media {
 
@@ -21,14 +23,15 @@
 class MEDIA_EXPORT AudioRendererMixer
     : NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
  public:
-  AudioRendererMixer(const AudioParameters& input_params,
-                     const AudioParameters& output_params,
+  AudioRendererMixer(const AudioParameters& output_params,
                      const scoped_refptr<AudioRendererSink>& sink);
   ~AudioRendererMixer() override;
 
   // Add or remove a mixer input from mixing; called by AudioRendererMixerInput.
-  void AddMixerInput(AudioConverter::InputCallback* input);
-  void RemoveMixerInput(AudioConverter::InputCallback* input);
+  void AddMixerInput(const AudioParameters& input_params,
+                     AudioConverter::InputCallback* input);
+  void RemoveMixerInput(const AudioParameters& input_params,
+                        AudioConverter::InputCallback* input);
 
   // Since errors may occur even when no inputs are playing, an error callback
   // must be registered separately from adding a mixer input.  The same callback
@@ -47,13 +50,23 @@
   OutputDevice* GetOutputDevice();
 
  private:
+  // Maps input sample rate to the dedicated converter.
+  typedef std::map<int, scoped_ptr<LoopbackAudioConverter>> AudioConvertersMap;
+
   // AudioRendererSink::RenderCallback implementation.
   int Render(AudioBus* audio_bus, int audio_delay_milliseconds) override;
   void OnRenderError() override;
 
+  bool is_master_sample_rate(int sample_rate) {
+    return sample_rate == output_params_.sample_rate();
+  }
+
   // Output sink for this mixer.
   scoped_refptr<AudioRendererSink> audio_sink_;
 
+  // Output parameters for this mixer.
+  AudioParameters output_params_;
+
   // ---------------[ All variables below protected by |lock_| ]---------------
   base::Lock lock_;
 
@@ -61,8 +74,14 @@
   typedef std::list<base::Closure> ErrorCallbackList;
   ErrorCallbackList error_callbacks_;
 
-  // Handles mixing and resampling between input and output parameters.
-  AudioConverter audio_converter_;
+  // Each of these converters mixes inputs with a given sample rate and
+  // resamples them to the output sample rate. Inputs not reqiuring resampling
+  // go directly to |master_converter_|.
+  AudioConvertersMap converters_;
+
+  // Master converter which mixes all the outputs from |converters_| as well as
+  // mixer inputs that are in the output sample rate.
+  AudioConverter master_converter_;
 
   // Handles physical stream pause when no inputs are playing.  For latency
   // reasons we don't want to immediately pause the physical stream.
diff --git a/media/base/audio_renderer_mixer_input.cc b/media/base/audio_renderer_mixer_input.cc
index 9c5c3726..539cdf3 100644
--- a/media/base/audio_renderer_mixer_input.cc
+++ b/media/base/audio_renderer_mixer_input.cc
@@ -65,7 +65,7 @@
   // Stop() may be called at any time, if Pause() hasn't been called we need to
   // remove our mixer input before shutdown.
   if (playing_) {
-    mixer_->RemoveMixerInput(this);
+    mixer_->RemoveMixerInput(params_, this);
     playing_ = false;
   }
 
@@ -88,7 +88,7 @@
   if (playing_ || !mixer_)
     return;
 
-  mixer_->AddMixerInput(this);
+  mixer_->AddMixerInput(params_, this);
   playing_ = true;
 }
 
@@ -96,7 +96,7 @@
   if (!playing_ || !mixer_)
     return;
 
-  mixer_->RemoveMixerInput(this);
+  mixer_->RemoveMixerInput(params_, this);
   playing_ = false;
 }
 
diff --git a/media/base/audio_renderer_mixer_input_unittest.cc b/media/base/audio_renderer_mixer_input_unittest.cc
index 2f8f9772..8cc9e46 100644
--- a/media/base/audio_renderer_mixer_input_unittest.cc
+++ b/media/base/audio_renderer_mixer_input_unittest.cc
@@ -67,8 +67,7 @@
       EXPECT_CALL(*sink.get(), Start());
       EXPECT_CALL(*sink.get(), Stop());
 
-      mixers_[idx].reset(
-          new AudioRendererMixer(audio_parameters_, audio_parameters_, sink));
+      mixers_[idx].reset(new AudioRendererMixer(audio_parameters_, sink));
     }
     EXPECT_CALL(*this, RemoveMixer(testing::_, device_id, testing::_));
 
diff --git a/media/base/audio_renderer_mixer_unittest.cc b/media/base/audio_renderer_mixer_unittest.cc
index b218fa0..8d2b5d4 100644
--- a/media/base/audio_renderer_mixer_unittest.cc
+++ b/media/base/audio_renderer_mixer_unittest.cc
@@ -23,6 +23,7 @@
 
 // Parameters which control the many input case tests.
 const int kMixerInputs = 8;
+const int kOddMixerInputs = 7;
 const int kMixerCycles = 3;
 
 // Parameters used for testing.
@@ -34,22 +35,37 @@
 // Number of full sine wave cycles for each Render() call.
 const int kSineCycles = 4;
 
-// Default device ID
+// Default device ID.
 const std::string kDefaultDeviceId;
 const url::Origin kDefaultSecurityOrigin;
 
-// Tuple of <input sampling rate, output sampling rate, epsilon>.
-typedef std::tr1::tuple<int, int, double> AudioRendererMixerTestData;
+// Input sample frequencies for testing.
+std::vector<int> kTestInputLower(1, 44100);
+std::vector<int> kTestInputHigher(1, 48000);
+const int kSampleRates[] = {22050, 44100, 48000};
+std::vector<int> kTestInput3Rates(kSampleRates,
+                                  kSampleRates +
+                                      sizeof(kSampleRates) /
+                                          sizeof(kSampleRates[0]));
+
+// Tuple of <input sampling rates, output sampling rate, epsilon>.
+typedef std::tr1::tuple<std::vector<int>, int, double>
+    AudioRendererMixerTestData;
+
 class AudioRendererMixerTest
     : public testing::TestWithParam<AudioRendererMixerTestData> {
  public:
   AudioRendererMixerTest()
       : epsilon_(std::tr1::get<2>(GetParam())),
         half_fill_(false) {
-    // Create input and output parameters based on test parameters.
-    input_parameters_ = AudioParameters(
-        AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
-        std::tr1::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize);
+    // Create input parameters based on test parameters.
+    const std::vector<int>& sample_rates(std::tr1::get<0>(GetParam()));
+    for (size_t i = 0; i < sample_rates.size(); ++i)
+      input_parameters_.push_back(AudioParameters(
+          AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, sample_rates[i],
+          kBitsPerChannel, kHighLatencyBufferSize));
+
+    // Create output parameters based on test parameters.
     output_parameters_ = AudioParameters(
         AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout,
         std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize);
@@ -58,8 +74,7 @@
     EXPECT_CALL(*sink_.get(), Start());
     EXPECT_CALL(*sink_.get(), Stop());
 
-    mixer_.reset(new AudioRendererMixer(
-        input_parameters_, output_parameters_, sink_));
+    mixer_.reset(new AudioRendererMixer(output_parameters_, sink_));
     mixer_callback_ = sink_->callback();
 
     audio_bus_ = AudioBus::Create(output_parameters_);
@@ -83,28 +98,35 @@
                     const std::string&,
                     const url::Origin&));
 
-  void InitializeInputs(int count) {
-    mixer_inputs_.reserve(count);
-    fake_callbacks_.reserve(count);
+  void InitializeInputs(int inputs_per_sample_rate) {
+    mixer_inputs_.reserve(inputs_per_sample_rate * input_parameters_.size());
+    fake_callbacks_.reserve(inputs_per_sample_rate * input_parameters_.size());
 
-    // Setup FakeAudioRenderCallback step to compensate for resampling.
-    double scale_factor = input_parameters_.sample_rate() /
-        static_cast<double>(output_parameters_.sample_rate());
-    double step = kSineCycles / (scale_factor *
-        static_cast<double>(output_parameters_.frames_per_buffer()));
+    for (size_t i = 0, input = 0; i < input_parameters_.size(); ++i) {
+      // Setup FakeAudioRenderCallback step to compensate for resampling.
+      double scale_factor =
+          input_parameters_[i].sample_rate() /
+          static_cast<double>(output_parameters_.sample_rate());
+      double step =
+          kSineCycles /
+          (scale_factor *
+           static_cast<double>(output_parameters_.frames_per_buffer()));
 
-    for (int i = 0; i < count; ++i) {
-      fake_callbacks_.push_back(new FakeAudioRenderCallback(step));
-      mixer_inputs_.push_back(new AudioRendererMixerInput(
-          base::Bind(&AudioRendererMixerTest::GetMixer, base::Unretained(this)),
-          base::Bind(&AudioRendererMixerTest::RemoveMixer,
-                     base::Unretained(this)),
-          kDefaultDeviceId, kDefaultSecurityOrigin));
-      mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]);
-      mixer_inputs_[i]->SetVolume(1.0f);
+      for (int j = 0; j < inputs_per_sample_rate; ++j, ++input) {
+        fake_callbacks_.push_back(new FakeAudioRenderCallback(step));
+        mixer_inputs_.push_back(new AudioRendererMixerInput(
+            base::Bind(&AudioRendererMixerTest::GetMixer,
+                       base::Unretained(this)),
+            base::Bind(&AudioRendererMixerTest::RemoveMixer,
+                       base::Unretained(this)),
+            kDefaultDeviceId, kDefaultSecurityOrigin));
+        mixer_inputs_[input]->Initialize(input_parameters_[i],
+                                         fake_callbacks_[input]);
+        mixer_inputs_[input]->SetVolume(1.0f);
+      }
     }
     EXPECT_CALL(*this, RemoveMixer(testing::_, testing::_, testing::_))
-        .Times(count);
+        .Times(mixer_inputs_.size());
   }
 
   bool ValidateAudioData(int index, int frames, float scale, double epsilon) {
@@ -112,9 +134,11 @@
       for (int j = index; j < frames; j++) {
         double error = fabs(audio_bus_->channel(i)[j] -
             expected_audio_bus_->channel(i)[j] * scale);
-        if (error > epsilon) {
+        // The second comparison is for the case when scale is set to 0
+        // (and less that 1 in general)
+        if ((error > epsilon * scale) && (error > epsilon)) {
           EXPECT_NEAR(expected_audio_bus_->channel(i)[j] * scale,
-                      audio_bus_->channel(i)[j], epsilon)
+                      audio_bus_->channel(i)[j], epsilon * scale)
               << " i=" << i << ", j=" << j;
           return false;
         }
@@ -279,13 +303,40 @@
     EXPECT_TRUE(RenderAndValidateAudioData(0.0f));
   }
 
+  // Verify output when mixer inputs in mixed post-Stop() and post-Play()
+  // states.
+  void MixedStopPlayTest(int inputs) {
+    InitializeInputs(inputs);
+
+    // Start() all inputs.
+    for (size_t i = 0; i < mixer_inputs_.size(); ++i)
+      mixer_inputs_[i]->Start();
+
+    // Stop() all even numbered mixer inputs and Play() all odd numbered inputs
+    // and ensure we get the right value.
+    for (size_t i = 1; i < mixer_inputs_.size(); i += 2) {
+      mixer_inputs_[i - 1]->Stop();
+      mixer_inputs_[i]->Play();
+    }
+
+    // Stop the last input in case the number of inputs is odd
+    if (mixer_inputs_.size() % 2)
+      mixer_inputs_[mixer_inputs_.size() - 1]->Stop();
+
+    ASSERT_TRUE(RenderAndValidateAudioData(
+        std::max(1.f, static_cast<float>(floor(mixer_inputs_.size() / 2.f)))));
+
+    for (size_t i = 1; i < mixer_inputs_.size(); i += 2)
+      mixer_inputs_[i]->Stop();
+  }
+
  protected:
   virtual ~AudioRendererMixerTest() {}
 
   scoped_refptr<MockAudioRendererSink> sink_;
   scoped_ptr<AudioRendererMixer> mixer_;
   AudioRendererSink::RenderCallback* mixer_callback_;
-  AudioParameters input_parameters_;
+  std::vector<AudioParameters> input_parameters_;
   AudioParameters output_parameters_;
   scoped_ptr<AudioBus> audio_bus_;
   scoped_ptr<AudioBus> expected_audio_bus_;
@@ -373,23 +424,13 @@
 
 // Test mixer with many inputs in mixed post-Stop() and post-Play() states.
 TEST_P(AudioRendererMixerTest, ManyInputMixedStopPlay) {
-  InitializeInputs(kMixerInputs);
+  MixedStopPlayTest(kMixerInputs);
+}
 
-  // Start() all inputs.
-  for (size_t i = 0; i < mixer_inputs_.size(); ++i)
-    mixer_inputs_[i]->Start();
-
-  // Stop() all even numbered mixer inputs and Play() all odd numbered inputs
-  // and ensure we get the right value.
-  for (size_t i = 1; i < mixer_inputs_.size(); i += 2) {
-    mixer_inputs_[i - 1]->Stop();
-    mixer_inputs_[i]->Play();
-  }
-  ASSERT_TRUE(RenderAndValidateAudioData(std::max(
-      mixer_inputs_.size() / 2, static_cast<size_t>(1))));
-
-  for (size_t i = 1; i < mixer_inputs_.size(); i += 2)
-    mixer_inputs_[i]->Stop();
+// Test mixer with many inputs in mixed post-Stop() and post-Play() states.
+TEST_P(AudioRendererMixerTest, ManyInputMixedStopPlayOdd) {
+  // Odd number of inputs per sample rate, to stop them unevenly.
+  MixedStopPlayTest(kOddMixerInputs);
 }
 
 TEST_P(AudioRendererMixerBehavioralTest, OnRenderError) {
@@ -474,22 +515,36 @@
 }
 
 INSTANTIATE_TEST_CASE_P(
-    AudioRendererMixerTest, AudioRendererMixerTest, testing::Values(
-        // No resampling.
-        std::tr1::make_tuple(44100, 44100, 0.00000048),
+    AudioRendererMixerTest,
+    AudioRendererMixerTest,
+    testing::Values(
+        // No resampling, 1 input sample rate.
+        std::tr1::make_tuple(kTestInputLower, kTestInputLower[0], 0.00000048),
 
-        // Upsampling.
-        std::tr1::make_tuple(44100, 48000, 0.033),
+        // Upsampling, 1 input sample rate.
+        std::tr1::make_tuple(kTestInputLower, kTestInputHigher[0], 0.01),
 
-        // Downsampling.
-        std::tr1::make_tuple(48000, 41000, 0.042)));
+        // Downsampling, 1 input sample rate.
+        std::tr1::make_tuple(kTestInputHigher, kTestInputLower[0], 0.01),
+
+        // Downsampling, multuple input sample rates.
+        std::tr1::make_tuple(kTestInput3Rates, kTestInput3Rates[0], 0.01),
+
+        // Upsampling, multiple sinput sample rates.
+        std::tr1::make_tuple(kTestInput3Rates, kTestInput3Rates[2], 0.01),
+
+        // Both downsampling and upsampling, multiple input sample rates
+        std::tr1::make_tuple(kTestInput3Rates, kTestInput3Rates[1], 0.01)));
 
 // Test cases for behavior which is independent of parameters.  Values() doesn't
 // support single item lists and we don't want these test cases to run for every
 // parameter set.
 INSTANTIATE_TEST_CASE_P(
-    AudioRendererMixerBehavioralTest, AudioRendererMixerBehavioralTest,
+    AudioRendererMixerBehavioralTest,
+    AudioRendererMixerBehavioralTest,
     testing::ValuesIn(std::vector<AudioRendererMixerTestData>(
-        1, std::tr1::make_tuple(44100, 44100, 0))));
-
+        1,
+        std::tr1::make_tuple(kTestInputLower,
+                             kTestInputLower[0],
+                             0.00000048))));
 }  // namespace media
diff --git a/media/base/loopback_audio_converter.cc b/media/base/loopback_audio_converter.cc
new file mode 100644
index 0000000..0ae3df1
--- /dev/null
+++ b/media/base/loopback_audio_converter.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/loopback_audio_converter.h"
+
+namespace media {
+
+LoopbackAudioConverter::LoopbackAudioConverter(
+    const AudioParameters& input_params,
+    const AudioParameters& output_params,
+    bool disable_fifo)
+    : audio_converter_(input_params, output_params, disable_fifo) {}
+
+LoopbackAudioConverter::~LoopbackAudioConverter() {}
+
+double LoopbackAudioConverter::ProvideInput(AudioBus* audio_bus,
+                                            base::TimeDelta buffer_delay) {
+  audio_converter_.ConvertWithDelay(buffer_delay, audio_bus);
+  return 1.0;
+}
+
+}  // namespace media
diff --git a/media/base/loopback_audio_converter.h b/media/base/loopback_audio_converter.h
new file mode 100644
index 0000000..9bfd00f2
--- /dev/null
+++ b/media/base/loopback_audio_converter.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_BASE_LOOPBACK_AUDIO_CONVERTER_H_
+#define MEDIA_BASE_LOOPBACK_AUDIO_CONVERTER_H_
+
+#include "base/macros.h"
+#include "media/base/audio_converter.h"
+
+namespace media {
+
+// LoopbackAudioConverter works similar to AudioConverter and converts input
+// streams to different audio parameters. Then, the LoopbackAudioConverter can
+// be used as an input to another AudioConverter. This allows us to
+// use converted audio from AudioOutputStreams as input to an AudioConverter.
+// For example, this allows converting multiple streams into a common format and
+// using the converted audio as input to another AudioConverter (i.e. a mixer).
+class LoopbackAudioConverter : public AudioConverter::InputCallback {
+ public:
+  LoopbackAudioConverter(const AudioParameters& input_params,
+                         const AudioParameters& output_params,
+                         bool disable_fifo);
+
+  ~LoopbackAudioConverter() override;
+
+  void AddInput(AudioConverter::InputCallback* input) {
+    audio_converter_.AddInput(input);
+  }
+
+  void RemoveInput(AudioConverter::InputCallback* input) {
+    audio_converter_.RemoveInput(input);
+  }
+
+  bool empty() { return audio_converter_.empty(); }
+
+ private:
+  double ProvideInput(AudioBus* audio_bus,
+                      base::TimeDelta buffer_delay) override;
+
+  AudioConverter audio_converter_;
+
+  DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_BASE_LOOPBACK_AUDIO_CONVERTER_H_
diff --git a/media/base/video_capture_types.cc b/media/base/video_capture_types.cc
index f68eeb38a..1bd91faa 100644
--- a/media/base/video_capture_types.cc
+++ b/media/base/video_capture_types.cc
@@ -69,8 +69,10 @@
 
 //static
 std::string VideoCaptureFormat::ToString(const VideoCaptureFormat& format) {
+  // Beware: This string is parsed by manager.js:parseVideoCaptureFormat_,
+  // take care when changing the formatting.
   return base::StringPrintf(
-      "(%s)@%.3ffps, pixel format: %s storage: %s.",
+      "(%s)@%.3ffps, pixel format: %s, storage: %s",
       format.frame_size.ToString().c_str(), format.frame_rate,
       VideoPixelFormatToString(format.pixel_format).c_str(),
       PixelStorageToString(format.pixel_storage).c_str());
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc
index 0f07b4a7..79d7702 100644
--- a/media/filters/audio_decoder_unittest.cc
+++ b/media/filters/audio_decoder_unittest.cc
@@ -407,7 +407,7 @@
       base::TimeDelta::FromMilliseconds(80),
       // Use a different codec delay than in the extradata.
       100);
-  InitializeDecoderWithResult(decoder_config, false);
+  InitializeDecoderWithResult(decoder_config, true);
 }
 
 #if defined(OPUS_FIXED_POINT)
diff --git a/media/filters/opus_audio_decoder.cc b/media/filters/opus_audio_decoder.cc
index 01539ab..2fd9950 100644
--- a/media/filters/opus_audio_decoder.cc
+++ b/media/filters/opus_audio_decoder.cc
@@ -258,10 +258,13 @@
   }
 
   if (config_.codec_delay() != opus_extra_data.skip_samples) {
-    DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the "
-                << "value in Opus Extra Data. " << config_.codec_delay()
-                << " vs " << opus_extra_data.skip_samples;
-    return false;
+    DLOG(WARNING) << "Invalid file. Codec Delay in container does not match "
+                  << "the value in Opus Extra Data. " << config_.codec_delay()
+                  << " vs " << opus_extra_data.skip_samples;
+    config_.Initialize(config_.codec(), config_.sample_format(),
+                       config_.channel_layout(), config_.samples_per_second(),
+                       config_.extra_data(), config_.is_encrypted(),
+                       config_.seek_preroll(), opus_extra_data.skip_samples);
   }
 
   uint8 channel_mapping[OPUS_MAX_VORBIS_CHANNELS] = {0};
diff --git a/media/media.gyp b/media/media.gyp
index 4b25ca1..67cbe5d 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -304,6 +304,8 @@
         'base/key_systems_support_uma.h',
         'base/keyboard_event_counter.cc',
         'base/keyboard_event_counter.h',
+        'base/loopback_audio_converter.cc',
+        'base/loopback_audio_converter.h',
         'base/mac/avfoundation_glue.h',
         'base/mac/avfoundation_glue.mm',
         'base/mac/coremedia_glue.h',
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index be2a1d5..5fe9f213 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -149,11 +149,10 @@
 }
 
 void MidiManager::AccumulateMidiBytesSent(MidiManagerClient* client, size_t n) {
-  {
-    base::AutoLock auto_lock(lock_);
-    if (clients_.find(client) == clients_.end())
-      return;
-  }
+  base::AutoLock auto_lock(lock_);
+  if (clients_.find(client) == clients_.end())
+    return;
+
   client->AccumulateMidiBytesSent(n);
 }
 
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index 7f213730..ad802c5 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -299,8 +299,8 @@
 
   // Acknowledge send.
   send_thread_.message_loop()->PostTask(
-      FROM_HERE, base::Bind(&MidiManagerClient::AccumulateMidiBytesSent,
-                            base::Unretained(client), data.size()));
+      FROM_HERE, base::Bind(&MidiManagerAlsa::AccumulateMidiBytesSent,
+                            base::Unretained(this), client, data.size()));
 }
 
 MidiManagerAlsa::MidiPort::Id::Id() = default;
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
index 6e3e2a64..fc9e5f0 100644
--- a/mojo/gles2/command_buffer_client_impl.cc
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -43,95 +43,17 @@
   return true;
 }
 
+template <typename T>
+void Copy(T* output, T input) {
+  *output = std::move(input);
+}
+
 }  // namespace
 
 CommandBufferDelegate::~CommandBufferDelegate() {}
 
 void CommandBufferDelegate::ContextLost() {}
 
-class CommandBufferClientImpl::SyncClientImpl
-    : public mus::mojom::CommandBufferSyncClient {
- public:
-  SyncClientImpl(mus::mojom::CommandBufferSyncClientPtr* ptr,
-                 const MojoAsyncWaiter* async_waiter)
-      : initialized_successfully_(false),
-        command_buffer_id_(0),
-        binding_(this, ptr, async_waiter) {}
-
-  bool WaitForInitialization() {
-    base::ThreadRestrictions::ScopedAllowWait wait;
-    if (!binding_.WaitForIncomingMethodCall())
-      return false;
-    return initialized_successfully_;
-  }
-
-  mus::mojom::CommandBufferStatePtr WaitForProgress() {
-    base::ThreadRestrictions::ScopedAllowWait wait;
-    if (!binding_.WaitForIncomingMethodCall())
-      return mus::mojom::CommandBufferStatePtr();
-    return command_buffer_state_.Pass();
-  }
-
-  gpu::Capabilities GetCapabilities() {
-    if (capabilities_)
-      return capabilities_.To<gpu::Capabilities>();
-    return gpu::Capabilities();
-  }
-
-  uint64_t GetCommandBufferID() const {
-    return command_buffer_id_;
-  }
-
- private:
-  // CommandBufferSyncClient methods:
-  void DidInitialize(bool success,
-                     int32_t command_buffer_namespace,
-                     uint64_t command_buffer_id,
-                     mus::mojom::GpuCapabilitiesPtr capabilities) override {
-    DCHECK_EQ(command_buffer_namespace, gpu::CommandBufferNamespace::MOJO);
-    initialized_successfully_ = success;
-    command_buffer_id_ = command_buffer_id;
-    capabilities_ = capabilities.Pass();
-  }
-  void DidMakeProgress(mus::mojom::CommandBufferStatePtr state) override {
-    command_buffer_state_ = state.Pass();
-  }
-
-  bool initialized_successfully_;
-  uint64_t command_buffer_id_;
-  mus::mojom::GpuCapabilitiesPtr capabilities_;
-  mus::mojom::CommandBufferStatePtr command_buffer_state_;
-  mojo::Binding<mus::mojom::CommandBufferSyncClient> binding_;
-
-  DISALLOW_COPY_AND_ASSIGN(SyncClientImpl);
-};
-
-class CommandBufferClientImpl::SyncPointClientImpl
-    : public mus::mojom::CommandBufferSyncPointClient {
- public:
-  SyncPointClientImpl(mus::mojom::CommandBufferSyncPointClientPtr* ptr,
-                      const MojoAsyncWaiter* async_waiter)
-      : sync_point_(0u), binding_(this, ptr, async_waiter) {}
-
-  uint32_t WaitForInsertSyncPoint() {
-    base::ThreadRestrictions::ScopedAllowWait wait;
-    if (!binding_.WaitForIncomingMethodCall())
-      return 0u;
-    uint32_t result = sync_point_;
-    sync_point_ = 0u;
-    return result;
-  }
-
- private:
-  void DidInsertSyncPoint(uint32_t sync_point) override {
-    sync_point_ = sync_point;
-  }
-
-  uint32_t sync_point_;
-
-  mojo::Binding<mus::mojom::CommandBufferSyncPointClient> binding_;
-};
-
 CommandBufferClientImpl::CommandBufferClientImpl(
     CommandBufferDelegate* delegate,
     const std::vector<int32_t>& attribs,
@@ -140,6 +62,7 @@
     : delegate_(delegate),
       attribs_(attribs),
       observer_binding_(this),
+      command_buffer_id_(0),
       shared_state_(NULL),
       last_put_offset_(-1),
       next_transfer_buffer_id_(0),
@@ -169,27 +92,26 @@
 
   shared_state()->Initialize();
 
-  mus::mojom::CommandBufferSyncClientPtr sync_client;
-  sync_client_impl_.reset(new SyncClientImpl(&sync_client, async_waiter_));
-
-  mus::mojom::CommandBufferSyncPointClientPtr sync_point_client;
-  sync_point_client_impl_.reset(
-      new SyncPointClientImpl(&sync_point_client, async_waiter_));
-
   mus::mojom::CommandBufferLostContextObserverPtr observer_ptr;
   observer_binding_.Bind(GetProxy(&observer_ptr), async_waiter_);
-  command_buffer_->Initialize(sync_client.Pass(),
-                              sync_point_client.Pass(),
-                              observer_ptr.Pass(),
-                              duped.Pass(),
-                              mojo::Array<int32_t>::From(attribs_));
+  mus::mojom::CommandBufferInfoPtr info;
+  command_buffer_->Initialize(
+      observer_ptr.Pass(), duped.Pass(), mojo::Array<int32_t>::From(attribs_),
+      base::Bind(&Copy<mus::mojom::CommandBufferInfoPtr>, &info));
 
-  // Wait for DidInitialize to come on the sync client pipe.
-  if (!sync_client_impl_->WaitForInitialization()) {
-    VLOG(1) << "Channel encountered error while creating command buffer";
+  if (!command_buffer_.WaitForIncomingResponse()) {
+    VLOG(1) << "Channel encountered error while creating command buffer.";
     return false;
   }
-  capabilities_ = sync_client_impl_->GetCapabilities();
+
+  if (!info) {
+    VLOG(1) << "Command buffer cannot be initialized successfully.";
+    return false;
+  }
+
+  DCHECK_EQ(gpu::CommandBufferNamespace::MOJO, info->command_buffer_namespace);
+  command_buffer_id_ = info->command_buffer_id;
+  capabilities_ = info->capabilities.To<gpu::Capabilities>();
   return true;
 }
 
@@ -345,13 +267,23 @@
 }
 
 uint32_t CommandBufferClientImpl::InsertSyncPoint() {
-  command_buffer_->InsertSyncPoint(true);
-  return sync_point_client_impl_->WaitForInsertSyncPoint();
+  uint32_t sync_point = 0;
+  command_buffer_->InsertSyncPoint(true,
+                                   base::Bind(&Copy<uint32_t>, &sync_point));
+  if (!command_buffer_.WaitForIncomingResponse()) {
+    VLOG(1) << "Channel encountered error while creating command buffer.";
+  }
+  return sync_point;
 }
 
 uint32_t CommandBufferClientImpl::InsertFutureSyncPoint() {
-  command_buffer_->InsertSyncPoint(false);
-  return sync_point_client_impl_->WaitForInsertSyncPoint();
+  uint32_t sync_point = 0;
+  command_buffer_->InsertSyncPoint(false,
+                                   base::Bind(&Copy<uint32_t>, &sync_point));
+  if (!command_buffer_.WaitForIncomingResponse()) {
+    VLOG(1) << "Channel encountered error while creating command buffer.";
+  }
+  return sync_point;
 }
 
 void CommandBufferClientImpl::RetireSyncPoint(uint32_t sync_point) {
@@ -382,12 +314,12 @@
 }
 
 void CommandBufferClientImpl::MakeProgressAndUpdateState() {
-  command_buffer_->MakeProgress(last_state_.get_offset);
-
-  mus::mojom::CommandBufferStatePtr state =
-      sync_client_impl_->WaitForProgress();
-  if (!state) {
-    VLOG(1) << "Channel encountered error while waiting for command buffer";
+  mus::mojom::CommandBufferStatePtr state;
+  command_buffer_->MakeProgress(
+      last_state_.get_offset,
+      base::Bind(&Copy<mus::mojom::CommandBufferStatePtr>, &state));
+  if (!command_buffer_.WaitForIncomingResponse()) {
+    VLOG(1) << "Channel encountered error while waiting for command buffer.";
     // TODO(piman): is it ok for this to re-enter?
     DidLoseContext(gpu::error::kUnknown);
     return;
@@ -410,7 +342,7 @@
 }
 
 uint64_t CommandBufferClientImpl::GetCommandBufferID() const {
-  return sync_client_impl_->GetCommandBufferID();
+  return command_buffer_id_;
 }
 
 uint64_t CommandBufferClientImpl::GenerateFenceSyncRelease() {
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h
index 92524f6..7d7d38f5 100644
--- a/mojo/gles2/command_buffer_client_impl.h
+++ b/mojo/gles2/command_buffer_client_impl.h
@@ -84,9 +84,6 @@
   bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override;
 
  private:
-  class SyncClientImpl;
-  class SyncPointClientImpl;
-
   // mus::mojom::CommandBufferLostContextObserver implementation:
   void DidLoseContext(int32_t lost_reason) override;
 
@@ -99,9 +96,8 @@
   std::vector<int32_t> attribs_;
   mojo::Binding<mus::mojom::CommandBufferLostContextObserver> observer_binding_;
   mus::mojom::CommandBufferPtr command_buffer_;
-  scoped_ptr<SyncClientImpl> sync_client_impl_;
-  scoped_ptr<SyncPointClientImpl> sync_point_client_impl_;
 
+  uint64_t command_buffer_id_;
   gpu::Capabilities capabilities_;
   State last_state_;
   mojo::ScopedSharedBufferHandle shared_state_handle_;
diff --git a/net/base/net_error_details.h b/net/base/net_error_details.h
new file mode 100644
index 0000000..d330e91a
--- /dev/null
+++ b/net/base/net_error_details.h
@@ -0,0 +1,25 @@
+// Copyright 2015 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 NET_BASE_NET_ERROR_DETAILS_H_
+#define NET_BASE_NET_ERROR_DETAILS_H_
+
+#include "net/base/net_errors.h"
+
+namespace net {
+
+// A record of net errors with granular error specification generated by
+// net stack.
+struct NET_EXPORT NetErrorDetails {
+  NetErrorDetails() : quic_broken(false) {}
+
+  NetErrorDetails(bool quic_broken) : quic_broken(quic_broken) {}
+
+  // True if all QUIC alternative services are marked broken for the origin.
+  bool quic_broken;
+};
+
+}  // namespace net
+
+#endif
diff --git a/net/http/failing_http_transaction_factory.cc b/net/http/failing_http_transaction_factory.cc
index fb593f0e..c15af21 100644
--- a/net/http/failing_http_transaction_factory.cc
+++ b/net/http/failing_http_transaction_factory.cc
@@ -13,6 +13,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "net/base/load_timing_info.h"
+#include "net/base/net_error_details.h"
 #include "net/base/upload_progress.h"
 #include "net/http/http_response_info.h"
 #include "net/socket/connection_attempts.h"
@@ -61,6 +62,7 @@
   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
   void SetPriority(RequestPriority priority) override;
   void SetWebSocketHandshakeStreamCreateHelper(
       WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -162,6 +164,11 @@
   return false;
 }
 
+void FailingHttpTransaction::PopulateNetErrorDetails(
+    NetErrorDetails* details) const {
+  return;
+}
+
 void FailingHttpTransaction::SetPriority(RequestPriority priority)  {}
 
 void FailingHttpTransaction::SetWebSocketHandshakeStreamCreateHelper(
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 38b100d..39a65f3 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -31,7 +31,6 @@
 #include "net/base/auth.h"
 #include "net/base/load_flags.h"
 #include "net/base/load_timing_info.h"
-#include "net/base/net_errors.h"
 #include "net/base/upload_data_stream.h"
 #include "net/cert/cert_status_flags.h"
 #include "net/cert/x509_certificate.h"
@@ -612,6 +611,13 @@
   return false;
 }
 
+void HttpCache::Transaction::PopulateNetErrorDetails(
+    NetErrorDetails* details) const {
+  if (network_trans_)
+    return network_trans_->PopulateNetErrorDetails(details);
+  return;
+}
+
 void HttpCache::Transaction::SetPriority(RequestPriority priority) {
   priority_ = priority;
   if (network_trans_)
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index 3256c1a..ac84578 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -22,6 +22,7 @@
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
 #include "net/base/request_priority.h"
 #include "net/base/upload_progress.h"
 #include "net/http/http_cache.h"
@@ -154,6 +155,7 @@
   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
   void SetPriority(RequestPriority priority) override;
   void SetWebSocketHandshakeStreamCreateHelper(
       WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 339bb75..62b2117 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -153,7 +153,8 @@
       total_sent_bytes_(0),
       next_state_(STATE_NONE),
       establishing_tunnel_(false),
-      websocket_handshake_stream_base_create_helper_(NULL) {
+      websocket_handshake_stream_base_create_helper_(NULL),
+      quic_broken_(false) {
   session->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
   session->GetAlpnProtos(&server_ssl_config_.alpn_protos);
   session->GetNpnProtos(&server_ssl_config_.npn_protos);
@@ -465,6 +466,11 @@
   return true;
 }
 
+void HttpNetworkTransaction::PopulateNetErrorDetails(
+    NetErrorDetails* details) const {
+  details->quic_broken = quic_broken_;
+}
+
 void HttpNetworkTransaction::SetPriority(RequestPriority priority) {
   priority_ = priority;
   if (stream_request_)
@@ -610,6 +616,10 @@
   OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
 }
 
+void HttpNetworkTransaction::OnQuicBroken() {
+  quic_broken_ = true;
+}
+
 void HttpNetworkTransaction::GetConnectionAttempts(
     ConnectionAttempts* out) const {
   *out = connection_attempts_;
@@ -1464,6 +1474,7 @@
   response_ = HttpResponseInfo();
   establishing_tunnel_ = false;
   remote_endpoint_ = IPEndPoint();
+  quic_broken_ = false;
 }
 
 void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) {
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 32dd905..c087ac8b 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -14,6 +14,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
+#include "net/base/net_error_details.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_auth.h"
 #include "net/http/http_request_headers.h"
@@ -75,6 +76,7 @@
   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
   void SetPriority(RequestPriority priority) override;
   void SetWebSocketHandshakeStreamCreateHelper(
       WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -109,6 +111,7 @@
                                   const ProxyInfo& used_proxy_info,
                                   HttpStream* stream) override;
 
+  void OnQuicBroken() override;
   void GetConnectionAttempts(ConnectionAttempts* out) const override;
 
  private:
@@ -358,6 +361,10 @@
   ConnectionAttempts connection_attempts_;
   IPEndPoint remote_endpoint_;
 
+  // True when all QUIC alternative services are marked broken for the origin
+  // in this request which advertises supporting QUIC.
+  bool quic_broken_;
+
   DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
 };
 
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 26011a8..5512f55 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -9883,6 +9883,141 @@
   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
 }
 
+TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
+  HostPortPair origin("origin.example.org", 443);
+  HostPortPair alternative("alternative.example.org", 443);
+  std::string origin_url = "https://origin.example.org:443";
+  std::string alternative_url = "https://alternative.example.org:443";
+
+  // Negotiate HTTP/1.1 with alternative.example.org.
+  SSLSocketDataProvider ssl(ASYNC, OK);
+  ssl.SetNextProto(kProtoHTTP11);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  // HTTP/1.1 data for request.
+  MockWrite http_writes[] = {
+      MockWrite("GET / HTTP/1.1\r\n"
+                "Host: alternative.example.org\r\n"
+                "Connection: keep-alive\r\n\r\n"),
+  };
+
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n"
+               "Content-Type: text/html; charset=iso-8859-1\r\n"
+               "Content-Length: 40\r\n\r\n"
+               "first HTTP/1.1 response from alternative"),
+  };
+  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+                                     http_writes, arraysize(http_writes));
+  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
+
+  StaticSocketDataProvider data_refused;
+  data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
+  session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
+
+  // Set up a QUIC alternative service for origin.
+  session_deps_.use_alternative_services = true;
+  scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+  base::WeakPtr<HttpServerProperties> http_server_properties =
+      session->http_server_properties();
+  AlternativeService alternative_service(QUIC, alternative);
+  base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+  http_server_properties->SetAlternativeService(origin, alternative_service,
+                                                1.0, expiration);
+  // Mark the QUIC alternative service as broken.
+  http_server_properties->MarkAlternativeServiceBroken(alternative_service);
+
+  scoped_ptr<HttpTransaction> trans(
+      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL(origin_url);
+  request.load_flags = 0;
+  TestCompletionCallback callback;
+  NetErrorDetails details;
+  EXPECT_FALSE(details.quic_broken);
+
+  trans->Start(&request, callback.callback(), BoundNetLog());
+  trans->PopulateNetErrorDetails(&details);
+  EXPECT_TRUE(details.quic_broken);
+}
+
+TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
+  HostPortPair origin("origin.example.org", 443);
+  HostPortPair alternative1("alternative1.example.org", 443);
+  HostPortPair alternative2("alternative2.example.org", 443);
+  std::string origin_url = "https://origin.example.org:443";
+  std::string alternative_url1 = "https://alternative1.example.org:443";
+  std::string alternative_url2 = "https://alternative2.example.org:443";
+
+  // Negotiate HTTP/1.1 with alternative1.example.org.
+  SSLSocketDataProvider ssl(ASYNC, OK);
+  ssl.SetNextProto(kProtoHTTP11);
+  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+  // HTTP/1.1 data for request.
+  MockWrite http_writes[] = {
+      MockWrite("GET / HTTP/1.1\r\n"
+                "Host: alternative1.example.org\r\n"
+                "Connection: keep-alive\r\n\r\n"),
+  };
+
+  MockRead http_reads[] = {
+      MockRead("HTTP/1.1 200 OK\r\n"
+               "Content-Type: text/html; charset=iso-8859-1\r\n"
+               "Content-Length: 40\r\n\r\n"
+               "first HTTP/1.1 response from alternative1"),
+  };
+  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+                                     http_writes, arraysize(http_writes));
+  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
+
+  StaticSocketDataProvider data_refused;
+  data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
+  session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
+
+  session_deps_.use_alternative_services = true;
+  scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+  base::WeakPtr<HttpServerProperties> http_server_properties =
+      session->http_server_properties();
+
+  // Set up two QUIC alternative services for origin.
+  AlternativeServiceInfoVector alternative_service_info_vector;
+  base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+
+  AlternativeService alternative_service1(QUIC, alternative1);
+  AlternativeServiceInfo alternative_service_info1(alternative_service1, 1.0,
+                                                   expiration);
+  alternative_service_info_vector.push_back(alternative_service_info1);
+  AlternativeService alternative_service2(QUIC, alternative2);
+  AlternativeServiceInfo alternative_service_info2(alternative_service2, 1.0,
+                                                   expiration);
+  alternative_service_info_vector.push_back(alternative_service_info2);
+
+  http_server_properties->SetAlternativeServices(
+      origin, alternative_service_info_vector);
+
+  // Mark one of the QUIC alternative service as broken.
+  http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
+
+  const AlternativeServiceVector alternative_service_vector =
+      http_server_properties->GetAlternativeServices(origin);
+
+  scoped_ptr<HttpTransaction> trans(
+      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL(origin_url);
+  request.load_flags = 0;
+  TestCompletionCallback callback;
+  NetErrorDetails details;
+  EXPECT_FALSE(details.quic_broken);
+
+  trans->Start(&request, callback.callback(), BoundNetLog());
+  trans->PopulateNetErrorDetails(&details);
+  EXPECT_FALSE(details.quic_broken);
+}
+
 TEST_P(HttpNetworkTransactionTest,
        MarkBrokenAlternateProtocolAndFallback) {
   session_deps_.use_alternative_services = true;
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h
index 231271d..c2f4b6e9 100644
--- a/net/http/http_stream_factory.h
+++ b/net/http/http_stream_factory.h
@@ -148,6 +148,10 @@
         const SSLConfig& used_ssl_config,
         const ProxyInfo& used_proxy_info,
         HttpStream* stream) = 0;
+
+    // Called when finding all QUIC alternative services are marked broken for
+    // the origin in this request which advertises supporting QUIC.
+    virtual void OnQuicBroken() = 0;
   };
 
   virtual ~HttpStreamRequest() {}
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index 4d32ffcf..81bfd5f 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -94,7 +94,8 @@
   request->AttachJob(job);
 
   const AlternativeServiceVector alternative_service_vector =
-      GetAlternativeServicesFor(request_info.url);
+      GetAlternativeServicesFor(request_info.url, delegate);
+
   if (!alternative_service_vector.empty()) {
     // TODO(bnc): Pass on multiple alternative services to Job.
     const AlternativeService& alternative_service =
@@ -129,7 +130,7 @@
   DCHECK(!for_websockets_);
   AlternativeService alternative_service;
   AlternativeServiceVector alternative_service_vector =
-      GetAlternativeServicesFor(request_info.url);
+      GetAlternativeServicesFor(request_info.url, nullptr);
   if (!alternative_service_vector.empty()) {
     // TODO(bnc): Pass on multiple alternative services to Job.
     alternative_service = alternative_service_vector[0];
@@ -151,7 +152,8 @@
 }
 
 AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
-    const GURL& original_url) {
+    const GURL& original_url,
+    HttpStreamRequest::Delegate* delegate) {
   if (original_url.SchemeIs("ftp"))
     return AlternativeServiceVector();
 
@@ -163,6 +165,9 @@
   if (alternative_service_vector.empty())
     return AlternativeServiceVector();
 
+  bool quic_advertised = false;
+  bool quic_all_broken = true;
+
   const bool enable_different_host =
       session_->params().use_alternative_services;
 
@@ -170,6 +175,8 @@
   for (const AlternativeService& alternative_service :
        alternative_service_vector) {
     DCHECK(IsAlternateProtocolValid(alternative_service.protocol));
+    if (!quic_advertised && alternative_service.protocol == QUIC)
+      quic_advertised = true;
     if (http_server_properties.IsAlternativeServiceBroken(
             alternative_service)) {
       HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN);
@@ -205,6 +212,7 @@
     }
 
     DCHECK_EQ(QUIC, alternative_service.protocol);
+    quic_all_broken = false;
     if (!session_->params().enable_quic)
       continue;
 
@@ -217,6 +225,8 @@
 
     enabled_alternative_service_vector.push_back(alternative_service);
   }
+  if (quic_advertised && quic_all_broken && delegate != nullptr)
+    delegate->OnQuicBroken();
   return enabled_alternative_service_vector;
 }
 
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h
index 1ac451d..6ed8b2cc 100644
--- a/net/http/http_stream_factory_impl.h
+++ b/net/http/http_stream_factory_impl.h
@@ -74,7 +74,9 @@
       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
       const BoundNetLog& net_log);
 
-  AlternativeServiceVector GetAlternativeServicesFor(const GURL& original_url);
+  AlternativeServiceVector GetAlternativeServicesFor(
+      const GURL& original_url,
+      HttpStreamRequest::Delegate* delegate);
 
   // Detaches |job| from |request|.
   void OrphanJob(Job* job, const Request* request);
diff --git a/net/http/http_stream_factory_impl_request_unittest.cc b/net/http/http_stream_factory_impl_request_unittest.cc
index a68d164..8324d614 100644
--- a/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/net/http/http_stream_factory_impl_request_unittest.cc
@@ -55,6 +55,7 @@
                                   const SSLConfig& used_ssl_config,
                                   const ProxyInfo& used_proxy_info,
                                   HttpStream* stream) override {}
+  void OnQuicBroken() override {}
 };
 
 }  // namespace
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 637b6124..45f52dc 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -189,6 +189,8 @@
                                   const ProxyInfo& used_proxy_info,
                                   HttpStream* stream) override {}
 
+  void OnQuicBroken() override {}
+
   void WaitForStream() {
     while (!stream_done_) {
       waiting_for_stream_ = true;
diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h
index f7f7904..8ee3723 100644
--- a/net/http/http_transaction.h
+++ b/net/http/http_transaction.h
@@ -9,6 +9,7 @@
 
 #include "net/base/completion_callback.h"
 #include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
 #include "net/base/net_export.h"
 #include "net/base/request_priority.h"
 #include "net/base/upload_progress.h"
@@ -168,6 +169,9 @@
   // unavailable.
   virtual bool GetRemoteEndpoint(IPEndPoint* endpoint) const = 0;
 
+  // Populates network error details for this transaction.
+  virtual void PopulateNetErrorDetails(NetErrorDetails* details) const = 0;
+
   // Called when the priority of the parent job changes.
   virtual void SetPriority(RequestPriority priority) = 0;
 
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc
index 0bee91f..c619f10 100644
--- a/net/http/http_transaction_test_util.cc
+++ b/net/http/http_transaction_test_util.cc
@@ -286,6 +286,11 @@
   return StartInternal(&auth_request_info, callback, BoundNetLog());
 }
 
+void MockNetworkTransaction::PopulateNetErrorDetails(
+    NetErrorDetails* details) const {
+  NOTIMPLEMENTED();
+}
+
 bool MockNetworkTransaction::IsReadyToRestartForAuth() {
   if (!request_)
     return false;
diff --git a/net/http/http_transaction_test_util.h b/net/http/http_transaction_test_util.h
index 7744909..54e7c522 100644
--- a/net/http/http_transaction_test_util.h
+++ b/net/http/http_transaction_test_util.h
@@ -17,6 +17,7 @@
 #include "base/strings/string16.h"
 #include "net/base/io_buffer.h"
 #include "net/base/load_flags.h"
+#include "net/base/net_error_details.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/base/test_completion_callback.h"
@@ -194,6 +195,7 @@
   int Read(IOBuffer* buf,
            int buf_len,
            const CompletionCallback& callback) override;
+  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
 
   void StopCaching() override;
 
diff --git a/net/log/net_log_util_unittest.cc b/net/log/net_log_util_unittest.cc
index ee6cf731..d03a9c7 100644
--- a/net/log/net_log_util_unittest.cc
+++ b/net/log/net_log_util_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
 #include "base/values.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
diff --git a/net/net.gypi b/net/net.gypi
index e38f2e33..d8f9ffa 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -38,6 +38,7 @@
       'base/load_timing_info.h',
       'base/lookup_string_in_fixed_set.cc',
       'base/lookup_string_in_fixed_set.h',
+      'base/net_error_details.h',
       'base/net_error_list.h',
       'base/net_errors.cc',
       'base/net_errors.h',
diff --git a/net/quic/crypto/crypto_handshake_message_test.cc b/net/quic/crypto/crypto_handshake_message_test.cc
index 0acace1f..c53f895 100644
--- a/net/quic/crypto/crypto_handshake_message_test.cc
+++ b/net/quic/crypto/crypto_handshake_message_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index d981506..2bb8d0e 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -1112,6 +1112,12 @@
     LOG(DFATAL) << "Attempt to send empty stream frame";
     return QuicConsumedData(0, false);
   }
+  if (FLAGS_quic_never_write_unencrypted_data && id != kCryptoStreamId &&
+      encryption_level_ == ENCRYPTION_NONE) {
+    LOG(DFATAL) << "Cannot send stream data without encryption.";
+    CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA, false);
+    return QuicConsumedData(0, false);
+  }
 
   // Opportunistically bundle an ack with every outgoing packet.
   // Particularly, we want to bundle with handshake packets since we don't know
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index d9ccefd..f33696a 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -739,6 +739,9 @@
       EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
           .WillRepeatedly(Return(PacketNumberSet()));
     }
+    // TODO(ianswett): Fix QuicConnectionTests so they don't attempt to write
+    // non-crypto stream data at ENCRYPTION_NONE.
+    FLAGS_quic_never_write_unencrypted_data = false;
   }
 
   QuicVersion version() { return GetParam().version; }
@@ -3879,7 +3882,7 @@
 }
 
 TEST_P(QuicConnectionTest, OldTimeoutAfterSend) {
-  FLAGS_quic_use_new_idle_timeout = false;
+  ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
   QuicConfig config;
@@ -3920,7 +3923,7 @@
 }
 
 TEST_P(QuicConnectionTest, OldTimeoutAfterSendSilentClose) {
-  FLAGS_quic_use_new_idle_timeout = false;
+  ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, false);
   // Same test as above, but complete a handshake which enables silent close,
   // causing no connection close packet to be sent.
   EXPECT_TRUE(connection_.connected());
@@ -3979,7 +3982,7 @@
 }
 
 TEST_P(QuicConnectionTest, TimeoutAfterSend) {
-  FLAGS_quic_use_new_idle_timeout = true;
+  ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
   QuicConfig config;
@@ -4024,7 +4027,7 @@
 }
 
 TEST_P(QuicConnectionTest, NewTimeoutAfterSendSilentClose) {
-  FLAGS_quic_use_new_idle_timeout = true;
+  ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
   // Same test as above, but complete a handshake which enables silent close,
   // causing no connection close packet to be sent.
   EXPECT_TRUE(connection_.connected());
@@ -4134,7 +4137,7 @@
 }
 
 TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
-  FLAGS_quic_use_new_idle_timeout = true;
+  ValueRestore<bool> old_flags(&FLAGS_quic_use_new_idle_timeout, true);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
@@ -5472,7 +5475,7 @@
 }
 
 TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
-  FLAGS_quic_respect_send_alarm = true;
+  ValueRestore<bool> old_flag(&FLAGS_quic_respect_send_alarm, true);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
                                        nullptr);
@@ -5505,6 +5508,15 @@
   writer_->Reset();
 }
 
+TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
+  FLAGS_quic_never_write_unencrypted_data = true;
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(QUIC_UNENCRYPTED_STREAM_DATA, false));
+  EXPECT_DFATAL(connection_.SendStreamDataWithString(3, "", 0, kFin, nullptr),
+                "Cannot send stream data without encryption.");
+  EXPECT_FALSE(connection_.connected());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index ef53a58..232bb17 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -472,7 +472,7 @@
 TEST_P(QuicCryptoServerStreamTest, CancelRPCBeforeVerificationCompletes) {
   // Tests that the client can close the connection while the remote strike
   // register verification RPC is still pending.
-  FLAGS_quic_set_client_hello_cb_nullptr = true;
+  ValueRestore<bool> old_flag(&FLAGS_quic_set_client_hello_cb_nullptr, true);
 
   // Set version to QUIC_VERSION_25 as QUIC_VERSION_26 and later don't support
   // asynchronous strike register RPCs.
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 8d45f32e..2cf2450 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -4,8 +4,6 @@
 
 #include "net/quic/quic_flags.h"
 
-bool FLAGS_quic_allow_oversized_packets_for_test = false;
-
 // When true, the use time based loss detection instead of nack.
 bool FLAGS_quic_use_time_loss_detection = false;
 
@@ -50,9 +48,6 @@
 // If true, flow controller may grow the receive window size if necessary.
 bool FLAGS_quic_auto_tune_receive_window = true;
 
-// If true, record received connection options to TransportConnectionStats.
-bool FLAGS_quic_connection_options_to_transport_stats = true;
-
 // Limits QUIC's max CWND to 200 packets.
 bool FLAGS_quic_limit_max_cwnd = true;
 
@@ -61,14 +56,6 @@
 // TODO(rtenneti): Enable this flag after CryptoServerTest's are fixed.
 bool FLAGS_quic_require_handshake_confirmation = false;
 
-// If true, after a server silo receives a packet from a migrated QUIC
-// client, a GO_AWAY frame is sent to the client.
-bool FLAGS_send_goaway_after_client_migration = true;
-
-// If true, use an interval set as the internal representation of a packet queue
-// instead of a set.
-bool FLAGS_quic_packet_queue_use_interval_set = true;
-
 // If true, Cubic's epoch is shifted when the sender is application-limited.
 bool FLAGS_shift_quic_cubic_epoch_when_app_limited = true;
 
@@ -85,10 +72,6 @@
 // TcpLossAlgorithm or TimeLossAlgorithm.
 bool FLAGS_quic_general_loss_algorithm = true;
 
-// Invoke the QuicAckListener directly, instead of going through the AckNotifier
-// and AckNotifierManager.
-bool FLAGS_quic_no_ack_notifier = true;
-
 // If true, use the unrolled prefetch path in QuicPacketCreator::CopyToBuffer.
 bool FLAGS_quic_packet_creator_prefetch = false;
 
@@ -122,3 +105,6 @@
 // If true, QUIC sessions will write block streams that attempt to write
 // unencrypted data.
 bool FLAGS_quic_block_unencrypted_writes = true;
+
+// If true, Close the connection instead of writing unencrypted stream data.
+bool FLAGS_quic_never_write_unencrypted_data = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index 78c5c50..9e680687 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -8,28 +8,22 @@
 #include "base/basictypes.h"
 #include "net/base/net_export.h"
 
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_oversized_packets_for_test;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_time_loss_detection;
 NET_EXPORT_PRIVATE extern bool FLAGS_use_early_return_when_verifying_chlo;
 NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_fec;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_bbr_congestion_control;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_bbr;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_too_many_outstanding_packets;
 NET_EXPORT_PRIVATE extern int64 FLAGS_quic_time_wait_list_seconds;
 NET_EXPORT_PRIVATE extern int64 FLAGS_quic_time_wait_list_max_connections;
 NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_stateless_reject_support;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_ack_decimation;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_auto_tune_receive_window;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_connection_options_to_transport_stats;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_limit_max_cwnd;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_handshake_confirmation;
-NET_EXPORT_PRIVATE extern bool FLAGS_send_goaway_after_client_migration;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_packet_queue_use_interval_set;
 NET_EXPORT_PRIVATE extern bool FLAGS_shift_quic_cubic_epoch_when_app_limited;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_measure_headers_hol_blocking_time;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_pacing;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_general_loss_algorithm;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_no_ack_notifier;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_packet_creator_prefetch;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_disable_non_nat_address_migration;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_new_idle_timeout;
@@ -39,5 +33,6 @@
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_track_single_retransmission;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_batch_writes;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_block_unencrypted_writes;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_never_write_unencrypted_data;
 
 #endif  // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index 7299c40..7b0e0604 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -241,6 +241,9 @@
         "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
         "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    // TODO(ianswett): Fix QuicSessionTests so they don't attempt to write
+    // non-crypto stream data at ENCRYPTION_NONE.
+    FLAGS_quic_never_write_unencrypted_data = false;
   }
 
   void CheckClosedStreams() {
@@ -424,7 +427,7 @@
 }
 
 TEST_P(QuicSessionTestServer, TestBatchedWrites) {
-  FLAGS_quic_batch_writes = true;
+  ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
   TestStream* stream2 = session_.CreateOutgoingDynamicStream();
   TestStream* stream4 = session_.CreateOutgoingDynamicStream();
   TestStream* stream6 = session_.CreateOutgoingDynamicStream();
diff --git a/net/quic/quic_write_blocked_list_test.cc b/net/quic/quic_write_blocked_list_test.cc
index 46e9c88..774ccbc1 100644
--- a/net/quic/quic_write_blocked_list_test.cc
+++ b/net/quic/quic_write_blocked_list_test.cc
@@ -104,7 +104,7 @@
 }
 
 TEST(QuicWriteBlockedListTest, BatchingWrites) {
-  FLAGS_quic_batch_writes = true;
+  ValueRestore<bool> old_flag(&FLAGS_quic_batch_writes, true);
   QuicWriteBlockedList write_blocked_list;
 
   const QuicStreamId id1 = kClientDataStreamId1;
diff --git a/net/quic/test_tools/mock_crypto_client_stream.cc b/net/quic/test_tools/mock_crypto_client_stream.cc
index 2906939..c54ccff 100644
--- a/net/quic/test_tools/mock_crypto_client_stream.cc
+++ b/net/quic/test_tools/mock_crypto_client_stream.cc
@@ -5,6 +5,7 @@
 #include "net/quic/test_tools/mock_crypto_client_stream.h"
 
 #include "net/quic/crypto/quic_decrypter.h"
+#include "net/quic/crypto/quic_encrypter.h"
 #include "net/quic/quic_client_session_base.h"
 #include "net/quic/quic_server_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -40,6 +41,9 @@
       handshake_confirmed_ = false;
       session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
                                             QuicDecrypter::Create(kNULL));
+      session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
+                                            QuicEncrypter::Create(kNULL));
+      session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
       session()->OnCryptoHandshakeEvent(
           QuicSession::ENCRYPTION_FIRST_ESTABLISHED);
       break;
@@ -56,6 +60,10 @@
       SetConfigNegotiated();
       session()->connection()->SetDecrypter(ENCRYPTION_FORWARD_SECURE,
                                             QuicDecrypter::Create(kNULL));
+      session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                                            QuicEncrypter::Create(kNULL));
+      session()->connection()->SetDefaultEncryptionLevel(
+          ENCRYPTION_FORWARD_SECURE);
       session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
       break;
     }
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index f725d05..3db47d2b2 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -392,6 +392,12 @@
   *load_timing_info = load_timing_info_;
 }
 
+void URLRequest::PopulateNetErrorDetails(NetErrorDetails* details) const {
+  if (!job_)
+    return;
+  return job_->PopulateNetErrorDetails(details);
+}
+
 bool URLRequest::GetRemoteEndpoint(IPEndPoint* endpoint) const {
   if (!job_)
     return false;
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index bb7d4d6..33b28594 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -22,6 +22,7 @@
 #include "net/base/completion_callback.h"
 #include "net/base/load_states.h"
 #include "net/base/load_timing_info.h"
+#include "net/base/net_error_details.h"
 #include "net/base/net_export.h"
 #include "net/base/network_delegate.h"
 #include "net/base/request_priority.h"
@@ -462,6 +463,10 @@
   // non-cached HTTP responses.
   void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
 
+  // Gets the networkd error details of the most recent origin that the network
+  // stack makes the request to.
+  void PopulateNetErrorDetails(NetErrorDetails* details) const;
+
   // Gets the remote endpoint of the most recent socket that the network stack
   // used to make this request.
   //
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index bf9f63b..929d194 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -1126,6 +1126,13 @@
   return GetResponseHeaders()->response_code();
 }
 
+void URLRequestHttpJob::PopulateNetErrorDetails(
+    NetErrorDetails* details) const {
+  if (!transaction_)
+    return;
+  return transaction_->PopulateNetErrorDetails(details);
+}
+
 Filter* URLRequestHttpJob::SetupFilter() const {
   DCHECK(transaction_.get());
   if (!response_info_)
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index 62162b5..d39d739d 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -16,6 +16,7 @@
 #include "base/time/time.h"
 #include "net/base/auth.h"
 #include "net/base/completion_callback.h"
+#include "net/base/net_error_details.h"
 #include "net/base/net_export.h"
 #include "net/base/sdch_manager.h"
 #include "net/cookies/cookie_store.h"
@@ -119,6 +120,7 @@
   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
   bool GetResponseCookies(std::vector<std::string>* cookies) override;
   int GetResponseCode() const override;
+  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
   Filter* SetupFilter() const override;
   bool CopyFragmentOnRedirect(const GURL& location) const override;
   bool IsSafeRedirect(const GURL& location) override;
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 140ab80..fc9f4a96 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -187,6 +187,10 @@
   return false;
 }
 
+void URLRequestJob::PopulateNetErrorDetails(NetErrorDetails* details) const {
+  return;
+}
+
 Filter* URLRequestJob::SetupFilter() const {
   return NULL;
 }
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index 83358f361..d3282cb 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -17,6 +17,7 @@
 #include "base/power_monitor/power_observer.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_export.h"
 #include "net/base/request_priority.h"
@@ -151,6 +152,10 @@
   //       useful results once per job.
   virtual bool GetResponseCookies(std::vector<std::string>* cookies);
 
+  // Populates the network error details of the most recent origin that the
+  // network stack makes the request to.
+  virtual void PopulateNetErrorDetails(NetErrorDetails* details) const;
+
   // Called to setup a stream filter for this request. An example of filter is
   // content encoding/decoding.
   // Subclasses should return the appropriate Filter, or NULL for no Filter.
diff --git a/net/websockets/websocket_basic_stream.cc b/net/websockets/websocket_basic_stream.cc
index 440bd266..29fe581b 100644
--- a/net/websockets/websocket_basic_stream.cc
+++ b/net/websockets/websocket_basic_stream.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <limits>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -41,18 +42,15 @@
 //     packet sizes / encryption block sizes / IPC alignment issues, etc.
 const int kReadBufferSize = 32 * 1024;
 
-typedef ScopedVector<WebSocketFrame>::const_iterator WebSocketFrameIterator;
-
 // Returns the total serialized size of |frames|. This function assumes that
 // |frames| will be serialized with mask field. This function forces the
 // masked bit of the frames on.
 int CalculateSerializedSizeAndTurnOnMaskBit(
-    ScopedVector<WebSocketFrame>* frames) {
+    std::vector<scoped_ptr<WebSocketFrame>>* frames) {
   const uint64_t kMaximumTotalSize = std::numeric_limits<int>::max();
 
   uint64_t total_size = 0;
-  for (WebSocketFrameIterator it = frames->begin(); it != frames->end(); ++it) {
-    WebSocketFrame* frame = *it;
+  for (const auto& frame : *frames) {
     // Force the masked bit on.
     frame->header.masked = true;
     // We enforce flow control so the renderer should never be able to force us
@@ -87,8 +85,9 @@
 
 WebSocketBasicStream::~WebSocketBasicStream() { Close(); }
 
-int WebSocketBasicStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
-                                     const CompletionCallback& callback) {
+int WebSocketBasicStream::ReadFrames(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    const CompletionCallback& callback) {
   DCHECK(frames->empty());
   // If there is data left over after parsing the HTTP headers, attempt to parse
   // it as WebSocket frames.
@@ -99,7 +98,7 @@
     scoped_refptr<GrowableIOBuffer> buffered_data;
     buffered_data.swap(http_read_buffer_);
     DCHECK(http_read_buffer_.get() == NULL);
-    ScopedVector<WebSocketFrameChunk> frame_chunks;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frame_chunks;
     if (!parser_.Decode(buffered_data->StartOfBuffer(),
                         buffered_data->offset(),
                         &frame_chunks))
@@ -133,8 +132,9 @@
   }
 }
 
-int WebSocketBasicStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
-                                      const CompletionCallback& callback) {
+int WebSocketBasicStream::WriteFrames(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    const CompletionCallback& callback) {
   // This function always concatenates all frames into a single buffer.
   // TODO(ricea): Investigate whether it would be better in some cases to
   // perform multiple writes with smaller buffers.
@@ -146,8 +146,7 @@
 
   char* dest = combined_buffer->data();
   int remaining_size = total_size;
-  for (WebSocketFrameIterator it = frames->begin(); it != frames->end(); ++it) {
-    WebSocketFrame* frame = *it;
+  for (const auto& frame : *frames) {
     WebSocketMaskingKey mask = generate_websocket_masking_key_();
     int result =
         WriteWebSocketFrameHeader(frame->header, &mask, dest, remaining_size);
@@ -239,14 +238,14 @@
 
 int WebSocketBasicStream::HandleReadResult(
     int result,
-    ScopedVector<WebSocketFrame>* frames) {
+    std::vector<scoped_ptr<WebSocketFrame>>* frames) {
   DCHECK_NE(ERR_IO_PENDING, result);
   DCHECK(frames->empty());
   if (result < 0)
     return result;
   if (result == 0)
     return ERR_CONNECTION_CLOSED;
-  ScopedVector<WebSocketFrameChunk> frame_chunks;
+  std::vector<scoped_ptr<WebSocketFrameChunk>> frame_chunks;
   if (!parser_.Decode(read_buffer_->data(), result, &frame_chunks))
     return WebSocketErrorToNetError(parser_.websocket_error());
   if (frame_chunks.empty())
@@ -255,21 +254,17 @@
 }
 
 int WebSocketBasicStream::ConvertChunksToFrames(
-    ScopedVector<WebSocketFrameChunk>* frame_chunks,
-    ScopedVector<WebSocketFrame>* frames) {
+    std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks,
+    std::vector<scoped_ptr<WebSocketFrame>>* frames) {
   for (size_t i = 0; i < frame_chunks->size(); ++i) {
     scoped_ptr<WebSocketFrame> frame;
-    int result = ConvertChunkToFrame(
-        scoped_ptr<WebSocketFrameChunk>((*frame_chunks)[i]), &frame);
-    (*frame_chunks)[i] = NULL;
+    int result = ConvertChunkToFrame(std::move((*frame_chunks)[i]), &frame);
     if (result != OK)
       return result;
     if (frame)
       frames->push_back(frame.Pass());
   }
-  // All the elements of |frame_chunks| are now NULL, so there is no point in
-  // calling delete on them all.
-  frame_chunks->weak_clear();
+  frame_chunks->clear();
   if (frames->empty())
     return ERR_IO_PENDING;
   return OK;
@@ -413,9 +408,10 @@
   incomplete_control_frame_body_->set_offset(new_offset);
 }
 
-void WebSocketBasicStream::OnReadComplete(ScopedVector<WebSocketFrame>* frames,
-                                          const CompletionCallback& callback,
-                                          int result) {
+void WebSocketBasicStream::OnReadComplete(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    const CompletionCallback& callback,
+    int result) {
   result = HandleReadResult(result, frames);
   if (result == ERR_IO_PENDING)
     result = ReadFrames(frames, callback);
diff --git a/net/websockets/websocket_basic_stream.h b/net/websockets/websocket_basic_stream.h
index d456d8d..d035639b 100644
--- a/net/websockets/websocket_basic_stream.h
+++ b/net/websockets/websocket_basic_stream.h
@@ -6,11 +6,11 @@
 #define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_H_
 
 #include <string>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/websockets/websocket_frame_parser.h"
 #include "net/websockets/websocket_stream.h"
 
@@ -43,10 +43,10 @@
   ~WebSocketBasicStream() override;
 
   // WebSocketStream implementation.
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override;
 
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override;
 
   void Close() override;
@@ -78,14 +78,16 @@
 
   // Attempts to parse the output of a read as WebSocket frames. On success,
   // returns OK and places the frame(s) in |frames|.
-  int HandleReadResult(int result, ScopedVector<WebSocketFrame>* frames);
+  int HandleReadResult(int result,
+                       std::vector<scoped_ptr<WebSocketFrame>>* frames);
 
   // Converts the chunks in |frame_chunks| into frames and writes them to
   // |frames|. |frame_chunks| is destroyed in the process. Returns
   // ERR_WS_PROTOCOL_ERROR if an invalid chunk was found. If one or more frames
   // was added to |frames|, then returns OK, otherwise returns ERR_IO_PENDING.
-  int ConvertChunksToFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks,
-                            ScopedVector<WebSocketFrame>* frames);
+  int ConvertChunksToFrames(
+      std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks,
+      std::vector<scoped_ptr<WebSocketFrame>>* frames);
 
   // Converts a |chunk| to a |frame|. |*frame| should be NULL on entry to this
   // method. If |chunk| is an incomplete control frame, or an empty middle
@@ -113,7 +115,7 @@
 
   // Called when a read completes. Parses the result and (unless no complete
   // header has been received) calls |callback|.
-  void OnReadComplete(ScopedVector<WebSocketFrame>* frames,
+  void OnReadComplete(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                       const CompletionCallback& callback,
                       int result);
 
diff --git a/net/websockets/websocket_basic_stream_test.cc b/net/websockets/websocket_basic_stream_test.cc
index d4c73e8..81be165d 100644
--- a/net/websockets/websocket_basic_stream_test.cc
+++ b/net/websockets/websocket_basic_stream_test.cc
@@ -13,6 +13,7 @@
 #include <string.h>  // for memcpy() and memset().
 
 #include <string>
+#include <vector>
 
 #include "base/big_endian.h"
 #include "base/macros.h"
@@ -166,7 +167,7 @@
   MockClientSocketFactory factory_;
   MockTransportClientSocketPool pool_;
   BoundTestNetLog(bound_net_log_);
-  ScopedVector<WebSocketFrame> frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_;
   TestCompletionCallback cb_;
   scoped_refptr<GrowableIOBuffer> http_read_buffer_;
   std::string sub_protocol_;
@@ -896,7 +897,7 @@
   header.final = true;
   header.masked = true;
   header.payload_length = 0;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   frames.push_back(frame.Pass());
   EXPECT_EQ(OK, stream_->WriteFrames(&frames, cb_.callback()));
 }
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc
index 81269ac3..f26a012 100644
--- a/net/websockets/websocket_channel.cc
+++ b/net/websockets/websocket_channel.cc
@@ -9,6 +9,8 @@
 
 #include <algorithm>
 #include <deque>
+#include <utility>
+#include <vector>
 
 #include "base/big_endian.h"
 #include "base/bind.h"
@@ -136,11 +138,11 @@
   void AddFrame(scoped_ptr<WebSocketFrame> chunk);
 
   // Return a pointer to the frames_ for write purposes.
-  ScopedVector<WebSocketFrame>* frames() { return &frames_; }
+  std::vector<scoped_ptr<WebSocketFrame>>* frames() { return &frames_; }
 
  private:
   // The frames_ that will be sent in the next call to WriteFrames().
-  ScopedVector<WebSocketFrame> frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_;
 
   // The total size of the payload data in |frames_|. This will be used to
   // measure the throughput of the link.
@@ -738,9 +740,7 @@
       DCHECK(!read_frames_.empty())
           << "ReadFrames() returned OK, but nothing was read.";
       for (size_t i = 0; i < read_frames_.size(); ++i) {
-        scoped_ptr<WebSocketFrame> frame(read_frames_[i]);
-        read_frames_[i] = NULL;
-        if (HandleFrame(frame.Pass()) == CHANNEL_DELETED)
+        if (HandleFrame(std::move(read_frames_[i])) == CHANNEL_DELETED)
           return CHANNEL_DELETED;
       }
       read_frames_.clear();
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h
index abe08b0..612c8d95 100644
--- a/net/websockets/websocket_channel.h
+++ b/net/websockets/websocket_channel.h
@@ -16,7 +16,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "net/base/net_export.h"
@@ -351,7 +350,7 @@
   scoped_ptr<SendBuffer> data_to_send_next_;
 
   // Destination for the current call to WebSocketStream::ReadFrames
-  ScopedVector<WebSocketFrame> read_frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> read_frames_;
 
   // Frames that have been read but not yet forwarded to the renderer due to
   // lack of quota.
diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc
index acbbb8a..4bf039b 100644
--- a/net/websockets/websocket_channel_test.cc
+++ b/net/websockets/websocket_channel_test.cc
@@ -8,7 +8,9 @@
 #include <string.h>
 
 #include <iostream>
+#include <iterator>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -16,7 +18,6 @@
 #include "base/callback.h"
 #include "base/location.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/single_thread_task_runner.h"
@@ -69,25 +70,25 @@
   return os << "NULL}";
 }
 
-std::ostream& operator<<(std::ostream& os,
-                         const ScopedVector<WebSocketFrame>& vector) {
+std::ostream& operator<<(
+    std::ostream& os,
+    const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
   os << "{";
   bool first = true;
-  for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin();
-       it != vector.end();
-       ++it) {
+  for (const auto& frame : frames) {
     if (!first) {
       os << ",\n";
     } else {
       first = false;
     }
-    os << **it;
+    os << *frame;
   }
   return os << "}";
 }
 
-std::ostream& operator<<(std::ostream& os,
-                         const ScopedVector<WebSocketFrame>* vector) {
+std::ostream& operator<<(
+    std::ostream& os,
+    const std::vector<scoped_ptr<WebSocketFrame>>* vector) {
   return os << '&' << *vector;
 }
 
@@ -244,12 +245,12 @@
                       const std::string& extensions)
       : protocol_(protocol), extensions_(extensions) {}
 
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override {
     return ERR_IO_PENDING;
   }
 
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override {
     return ERR_IO_PENDING;
   }
@@ -319,9 +320,9 @@
 // Convert a const array of InitFrame structs to the format used at
 // runtime. Templated on the size of the array to save typing.
 template <size_t N>
-ScopedVector<WebSocketFrame> CreateFrameVector(
-    const InitFrame (&source_frames)[N]) {
-  ScopedVector<WebSocketFrame> result_frames;
+std::vector<scoped_ptr<WebSocketFrame>> CreateFrameVector(
+    const InitFrame(&source_frames)[N]) {
+  std::vector<scoped_ptr<WebSocketFrame>> result_frames;
   result_frames.reserve(N);
   for (size_t i = 0; i < N; ++i) {
     const InitFrame& source_frame = source_frames[i];
@@ -338,7 +339,7 @@
     }
     result_frames.push_back(result_frame.Pass());
   }
-  return result_frames.Pass();
+  return result_frames;
 }
 
 // A GoogleMock action which can be used to respond to call to ReadFrames with
@@ -352,19 +353,20 @@
 }
 
 // The implementation of a GoogleMock matcher which can be used to compare a
-// ScopedVector<WebSocketFrame>* against an expectation defined as an array of
-// InitFrame objects. Although it is possible to compose built-in GoogleMock
-// matchers to check the contents of a WebSocketFrame, the results are so
-// unreadable that it is better to use this matcher.
+// std::vector<scoped_ptr<WebSocketFrame>>* against an expectation defined as an
+// array of InitFrame objects. Although it is possible to compose built-in
+// GoogleMock matchers to check the contents of a WebSocketFrame, the results
+// are so unreadable that it is better to use this matcher.
 template <size_t N>
-class EqualsFramesMatcher
-    : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> {
+class EqualsFramesMatcher : public ::testing::MatcherInterface<
+                                std::vector<scoped_ptr<WebSocketFrame>>*> {
  public:
   EqualsFramesMatcher(const InitFrame (*expect_frames)[N])
       : expect_frames_(expect_frames) {}
 
-  virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames,
-                               ::testing::MatchResultListener* listener) const {
+  virtual bool MatchAndExplain(
+      std::vector<scoped_ptr<WebSocketFrame>>* actual_frames,
+      ::testing::MatchResultListener* listener) const {
     if (actual_frames->size() != N) {
       *listener << "the vector size is " << actual_frames->size();
       return false;
@@ -419,8 +421,8 @@
 // The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames
 // action, this can take the array by reference.
 template <size_t N>
-::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames(
-    const InitFrame (&frames)[N]) {
+::testing::Matcher<std::vector<scoped_ptr<WebSocketFrame>>*> EqualsFrames(
+    const InitFrame(&frames)[N]) {
   return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames));
 }
 
@@ -456,30 +458,32 @@
   // |async| is SYNC, the response will be returned synchronously. |error| is
   // returned directly from ReadFrames() in the synchronous case, or passed to
   // the callback in the asynchronous case. |frames| will be converted to a
-  // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to
-  // ReadFrames().
+  // std::vector<scoped_ptr<WebSocketFrame>> and copied to the pointer that was
+  // passed to ReadFrames().
   template <size_t N>
   void PrepareReadFrames(IsSync async,
                          int error,
                          const InitFrame (&frames)[N]) {
-    responses_.push_back(new Response(async, error, CreateFrameVector(frames)));
+    responses_.push_back(
+        make_scoped_ptr(new Response(async, error, CreateFrameVector(frames))));
   }
 
   // An alternate version of PrepareReadFrames for when we need to construct
   // the frames manually.
   void PrepareRawReadFrames(IsSync async,
                             int error,
-                            ScopedVector<WebSocketFrame> frames) {
-    responses_.push_back(new Response(async, error, frames.Pass()));
+                            std::vector<scoped_ptr<WebSocketFrame>> frames) {
+    responses_.push_back(
+        make_scoped_ptr(new Response(async, error, std::move(frames))));
   }
 
   // Prepares a fake error response (ie. there is no data).
   void PrepareReadFramesError(IsSync async, int error) {
-    responses_.push_back(
-        new Response(async, error, ScopedVector<WebSocketFrame>()));
+    responses_.push_back(make_scoped_ptr(
+        new Response(async, error, std::vector<scoped_ptr<WebSocketFrame>>())));
   }
 
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override {
     CHECK(!read_frames_pending_);
     if (index_ >= responses_.size())
@@ -497,7 +501,7 @@
   }
 
  private:
-  void DoCallback(ScopedVector<WebSocketFrame>* frames,
+  void DoCallback(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) {
     read_frames_pending_ = false;
     frames->swap(responses_[index_]->frames);
@@ -506,18 +510,20 @@
   }
 
   struct Response {
-    Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames)
-        : async(async), error(error), frames(frames.Pass()) {}
+    Response(IsSync async,
+             int error,
+             std::vector<scoped_ptr<WebSocketFrame>> frames)
+        : async(async), error(error), frames(std::move(frames)) {}
 
     IsSync async;
     int error;
-    ScopedVector<WebSocketFrame> frames;
+    std::vector<scoped_ptr<WebSocketFrame>> frames;
 
    private:
     // Bad things will happen if we attempt to copy or assign |frames|.
     DISALLOW_COPY_AND_ASSIGN(Response);
   };
-  ScopedVector<Response> responses_;
+  std::vector<scoped_ptr<Response>> responses_;
 
   // The index into the responses_ array of the next response to be returned.
   size_t index_;
@@ -533,7 +539,7 @@
 // synchronously.
 class WriteableFakeWebSocketStream : public FakeWebSocketStream {
  public:
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override {
     return OK;
   }
@@ -542,7 +548,7 @@
 // A FakeWebSocketStream where writes always fail.
 class UnWriteableFakeWebSocketStream : public FakeWebSocketStream {
  public:
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override {
     return ERR_CONNECTION_RESET;
   }
@@ -558,17 +564,19 @@
  public:
   EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {}
 
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override {
+    stored_frames_.insert(stored_frames_.end(),
+                          std::make_move_iterator(frames->begin()),
+                          std::make_move_iterator(frames->end()));
+    frames->clear();
     // Users of WebSocketStream will not expect the ReadFrames() callback to be
     // called from within WriteFrames(), so post it to the message loop instead.
-    stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end());
-    frames->weak_clear();
     PostCallback();
     return OK;
   }
 
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override {
     read_callback_ = callback;
     read_frames_ = frames;
@@ -597,13 +605,11 @@
   // Copy the frames stored in stored_frames_ to |out|, while clearing the
   // "masked" header bit. Returns true if a Close Frame was seen, false
   // otherwise.
-  bool MoveFrames(ScopedVector<WebSocketFrame>* out) {
+  bool MoveFrames(std::vector<scoped_ptr<WebSocketFrame>>* out) {
     bool seen_close = false;
-    *out = stored_frames_.Pass();
-    for (ScopedVector<WebSocketFrame>::iterator it = out->begin();
-         it != out->end();
-         ++it) {
-      WebSocketFrameHeader& header = (*it)->header;
+    *out = std::move(stored_frames_);
+    for (const auto& frame : *out) {
+      WebSocketFrameHeader& header = frame->header;
       header.masked = false;
       if (header.opcode == WebSocketFrameHeader::kOpCodeClose)
         seen_close = true;
@@ -611,10 +617,10 @@
     return seen_close;
   }
 
-  ScopedVector<WebSocketFrame> stored_frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> stored_frames_;
   CompletionCallback read_callback_;
   // Owned by the caller of ReadFrames().
-  ScopedVector<WebSocketFrame>* read_frames_;
+  std::vector<scoped_ptr<WebSocketFrame>>* read_frames_;
   // True if we should close the connection.
   bool done_;
 };
@@ -630,7 +636,7 @@
  public:
   ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {}
 
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
@@ -645,7 +651,7 @@
     return ERR_IO_PENDING;
   }
 
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override {
     read_callback_ = callback;
     return ERR_IO_PENDING;
@@ -671,10 +677,10 @@
 class MockWebSocketStream : public WebSocketStream {
  public:
   MOCK_METHOD2(ReadFrames,
-               int(ScopedVector<WebSocketFrame>* frames,
+               int(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                    const CompletionCallback& callback));
   MOCK_METHOD2(WriteFrames,
-               int(ScopedVector<WebSocketFrame>* frames,
+               int(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                    const CompletionCallback& callback));
   MOCK_METHOD0(Close, void());
   MOCK_CONST_METHOD0(GetSubProtocol, std::string());
@@ -2095,10 +2101,11 @@
        NOT_MASKED,  "sakana"}};
   // It is not worth adding support for reserved bits to InitFrame just for this
   // one test, so set the bit manually.
-  ScopedVector<WebSocketFrame> raw_frames = CreateFrameVector(frames);
+  std::vector<scoped_ptr<WebSocketFrame>> raw_frames =
+      CreateFrameVector(frames);
   raw_frames[0]->header.reserved1 = true;
-  stream->PrepareRawReadFrames(
-      ReadableFakeWebSocketStream::SYNC, OK, raw_frames.Pass());
+  stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
+                               std::move(raw_frames));
   set_stream(stream.Pass());
   EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
   EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -2520,7 +2527,7 @@
   // We store the parameters that were passed to ReadFrames() so that we can
   // call them explicitly later.
   CompletionCallback read_callback;
-  ScopedVector<WebSocketFrame>* frames = NULL;
+  std::vector<scoped_ptr<WebSocketFrame>>* frames = NULL;
 
   // These are not interesting.
   EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
@@ -2702,7 +2709,7 @@
   static const InitFrame expected3[] = {
       {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
        MASKED,      "World"}};
-  ScopedVector<WebSocketFrame>* read_frames;
+  std::vector<scoped_ptr<WebSocketFrame>>* read_frames;
   CompletionCallback read_callback;
   EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
   EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
@@ -2823,7 +2830,7 @@
 // protocol also has Binary frames and those need to be 8-bit clean. For the
 // sake of completeness, this test verifies that they are.
 TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) {
-  ScopedVector<WebSocketFrame>* frames = NULL;
+  std::vector<scoped_ptr<WebSocketFrame>>* frames = NULL;
 
   EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
   EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
@@ -2838,7 +2845,7 @@
       std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize));
   ASSERT_TRUE(frames != NULL);
   ASSERT_EQ(1U, frames->size());
-  const WebSocketFrame* out_frame = (*frames)[0];
+  const WebSocketFrame* out_frame = (*frames)[0].get();
   EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length);
   ASSERT_TRUE(out_frame->data.get());
   EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize));
@@ -2853,12 +2860,12 @@
   frame_header.payload_length = kBinaryBlobSize;
   frame->data = new IOBuffer(kBinaryBlobSize);
   memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize);
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   frames.push_back(frame.Pass());
   scoped_ptr<ReadableFakeWebSocketStream> stream(
       new ReadableFakeWebSocketStream);
-  stream->PrepareRawReadFrames(
-      ReadableFakeWebSocketStream::SYNC, OK, frames.Pass());
+  stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
+                               std::move(frames));
   set_stream(stream.Pass());
   EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _));
   EXPECT_CALL(*event_interface_, OnFlowControl(_));
@@ -3380,7 +3387,7 @@
   EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
   EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
   TestClosure completion;
-  ScopedVector<WebSocketFrame>* read_frames = NULL;
+  std::vector<scoped_ptr<WebSocketFrame>>* read_frames = NULL;
   CompletionCallback read_callback;
   {
     InSequence s;
diff --git a/net/websockets/websocket_deflate_predictor.h b/net/websockets/websocket_deflate_predictor.h
index 9413fa0..4b7b7783 100644
--- a/net/websockets/websocket_deflate_predictor.h
+++ b/net/websockets/websocket_deflate_predictor.h
@@ -6,8 +6,9 @@
 #define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_H_
 
 #include <stddef.h>
+#include <vector>
 
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "net/base/net_export.h"
 
 namespace net {
@@ -39,7 +40,7 @@
   // but future frames may contain control message frames.
   // |frames[frame_index]| cannot be recorded yet and all preceding
   // data frames have to be already recorded when this method is called.
-  virtual Result Predict(const ScopedVector<WebSocketFrame>& frames,
+  virtual Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
                          size_t frame_index) = 0;
 
   // Records frame data for future prediction.
diff --git a/net/websockets/websocket_deflate_predictor_impl.cc b/net/websockets/websocket_deflate_predictor_impl.cc
index 0d1a5c20..7736607 100644
--- a/net/websockets/websocket_deflate_predictor_impl.cc
+++ b/net/websockets/websocket_deflate_predictor_impl.cc
@@ -9,7 +9,7 @@
 typedef WebSocketDeflatePredictor::Result Result;
 
 Result WebSocketDeflatePredictorImpl::Predict(
-    const ScopedVector<WebSocketFrame>& frames,
+    const std::vector<scoped_ptr<WebSocketFrame>>& frames,
     size_t frame_index) {
   return DEFLATE;
 }
diff --git a/net/websockets/websocket_deflate_predictor_impl.h b/net/websockets/websocket_deflate_predictor_impl.h
index 72c96ee..ea751fe1 100644
--- a/net/websockets/websocket_deflate_predictor_impl.h
+++ b/net/websockets/websocket_deflate_predictor_impl.h
@@ -6,8 +6,9 @@
 #define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PREDICTOR_IMPL_H_
 
 #include <stddef.h>
+#include <vector>
 
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "net/base/net_export.h"
 #include "net/websockets/websocket_deflate_predictor.h"
 
@@ -20,7 +21,7 @@
  public:
   ~WebSocketDeflatePredictorImpl() override {}
 
-  Result Predict(const ScopedVector<WebSocketFrame>& frames,
+  Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
                  size_t frame_index) override;
   void RecordInputDataFrame(const WebSocketFrame* frame) override;
   void RecordWrittenDataFrame(const WebSocketFrame* frame) override;
diff --git a/net/websockets/websocket_deflate_predictor_impl_test.cc b/net/websockets/websocket_deflate_predictor_impl_test.cc
index f1bfd56..279ca48 100644
--- a/net/websockets/websocket_deflate_predictor_impl_test.cc
+++ b/net/websockets/websocket_deflate_predictor_impl_test.cc
@@ -4,7 +4,8 @@
 
 #include "net/websockets/websocket_deflate_predictor_impl.h"
 
-#include "base/memory/scoped_vector.h"
+#include <vector>
+
 #include "net/websockets/websocket_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -16,8 +17,9 @@
 
 TEST(WebSocketDeflatePredictorImpl, Predict) {
   WebSocketDeflatePredictorImpl predictor;
-  ScopedVector<WebSocketFrame> frames;
-  frames.push_back(new WebSocketFrame(WebSocketFrameHeader::kOpCodeText));
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
+  frames.push_back(
+      make_scoped_ptr(new WebSocketFrame(WebSocketFrameHeader::kOpCodeText)));
   Result result = predictor.Predict(frames, 0);
 
   EXPECT_EQ(WebSocketDeflatePredictor::DEFLATE, result);
diff --git a/net/websockets/websocket_deflate_stream.cc b/net/websockets/websocket_deflate_stream.cc
index 47d2a5b..8eae497 100644
--- a/net/websockets/websocket_deflate_stream.cc
+++ b/net/websockets/websocket_deflate_stream.cc
@@ -7,12 +7,13 @@
 #include <stdint.h>
 #include <algorithm>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -60,8 +61,9 @@
 
 WebSocketDeflateStream::~WebSocketDeflateStream() {}
 
-int WebSocketDeflateStream::ReadFrames(ScopedVector<WebSocketFrame>* frames,
-                                       const CompletionCallback& callback) {
+int WebSocketDeflateStream::ReadFrames(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    const CompletionCallback& callback) {
   int result = stream_->ReadFrames(
       frames,
       base::Bind(&WebSocketDeflateStream::OnReadComplete,
@@ -76,8 +78,9 @@
   return InflateAndReadIfNecessary(frames, callback);
 }
 
-int WebSocketDeflateStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
-                                        const CompletionCallback& callback) {
+int WebSocketDeflateStream::WriteFrames(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    const CompletionCallback& callback) {
   int result = Deflate(frames);
   if (result != OK)
     return result;
@@ -97,7 +100,7 @@
 }
 
 void WebSocketDeflateStream::OnReadComplete(
-    ScopedVector<WebSocketFrame>* frames,
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
     const CompletionCallback& callback,
     int result) {
   if (result != OK) {
@@ -111,23 +114,22 @@
     callback.Run(r);
 }
 
-int WebSocketDeflateStream::Deflate(ScopedVector<WebSocketFrame>* frames) {
-  ScopedVector<WebSocketFrame> frames_to_write;
+int WebSocketDeflateStream::Deflate(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames) {
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_write;
   // Store frames of the currently processed message if writing_state_ equals to
   // WRITING_POSSIBLY_COMPRESSED_MESSAGE.
-  ScopedVector<WebSocketFrame> frames_of_message;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_of_message;
   for (size_t i = 0; i < frames->size(); ++i) {
     DCHECK(!(*frames)[i]->header.reserved1);
     if (!WebSocketFrameHeader::IsKnownDataOpCode((*frames)[i]->header.opcode)) {
-      frames_to_write.push_back((*frames)[i]);
-      (*frames)[i] = NULL;
+      frames_to_write.push_back(std::move((*frames)[i]));
       continue;
     }
     if (writing_state_ == NOT_WRITING)
       OnMessageStart(*frames, i);
 
-    scoped_ptr<WebSocketFrame> frame((*frames)[i]);
-    (*frames)[i] = NULL;
+    scoped_ptr<WebSocketFrame> frame(std::move((*frames)[i]));
     predictor_->RecordInputDataFrame(frame.get());
 
     if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) {
@@ -181,8 +183,9 @@
 }
 
 void WebSocketDeflateStream::OnMessageStart(
-    const ScopedVector<WebSocketFrame>& frames, size_t index) {
-  WebSocketFrame* frame = frames[index];
+    const std::vector<scoped_ptr<WebSocketFrame>>& frames,
+    size_t index) {
+  WebSocketFrame* frame = frames[index].get();
   current_writing_opcode_ = frame->header.opcode;
   DCHECK(current_writing_opcode_ == WebSocketFrameHeader::kOpCodeText ||
          current_writing_opcode_ == WebSocketFrameHeader::kOpCodeBinary);
@@ -205,7 +208,7 @@
 
 int WebSocketDeflateStream::AppendCompressedFrame(
     const WebSocketFrameHeader& header,
-    ScopedVector<WebSocketFrame>* frames_to_write) {
+    std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write) {
   const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_;
   scoped_refptr<IOBufferWithSize> compressed_payload =
       deflater_.GetOutput(deflater_.CurrentOutputSize());
@@ -230,8 +233,8 @@
 }
 
 int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
-    ScopedVector<WebSocketFrame>* frames,
-    ScopedVector<WebSocketFrame>* frames_to_write) {
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
+    std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write) {
   DCHECK(!frames->empty());
 
   const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_;
@@ -245,7 +248,7 @@
 
   uint64_t original_payload_length = 0;
   for (size_t i = 0; i < frames->size(); ++i) {
-    WebSocketFrame* frame = (*frames)[i];
+    WebSocketFrame* frame = (*frames)[i].get();
     // Asserts checking that frames represent one whole data message.
     DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode));
     DCHECK_EQ(i == 0,
@@ -258,12 +261,11 @@
       static_cast<uint64_t>(compressed_payload->size())) {
     // Compression is not effective. Use the original frames.
     for (size_t i = 0; i < frames->size(); ++i) {
-      WebSocketFrame* frame = (*frames)[i];
-      frames_to_write->push_back(frame);
-      predictor_->RecordWrittenDataFrame(frame);
-      (*frames)[i] = NULL;
+      scoped_ptr<WebSocketFrame> frame = std::move((*frames)[i]);
+      predictor_->RecordWrittenDataFrame(frame.get());
+      frames_to_write->push_back(std::move(frame));
     }
-    frames->weak_clear();
+    frames->clear();
     return OK;
   }
   scoped_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode));
@@ -279,12 +281,13 @@
   return OK;
 }
 
-int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) {
-  ScopedVector<WebSocketFrame> frames_to_output;
-  ScopedVector<WebSocketFrame> frames_passed;
+int WebSocketDeflateStream::Inflate(
+    std::vector<scoped_ptr<WebSocketFrame>>* frames) {
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_passed;
   frames->swap(frames_passed);
   for (size_t i = 0; i < frames_passed.size(); ++i) {
-    scoped_ptr<WebSocketFrame> frame(frames_passed[i]);
+    scoped_ptr<WebSocketFrame> frame(std::move(frames_passed[i]));
     frames_passed[i] = NULL;
     DVLOG(3) << "Input frame: opcode=" << frame->header.opcode
              << " final=" << frame->header.final
@@ -372,7 +375,7 @@
 }
 
 int WebSocketDeflateStream::InflateAndReadIfNecessary(
-    ScopedVector<WebSocketFrame>* frames,
+    std::vector<scoped_ptr<WebSocketFrame>>* frames,
     const CompletionCallback& callback) {
   int result = Inflate(frames);
   while (result == ERR_IO_PENDING) {
diff --git a/net/websockets/websocket_deflate_stream.h b/net/websockets/websocket_deflate_stream.h
index c0d0915..470be41 100644
--- a/net/websockets/websocket_deflate_stream.h
+++ b/net/websockets/websocket_deflate_stream.h
@@ -7,10 +7,10 @@
 
 #include <stddef.h>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
 #include "net/websockets/websocket_deflater.h"
@@ -47,9 +47,9 @@
   ~WebSocketDeflateStream() override;
 
   // WebSocketStream functions.
-  int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                  const CompletionCallback& callback) override;
-  int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                   const CompletionCallback& callback) override;
   void Close() override;
   std::string GetSubProtocol() const override;
@@ -70,23 +70,25 @@
   };
 
   // Handles asynchronous completion of ReadFrames() call on |stream_|.
-  void OnReadComplete(ScopedVector<WebSocketFrame>* frames,
+  void OnReadComplete(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                       const CompletionCallback& callback,
                       int result);
 
   // This function deflates |frames| and stores the result to |frames| itself.
-  int Deflate(ScopedVector<WebSocketFrame>* frames);
-  void OnMessageStart(const ScopedVector<WebSocketFrame>& frames, size_t index);
-  int AppendCompressedFrame(const WebSocketFrameHeader& header,
-                            ScopedVector<WebSocketFrame>* frames_to_write);
+  int Deflate(std::vector<scoped_ptr<WebSocketFrame>>* frames);
+  void OnMessageStart(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
+                      size_t index);
+  int AppendCompressedFrame(
+      const WebSocketFrameHeader& header,
+      std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write);
   int AppendPossiblyCompressedMessage(
-      ScopedVector<WebSocketFrame>* frames,
-      ScopedVector<WebSocketFrame>* frames_to_write);
+      std::vector<scoped_ptr<WebSocketFrame>>* frames,
+      std::vector<scoped_ptr<WebSocketFrame>>* frames_to_write);
 
   // This function inflates |frames| and stores the result to |frames| itself.
-  int Inflate(ScopedVector<WebSocketFrame>* frames);
+  int Inflate(std::vector<scoped_ptr<WebSocketFrame>>* frames);
 
-  int InflateAndReadIfNecessary(ScopedVector<WebSocketFrame>* frames,
+  int InflateAndReadIfNecessary(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                                 const CompletionCallback& callback);
 
   const scoped_ptr<WebSocketStream> stream_;
diff --git a/net/websockets/websocket_deflate_stream_test.cc b/net/websockets/websocket_deflate_stream_test.cc
index 9c6fc72a..8bd02ac7 100644
--- a/net/websockets/websocket_deflate_stream_test.cc
+++ b/net/websockets/websocket_deflate_stream_test.cc
@@ -7,12 +7,14 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <deque>
+#include <iterator>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -73,7 +75,11 @@
                            : "";
 }
 
-void AppendTo(ScopedVector<WebSocketFrame>* frames,
+std::string ToString(const scoped_ptr<WebSocketFrame>& frame) {
+  return ToString(frame.get());
+}
+
+void AppendTo(std::vector<scoped_ptr<WebSocketFrame>>* frames,
               WebSocketFrameHeader::OpCode opcode,
               FrameFlag flag,
               const std::string& data) {
@@ -82,24 +88,26 @@
   frame->header.reserved1 = (flag & kReserved1);
   frame->data = ToIOBuffer(data);
   frame->header.payload_length = data.size();
-  frames->push_back(frame.release());
+  frames->push_back(std::move(frame));
 }
 
-void AppendTo(ScopedVector<WebSocketFrame>* frames,
+void AppendTo(std::vector<scoped_ptr<WebSocketFrame>>* frames,
               WebSocketFrameHeader::OpCode opcode,
               FrameFlag flag) {
   scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
   frame->header.final = (flag & kFinal);
   frame->header.reserved1 = (flag & kReserved1);
-  frames->push_back(frame.release());
+  frames->push_back(std::move(frame));
 }
 
 class MockWebSocketStream : public WebSocketStream {
  public:
-  MOCK_METHOD2(ReadFrames, int(ScopedVector<WebSocketFrame>*,
-                               const CompletionCallback&));
-  MOCK_METHOD2(WriteFrames, int(ScopedVector<WebSocketFrame>*,
-                                const CompletionCallback&));
+  MOCK_METHOD2(ReadFrames,
+               int(std::vector<scoped_ptr<WebSocketFrame>>*,
+                   const CompletionCallback&));
+  MOCK_METHOD2(WriteFrames,
+               int(std::vector<scoped_ptr<WebSocketFrame>>*,
+                   const CompletionCallback&));
   MOCK_METHOD0(Close, void());
   MOCK_CONST_METHOD0(GetSubProtocol, std::string());
   MOCK_CONST_METHOD0(GetExtensions, std::string());
@@ -125,7 +133,7 @@
   }
 
   // WebSocketDeflatePredictor functions.
-  Result Predict(const ScopedVector<WebSocketFrame>& frames,
+  Result Predict(const std::vector<scoped_ptr<WebSocketFrame>>& frames,
                  size_t frame_index) override {
     return result_;
   }
@@ -179,13 +187,14 @@
     }
     frames_written_.pop_front();
   }
-  void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) {
+  void AddFramesToBeInput(
+      const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
     for (size_t i = 0; i < frames.size(); ++i)
-      AddFrameToBeInput(frames[i]);
+      AddFrameToBeInput(frames[i].get());
   }
-  void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) {
+  void VerifySentFrames(const std::vector<scoped_ptr<WebSocketFrame>>& frames) {
     for (size_t i = 0; i < frames.size(); ++i)
-      VerifySentFrame(frames[i]);
+      VerifySentFrame(frames[i].get());
   }
   // Call this method in order to disable checks in the destructor when
   // WriteFrames fails.
@@ -280,7 +289,7 @@
   }
 
  protected:
-  ScopedVector<WebSocketFrame> frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_;
 };
 
 // ReadFrameStub is a stub for WebSocketStream::ReadFrames.
@@ -290,12 +299,13 @@
  public:
   explicit ReadFramesStub(int result) : result_(result) {}
 
-  ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output)
+  ReadFramesStub(int result,
+                 std::vector<scoped_ptr<WebSocketFrame>>* frames_to_output)
       : result_(result) {
     frames_to_output_.swap(*frames_to_output);
   }
 
-  int Call(ScopedVector<WebSocketFrame>* frames,
+  int Call(std::vector<scoped_ptr<WebSocketFrame>>* frames,
            const CompletionCallback& callback) {
     DCHECK(frames->empty());
     frames_passed_ = frames;
@@ -306,15 +316,15 @@
 
   int result() const { return result_; }
   const CompletionCallback callback() const { return callback_; }
-  ScopedVector<WebSocketFrame>* frames_passed() {
+  std::vector<scoped_ptr<WebSocketFrame>>* frames_passed() {
     return frames_passed_;
   }
 
  private:
   int result_;
   CompletionCallback callback_;
-  ScopedVector<WebSocketFrame> frames_to_output_;
-  ScopedVector<WebSocketFrame>* frames_passed_;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output_;
+  std::vector<scoped_ptr<WebSocketFrame>>* frames_passed_;
 };
 
 // WriteFramesStub is a stub for WebSocketStream::WriteFrames.
@@ -326,10 +336,11 @@
                            int result)
       : result_(result), predictor_(predictor) {}
 
-  int Call(ScopedVector<WebSocketFrame>* frames,
+  int Call(std::vector<scoped_ptr<WebSocketFrame>>* frames,
            const CompletionCallback& callback) {
-    frames_.insert(frames_.end(), frames->begin(), frames->end());
-    frames->weak_clear();
+    frames_.insert(frames_.end(), std::make_move_iterator(frames->begin()),
+                   std::make_move_iterator(frames->end()));
+    frames->clear();
     callback_ = callback;
     predictor_->VerifySentFrames(frames_);
     return result_;
@@ -337,17 +348,17 @@
 
   int result() const { return result_; }
   const CompletionCallback callback() const { return callback_; }
-  ScopedVector<WebSocketFrame>* frames() { return &frames_; }
+  std::vector<scoped_ptr<WebSocketFrame>>* frames() { return &frames_; }
 
  private:
   int result_;
   CompletionCallback callback_;
-  ScopedVector<WebSocketFrame> frames_;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_;
   WebSocketDeflatePredictorMock* predictor_;
 };
 
 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   CompletionCallback callback;
   {
     InSequence s;
@@ -358,13 +369,13 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal,
            "hello");
   ReadFramesStub stub(OK, &frames_to_output);
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -382,7 +393,7 @@
 
 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
   ReadFramesStub stub(ERR_IO_PENDING);
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   MockCallback mock_callback, checkpoint;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
@@ -413,7 +424,7 @@
 
 TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
   ReadFramesStub stub(ERR_IO_PENDING);
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   MockCallback mock_callback, checkpoint;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
@@ -439,14 +450,14 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal | kReserved1,
            std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -465,7 +476,7 @@
   MockCallback mock_callback, checkpoint;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -492,7 +503,7 @@
 
 TEST_F(WebSocketDeflateStreamTest,
        ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   const std::string data1("\xf2", 1);
   const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
   AppendTo(&frames_to_output,
@@ -503,7 +514,7 @@
   MockCallback mock_callback, checkpoint;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -533,14 +544,14 @@
 
 TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
   const std::string data("\xf2\x48\xcdINVALID", 10);
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal | kReserved1,
            data);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -555,7 +566,7 @@
 TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
   const std::string data1("\xf2\x48\xcd", 3);
   const std::string data2("\xc9\xc9\x07\x00", 4);
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kReserved1,
@@ -566,7 +577,7 @@
            data2);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -582,7 +593,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kNoFlag);
@@ -591,7 +602,7 @@
            kFinal);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -612,7 +623,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kReserved1,
@@ -622,7 +633,7 @@
            kFinal);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -640,7 +651,7 @@
 TEST_F(WebSocketDeflateStreamTest,
        ReadCompressedFrameFollowedByEmptyFrame) {
   const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kReserved1,
@@ -650,7 +661,7 @@
            kFinal);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -668,7 +679,7 @@
 TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
   const std::string data1("\xf2\x48\xcd", 3);
   const std::string data2("\xc9\xc9\x07\x00", 4);
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kReserved1,
@@ -677,7 +688,7 @@
   AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -703,7 +714,7 @@
   deflater.AddBytes(original_data.data(), original_data.size());
   deflater.Finish();
 
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeBinary,
            kFinal | kReserved1,
@@ -711,7 +722,7 @@
 
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -745,7 +756,7 @@
   deflater.AddBytes(original_data.data(), original_data.size());
   deflater.Finish();
 
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeBinary,
            kReserved1,
@@ -757,7 +768,7 @@
 
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
@@ -783,7 +794,7 @@
        Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
   const std::string data1("\xf2\x48\xcd", 3);
   const std::string data2("\xc9\xc9\x07\x00", 4);
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kReserved1,
@@ -794,7 +805,7 @@
            data2);
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -807,7 +818,7 @@
 
 TEST_F(WebSocketDeflateStreamTest,
        Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kNoFlag,
@@ -818,7 +829,7 @@
            "world");
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -830,7 +841,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal | kReserved1,
@@ -842,7 +853,7 @@
            std::string("\x4a\x86\x33\x8d\x00\x00", 6));
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -862,7 +873,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal,
@@ -873,7 +884,7 @@
            "uncompressed2");
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -894,7 +905,7 @@
 
 TEST_F(WebSocketDeflateStreamTest,
        ReadCompressedMessageThenUncompressedMessage) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal | kReserved1,
@@ -906,7 +917,7 @@
            "uncompressed");
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -927,7 +938,7 @@
 
 TEST_F(WebSocketDeflateStreamTest,
        ReadUncompressedMessageThenCompressedMessage) {
-  ScopedVector<WebSocketFrame> frames_to_output;
+  std::vector<scoped_ptr<WebSocketFrame>> frames_to_output;
   AppendTo(&frames_to_output,
            WebSocketFrameHeader::kOpCodeText,
            kFinal,
@@ -939,7 +950,7 @@
                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
   ReadFramesStub stub(OK, &frames_to_output);
   CompletionCallback callback;
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
@@ -960,21 +971,21 @@
 
 // This is a regression test for crbug.com/343506.
 TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
-  ScopedVector<ReadFramesStub> stub_vector;
-  stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
-  stub_vector.push_back(new ReadFramesStub(ERR_IO_PENDING));
+  std::vector<scoped_ptr<ReadFramesStub>> stub_vector;
+  stub_vector.push_back(make_scoped_ptr(new ReadFramesStub(ERR_IO_PENDING)));
+  stub_vector.push_back(make_scoped_ptr(new ReadFramesStub(ERR_IO_PENDING)));
   MockCallback mock_callback;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
 
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
-        .WillOnce(Invoke(stub_vector[0], &ReadFramesStub::Call));
+        .WillOnce(Invoke(stub_vector[0].get(), &ReadFramesStub::Call));
 
     EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
-        .WillOnce(Invoke(stub_vector[1], &ReadFramesStub::Call));
+        .WillOnce(Invoke(stub_vector[1].get(), &ReadFramesStub::Call));
 
     EXPECT_CALL(mock_callback, Call(OK));
   }
@@ -996,7 +1007,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   CompletionCallback callback;
   {
     InSequence s;
@@ -1006,7 +1017,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   CompletionCallback callback;
   {
     InSequence s;
@@ -1021,7 +1032,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   CompletionCallback callback;
   WriteFramesStub stub(predictor_, OK);
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
@@ -1032,7 +1043,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(1u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1046,7 +1057,7 @@
   MockCallback mock_callback, checkpoint;
   CompletionCallback callback =
       base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   {
     InSequence s;
     EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
@@ -1061,7 +1072,7 @@
   checkpoint.Call(0);
   stub.callback().Run(OK);
 
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(1u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1071,7 +1082,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
@@ -1085,7 +1096,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(2u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1098,7 +1109,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
   predictor_->AddFramesToBeInput(frames);
   WriteFramesStub stub(predictor_, OK);
@@ -1110,7 +1121,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(1u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1119,7 +1130,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
   predictor_->AddFramesToBeInput(frames);
@@ -1134,7 +1145,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(2u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_FALSE(frames_passed[0]->header.final);
@@ -1159,12 +1170,12 @@
     EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
         .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
   }
-  ScopedVector<WebSocketFrame> total_compressed_frames;
+  std::vector<scoped_ptr<WebSocketFrame>> total_compressed_frames;
 
   deflater.Initialize(kWindowBits);
   while (true) {
     bool is_final = (total_compressed_frames.size() >= 2);
-    ScopedVector<WebSocketFrame> frames;
+    std::vector<scoped_ptr<WebSocketFrame>> frames;
     std::string data;
     for (size_t i = 0; i < size; ++i)
       data += static_cast<char>(lcg.Generate());
@@ -1173,17 +1184,18 @@
     AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
     predictor_->AddFramesToBeInput(frames);
     ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-    total_compressed_frames.insert(total_compressed_frames.end(),
-                                   stub.frames()->begin(),
-                                   stub.frames()->end());
-    stub.frames()->weak_clear();
+    total_compressed_frames.insert(
+        total_compressed_frames.end(),
+        std::make_move_iterator(stub.frames()->begin()),
+        std::make_move_iterator(stub.frames()->end()));
+    stub.frames()->clear();
     if (is_final)
       break;
   }
   deflater.Finish();
   std::string total_deflated;
   for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
-    WebSocketFrame* frame = total_compressed_frames[i];
+    WebSocketFrame* frame = total_compressed_frames[i].get();
     const WebSocketFrameHeader& header = frame->header;
     if (i > 0) {
       EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
@@ -1203,7 +1215,7 @@
 }
 
 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
   predictor_->AddFramesToBeInput(frames);
@@ -1216,7 +1228,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(2u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1231,7 +1243,7 @@
 
 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
        WriteMultipleMessages) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
   predictor_->AddFramesToBeInput(frames);
@@ -1244,7 +1256,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(2u, frames_passed.size());
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
   EXPECT_TRUE(frames_passed[0]->header.final);
@@ -1262,7 +1274,7 @@
 // "PossiblyCompressedMessage"s, we test various messages at one test case.
 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
        WritePossiblyCompressMessages) {
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
@@ -1280,7 +1292,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(5u, frames_passed.size());
 
   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
@@ -1322,7 +1334,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(1u, frames_passed.size());
   EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
                         "(?7\xb3\x34\x17\x00", 21),
@@ -1341,7 +1353,7 @@
         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
   }
   ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
-  const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
+  const std::vector<scoped_ptr<WebSocketFrame>>& frames_passed = *stub.frames();
   ASSERT_EQ(1u, frames_passed.size());
   EXPECT_EQ(
       std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
diff --git a/net/websockets/websocket_frame_parser.cc b/net/websockets/websocket_frame_parser.cc
index c36c467..51581e91 100644
--- a/net/websockets/websocket_frame_parser.cc
+++ b/net/websockets/websocket_frame_parser.cc
@@ -6,12 +6,12 @@
 
 #include <algorithm>
 #include <limits>
+#include <vector>
 
 #include "base/big_endian.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/io_buffer.h"
 #include "net/websockets/websocket_frame.h"
 
@@ -46,7 +46,7 @@
 bool WebSocketFrameParser::Decode(
     const char* data,
     size_t length,
-    ScopedVector<WebSocketFrameChunk>* frame_chunks) {
+    std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks) {
   if (websocket_error_ != kWebSocketNormalClosure)
     return false;
   if (!length)
diff --git a/net/websockets/websocket_frame_parser.h b/net/websockets/websocket_frame_parser.h
index 8752862d..ac296cd 100644
--- a/net/websockets/websocket_frame_parser.h
+++ b/net/websockets/websocket_frame_parser.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/net_export.h"
 #include "net/websockets/websocket_errors.h"
 #include "net/websockets/websocket_frame.h"
@@ -40,7 +39,7 @@
   // websocket_frame.h for more details.
   bool Decode(const char* data,
               size_t length,
-              ScopedVector<WebSocketFrameChunk>* frame_chunks);
+              std::vector<scoped_ptr<WebSocketFrameChunk>>* frame_chunks);
 
   // Returns kWebSocketNormalClosure if the parser has not failed to decode
   // WebSocket frames. Otherwise returns WebSocketError which is defined in
diff --git a/net/websockets/websocket_frame_parser_test.cc b/net/websockets/websocket_frame_parser_test.cc
index 3d858a9..09557852 100644
--- a/net/websockets/websocket_frame_parser_test.cc
+++ b/net/websockets/websocket_frame_parser_test.cc
@@ -8,10 +8,7 @@
 #include <algorithm>
 #include <vector>
 
-#include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "net/base/io_buffer.h"
-#include "net/websockets/websocket_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
@@ -53,11 +50,11 @@
 TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
   WebSocketFrameParser parser;
 
-  ScopedVector<WebSocketFrameChunk> frames;
+  std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
   EXPECT_TRUE(parser.Decode(kHelloFrame, kHelloFrameLength, &frames));
   EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
   ASSERT_EQ(1u, frames.size());
-  WebSocketFrameChunk* frame = frames[0];
+  WebSocketFrameChunk* frame = frames[0].get();
   ASSERT_TRUE(frame != NULL);
   const WebSocketFrameHeader* header = frame->header.get();
   EXPECT_TRUE(header != NULL);
@@ -79,12 +76,12 @@
 TEST(WebSocketFrameParserTest, DecodeMaskedFrame) {
   WebSocketFrameParser parser;
 
-  ScopedVector<WebSocketFrameChunk> frames;
+  std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
   EXPECT_TRUE(
       parser.Decode(kMaskedHelloFrame, kMaskedHelloFrameLength, &frames));
   EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
   ASSERT_EQ(1u, frames.size());
-  WebSocketFrameChunk* frame = frames[0];
+  WebSocketFrameChunk* frame = frames[0].get();
   ASSERT_TRUE(frame != NULL);
   const WebSocketFrameHeader* header = frame->header.get();
   EXPECT_TRUE(header != NULL);
@@ -138,13 +135,13 @@
 
   WebSocketFrameParser parser;
 
-  ScopedVector<WebSocketFrameChunk> frames;
+  std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
   EXPECT_TRUE(parser.Decode(&input.front(), input.size(), &frames));
   EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
   ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size());
 
   for (int i = 0; i < kNumInputs; ++i) {
-    WebSocketFrameChunk* frame = frames[i];
+    WebSocketFrameChunk* frame = frames[i].get();
     EXPECT_TRUE(frame != NULL);
     if (!frame)
       continue;
@@ -184,13 +181,13 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames1;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames1;
     EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames1.size());
     if (frames1.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame1 = frames1[0];
+    WebSocketFrameChunk* frame1 = frames1[0].get();
     EXPECT_TRUE(frame1 != NULL);
     if (!frame1)
       continue;
@@ -214,13 +211,13 @@
     EXPECT_FALSE(header1->masked);
     EXPECT_EQ(kHelloLength, header1->payload_length);
 
-    ScopedVector<WebSocketFrameChunk> frames2;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames2;
     EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames2.size());
     if (frames2.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame2 = frames2[0];
+    WebSocketFrameChunk* frame2 = frames2[0].get();
     EXPECT_TRUE(frame2 != NULL);
     if (!frame2)
       continue;
@@ -251,13 +248,13 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames1;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames1;
     EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames1.size());
     if (frames1.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame1 = frames1[0];
+    WebSocketFrameChunk* frame1 = frames1[0].get();
     EXPECT_TRUE(frame1 != NULL);
     if (!frame1)
       continue;
@@ -281,13 +278,13 @@
     EXPECT_TRUE(header1->masked);
     EXPECT_EQ(kHelloLength, header1->payload_length);
 
-    ScopedVector<WebSocketFrameChunk> frames2;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames2;
     EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames2.size());
     if (frames2.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame2 = frames2[0];
+    WebSocketFrameChunk* frame2 = frames2[0].get();
     EXPECT_TRUE(frame2 != NULL);
     if (!frame2)
       continue;
@@ -318,7 +315,7 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
     EXPECT_EQ(kFrameHeaderTests[i].error_code == kWebSocketNormalClosure,
               parser.Decode(&input.front(), input.size(), &frames));
     EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
@@ -329,7 +326,7 @@
     }
     if (frames.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame = frames[0];
+    WebSocketFrameChunk* frame = frames[0].get();
     EXPECT_TRUE(frame != NULL);
     if (!frame)
       continue;
@@ -370,7 +367,7 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
     // Feed each byte to the parser to see if the parser behaves correctly
     // when it receives partial frame header.
     size_t last_byte_offset = frame_header_length - 1;
@@ -393,7 +390,7 @@
     }
     if (frames.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame = frames[0];
+    WebSocketFrameChunk* frame = frames[0].get();
     EXPECT_TRUE(frame != NULL);
     if (!frame)
       continue;
@@ -440,7 +437,7 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_FALSE(parser.Decode(frame_header, frame_header_length, &frames));
     EXPECT_EQ(kWebSocketErrorProtocolError, parser.websocket_error());
@@ -489,13 +486,13 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
     EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames.size());
     if (frames.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame = frames[0];
+    WebSocketFrameChunk* frame = frames[0].get();
     EXPECT_TRUE(frame != NULL);
     if (!frame)
       continue;
@@ -545,13 +542,13 @@
 
     WebSocketFrameParser parser;
 
-    ScopedVector<WebSocketFrameChunk> frames;
+    std::vector<scoped_ptr<WebSocketFrameChunk>> frames;
     EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
     EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error());
     EXPECT_EQ(1u, frames.size());
     if (frames.size() != 1u)
       continue;
-    WebSocketFrameChunk* frame = frames[0];
+    WebSocketFrameChunk* frame = frames[0].get();
     EXPECT_TRUE(frame != NULL);
     if (!frame)
       continue;
diff --git a/net/websockets/websocket_stream.h b/net/websockets/websocket_stream.h
index 658a9c9b..8a2b371 100644
--- a/net/websockets/websocket_stream.h
+++ b/net/websockets/websocket_stream.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
@@ -159,7 +158,7 @@
   // Extensions which use reserved header bits should clear them when they are
   // set correctly. If the reserved header bits are set incorrectly, it is okay
   // to leave it to the caller to report the error.
-  virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
+  virtual int ReadFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                          const CompletionCallback& callback) = 0;
 
   // Writes WebSocket frame data.
@@ -176,7 +175,7 @@
   // object. Implementations of WriteFrames() should be robust against
   // this. This generally means returning to the event loop immediately after
   // calling the callback.
-  virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
+  virtual int WriteFrames(std::vector<scoped_ptr<WebSocketFrame>>* frames,
                           const CompletionCallback& callback) = 0;
 
   // Closes the stream. All pending I/O operations (if any) are cancelled
diff --git a/net/websockets/websocket_stream_cookie_test.cc b/net/websockets/websocket_stream_cookie_test.cc
index 0e65ba7..c45fac4 100644
--- a/net/websockets/websocket_stream_cookie_test.cc
+++ b/net/websockets/websocket_stream_cookie_test.cc
@@ -118,7 +118,7 @@
 
 TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
   // For wss tests.
-  ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK));
+  ssl_data_.push_back(make_scoped_ptr(new SSLSocketDataProvider(ASYNC, OK)));
 
   CookieStore* store =
       url_request_context_host_.GetURLRequestContext()->cookie_store();
@@ -151,7 +151,7 @@
 
 TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
   // For wss tests.
-  ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK));
+  ssl_data_.push_back(make_scoped_ptr(new SSLSocketDataProvider(ASYNC, OK)));
 
   const GURL url(GetParam().url);
   const GURL cookie_url(GetParam().cookie_url);
diff --git a/net/websockets/websocket_stream_create_test_base.cc b/net/websockets/websocket_stream_create_test_base.cc
index 387ce8a..fa70198 100644
--- a/net/websockets/websocket_stream_create_test_base.cc
+++ b/net/websockets/websocket_stream_create_test_base.cc
@@ -100,10 +100,9 @@
     const url::Origin& origin,
     scoped_ptr<base::Timer> timer) {
   for (size_t i = 0; i < ssl_data_.size(); ++i) {
-    scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]);
-    url_request_context_host_.AddSSLSocketDataProvider(ssl_data.Pass());
+    url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data_[i]));
   }
-  ssl_data_.weak_clear();
+  ssl_data_.clear();
   scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
       new TestConnectDelegate(this, connect_run_loop_.QuitClosure()));
   WebSocketStream::ConnectDelegate* delegate = connect_delegate.get();
diff --git a/net/websockets/websocket_stream_create_test_base.h b/net/websockets/websocket_stream_create_test_base.h
index 70451ef..8fbb48d 100644
--- a/net/websockets/websocket_stream_create_test_base.h
+++ b/net/websockets/websocket_stream_create_test_base.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/run_loop.h"
 #include "base/timer/timer.h"
 #include "net/base/net_export.h"
@@ -70,7 +69,7 @@
   scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks_;
   SSLInfo ssl_info_;
   bool ssl_fatal_;
-  ScopedVector<SSLSocketDataProvider> ssl_data_;
+  std::vector<scoped_ptr<SSLSocketDataProvider>> ssl_data_;
 
   // This temporarily sets WebSocketEndpointLockManager unlock delay to zero
   // during tests.
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 43930496..9467e09c 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/compiler_specific.h"
-#include "base/memory/scoped_vector.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/statistics_recorder.h"
@@ -520,7 +519,7 @@
   WaitUntilConnectDone();
 
   ASSERT_TRUE(stream_);
-  ScopedVector<WebSocketFrame> frames;
+  std::vector<scoped_ptr<WebSocketFrame>> frames;
   CompletionCallback callback;
   ASSERT_EQ(OK, stream_->ReadFrames(&frames, callback));
   ASSERT_EQ(1U, frames.size());
@@ -984,8 +983,8 @@
 }
 
 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
-  ssl_data_.push_back(
-      new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
+  ssl_data_.push_back(make_scoped_ptr(
+      new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)));
   ssl_data_[0]->cert =
       ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
   ASSERT_TRUE(ssl_data_[0]->cert.get());
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc
index e5cdd0a..5b5d13a4 100644
--- a/net/websockets/websocket_test_util.cc
+++ b/net/websockets/websocket_test_util.cc
@@ -8,7 +8,6 @@
 #include <algorithm>
 #include <vector>
 
-#include "base/memory/scoped_vector.h"
 #include "base/strings/stringprintf.h"
 #include "net/proxy/proxy_service.h"
 #include "net/socket/socket_test_util.h"
@@ -86,8 +85,8 @@
   std::string return_to_read;
   std::vector<MockRead> reads;
   MockWrite write;
-  ScopedVector<SequencedSocketData> socket_data_vector;
-  ScopedVector<SSLSocketDataProvider> ssl_socket_data_vector;
+  std::vector<scoped_ptr<SequencedSocketData>> socket_data_vector;
+  std::vector<scoped_ptr<SSLSocketDataProvider>> ssl_socket_data_vector;
   MockClientSocketFactory factory;
 };
 
diff --git a/storage/browser/fileapi/file_system_usage_cache.cc b/storage/browser/fileapi/file_system_usage_cache.cc
index f1d3ece..3ef195f 100644
--- a/storage/browser/fileapi/file_system_usage_cache.cc
+++ b/storage/browser/fileapi/file_system_usage_cache.cc
@@ -151,7 +151,7 @@
   TRACE_EVENT0("FileSystem", "UsageCache::Delete");
   DCHECK(CalledOnValidThread());
   CloseCacheFiles();
-  return base::DeleteFile(usage_file_path, true);
+  return base::DeleteFile(usage_file_path, false);
 }
 
 void FileSystemUsageCache::CloseCacheFiles() {
diff --git a/storage/browser/fileapi/obfuscated_file_util.cc b/storage/browser/fileapi/obfuscated_file_util.cc
index d46078e8..a9fdb8c 100644
--- a/storage/browser/fileapi/obfuscated_file_util.cc
+++ b/storage/browser/fileapi/obfuscated_file_util.cc
@@ -1052,7 +1052,7 @@
     return base::File(error);
 
   if (base::PathExists(dest_local_path)) {
-    if (!base::DeleteFile(dest_local_path, true /* recursive */))
+    if (!base::DeleteFile(dest_local_path, false /* recursive */))
       return base::File(base::File::FILE_ERROR_FAILED);
     LOG(WARNING) << "A stray file detected";
     InvalidateUsageCache(context, dest_url.origin(), dest_url.type());
@@ -1094,7 +1094,7 @@
   bool created = false;
   if (src_file_path.empty()) {
     if (base::PathExists(dest_local_path)) {
-      if (!base::DeleteFile(dest_local_path, true /* recursive */))
+      if (!base::DeleteFile(dest_local_path, false /* recursive */))
         return base::File::FILE_ERROR_FAILED;
       LOG(WARNING) << "A stray file detected";
       InvalidateUsageCache(context, dest_url.origin(), dest_url.type());
diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc
index 52baee4..6430aab7 100644
--- a/sync/syncable/syncable_unittest.cc
+++ b/sync/syncable/syncable_unittest.cc
@@ -157,7 +157,7 @@
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     file_path_ = temp_dir_.path().Append(
         FILE_PATH_LITERAL("Test.sqlite3"));
-    base::DeleteFile(file_path_, true);
+    base::DeleteFile(file_path_, false);
     CreateDirectory();
   }
 
@@ -165,7 +165,7 @@
     // This also closes file handles.
     dir()->SaveChanges();
     dir().reset();
-    base::DeleteFile(file_path_, true);
+    base::DeleteFile(file_path_, false);
     SyncableDirectoryTest::TearDown();
   }
 
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5ebb58b..4281c91 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -81,6 +81,16 @@
 
 crbug.com/267206 [ Mac ] virtual/rootlayerscrolls/fast/scrolling/scrollbar-tickmarks-hittest.html [ Timeout ]
 
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html [ Failure ]
+crbug.com/561418 imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html [ Failure ]
+
 crbug.com/465126 imported/gecko/variables/variable-declaration-24.html [ Failure ]
 crbug.com/465126 imported/gecko/variables/variable-declaration-25.html [ Failure ]
 crbug.com/465126 imported/gecko/variables/variable-external-font-face-01.html [ Failure ]
@@ -756,6 +766,8 @@
 crbug.com/377696 printing/setPrinting.html [ Skip ]
 crbug.com/377696 printing/width-overflow.html [ Skip ]
 
+crbug.com/567039 fast/block/skip-cleaning-up-anonymous-wrappers-when-subtree-being-destroyed.html [ Failure Pass ]
+
 # Reftests that needs investigation.
 crbug.com/397232 [ XP ] css2.1/20110323/c541-word-sp-000.htm [ Failure ]
 crbug.com/397232 [ XP ] css2.1/20110323/vertical-align-boxes-001.htm [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index 5cb95bf..d7c2fa7 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -483,6 +483,8 @@
 imported/csswg-test/css-writing-modes-3/block-flow-direction-srl-061.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/block-flow-direction-srl-064.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/block-flow-direction-srl-065.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/inline-block-alignment-slr-009.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/inline-block-alignment-srl-008.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/line-box-direction-slr-043.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/line-box-direction-slr-047.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/line-box-direction-slr-048.xht [ Skip ]
@@ -505,12 +507,30 @@
 imported/csswg-test/css-writing-modes-3/row-progression-slr-029.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/row-progression-srl-022.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/row-progression-srl-028.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-column-order-slr-007.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-column-order-srl-006.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-progression-slr-001.html [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-progression-slr-002.html [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-progression-srl-001.html [ Skip ]
+imported/csswg-test/css-writing-modes-3/table-progression-srl-002.html [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-slr-009.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-slr-011.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-slr-013.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-srl-008.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-srl-010.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/text-baseline-srl-012.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-slr-029.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-slr-031.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-slr-033.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-slr-035.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-slr-041.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-srl-028.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-srl-030.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-srl-032.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-srl-034.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/vertical-alignment-srl-040.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001.html [ Skip ]
+imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001.html [ Skip ]
 
 # CSS Writing Modes Level 3: Following tests require applying writing-mode to table-cell, which we do not support today. crbug.com/409155
 imported/csswg-test/css-writing-modes-3/block-flow-direction-vlr-018.xht [ Skip ]
@@ -538,17 +558,6 @@
 imported/web-platform-tests/FileAPI/url/url_xmlhttprequest_img.html [ Skip ]
 imported/web-platform-tests/html/semantics/forms/form-submission-0/url-encoded.html [ Skip ]
 
-# crbug.com/561418: <ul type=decimal> and values other than 1/a/A/i/I/none/disc/circle/square should not be supported
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html [ Skip ]
-imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html [ Skip ]
-
 # crbug.com/561421: Update meta refresh parsing to match the new spec
 imported/web-platform-tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html [ Skip ]
 imported/web-platform-tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/animations/clear-svg-animation-effects.html b/third_party/WebKit/LayoutTests/animations/clear-svg-animation-effects.html
index a6cd5de..8b75bdc 100644
--- a/third_party/WebKit/LayoutTests/animations/clear-svg-animation-effects.html
+++ b/third_party/WebKit/LayoutTests/animations/clear-svg-animation-effects.html
@@ -7,8 +7,8 @@
 var asyncHandle = async_test('SVG Attributes should return to their base values after animations have stopped applying.');
 
 var animation = target.animate([
-  {svgOffset: '0'},
-  {svgOffset: '0.5'},
+  {'svg-offset': '0'},
+  {'svg-offset': '0.5'},
 ], 1000);
 animation.pause();
 animation.currentTime = 500;
diff --git a/third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js b/third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js
index d9201d0..bbf7a1a 100644
--- a/third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js
+++ b/third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js
@@ -74,7 +74,7 @@
     options,
     bindings: {
       prefixProperty(property) {
-        return 'svg' + property[0].toUpperCase() + property.slice(1);
+        return 'svg-' + property;
       },
       createTargetContainer(container) {
         var svgRoot = createElement('svg', container, 'svg-root', svgNamespace);
diff --git a/third_party/WebKit/LayoutTests/animations/restart-not-visible.html b/third_party/WebKit/LayoutTests/animations/restart-not-visible.html
new file mode 100644
index 0000000..f8c094b7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/restart-not-visible.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<style>
+.run {
+  animation: foo 1s infinite alternate;
+}
+
+@keyframes foo {
+  100% {
+    transform: translateX(100px)
+  }
+}
+</style>
+<div id="target"></div>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+var test = async_test('Race between visibility and set compositor pending should not crash');
+requestAnimationFrame(t => {
+  requestAnimationFrame(t => {
+    target.classList.add('run');
+    setTimeout(() => {
+      testRunner.setPageVisibility("hidden");
+      target.style.transform = 'translateX(50px)';
+      target.offsetTop;
+      setTimeout(() => {
+        test.done();
+      }, 0);
+    }, 0);
+  });
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
index bdb47d1..78774fe 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
@@ -320,8 +320,8 @@
         }
         break;
       case 'Web Animations':
-        // Replace 'transform' with 'svgTransform', etc. This avoids collisions with CSS properties or the Web Animations API (offset).
-        var prefixedProperty = 'svg' + params.property[0].toUpperCase() + params.property.slice(1);
+        // Replace 'transform' with 'svg-transform', etc. This avoids collisions with CSS properties or the Web Animations API (offset).
+        var prefixedProperty = 'svg-' + params.property;
         var keyframes = [];
         if (!isNeutralKeyframe(params.from)) {
           keyframes.push({
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-responsive/svg-transform-responsive-expected.txt b/third_party/WebKit/LayoutTests/animations/svg-attribute-responsive/svg-transform-responsive-expected.txt
index a7e3509..2c76784 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-responsive/svg-transform-responsive-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-responsive/svg-transform-responsive-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
 PASS This test uses responsive-test.js. 
-FAIL Animation on property <svgTransform> from neutral to [translate(30 70)] with {"underlying":"translate(10 10)"} changed to {"underlying":"translate(20 30) skewX(10)"} at (0.25) is [translate(20 30) skewX(10)] assert_equals: expected "2,0,1,0,0,1,20,30,5,10,1,0,0.17632698070846498,1,0,0" but got "2,0,1,0,0,1,0,0,5,0,1,0,0,1,0,0"
-PASS Animation on property <svgTransform> from neutral to [translate(30 70)] with {"underlying":"translate(10 10)"} changed to {"underlying":"translate(20 30) skewX(10)"} at (0.75) is [translate(30 70)] 
-FAIL Animation on property <svgTransform> from neutral to [translate(30 70)] with {"underlying":"translate(20 30) skewX(10)"} changed to {"underlying":"translate(10 10)"} at (0.25) is [translate(15 25)] assert_equals: expected "2,0,1,0,0,1,15,25" but got "2,0,1,0,0,1,7.5,17.5"
-FAIL Animation on property <svgTransform> from neutral to [translate(30 70)] with {"underlying":"translate(20 30) skewX(10)"} changed to {"underlying":"translate(10 10)"} at (0.75) is [translate(25 55)] assert_equals: expected "2,0,1,0,0,1,25,55" but got "2,0,1,0,0,1,22.5,52.5"
+FAIL Animation on property <svg-transform> from neutral to [translate(30 70)] with {"underlying":"translate(10 10)"} changed to {"underlying":"translate(20 30) skewX(10)"} at (0.25) is [translate(20 30) skewX(10)] assert_equals: expected "2,0,1,0,0,1,20,30,5,10,1,0,0.17632698070846498,1,0,0" but got "2,0,1,0,0,1,0,0,5,0,1,0,0,1,0,0"
+PASS Animation on property <svg-transform> from neutral to [translate(30 70)] with {"underlying":"translate(10 10)"} changed to {"underlying":"translate(20 30) skewX(10)"} at (0.75) is [translate(30 70)] 
+FAIL Animation on property <svg-transform> from neutral to [translate(30 70)] with {"underlying":"translate(20 30) skewX(10)"} changed to {"underlying":"translate(10 10)"} at (0.25) is [translate(15 25)] assert_equals: expected "2,0,1,0,0,1,15,25" but got "2,0,1,0,0,1,7.5,17.5"
+FAIL Animation on property <svg-transform> from neutral to [translate(30 70)] with {"underlying":"translate(20 30) skewX(10)"} changed to {"underlying":"translate(10 10)"} at (0.75) is [translate(25 55)] assert_equals: expected "2,0,1,0,0,1,25,55" but got "2,0,1,0,0,1,22.5,52.5"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/animations/svg-length-unittype-crash.html b/third_party/WebKit/LayoutTests/animations/svg-length-unittype-crash.html
index a33a21884..a3dcca5 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-length-unittype-crash.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-length-unittype-crash.html
@@ -4,6 +4,6 @@
 <svg><circle id="target"/></svg>
 <script>
 test(() => {
-  target.animate([{svgR: '10px'}, {svgR: '100px'}], 1000);
+  target.animate([{'svg-r': '10px'}, {'svg-r': '100px'}], 1000);
 }, "Don't crash when applying SVG R attribute.");
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html
index 85173363..e2afad9 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-out-of-bounds-src.html
@@ -36,15 +36,17 @@
 ctx1.drawImage(bgcanvas, 0,    0,    100, 200, 75,  175, 100, 100);
 ctx1.drawImage(bgcanvas, 0,    0,    200, 200, 175, 175, 100, 100);
 
-ctx2.drawImage(img, -100, -100, 300, 300, -25, -25, 300, 300);
-ctx2.drawImage(img, -100, -100, 200, 200, -25, -25, 100, 100);
-ctx2.drawImage(img, 0,    -100, 100, 200, 75,  -25, 100, 100);
-ctx2.drawImage(img, 0,    -100, 200, 200, 175, -25, 100, 100);
-ctx2.drawImage(img, -100, 0,    200, 100, -25, 75,  100, 100);
-ctx2.drawImage(img, 0,  0,      200, 100, 175, 75,  100, 100);
-ctx2.drawImage(img, -100, 0,    200, 200, -25, 175, 100, 100);
-ctx2.drawImage(img, 0,    0,    100, 200, 75,  175, 100, 100);
-ctx2.drawImage(img, 0,    0,    200, 200, 175, 175, 100, 100);
+img.onload = function() {
+    ctx2.drawImage(img, -100, -100, 300, 300, -25, -25, 300, 300);
+    ctx2.drawImage(img, -100, -100, 200, 200, -25, -25, 100, 100);
+    ctx2.drawImage(img, 0,    -100, 100, 200, 75,  -25, 100, 100);
+    ctx2.drawImage(img, 0,    -100, 200, 200, 175, -25, 100, 100);
+    ctx2.drawImage(img, -100, 0,    200, 100, -25, 75,  100, 100);
+    ctx2.drawImage(img, 0,  0,      200, 100, 175, 75,  100, 100);
+    ctx2.drawImage(img, -100, 0,    200, 200, -25, 175, 100, 100);
+    ctx2.drawImage(img, 0,    0,    100, 200, 75,  175, 100, 100);
+    ctx2.drawImage(img, 0,    0,    200, 200, 175, 175, 100, 100);
+}
 
 if (window.testRunner) {
     testRunner.waitUntilDone();
@@ -96,4 +98,4 @@
 }
 
 </script>
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-async-loading-data-uris.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-async-loading-data-uris.html
new file mode 100644
index 0000000..458b84930b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLImageElement/image-async-loading-data-uris.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script>
+    test(function() {
+        var img = new Image();
+        img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
+        assert_equals(img.width, 0);
+    }, "Test that a data URI resource doesn't get loaded synchronously");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/basic-buttons.html b/third_party/WebKit/LayoutTests/fast/forms/basic-buttons.html
index 1ff9824..47fbe97 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/basic-buttons.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/basic-buttons.html
@@ -48,8 +48,10 @@
     }
 }
 
-printSize('button');
-printSize('input');
+window.onload = function() {
+    printSize('button');
+    printSize('input');
+};
 </script>
 
 </body> 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/popup-menu-event-order.html b/third_party/WebKit/LayoutTests/fast/forms/select/popup-menu-event-order.html
new file mode 100644
index 0000000..9add92ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/forms/select/popup-menu-event-order.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../resources/common.js"></script>
+<script src="../resources/picker-common.js"></script>
+</head>
+<body>
+<select id="menu">
+  <option>foo</option>
+  <option selected>bar</option>
+  <option hidden>baz</option>
+  <optgroup label="qux">
+      <option>garply</option>
+  </optgroup>
+</select>
+<script>
+
+var events = [];
+function recordEvent(event) {
+    events.push(event.type);
+}
+
+var menu = document.getElementById('menu');
+var picker = null;
+function openPickerErrorCallback() {
+    testFailed('picker didn\'t open')
+    finishJSTest();
+}
+openPicker(menu, test1, openPickerErrorCallback);
+
+function test1() {
+    picker = window.internals.pagePopupWindow.global.picker;
+    menu.addEventListener('mouseup', recordEvent);
+    menu.addEventListener('click', recordEvent);
+    menu.addEventListener('change', recordEvent);
+    eventSender.keyDown('downArrow');
+    eventSender.keyDown('\n');
+    shouldBeNull('window.internals.pagePopupWindow');
+    shouldBeEqualToString('menu.value', 'garply');
+    shouldBeEqualToString('internals.selectMenuListText(menu)', 'garply');
+    shouldBeEqualToString('events[0]', 'change');
+    shouldBeEqualToString('events[1]', 'mouseup');
+    shouldBeEqualToString('events[2]', 'click');
+
+    finishJSTest();
+}
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/create-shared-worker-frame.html b/third_party/WebKit/LayoutTests/fast/workers/resources/create-shared-worker-frame.html
index 8c7be30..74b7dfc 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/resources/create-shared-worker-frame.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/resources/create-shared-worker-frame.html
@@ -2,8 +2,17 @@
 <script>
 var workerNames = window.location.search.toString().substring(1);
 var nameArray = workerNames.split(",");
+var wait_pong_promises = [];
+
 for (var i = 0; i < nameArray.length; i++) {
-    var worker = new SharedWorker("shared-worker-common.js", nameArray[i]);
+    wait_pong_promises.push(new Promise(function(resolve) {
+        var worker = new SharedWorker("shared-worker-common.js", nameArray[i]);
+        worker.port.addEventListener('message', function(e) {
+                resolve(e.data);
+            }, false);
+        worker.port.start();
+        worker.port.postMessage('ping');
+    }));
 }
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-lifecycle.js b/third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-lifecycle.js
index e84353a..1ac80fc 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-lifecycle.js
+++ b/third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-lifecycle.js
@@ -1,30 +1,37 @@
-description("This test checks whether shared workers exit when the parent document closes");
 
 if (window.testRunner) {
     testRunner.dumpAsText();
     testRunner.waitUntilDone();
     waitUntilWorkerThreadsExit(runTests);
 } else {
-    debug("NOTE: This test relies on functionality in DumpRenderTree to detect when workers have exited - test results will be incorrect when run in a browser.");
+    log("NOTE: This test relies on functionality in DumpRenderTree to detect when workers have exited - test results will be incorrect when run in a browser.");
     runTests();
 }
 
 function runTests()
 {
-    createWorkerFrame("frame1", "worker1");
-    createWorkerFrame("frame2", "worker1,worker2");
-    createWorkerFrame("frame3", "worker3");
-    createWorkerFrame("frame4", "worker1");
-
-    waitUntilThreadCountMatches(closeFrame1, 3);
+    Promise.all([
+        createWorkerFrame("frame1", "worker1"),
+        createWorkerFrame("frame2", "worker1,worker2"),
+        createWorkerFrame("frame3", "worker3"),
+        createWorkerFrame("frame4", "worker1")])
+    .then(function() {
+        waitUntilThreadCountMatches(closeFrame1, 3);
+    });
 }
 
 function createWorkerFrame(id, workerNames)
 {
-    var iframe = document.createElement("iframe");
-    iframe.setAttribute("id", id);
-    iframe.setAttribute("src", "resources/create-shared-worker-frame.html?" + workerNames);
-    document.body.appendChild(iframe);
+    return new Promise(function(resolve) {
+            var frame = document.createElement("iframe");
+            frame.onload = function() { resolve(frame); };
+            frame.setAttribute("id", id);
+            frame.setAttribute("src", "resources/create-shared-worker-frame.html?" + workerNames);
+            document.body.appendChild(frame);
+        })
+        .then(function(frame) {
+            return Promise.all(frame.contentWindow.wait_pong_promises);
+        });
 }
 
 function closeFrame(id)
@@ -33,6 +40,18 @@
     frame.parentNode.removeChild(frame);
 }
 
+function reloadWorkerFrame(id)
+{
+    return new Promise(function(resolve) {
+            var frame = document.getElementById(id);
+            frame.onload = function() { resolve(frame); };
+            frame.contentWindow.location.reload();
+        })
+        .then(function(frame) {
+            return Promise.all(frame.contentWindow.wait_pong_promises);
+        });
+}
+
 function closeFrame1()
 {
     closeFrame("frame1");
@@ -41,27 +60,37 @@
 
 function closeFrame2()
 {
-    testPassed("Frame1 closed, shared workers kept running");
+    log("PASS: Frame1 closed, shared workers kept running");
     closeFrame("frame2");
     ensureThreadCountMatches(closeFrame3, 2);
 }
 
 function closeFrame3()
 {
-    testPassed("Frame2 closed, shared worker2 exited");
+    log("PASS: Frame2 closed, shared worker2 exited");
     closeFrame("frame3");
-    ensureThreadCountMatches(closeFrame4, 1);
+    ensureThreadCountMatches(reloadFrame4, 1);
+}
+
+function reloadFrame4() {
+    log("PASS: Frame3 closed, shared worker3 exited");
+    reloadWorkerFrame("frame4")
+        .then(function() {
+            ensureThreadCountMatches(closeFrame4, 1);
+        });
 }
 
 function closeFrame4()
 {
-    testPassed("Frame3 closed, shared worker3 exited");
+    log("PASS: Frame4 reloaded");
     closeFrame("frame4");
     waitUntilWorkerThreadsExit(complete);
 }
 
 function complete()
 {
-    testPassed("Frame4 closed, all workers closed");
-    done();
+    log("PASS: Frame4 closed, all workers closed");
+    log("DONE");
+    if (window.testRunner)
+        testRunner.notifyDone();
 }
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle-expected.txt
index 5284abf3..455135f 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle-expected.txt
@@ -1,7 +1,9 @@
 Test SharedWorker lifecycle. Will print PASS multiple times, followed by DONE.
 
-PASS: workerThreadCount = 0
-PASS: Worker thread created
-PASS: Worker exited when close() called.
+PASS: Frame1 closed, shared workers kept running
+PASS: Frame2 closed, shared worker2 exited
+PASS: Frame3 closed, shared worker3 exited
+PASS: Frame4 reloaded
+PASS: Frame4 closed, all workers closed
 DONE
 
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle.html b/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle.html
index 9c14424..f6353af 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/shared-worker-lifecycle.html
@@ -4,5 +4,5 @@
 <script src="../../resources/gc.js"></script>
 <script src="resources/shared-worker-create-common.js"></script>
 <script src="resources/worker-util.js"></script>
-<script src="resources/worker-lifecycle.js"></script>
+<script src="resources/shared-worker-lifecycle.js"></script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-none.cgi b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-none.cgi
new file mode 100755
index 0000000..71a0eef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-none.cgi
@@ -0,0 +1,8 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/html\n";
+print "Cache-Control: no-cache, no-store\n";
+print "X-FRAME-OPTIONS: \n\n";
+
+print "<p>PASS: This text should show up.</p>\n";
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none-expected.txt
new file mode 100644
index 0000000..89917ba0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none-expected.txt
@@ -0,0 +1,12 @@
+http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi, main document URL http://127.0.0.1:8000/security/XFrameOptions/x-frame-options-none.html, http method GET> redirectResponse (null)
+CONSOLE ERROR: Invalid 'X-Frame-Options' header encountered when loading 'http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi': '' is not a recognized directive. The header will be ignored.
+http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi, http status code 200>
+http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi - didFinishLoading
+The frame below should load, and a console message should be generated that notes the invalid header.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS: This text should show up.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none.html b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none.html
new file mode 100644
index 0000000..055d51b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-none.html
@@ -0,0 +1,12 @@
+<script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.dumpChildFramesAsText();
+        testRunner.dumpResourceLoadCallbacks();
+    }
+</script>
+
+<p>The frame below should load, and a console message should be generated
+that notes the invalid header.</p>
+<iframe style="width:500px; height:500px" src="http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-none.cgi"></iframe>
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-blocked-data-uri-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-blocked-data-uri-expected.txt
index 7897f99..c13fa03 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-blocked-data-uri-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/report-blocked-data-uri-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: line 8: Refused to load the image 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' because it violates the following Content Security Policy directive: "img-src 'none'".
+CONSOLE ERROR: line 9: Refused to load the image 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' because it violates the following Content Security Policy directive: "img-src 'none'".
 
 PingLoader dispatched to 'http://127.0.0.1:8000/security/contentSecurityPolicy/resources/save-report.php?test=report-blocked-data-uri.html'.
 CSP report received:
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/windowclient-navigate.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/windowclient-navigate.html
index ba7e3fb3..2d3e8e189 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/windowclient-navigate.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/windowclient-navigate.html
@@ -26,15 +26,11 @@
 
 var expected = [
   location.origin + '/serviceworker/resources/blank.html',
-  // TODO(zino): Should TypeError instead of UnknownError.
-  // Please see: http://crbug.com/540503
-  'UnknownError',
+  'TypeError',
   null,
   'TypeError',
-  // TODO(zino): Should TypeError instead of UnknownError.
-  // Please see: http://crbug.com/540503
-  'UnknownError',
-  'SecurityError',
+  'TypeError',
+  'TypeError',
   'TypeError',
   'TypeError'
 ];
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001-expected.txt b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001-expected.txt
deleted file mode 100644
index 11c1a839..0000000
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL writing-mode: sideways-lr assert_equals: expected "sideways-lr" but got "horizontal-tb"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001.html
deleted file mode 100644
index 3543b543..0000000
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-lr-001.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Writing Modes: parsing writing-mode: sideways-lr</title>
-<link rel="author" title="Koji Ishii" href="kojiishi@gmail.com">
-<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#block-flow">
-<meta name="assert" content="This test asserts the parser and getComputedStyle works correctly for the writing-mode: sideways-lr.">
-<meta name="flags" content="dom">
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-
-<div style="writing-mode: sideways-lr"
-  data-expected="sideways-lr"></div>
-
-<script>
-Array.prototype.forEach.call(document.querySelectorAll("[data-expected]"), function (element) {
-  test(function () {
-    var actual = getComputedStyle(element).writingMode;
-    assert_equals(actual, element.dataset.expected);
-  }, element.title || element.getAttribute("style"));
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001-expected.txt b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001-expected.txt
deleted file mode 100644
index 37962bf..0000000
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL writing-mode: sideways-rl assert_equals: expected "sideways-rl" but got "horizontal-tb"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001.html
deleted file mode 100644
index 0480d46..0000000
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/writing-mode-parsing-sideways-rl-001.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Writing Modes: parsing writing-mode: sideways-rl</title>
-<link rel="author" title="Koji Ishii" href="kojiishi@gmail.com">
-<link rel="help" href="https://drafts.csswg.org/css-writing-modes-3/#block-flow">
-<meta name="assert" content="This test asserts the parser and getComputedStyle works correctly for the writing-mode: sideways-rl.">
-<meta name="flags" content="dom">
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-
-<div style="writing-mode: sideways-rl"
-  data-expected="sideways-rl"></div>
-
-<script>
-Array.prototype.forEach.call(document.querySelectorAll("[data-expected]"), function (element) {
-  test(function () {
-    var actual = getComputedStyle(element).writingMode;
-    assert_equals(actual, element.dataset.expected);
-  }, element.title || element.getAttribute("style"));
-});
-</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha-expected.html
new file mode 100644
index 0000000..4fbc5ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha-expected.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported types</title>
+<li>first item</li>
+<li>second item</li>
+<ol>
+  <li>first ordered item</li>
+  <li>second ordered item</li>
+</ol>
+<ul>
+  <li>first unordered item</li>
+  <li>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html
new file mode 100644
index 0000000..81babe7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: lower-alpha</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=lower-alpha>first item</li>
+<li type=LOWER-ALPHA>second item</li>
+<ol>
+  <li type=lower-alpha>first ordered item</li>
+  <li type=LOWER-ALPHA>second ordered item</li>
+</ol>
+<ul>
+  <li type=lower-alpha>first unordered item</li>
+  <li type=LOWER-ALPHA>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman-expected.html
new file mode 100644
index 0000000..4fbc5ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman-expected.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported types</title>
+<li>first item</li>
+<li>second item</li>
+<ol>
+  <li>first ordered item</li>
+  <li>second ordered item</li>
+</ol>
+<ul>
+  <li>first unordered item</li>
+  <li>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html
new file mode 100644
index 0000000..e01cfdb7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: lower-roman</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=lower-roman>first item</li>
+<li type=LOWER-ROMAN>second item</li>
+<ol>
+  <li type=lower-roman>first ordered item</li>
+  <li type=LOWER-ROMAN>second ordered item</li>
+</ol>
+<ul>
+  <li type=lower-roman>first unordered item</li>
+  <li type=LOWER-ROMAN>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha-expected.html
new file mode 100644
index 0000000..4fbc5ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha-expected.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported types</title>
+<li>first item</li>
+<li>second item</li>
+<ol>
+  <li>first ordered item</li>
+  <li>second ordered item</li>
+</ol>
+<ul>
+  <li>first unordered item</li>
+  <li>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html
new file mode 100644
index 0000000..2efb65d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: upper-alpha</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=upper-alpha>first item</li>
+<li type=UPPER-ALPHA>second item</li>
+<ol>
+  <li type=upper-alpha>first ordered item</li>
+  <li type=UPPER-ALPHA>second ordered item</li>
+</ol>
+<ul>
+  <li type=upper-alpha>first unordered item</li>
+  <li type=UPPER-ALPHA>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman-expected.html
new file mode 100644
index 0000000..4fbc5ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman-expected.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported types</title>
+<li>first item</li>
+<li>second item</li>
+<ol>
+  <li>first ordered item</li>
+  <li>second ordered item</li>
+</ol>
+<ul>
+  <li>first unordered item</li>
+  <li>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html
new file mode 100644
index 0000000..bd8dafc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: upper-roman</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=upper-roman>first item</li>
+<li type=UPPER-ROMAN>second item</li>
+<ol>
+  <li type=upper-roman>first ordered item</li>
+  <li type=UPPER-ROMAN>second ordered item</li>
+</ol>
+<ul>
+  <li type=upper-roman>first unordered item</li>
+  <li type=UPPER-ROMAN>second unordered item</li>
+</ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal-expected.html
new file mode 100644
index 0000000..c53fe94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal-expected.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html
new file mode 100644
index 0000000..0fb0e14
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: decimal</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=decimal><li>first item</li><li>second item</li></ul>
+<ul type=DECIMAL><li>first item</li><li>second item</li></ul>
+<ul type=1><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha-expected.html
new file mode 100644
index 0000000..c53fe94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha-expected.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html
new file mode 100644
index 0000000..f31cc247
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: lower-alpha</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=lower-alpha><li>first item</li><li>second item</li></ul>
+<ul type=LOWER-ALPHA><li>first item</li><li>second item</li></ul>
+<ul type=a><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman-expected.html
new file mode 100644
index 0000000..c53fe94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman-expected.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html
new file mode 100644
index 0000000..bd86861
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: lower-roman</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=lower-roman><li>first item</li><li>second item</li></ul>
+<ul type=LOWER-ROMAN><li>first item</li><li>second item</li></ul>
+<ul type=i><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha-expected.html
new file mode 100644
index 0000000..c53fe94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha-expected.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html
new file mode 100644
index 0000000..3f880f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: upper-alpha</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=upper-alpha><li>first item</li><li>second item</li></ul>
+<ul type=UPPER-ALPHA><li>first item</li><li>second item</li></ul>
+<ul type=A><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman-expected.html
new file mode 100644
index 0000000..c53fe94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman-expected.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html
new file mode 100644
index 0000000..d7f1295
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: upper-roman</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=upper-roman><li>first item</li><li>second item</li></ul>
+<ul type=UPPER-ROMAN><li>first item</li><li>second item</li></ul>
+<ul type=I><li>first item</li><li>second item</li></ul>
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously-expected.txt b/third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously-expected.txt
new file mode 100644
index 0000000..21927c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously-expected.txt
@@ -0,0 +1,2 @@
+Test for crbug.com/224317: data:uri images should load asynchronously.
+PASS
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously.html b/third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously.html
rename to third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously.html
index 7746f5b5..370eff19 100644
--- a/third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously.html
+++ b/third_party/WebKit/LayoutTests/loader/data-uri-images-load-asynchronously.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <body>
-Test for crbug.com/224317: data:uri images should load synchronously.<br/>
+Test for crbug.com/224317: data:uri images should load asynchronously.<br/>
 <script>
     if (window.testRunner)
         testRunner.dumpAsText();
@@ -10,9 +10,9 @@
     image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAnklEQVR42u3QMQEAAAgDoGlyo1vBzwciUJlw1ApkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyfq2MosBSIeKONMAAAAASUVORK5CYII=";
 
     if (image.width == 100 && image.height == 100)
-        document.write("PASS");
-    else
         document.write("FAIL");
+    else
+        document.write("PASS");
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously-expected.txt b/third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously-expected.txt
deleted file mode 100644
index 1dddd7e..0000000
--- a/third_party/WebKit/LayoutTests/loader/data-uri-images-load-synchronously-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Test for crbug.com/224317: data:uri images should load synchronously.
-PASS
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously-expected.txt b/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously-expected.txt
new file mode 100644
index 0000000..8289b387
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously-expected.txt
@@ -0,0 +1,2 @@
+Test for crbug.com/224317: data:uri images should load asynchronously and reload synchronously.
+PASS
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously.html b/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously.html
similarity index 65%
rename from third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously.html
rename to third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously.html
index 9b583e07..cc83ee51 100644
--- a/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously.html
+++ b/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-asynchronously.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <body>
-Test for crbug.com/224317: data:uri images should reload synchronously.<br/>
+Test for crbug.com/224317: data:uri images should load asynchronously and reload synchronously.<br/>
 <script>
     if (window.testRunner) {
         testRunner.waitUntilDone();
@@ -11,17 +11,23 @@
     var image = new Image();
     image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAnklEQVR42u3QMQEAAAgDoGlyo1vBzwciUJlw1ApkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyfq2MosBSIeKONMAAAAASUVORK5CYII=";
 
-    if (image.width != 100 || image.height != 100) {
-        document.write("FAIL");
-    } else {
-        if (location.hash == "#reloaded") {
-            document.write("PASS");
+    if (location.hash != "#reloaded") {
+        if (image.width == 100 || image.height == 100) {
+            document.write("FAIL");
             if (window.testRunner)
                 testRunner.notifyDone();
         } else {
             location.hash = "#reloaded";
             location.reload();
         }
+    } else {
+        if (image.width == 100 || image.height == 100) {
+            document.write("PASS");
+        } else {
+            document.write("FAIL");
+        }
+        if (window.testRunner)
+            testRunner.notifyDone();
     }
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously-expected.txt b/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously-expected.txt
deleted file mode 100644
index c0ed5e95..0000000
--- a/third_party/WebKit/LayoutTests/loader/data-uri-images-reload-synchronously-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Test for crbug.com/224317: data:uri images should reload synchronously.
-PASS
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/popup-menu-event-order-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/popup-menu-event-order-expected.txt
new file mode 100644
index 0000000..88dc884a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/popup-menu-event-order-expected.txt
@@ -0,0 +1,5 @@
+FAIL picker didn't open
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/popup-menu-event-order-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/popup-menu-event-order-expected.txt
new file mode 100644
index 0000000..385add7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/popup-menu-event-order-expected.txt
@@ -0,0 +1,10 @@
+PASS window.internals.pagePopupWindow is null
+PASS menu.value is "garply"
+PASS internals.selectMenuListText(menu) is "garply"
+PASS events[0] is "change"
+PASS events[1] is "mouseup"
+PASS events[2] is "click"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-globalalpha.html b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-globalalpha.html
index dec1382..24ba5cd 100644
--- a/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-globalalpha.html
+++ b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-globalalpha.html
@@ -3,7 +3,9 @@
 <script>
 var img = new Image();
 img.src = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" fill="#008000"/></svg>';
-var c = document.querySelector('canvas').getContext('2d');
-c.globalAlpha = 0.5;
-c.drawImage(img, 0, 0);
+img.onload = function() {
+    var c = document.querySelector('canvas').getContext('2d');
+    c.globalAlpha = 0.5;
+    c.drawImage(img, 0, 0);
+}
 </script>
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment-expected.html b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment-expected.html
new file mode 100644
index 0000000..a92efd9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment-expected.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>drawImage() with SVG fragments</title>
+<script>
+    onload = function() {
+        var context = document.getElementsByTagName('canvas')[0].getContext('2d');
+        fillStyles = [ "green", "red", "blue" ];
+        fillStyles.forEach(function(fillStyle, i) {
+            context.fillStyle = fillStyle;
+            context.fillRect(i*60, i*60, 120, 120);
+        });
+    }
+</script>
+<canvas width="240" height="240"></canvas>
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment.html b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment.html
new file mode 100644
index 0000000..831729c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/canvas/canvas-draw-image-svg-fragment.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>drawImage() with SVG fragments</title>
+<script>
+    onload = function() {
+        var context = document.getElementsByTagName('canvas')[0].getContext('2d');
+        var images = document.getElementsByTagName('img');
+        for (var i = 0; i < images.length; i++) {
+            var newImage = new Image();
+            newImage.src = images[i].src;
+            context.drawImage(newImage, i*60, i*60, 120, 120);
+        }
+        while (images.length)
+            document.body.removeChild(images.item(0));
+    }
+</script>
+<canvas width="240" height="240"></canvas>
+<img src="../css/resources/fragment-identifiers.svg#green">
+<img src="../css/resources/fragment-identifiers.svg#red">
+<img src="../css/resources/fragment-identifiers.svg#blue">
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/image-svg-intrinsic-size.html b/third_party/WebKit/LayoutTests/svg/canvas/image-svg-intrinsic-size.html
index 917e029e8..bb94b5b 100644
--- a/third_party/WebKit/LayoutTests/svg/canvas/image-svg-intrinsic-size.html
+++ b/third_party/WebKit/LayoutTests/svg/canvas/image-svg-intrinsic-size.html
@@ -8,12 +8,15 @@
       image.src = "data:image/svg+xml," +
                   "<svg xmlns='http://www.w3.org/2000/svg' width='200' viewBox='0 0 1 1'>" +
                   "<rect width='1' height='1' fill='green'/></svg>";
+      image.onload = function() {
+          var canvas = document.querySelector('canvas');
+          var ctx = canvas.getContext("2d");
+          ctx.drawImage(document.querySelector('img'), 0, 0);
+          document.body.removeChild(document.querySelector('img'));
+      };
       return image;
   }
   document.body.appendChild(createSVGImage());
   document.body.offsetTop; // Force layout
-  var canvas = document.querySelector('canvas');
-  var ctx = canvas.getContext("2d");
-  ctx.drawImage(document.querySelector('img'), 0, 0);
-  document.body.removeChild(document.querySelector('img'));
+
 </script>
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp
index 5bfd50c..f15ce8ee 100644
--- a/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -251,7 +251,7 @@
     bool shouldCancel = (!playing() && m_compositorState) || changed;
     bool shouldStart = playing() && (!m_compositorState || changed);
 
-    if (shouldCancel && shouldStart && m_compositorState && m_compositorState->pendingAction == Start) {
+    if (startOnCompositor && shouldCancel && shouldStart && m_compositorState && m_compositorState->pendingAction == Start) {
         // Restarting but still waiting for a start time.
         return false;
     }
diff --git a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
index 19eb9a5..03f105c 100644
--- a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
@@ -77,6 +77,7 @@
         // Animations with a start time do not participate in compositor start-time grouping.
         if (animation->preCommit(animation->hasStartTime() ? 1 : compositorGroup, startOnCompositor)) {
             if (animation->hasActiveAnimationsOnCompositor() && !hadCompositorAnimation) {
+
                 startedSynchronizedOnCompositor = true;
             }
 
@@ -110,11 +111,10 @@
         animation->postCommit(animation->timeline()->currentTimeInternal());
 
     ASSERT(m_pending.isEmpty());
+    ASSERT(startOnCompositor || deferred.isEmpty());
     for (auto& animation : deferred)
         animation->setCompositorPending();
-#if ENABLE(ASSERT)
-    size_t pendingSize = m_pending.size();
-#endif
+    ASSERT(m_pending.size() == deferred.size());
 
     if (startedSynchronizedOnCompositor)
         return true;
@@ -131,7 +131,7 @@
     // If not, go ahead and start any animations that were waiting.
     notifyCompositorAnimationStarted(monotonicallyIncreasingTime());
 
-    ASSERT(pendingSize == m_pending.size());
+    ASSERT(m_pending.size() == deferred.size());
     return false;
 }
 
diff --git a/third_party/WebKit/Source/core/animation/EffectInput.cpp b/third_party/WebKit/Source/core/animation/EffectInput.cpp
index 2a73456e..52138d92 100644
--- a/third_party/WebKit/Source/core/animation/EffectInput.cpp
+++ b/third_party/WebKit/Source/core/animation/EffectInput.cpp
@@ -52,18 +52,16 @@
 
 namespace {
 
-bool svgPrefixed(const String& property)
+bool isSVGPrefixed(const String& property)
 {
-    return property.length() >= 4 && property.startsWith("svg") && isASCIIUpper(property[3]);
+    return property.startsWith("svg-");
 }
 
 QualifiedName svgAttributeName(String property)
 {
-    // Replace 'svgTransform' with 'transform', etc.
-    ASSERT(svgPrefixed(property));
-    UChar first = toASCIILower(property[3]);
+    // Replace 'svg-transform' with 'transform', etc.
+    ASSERT(isSVGPrefixed(property));
     property.remove(0, 4);
-    property.insert(&first, 1, 0);
 
     if (property == "href")
         return XLinkNames::hrefAttr;
@@ -71,9 +69,10 @@
     return QualifiedName(nullAtom, AtomicString(property), SVGNames::amplitudeAttr.namespaceURI());
 }
 
-const QualifiedName* supportedSVGAttribute(const String& property, SVGElement* svgElement)
+using AttributeNameMap = HashMap<QualifiedName, const QualifiedName*>;
+
+const AttributeNameMap& getSupportedAttributes()
 {
-    typedef HashMap<QualifiedName, const QualifiedName*> AttributeNameMap;
     DEFINE_STATIC_LOCAL(AttributeNameMap, supportedAttributes, ());
     if (supportedAttributes.isEmpty()) {
         // Fill the set for the first use.
@@ -178,12 +177,17 @@
         for (size_t i = 0; i < WTF_ARRAY_LENGTH(attributes); i++)
             supportedAttributes.set(*attributes[i], attributes[i]);
     }
+    return supportedAttributes;
+}
 
+const QualifiedName* findSVGAttributeForProperty(const String& property, SVGElement* svgElement)
+{
     if (isSVGSMILElement(*svgElement))
         return nullptr;
 
     QualifiedName attributeName = svgAttributeName(property);
 
+    const AttributeNameMap& supportedAttributes = getSupportedAttributes();
     auto iter = supportedAttributes.find(attributeName);
     if (iter == supportedAttributes.end() || !svgElement->propertyFromAttribute(*iter->value))
         return nullptr;
@@ -266,14 +270,12 @@
                 continue;
             }
 
-            if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled() || !element->isSVGElement() || !svgPrefixed(property))
+            if (!RuntimeEnabledFeatures::webAnimationsSVGEnabled() || !element->isSVGElement() || !isSVGPrefixed(property))
                 continue;
 
-            SVGElement* svgElement = toSVGElement(element);
-            const QualifiedName* qualifiedName = supportedSVGAttribute(property, svgElement);
-
+            const QualifiedName* qualifiedName = findSVGAttributeForProperty(property, toSVGElement(element));
             if (qualifiedName)
-                keyframe->setPropertyValue(*qualifiedName, value, svgElement);
+                keyframe->setPropertyValue(*qualifiedName, value);
         }
     }
 
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
index b3f4ffbe8..ec2f581 100644
--- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
+++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -73,9 +73,8 @@
     m_propertySet->setProperty(property, value, false);
 }
 
-void StringKeyframe::setPropertyValue(const QualifiedName& attributeName, const String& value, Element* element)
+void StringKeyframe::setPropertyValue(const QualifiedName& attributeName, const String& value)
 {
-    ASSERT(element->isSVGElement());
     m_svgPropertyMap.set(&attributeName, value);
 }
 
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.h b/third_party/WebKit/Source/core/animation/StringKeyframe.h
index 55e9edd0..6ffcfd5 100644
--- a/third_party/WebKit/Source/core/animation/StringKeyframe.h
+++ b/third_party/WebKit/Source/core/animation/StringKeyframe.h
@@ -23,7 +23,7 @@
 
     void setPropertyValue(CSSPropertyID, const String& value, Element*, StyleSheetContents*);
     void setPropertyValue(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>);
-    void setPropertyValue(const QualifiedName&, const String& value, Element*);
+    void setPropertyValue(const QualifiedName&, const String& value);
     CSSValue* cssPropertyValue(CSSPropertyID property) const
     {
         int index = m_propertySet->findPropertyIndex(property);
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index ca0c2f9..1f1f39e 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -964,9 +964,9 @@
     case CSSSelector::PseudoScope:
         if (m_mode == SharingRules)
             return true;
-        if (context.scope == element.document())
+        if (context.scope == &element.document())
             return element == element.document().documentElement();
-        return context.scope == element;
+        return context.scope == &element;
     case CSSSelector::PseudoUnresolved:
         return element.isUnresolvedCustomElement();
     case CSSSelector::PseudoHost:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 9168952..a715b32 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -2062,6 +2062,36 @@
     return list.release();
 }
 
+template <CSSValueID start, CSSValueID end>
+static PassRefPtrWillBeRawPtr<CSSValue> consumePositionLonghand(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    if (range.peek().type() == IdentToken) {
+        CSSValueID id = range.peek().id();
+        int percent;
+        if (id == start)
+            percent = 0;
+        else if (id == CSSValueCenter)
+            percent = 50;
+        else if (id == end)
+            percent = 100;
+        else
+            return nullptr;
+        range.consumeIncludingWhitespace();
+        return cssValuePool().createValue(percent, CSSPrimitiveValue::UnitType::Percentage);
+    }
+    return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, UnitlessQuirk::Forbid);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumePositionX(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    return consumePositionLonghand<CSSValueLeft, CSSValueRight>(range, cssParserMode);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumePositionY(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    return consumePositionLonghand<CSSValueTop, CSSValueBottom>(range, cssParserMode);
+}
+
 static PassRefPtrWillBeRawPtr<CSSValue> consumePaint(CSSParserTokenRange& range, CSSParserContext context)
 {
     if (range.peek().id() == CSSValueNone)
@@ -2440,6 +2470,14 @@
         return consumeLineWidth(m_range, m_context.mode());
     case CSSPropertyTransform:
         return consumeTransform(m_range, m_context.mode(), unresolvedProperty == CSSPropertyAliasWebkitTransform);
+    case CSSPropertyWebkitTransformOriginX:
+    case CSSPropertyWebkitPerspectiveOriginX:
+        return consumePositionX(m_range, m_context.mode());
+    case CSSPropertyWebkitTransformOriginY:
+    case CSSPropertyWebkitPerspectiveOriginY:
+        return consumePositionY(m_range, m_context.mode());
+    case CSSPropertyWebkitTransformOriginZ:
+        return consumeLength(m_range, m_context.mode(), ValueRangeAll);
     case CSSPropertyFill:
     case CSSPropertyStroke:
         return consumePaint(m_range, m_context);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index e0392a5..fd149b7b 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -568,21 +568,6 @@
         validPrimitive = validUnit(value, FInteger);
         break;
 
-    case CSSPropertyWebkitPerspectiveOriginX:
-    case CSSPropertyWebkitTransformOriginX:
-        parsedValue = parseFillPositionX(m_valueList);
-        if (parsedValue)
-            m_valueList->next();
-        break;
-    case CSSPropertyWebkitPerspectiveOriginY:
-    case CSSPropertyWebkitTransformOriginY:
-        parsedValue = parseFillPositionY(m_valueList);
-        if (parsedValue)
-            m_valueList->next();
-        break;
-    case CSSPropertyWebkitTransformOriginZ:
-        validPrimitive = validUnit(value, FLength);
-        break;
     case CSSPropertyPerspective:
         if (id == CSSValueNone) {
             validPrimitive = true;
@@ -765,6 +750,11 @@
         break;
 
     // These were not accepted by the new path above so we should return false.
+    case CSSPropertyWebkitPerspectiveOriginX:
+    case CSSPropertyWebkitTransformOriginX:
+    case CSSPropertyWebkitPerspectiveOriginY:
+    case CSSPropertyWebkitTransformOriginY:
+    case CSSPropertyWebkitTransformOriginZ:
     case CSSPropertyWebkitMarginCollapse:
     case CSSPropertyWillChange:
     case CSSPropertyPage:
diff --git a/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
index 2e8c27f..7bb35c8d 100644
--- a/third_party/WebKit/Source/core/dom/CrossThreadTask.h
+++ b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
@@ -36,7 +36,7 @@
 #include "platform/ThreadSafeFunctional.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
-#include "wtf/TypeTraits.h"
+#include <type_traits>
 
 namespace blink {
 
@@ -122,7 +122,7 @@
 // (P = <P1, ..., Pn>, MP = <MP1, ..., MPn, ExecutionContext*>)
 template<typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS + 1 == MPS, RETTYPE>::Type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
+typename std::enable_if<PS + 1 == MPS, RETTYPE>::type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
 {
     return internal::CallClosureWithExecutionContextTask::create(threadSafeBind<ExecutionContext*>(function, parameters...));
 }
@@ -131,7 +131,7 @@
 // (P = <P1, ..., Pn>, MP = <MP1, ..., MPn, ExecutionContext*>)
 template<typename C, typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS + 1 == MPS, RETTYPE>::Type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
+typename std::enable_if<PS + 1 == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
 {
     return internal::CallClosureWithExecutionContextTask::create(threadSafeBind<ExecutionContext*>(function, AllowCrossThreadAccess(p), parameters...));
 }
@@ -140,7 +140,7 @@
 // (P = <P1, ..., Pn>, MP = <MP1, ..., MPn>)
 template<typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS == MPS, RETTYPE>::Type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
+typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (*function)(MP...), const P&... parameters)
 {
     return internal::CallClosureTask::create(threadSafeBind(function, parameters...));
 }
@@ -150,14 +150,14 @@
 // (P = <P1, ..., Pn>, MP = <MP1, ..., MPn>)
 template<typename C, typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS == MPS, RETTYPE>::Type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
+typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), C* p, const P&... parameters)
 {
     return internal::CallClosureTask::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
 }
 
 template<typename C, typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS == MPS, RETTYPE>::Type createCrossThreadTask(void (C::*function)(MP...), const WeakPtr<C>& p, const P&... parameters)
+typename std::enable_if<PS == MPS, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), const WeakPtr<C>& p, const P&... parameters)
 {
     return internal::CallClosureTask::create(threadSafeBind(function, AllowCrossThreadAccess(p), parameters...));
 }
@@ -166,7 +166,7 @@
 // (P = <P0, P1, ..., Pn>, MP = <MP1, ..., MPn>)
 template<typename C, typename... P, typename... MP,
     typename RETTYPE = PassOwnPtr<ExecutionContextTask>, size_t PS = sizeof...(P), size_t MPS = sizeof...(MP)>
-typename WTF::EnableIf<PS == MPS + 1, RETTYPE>::Type createCrossThreadTask(void (C::*function)(MP...), const P&... parameters)
+typename std::enable_if<PS == MPS + 1, RETTYPE>::type createCrossThreadTask(void (C::*function)(MP...), const P&... parameters)
 {
     return internal::CallClosureTask::create(threadSafeBind(function, parameters...));
 }
diff --git a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h
index 77e1c0a..7159e67 100644
--- a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h
+++ b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h
@@ -29,10 +29,10 @@
 
 #include "core/CoreExport.h"
 #include "core/dom/Element.h"
+#include "core/dom/shadow/InsertionPoint.h"
 
 namespace blink {
 
-class InsertionPoint;
 class LayoutObject;
 
 namespace LayoutTreeBuilderTraversal {
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 6c492e27..858b47a 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -48,6 +48,7 @@
 #include "core/layout/LayoutImage.h"
 #include "core/page/Page.h"
 #include "core/style/ContentData.h"
+#include "core/svg/graphics/SVGImageForContainer.h"
 #include "platform/ContentType.h"
 #include "platform/EventDispatchForbiddenScope.h"
 #include "platform/MIMETypeRegistry.h"
@@ -604,16 +605,23 @@
         return nullptr;
     }
 
-    RefPtr<Image> sourceImage = cachedImage()->image();
-
-    // We need to synthesize a container size if a layoutObject is not available to provide one.
-    if (!layoutObject() && sourceImage->usesContainerSize())
-        sourceImage->setContainerSize(sourceImage->size());
+    RefPtr<Image> sourceImage;
+    if (cachedImage()->image()->isSVGImage()) {
+        sourceImage = SVGImageForContainer::create(toSVGImage(cachedImage()->image()),
+            cachedImage()->image()->size(), 1, document().completeURL(imageSourceURL()));
+    } else {
+        sourceImage = cachedImage()->image();
+    }
 
     *status = NormalSourceImageStatus;
     return sourceImage->imageForDefaultFrame();
 }
 
+bool HTMLImageElement::isSVGSource() const
+{
+    return cachedImage() && cachedImage()->image()->isSVGImage();
+}
+
 bool HTMLImageElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
 {
     ImageResource* image = cachedImage();
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.h b/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 311914d..1191799e6 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -99,6 +99,7 @@
 
     // CanvasImageSource implementation
     PassRefPtr<Image> getSourceImageForCanvas(SourceImageStatus*, AccelerationHint) const override;
+    bool isSVGSource() const override;
     bool wouldTaintOrigin(SecurityOrigin*) const override;
     FloatSize elementSize() const override;
     FloatSize defaultDestinationSize() const override;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
index b03965b..e74b0ce 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
@@ -56,6 +56,7 @@
 
     virtual bool isVideoElement() const { return false; }
     virtual bool isCanvasElement() const { return false; }
+    virtual bool isSVGSource() const { return false; }
 
     // Adjusts the source and destination rectangles for cases where the actual
     // source image is a subregion of the image returned by getSourceImageForCanvas.
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
index b9910d8..f3f08e1 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -355,7 +355,7 @@
         return winner;
     for (unsigned i = imageCandidates.size() - 1; i > winner; --i) {
         KURL url = document->completeURL(stripLeadingAndTrailingHTMLSpaces(imageCandidates[i]->url()));
-        if (memoryCache()->resourceForURL(url, document->fetcher()->getCacheIdentifier()))
+        if (memoryCache()->resourceForURL(url, document->fetcher()->getCacheIdentifier()) || url.protocolIsData())
             return i;
     }
     return winner;
diff --git a/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py b/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
index 8a707bccc..43091f3 100755
--- a/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
+++ b/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
@@ -1145,7 +1145,7 @@
 
                     @staticmethod
                     def get_setter_value_expression_pattern():
-                        return None
+                        return "static_pointer_cast<JSONValue>(%s)"
 
                     @staticmethod
                     def reduce_to_raw_type():
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index d8a4dd3..102b2ed 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -467,7 +467,7 @@
         if (resource && !resource->errorOccurred())
             return true;
     }
-    return (m_loadingImageDocument || isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || url.protocolIsData());
+    return (m_loadingImageDocument || isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element));
 }
 
 void ImageLoader::notifyFinished(Resource* resource)
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
index 416f265..0a5f77d3 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -89,7 +89,7 @@
 
     String filenameExtension() const override;
 
-    void setContainerSize(const IntSize&) override;
+    void setContainerSize(const IntSize&);
     IntSize containerSize() const;
     bool usesContainerSize() const override { return true; }
     void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override;
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
index 1145119..7976efe 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -1416,7 +1416,7 @@
 
     bool isExpensive = false;
 
-    if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && image && image->isSVGImage())
+    if (ExpensiveCanvasHeuristicParameters::SVGImageSourcesAreExpensive && imageSource->isSVGSource())
         isExpensive = true;
 
     if (imageSource->elementSize().width() * imageSource->elementSize().height() > canvas()->width() * canvas()->height() * ExpensiveCanvasHeuristicParameters::ExpensiveImageSizeRatio)
diff --git a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
index a45c182..67c7f9f5 100644
--- a/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
+++ b/third_party/WebKit/Source/modules/compositorworker/CompositorWorkerThreadTest.cpp
@@ -114,8 +114,11 @@
         return m_oldPlatform->createWaitableEvent(policy, state);
     }
 
+    WebCompositorSupport* compositorSupport() override { return &m_compositorSupport; }
+
 private:
     OwnPtr<WebThread> m_thread;
+    TestingCompositorSupport m_compositorSupport;
 };
 
 } // namespace
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBAny.h b/third_party/WebKit/Source/modules/indexeddb/IDBAny.h
index a43b651..8c31fec 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBAny.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBAny.h
@@ -27,6 +27,7 @@
 #define IDBAny_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/DOMStringList.h"
 #include "modules/ModulesExport.h"
 #include "modules/indexeddb/IDBKey.h"
 #include "modules/indexeddb/IDBValue.h"
@@ -35,7 +36,6 @@
 
 namespace blink {
 
-class DOMStringList;
 class IDBCursor;
 class IDBCursorWithValue;
 class IDBDatabase;
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi
index 5a911672..765731d 100644
--- a/third_party/WebKit/Source/modules/modules.gypi
+++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -1386,6 +1386,8 @@
       'serviceworkers/ServiceWorkerContainerClient.h',
       'serviceworkers/ServiceWorkerWindowClient.cpp',
       'serviceworkers/ServiceWorkerWindowClient.h',
+      'serviceworkers/ServiceWorkerWindowClientCallback.cpp',
+      'serviceworkers/ServiceWorkerWindowClientCallback.h',
       'serviceworkers/ServiceWorkerError.cpp',
       'serviceworkers/ServiceWorkerError.h',
       'serviceworkers/ServiceWorkerGlobalScope.cpp',
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClients.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClients.cpp
index a156a949..8070617f 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClients.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerClients.cpp
@@ -14,6 +14,7 @@
 #include "modules/serviceworkers/ServiceWorkerError.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
 #include "modules/serviceworkers/ServiceWorkerWindowClient.h"
+#include "modules/serviceworkers/ServiceWorkerWindowClientCallback.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerClientQueryOptions.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerClientsInfo.h"
 #include "wtf/OwnPtr.h"
@@ -127,7 +128,7 @@
     }
     context->consumeWindowInteraction();
 
-    ServiceWorkerGlobalScopeClient::from(context)->openWindow(parsedUrl, new CallbackPromiseAdapter<ServiceWorkerWindowClient, ServiceWorkerError>(resolver));
+    ServiceWorkerGlobalScopeClient::from(context)->openWindow(parsedUrl, new NavigateClientCallback(resolver));
     return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
index 53a41ba..550d67b 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
@@ -58,6 +58,10 @@
     case WebServiceWorkerError::ErrorTypeInstall:
         // FIXME: Introduce new InstallError type to ExceptionCodes?
         return createException(AbortError, "The Service Worker installation failed.", webError.message);
+    case WebServiceWorkerError::ErrorTypeNavigation:
+        // ErrorTypeNavigation should have bailed out before calling this.
+        ASSERT_NOT_REACHED();
+        return DOMException::create(UnknownError);
     case WebServiceWorkerError::ErrorTypeNetwork:
         return createException(NetworkError, "The Service Worker failed by network.", webError.message);
     case WebServiceWorkerError::ErrorTypeNotFound:
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClient.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClient.cpp
index fd3db7a..34d4588 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClient.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClient.cpp
@@ -14,6 +14,7 @@
 #include "core/workers/WorkerLocation.h"
 #include "modules/serviceworkers/ServiceWorkerError.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
+#include "modules/serviceworkers/ServiceWorkerWindowClientCallback.h"
 #include "public/platform/WebString.h"
 #include "wtf/RefPtr.h"
 
@@ -72,11 +73,11 @@
         return promise;
     }
     if (!context->securityOrigin()->canDisplay(parsedUrl)) {
-        resolver->reject(DOMException::create(SecurityError, "'" + parsedUrl.elidedString() + "' cannot navigate."));
+        resolver->reject(V8ThrowException::createTypeError(scriptState->isolate(), "'" + parsedUrl.elidedString() + "' cannot navigate."));
         return promise;
     }
 
-    ServiceWorkerGlobalScopeClient::from(context)->navigate(uuid(), parsedUrl, new CallbackPromiseAdapter<ServiceWorkerWindowClient, ServiceWorkerError>(resolver));
+    ServiceWorkerGlobalScopeClient::from(context)->navigate(uuid(), parsedUrl, new NavigateClientCallback(resolver));
     return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp
new file mode 100644
index 0000000..d660066
--- /dev/null
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp
@@ -0,0 +1,36 @@
+// Copyright 2015 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 "config.h"
+#include "modules/serviceworkers/ServiceWorkerWindowClientCallback.h"
+
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/DOMException.h"
+#include "modules/serviceworkers/ServiceWorkerError.h"
+#include "modules/serviceworkers/ServiceWorkerWindowClient.h"
+
+namespace blink {
+
+void NavigateClientCallback::onSuccess(WebPassOwnPtr<WebServiceWorkerClientInfo> clientInfo)
+{
+    if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
+        return;
+    m_resolver->resolve(ServiceWorkerWindowClient::take(m_resolver.get(), clientInfo.release()));
+}
+
+void NavigateClientCallback::onError(const WebServiceWorkerError& error)
+{
+    if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
+        return;
+
+    if (error.errorType == WebServiceWorkerError::ErrorTypeNavigation)  {
+        ScriptState::Scope scope(m_resolver->scriptState());
+        m_resolver->reject(V8ThrowException::createTypeError(m_resolver->scriptState()->isolate(), error.message));
+        return;
+    }
+
+    m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error));
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.h
new file mode 100644
index 0000000..f81fdef0
--- /dev/null
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.h
@@ -0,0 +1,29 @@
+// Copyright 2015 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 ServiceWorkerWindowClientCallback_h
+#define ServiceWorkerWindowClientCallback_h
+
+#include "public/platform/modules/serviceworker/WebServiceWorkerClientsInfo.h"
+
+namespace blink {
+
+class ScriptPromiseResolver;
+
+class NavigateClientCallback : public WebServiceWorkerClientCallbacks {
+public:
+    explicit NavigateClientCallback(ScriptPromiseResolver* resolver)
+        : m_resolver(resolver) { }
+
+    void onSuccess(WebPassOwnPtr<WebServiceWorkerClientInfo>) override;
+    void onError(const WebServiceWorkerError&) override;
+
+private:
+    Persistent<ScriptPromiseResolver> m_resolver;
+    WTF_MAKE_NONCOPYABLE(NavigateClientCallback);
+};
+
+} // namespace blink
+
+#endif // ServiceWorkerWindowClientCallback_h
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index be4958b..82a07c30 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -1066,14 +1066,22 @@
         return;
     if (!validateTexFunc3DTarget("compressedTexImage3D", target))
         return;
+    if (!validateTexFuncLevel("compressedTexImage3D", target, level))
+        return;
+    if (!validateCompressedTexFormat(internalformat)) {
+        synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage3D", "invalid internalformat");
+        return;
+    }
+    if (border) {
+        synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D", "border not 0");
+        return;
+    }
+    if (!validateCompressedTexDimensions("compressedTexImage3D", NotTexSubImage2D, target, level, width, height, depth, internalformat))
+        return;
 
     WebGLTexture* tex = validateTextureBinding("compressedTexImage3D", target, true);
     if (!tex)
         return;
-
-    if (!validateTexFuncLevel("compressedTexImage3D", target, level))
-        return;
-
     if (tex->isImmutable()) {
         synthesizeGLError(GL_INVALID_OPERATION, "compressedTexImage3D", "attempted to modify immutable texture");
         return;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 1dcf1f6e..6b90d1b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -1883,7 +1883,7 @@
         synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
         return;
     }
-    if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
+    if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, 1, internalformat))
         return;
     if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
         return;
@@ -6032,13 +6032,14 @@
     return true;
 }
 
-bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexImageFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
+bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexImageFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format)
 {
-    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height, 1))
+    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height, depth))
         return false;
 
     bool widthValid = false;
     bool heightValid = false;
+    bool depthValid = false;
 
     switch (format) {
     case GL_COMPRESSED_R11_EAC:
@@ -6053,6 +6054,7 @@
     case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: {
         widthValid = true;
         heightValid = true;
+        depthValid = true;
         break;
     }
     case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
@@ -6085,8 +6087,10 @@
     case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: {
         widthValid = true;
         heightValid = true;
+        depthValid = true;
         break;
     }
+    // FIXME: should check if ATC/S3TC/PVRTV extensions work with CompressedTexImage3D.
     case GC3D_COMPRESSED_ATC_RGB_AMD:
     case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
     case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
@@ -6098,6 +6102,7 @@
         const int kBlockHeight = 4;
         widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
         heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
+        depthValid = true;
         break;
     }
     case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
@@ -6107,19 +6112,21 @@
         // Must be a power of two
         widthValid = (width & (width - 1)) == 0;
         heightValid = (height & (height - 1)) == 0;
+        depthValid = (depth & (depth - 1)) == 0;
         break;
     }
     case GL_ETC1_RGB8_OES: {
         widthValid = true;
         heightValid = true;
+        depthValid = true;
         break;
     }
     default:
         return false;
     }
 
-    if (!widthValid || !heightValid) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
+    if (!widthValid || !heightValid || !depthValid) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "width, height or depth invalid for level");
         return false;
     }
 
@@ -6153,7 +6160,7 @@
             synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
             return false;
         }
-        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, 1, format);
     }
     case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
     case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
@@ -6168,7 +6175,7 @@
             synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions must match existing level");
             return false;
         }
-        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, 1, format);
     }
     case GC3D_COMPRESSED_ATC_RGB_AMD:
     case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index 9527dd8..e715d1e 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -967,7 +967,7 @@
 
     // Helper function to validate compressed texture dimensions are valid for
     // the given format.
-    bool validateCompressedTexDimensions(const char* functionName, TexImageFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
+    bool validateCompressedTexDimensions(const char* functionName, TexImageFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format);
 
     // Helper function to validate compressed texture dimensions are valid for
     // the given format.
diff --git a/third_party/WebKit/Source/platform/JSONValues.h b/third_party/WebKit/Source/platform/JSONValues.h
index aa882151..bdb9d2d 100644
--- a/third_party/WebKit/Source/platform/JSONValues.h
+++ b/third_party/WebKit/Source/platform/JSONValues.h
@@ -47,32 +47,6 @@
 
 } // namespace blink
 
-namespace WTF {
-
-class StringBuilder;
-
-// FIXME: Avoid the need for this global upcasting to JSONValue (for PassRefPtr<T>.)
-// The current CodeGeneratorInspector.py generates code which order sorts its input
-// types and generates forward declarations where needed. But with inline uses
-// of setValue(PassRefPtr<JSONValue>) this is not quite sufficient for the
-// implicit conversion of PassRefPtr<T> to PassRefPtr<JSONValue> for a T that
-// has only been forward declared -- IsPointerConvertible<> doesn't have
-// complete types to work with.
-//
-// Work around that problem here by hackily declaring this global & unsafe
-// specialization.
-//
-// (InspectorTypeBuilder.h is the only piece of code that relies on this specialization.)
-template<typename From> class IsPointerConvertible<From, blink::JSONValue> {
-    STATIC_ONLY(IsPointerConvertible);
-public:
-    enum {
-        Value = true
-    };
-};
-
-} // namespace WTF
-
 namespace blink {
 
 class JSONArray;
diff --git a/third_party/WebKit/Source/platform/graphics/CrossfadeGeneratedImage.h b/third_party/WebKit/Source/platform/graphics/CrossfadeGeneratedImage.h
index 7acf465..a13f640ff 100644
--- a/third_party/WebKit/Source/platform/graphics/CrossfadeGeneratedImage.h
+++ b/third_party/WebKit/Source/platform/graphics/CrossfadeGeneratedImage.h
@@ -41,7 +41,6 @@
         return adoptRef(new CrossfadeGeneratedImage(fromImage, toImage, percentage, crossfadeSize, size));
     }
 
-    void setContainerSize(const IntSize&) override { }
     bool usesContainerSize() const override { return false; }
     bool hasRelativeWidth() const override { return false; }
     bool hasRelativeHeight() const override { return false; }
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
index a1adcce..1277996 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
@@ -26,14 +26,13 @@
 #include "config.h"
 #include "platform/graphics/DecodingImageGenerator.h"
 
-#include "SkData.h"
-#include "SkImageInfo.h"
 #include "platform/PlatformInstrumentation.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/SharedBuffer.h"
 #include "platform/TraceEvent.h"
 #include "platform/graphics/ImageFrameGenerator.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "third_party/skia/include/core/SkData.h"
 
 namespace blink {
 
@@ -126,4 +125,3 @@
 }
 
 } // namespace blink
-
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
index 970d74e..9a9ac40b 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
@@ -26,10 +26,9 @@
 #ifndef DecodingImageGenerator_h
 #define DecodingImageGenerator_h
 
-#include "SkImageGenerator.h"
-#include "SkImageInfo.h"
-
 #include "platform/PlatformExport.h"
+#include "third_party/skia/include/core/SkImageGenerator.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/RefPtr.h"
@@ -40,11 +39,9 @@
 
 class ImageFrameGenerator;
 
-// Implements SkImageGenerator and used by SkPixelRef to populate a discardable
-// memory with decoded pixels.
+// Implements SkImageGenerator, used by SkPixelRef to populate a discardable memory
+// with a decoded image frame. ImageFrameGenerator does the actual decoding.
 //
-// This class does not own an ImageDecode. It does not own encoded data. It serves
-// as and adapter to ImageFrameGenerator which actually performs decoding.
 class PLATFORM_EXPORT DecodingImageGenerator final : public SkImageGenerator {
     USING_FAST_MALLOC(DecodingImageGenerator);
     WTF_MAKE_NONCOPYABLE(DecodingImageGenerator);
@@ -59,8 +56,7 @@
 protected:
     SkData* onRefEncodedData() override;
 
-    bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
-        SkPMColor ctable[], int* ctableCount) override;
+    bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkPMColor table[], int* tableCount) override;
 
     bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], SkYUVColorSpace*) override;
 
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
index a9621b5..e5a1c88 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
@@ -27,15 +27,31 @@
 #include "platform/graphics/DeferredImageDecoder.h"
 
 #include "platform/graphics/DecodingImageGenerator.h"
+#include "platform/graphics/FrameData.h"
 #include "platform/graphics/ImageDecodingStore.h"
+#include "platform/graphics/ImageFrameGenerator.h"
 #include "third_party/skia/include/core/SkImage.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
 #include "wtf/PassOwnPtr.h"
 
 namespace blink {
 
 bool DeferredImageDecoder::s_enabled = true;
 
+PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer& data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfileOption colorOptions)
+{
+    OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions);
+
+    if (!actualDecoder)
+        return nullptr;
+
+    return adoptPtr(new DeferredImageDecoder(actualDecoder.release()));
+}
+
+PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnPtr<ImageDecoder> actualDecoder)
+{
+    return adoptPtr(new DeferredImageDecoder(actualDecoder));
+}
+
 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecoder)
     : m_allDataReceived(false)
     , m_lastDataSize(0)
@@ -49,17 +65,6 @@
 {
 }
 
-PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer& data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfileOption colorOptions)
-{
-    OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions);
-    return actualDecoder ? adoptPtr(new DeferredImageDecoder(actualDecoder.release())) : nullptr;
-}
-
-PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnPtr<ImageDecoder> decoder)
-{
-    return adoptPtr(new DeferredImageDecoder(decoder));
-}
-
 void DeferredImageDecoder::setEnabled(bool enabled)
 {
     s_enabled = enabled;
@@ -78,23 +83,24 @@
 PassRefPtr<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index)
 {
     prepareLazyDecodedFrames();
+
     if (index < m_frameData.size()) {
         // ImageFrameGenerator has the latest known alpha state. There will be a
         // performance boost if this frame is opaque.
         FrameData* frameData = &m_frameData[index];
         frameData->m_hasAlpha = m_frameGenerator->hasAlpha(index);
-        frameData->m_frameBytes = m_size.area() *  sizeof(ImageFrame::PixelData);
-        return createImage(index, !frameData->m_hasAlpha);
+        frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData);
+        return createFrameImageAtIndex(index, !frameData->m_hasAlpha);
     }
 
     if (!m_actualDecoder)
         return nullptr;
 
-    ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index);
-    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
+    ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index);
+    if (!frame || frame->status() == ImageFrame::FrameEmpty)
         return nullptr;
 
-    return adoptRef(SkImage::NewFromBitmap(buffer->bitmap()));
+    return adoptRef(SkImage::NewFromBitmap(frame->bitmap()));
 }
 
 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
@@ -253,17 +259,18 @@
     }
 }
 
-// Creates an SkImage that is backed by SkDiscardablePixelRef.
-PassRefPtr<SkImage> DeferredImageDecoder::createImage(size_t index, bool knownToBeOpaque) const
+inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaque)
 {
-    SkISize decodedSize = m_frameGenerator->getFullSize();
+    return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), knownToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+}
+
+PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const
+{
+    const SkISize& decodedSize = m_frameGenerator->getFullSize();
     ASSERT(decodedSize.width() > 0);
     ASSERT(decodedSize.height() > 0);
 
-    const SkImageInfo info = SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(),
-        knownToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
-
-    DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, info, index);
+    DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, imageInfoFrom(decodedSize, knownToBeOpaque), index);
     RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator));
     if (!image)
         return nullptr;
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
index e77446c..25f3aaf0 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
@@ -26,13 +26,11 @@
 #ifndef DeferredImageDecoder_h
 #define DeferredImageDecoder_h
 
-#include "SkBitmap.h"
-#include "SkPixelRef.h"
 #include "platform/PlatformExport.h"
 #include "platform/geometry/IntSize.h"
-#include "platform/graphics/FrameData.h"
-#include "platform/graphics/ImageFrameGenerator.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
 #include "wtf/Allocator.h"
 #include "wtf/Forward.h"
 #include "wtf/OwnPtr.h"
@@ -44,16 +42,18 @@
 
 class ImageFrameGenerator;
 class SharedBuffer;
+struct FrameData;
 
 class PLATFORM_EXPORT DeferredImageDecoder final {
     WTF_MAKE_NONCOPYABLE(DeferredImageDecoder);
     USING_FAST_MALLOC(DeferredImageDecoder);
 public:
-    ~DeferredImageDecoder();
     static PassOwnPtr<DeferredImageDecoder> create(const SharedBuffer& data, ImageDecoder::AlphaOption, ImageDecoder::GammaAndColorProfileOption);
 
     static PassOwnPtr<DeferredImageDecoder> createForTesting(PassOwnPtr<ImageDecoder>);
 
+    ~DeferredImageDecoder();
+
     static void setEnabled(bool);
     static bool enabled();
 
@@ -69,22 +69,24 @@
     IntSize frameSizeAtIndex(size_t index) const;
     size_t frameCount();
     int repetitionCount() const;
-    size_t clearCacheExceptFrame(size_t);
+    size_t clearCacheExceptFrame(size_t index);
     bool frameHasAlphaAtIndex(size_t index) const;
-    bool frameIsCompleteAtIndex(size_t) const;
-    float frameDurationAtIndex(size_t) const;
+    bool frameIsCompleteAtIndex(size_t index) const;
+    float frameDurationAtIndex(size_t index) const;
     size_t frameBytesAtIndex(size_t index) const;
     ImageOrientation orientationAtIndex(size_t index) const;
     bool hotSpot(IntPoint&) const;
 
-    // For testing.
-    ImageFrameGenerator* frameGenerator() { return m_frameGenerator.get(); }
-
 private:
     explicit DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecoder);
-    void prepareLazyDecodedFrames();
-    PassRefPtr<SkImage> createImage(size_t index, bool knownToBeOpaque) const;
+
+    friend class DeferredImageDecoderTest;
+    ImageFrameGenerator* frameGenerator() { return m_frameGenerator.get(); }
+
     void activateLazyDecoding();
+    void prepareLazyDecodedFrames();
+
+    PassRefPtr<SkImage> createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const;
 
     RefPtr<SharedBuffer> m_data;
     bool m_allDataReceived;
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
index f874bc2..18b87b3 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -26,21 +26,22 @@
 #include "config.h"
 #include "platform/graphics/DeferredImageDecoder.h"
 
-#include "SkCanvas.h"
-#include "SkPicture.h"
-#include "SkPictureRecorder.h"
-#include "SkSurface.h"
 #include "platform/SharedBuffer.h"
 #include "platform/Task.h"
 #include "platform/ThreadSafeFunctional.h"
 #include "platform/graphics/ImageDecodingStore.h"
+#include "platform/graphics/ImageFrameGenerator.h"
 #include "platform/graphics/test/MockImageDecoder.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebThread.h"
 #include "public/platform/WebTraceLocation.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkPicture.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "third_party/skia/include/core/SkPixmap.h"
+#include "third_party/skia/include/core/SkSurface.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/platform/graphics/GeneratedImage.h b/third_party/WebKit/Source/platform/graphics/GeneratedImage.h
index 0a4297c..643312c 100644
--- a/third_party/WebKit/Source/platform/graphics/GeneratedImage.h
+++ b/third_party/WebKit/Source/platform/graphics/GeneratedImage.h
@@ -36,7 +36,6 @@
 public:
     bool currentFrameHasSingleSecurityOrigin() const override { return true; }
 
-    void setContainerSize(const IntSize& size) override { m_size = size; }
     bool usesContainerSize() const override { return true; }
     bool hasRelativeWidth() const override { return true; }
     bool hasRelativeHeight() const override { return true; }
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h
index 139d0bbf..bcf6000 100644
--- a/third_party/WebKit/Source/platform/graphics/Image.h
+++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -92,7 +92,6 @@
     static Image* nullImage();
     bool isNull() const { return size().isEmpty(); }
 
-    virtual void setContainerSize(const IntSize&) { }
     virtual bool usesContainerSize() const { return false; }
     virtual bool hasRelativeWidth() const { return false; }
     virtual bool hasRelativeHeight() const { return false; }
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
index 06664c71e..113ea88f 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
@@ -26,19 +26,19 @@
 #ifndef ImageFrameGenerator_h
 #define ImageFrameGenerator_h
 
-#include "SkBitmap.h"
-#include "SkSize.h"
-#include "SkTypes.h"
 #include "platform/PlatformExport.h"
 #include "platform/graphics/ThreadSafeDataTransport.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkSize.h"
+#include "third_party/skia/include/core/SkTypes.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
-#include "wtf/ThreadingPrimitives.h"
 #include "wtf/ThreadSafeRefCounted.h"
+#include "wtf/ThreadingPrimitives.h"
 #include "wtf/Vector.h"
 
 namespace blink {
@@ -63,14 +63,11 @@
         return adoptRef(new ImageFrameGenerator(fullSize, data, allDataReceived, isMultiFrame));
     }
 
-    ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer>, bool allDataReceived, bool isMultiFrame);
     ~ImageFrameGenerator();
 
-    // Decodes and scales the specified frame indicated by |index|. Dimensions
-    // and output format are specified in |info|. Decoded pixels are written
-    // into |pixels| with a stride of |rowBytes|.
-    //
-    // Returns true if decoding was successful.
+    // Decodes and scales the specified frame at |index|. The dimensions and output
+    // format are given in SkImageInfo. Decoded pixels are written into |pixels| with
+    // a stride of |rowBytes|. Returns true if decoding was successful.
     bool decodeAndScale(const SkImageInfo&, size_t index, void* pixels, size_t rowBytes);
 
     // Decodes YUV components directly into the provided memory planes.
@@ -81,17 +78,17 @@
     // Creates a new SharedBuffer containing the data received so far.
     void copyData(RefPtr<SharedBuffer>*, bool* allDataReceived);
 
-    SkISize getFullSize() const { return m_fullSize; }
+    const SkISize& getFullSize() const { return m_fullSize; }
 
     bool isMultiFrame() const { return m_isMultiFrame; }
 
-    // FIXME: Return alpha state for each frame.
-    bool hasAlpha(size_t);
+    bool hasAlpha(size_t index);
 
     bool getYUVComponentSizes(SkISize componentSizes[3]);
 
 private:
-    class ExternalMemoryAllocator;
+    ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer>, bool allDataReceived, bool isMultiFrame);
+
     friend class ImageFrameGeneratorTest;
     friend class DeferredImageDecoderTest;
     // For testing. |factory| will overwrite the default ImageDecoder creation logic if |factory->create()| returns non-zero.
@@ -114,6 +111,8 @@
     int m_decodeCount;
     Vector<bool> m_frameComplete;
     size_t m_frameCount;
+
+    class ExternalMemoryAllocator;
     OwnPtr<ExternalMemoryAllocator> m_externalAllocator;
 
     OwnPtr<ImageDecoderFactory> m_imageDecoderFactory;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index fd2b765e..0dc2f08 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -48,7 +48,6 @@
 #include "wtf/LeakAnnotations.h"
 #include "wtf/MainThread.h"
 #include "wtf/Partitions.h"
-#include "wtf/PassOwnPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 5dade814..3f25749d 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -1338,25 +1338,34 @@
     ASSERT(checkThread());
     ASSERT(!sweepForbidden());
     TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers");
+
     double startTime = WTF::currentTimeMS();
+    if (!m_orderedPreFinalizers.isEmpty()) {
+        SweepForbiddenScope forbiddenScope(this);
+        if (isMainThread())
+            ScriptForbiddenScope::enter();
 
-    if (isMainThread())
-        ScriptForbiddenScope::enter();
+        // Call the prefinalizers in the opposite order to their registration.
+        //
+        // The prefinalizer callback wrapper returns |true| when its associated
+        // object is unreachable garbage and the prefinalizer callback has run.
+        // The registered prefinalizer entry must then be removed and deleted.
+        //
+        auto it = --m_orderedPreFinalizers.end();
+        bool done;
+        do {
+            auto entry = it;
+            done = it == m_orderedPreFinalizers.begin();
+            if (!done)
+                --it;
+            if ((entry->second)(entry->first))
+                m_orderedPreFinalizers.remove(entry);
+        } while (!done);
 
-    SweepForbiddenScope forbiddenScope(this);
-    Vector<PreFinalizer> deadPreFinalizers;
-    // Call the pre-finalizers in the reverse order in which they
-    // are registered.
-    for (auto it = m_orderedPreFinalizers.rbegin(); it != m_orderedPreFinalizers.rend(); ++it) {
-        if (!(it->second)(it->first))
-            continue;
-        deadPreFinalizers.append(*it);
+        if (isMainThread())
+            ScriptForbiddenScope::exit();
     }
-    // FIXME: removeAll is inefficient.  It can shrink repeatedly.
-    m_orderedPreFinalizers.removeAll(deadPreFinalizers);
-
     if (isMainThread()) {
-        ScriptForbiddenScope::exit();
         double timeForInvokingPreFinalizers = WTF::currentTimeMS() - startTime;
         Platform::current()->histogramCustomCounts("BlinkGC.TimeForInvokingPreFinalizers", timeForInvokingPreFinalizers, 1, 10 * 1000, 50);
     }
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index 576519cd..d071e25f 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -40,7 +40,6 @@
 #include "wtf/Forward.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
 #include "wtf/ThreadSpecific.h"
 #include "wtf/Threading.h"
 #include "wtf/ThreadingPrimitives.h"
@@ -111,7 +110,7 @@
     self->Class::preFinalizer();                    \
     return true;                                    \
 }                                                   \
-using UsingPreFinazlizerMacroNeedsTrailingSemiColon = char
+using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
 
 #if ENABLE(OILPAN)
 #define WILL_BE_USING_PRE_FINALIZER(Class, method) USING_PRE_FINALIZER(Class, method)
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h
index 5dd37fa..e03a14a 100644
--- a/third_party/WebKit/Source/platform/heap/TraceTraits.h
+++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -24,8 +24,6 @@
 
 template<typename T> class CrossThreadPersistent;
 template<typename T> class CrossThreadWeakPersistent;
-template<typename T> struct GCInfoTrait;
-class HeapObjectHeader;
 template<typename T> class Member;
 template<typename T> class TraceTrait;
 template<typename T> class WeakMember;
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp
index e043166..0294ccdb 100644
--- a/third_party/WebKit/Source/platform/network/HTTPParsers.cpp
+++ b/third_party/WebKit/Source/platform/network/HTTPParsers.cpp
@@ -440,7 +440,7 @@
 
 XFrameOptionsDisposition parseXFrameOptionsHeader(const String& header)
 {
-    XFrameOptionsDisposition result = XFrameOptionsNone;
+    XFrameOptionsDisposition result = XFrameOptionsInvalid;
 
     if (header.isEmpty())
         return result;
@@ -448,22 +448,22 @@
     Vector<String> headers;
     header.split(',', headers);
 
+    bool hasValue = false;
     for (size_t i = 0; i < headers.size(); i++) {
         String currentHeader = headers[i].stripWhiteSpace();
-        XFrameOptionsDisposition currentValue = XFrameOptionsNone;
+        XFrameOptionsDisposition currentValue = XFrameOptionsInvalid;
         if (equalIgnoringCase(currentHeader, "deny"))
             currentValue = XFrameOptionsDeny;
         else if (equalIgnoringCase(currentHeader, "sameorigin"))
             currentValue = XFrameOptionsSameOrigin;
         else if (equalIgnoringCase(currentHeader, "allowall"))
             currentValue = XFrameOptionsAllowAll;
-        else
-            currentValue = XFrameOptionsInvalid;
 
-        if (result == XFrameOptionsNone)
+        if (!hasValue)
             result = currentValue;
         else if (result != currentValue)
             return XFrameOptionsConflict;
+        hasValue = true;
     }
     return result;
 }
diff --git a/third_party/WebKit/Source/platform/network/HTTPParsers.h b/third_party/WebKit/Source/platform/network/HTTPParsers.h
index 3a0708e..7bad5d8 100644
--- a/third_party/WebKit/Source/platform/network/HTTPParsers.h
+++ b/third_party/WebKit/Source/platform/network/HTTPParsers.h
@@ -52,11 +52,10 @@
 };
 
 enum XFrameOptionsDisposition {
-    XFrameOptionsNone,
+    XFrameOptionsInvalid,
     XFrameOptionsDeny,
     XFrameOptionsSameOrigin,
     XFrameOptionsAllowAll,
-    XFrameOptionsInvalid,
     XFrameOptionsConflict
 };
 
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
index 2b807d0..9e555ce 100644
--- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
@@ -76,7 +76,6 @@
         WebCompositorAnimationCurve::TimingFunctionTypeEaseInOut,
         WebScrollOffsetAnimationCurve::ScrollDurationDeltaBased));
 
-    m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition()));
     m_scrollableArea->registerForAnimation();
     if (!m_scrollableArea->scheduleAnimation()) {
         resetAnimationState();
@@ -201,6 +200,7 @@
 
         if (!sentToCompositor) {
             m_runState = RunState::RunningOnMainThread;
+            m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPosition()));
             if (!m_scrollableArea->scheduleAnimation()) {
                 notifyPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
                 resetAnimationState();
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
index e028e33..7759157 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -33,6 +33,7 @@
 
 #include "platform/PlatformExport.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebDiscardableMemory.h"
 #include "wtf/Vector.h"
 
@@ -57,6 +58,9 @@
     bool m_isLocked;
 };
 
+class TestingCompositorSupport : public WebCompositorSupport {
+};
+
 class TestingPlatformSupport : public Platform {
 public:
     struct Config {
diff --git a/third_party/WebKit/Source/web/PopupMenuImpl.cpp b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
index fb5b708..6807b84f 100644
--- a/third_party/WebKit/Source/web/PopupMenuImpl.cpp
+++ b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
@@ -406,14 +406,19 @@
 {
     ASSERT(m_popup);
     ASSERT(m_ownerElement);
-    EventQueueScope scope;
     RefPtrWillBeRawPtr<PopupMenuImpl> protector(this);
     bool success;
     int listIndex = stringValue.toInt(&success);
     ASSERT(success);
-    m_ownerElement->valueChanged(listIndex);
-    if (m_popup)
-        m_chromeClient->closePagePopup(m_popup);
+    {
+        EventQueueScope scope;
+        m_ownerElement->valueChanged(listIndex);
+        if (m_popup)
+            m_chromeClient->closePagePopup(m_popup);
+        // 'change' event is dispatched here.  For compatbility with
+        // Angular 1.2, we need to dispatch a change event before
+        // mouseup/click events.
+    }
     // We dispatch events on the owner element to match the legacy behavior.
     // Other browsers dispatch click events before and after showing the popup.
     if (m_ownerElement) {
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index e6417fad..3efbcdf 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1681,6 +1681,15 @@
 
 void WebViewImpl::enablePopupMouseWheelEventListener()
 {
+    // TODO(kenrb): Popup coordination for out-of-process iframes needs to be
+    // added. Because of the early return here (and also the one in
+    // ScrollingCoordinator::updateHaveWheelEventHandlers) a select element
+    // popup can remain visible even when the element underneath it is
+    // scrolled to a new position. This is part of a larger set of issues with
+    // popups.
+    // See https://crbug.com/566130
+    if (!mainFrameImpl() || !mainFrameImpl()->frame()->isLocalFrame())
+        return;
     ASSERT(!m_popupMouseWheelEventListener);
     Document* document = mainFrameImpl()->frame()->document();
     ASSERT(document);
@@ -1692,6 +1701,10 @@
 
 void WebViewImpl::disablePopupMouseWheelEventListener()
 {
+    // TODO(kenrb): Concerns the same as in enablePopupMouseWheelEventListener.
+    // See https://crbug.com/566130
+    if (!mainFrameImpl() || !mainFrameImpl()->frame()->isLocalFrame())
+        return;
     ASSERT(m_popupMouseWheelEventListener);
     Document* document = mainFrameImpl()->frame()->document();
     ASSERT(document);
diff --git a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
index 83a3d91..bbe111d 100644
--- a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
@@ -518,12 +518,12 @@
     const char* expectedActivities =
         "blinkAddElement | iframe | data:text/html;charset=utf-8,A\n"
         "blinkRequestResource | Main resource | data:text/html;charset=utf-8,A\n"
-        "blinkRequestResource | Image | data:text/html;charset=utf-8,B\n"
         "blinkAddElement | link | stylesheet | data:text/html;charset=utf-8,C\n"
         "blinkRequestResource | CSS stylesheet | data:text/html;charset=utf-8,C\n"
         "blinkAddElement | script | data:text/html;charset=utf-8,D\n"
         "blinkRequestResource | Script | data:text/html;charset=utf-8,D\n"
-        "blinkRequestResource | XMLHttpRequest | data:text/html;charset=utf-8,E";
+        "blinkRequestResource | XMLHttpRequest | data:text/html;charset=utf-8,E\n"
+        "blinkRequestResource | Image | data:text/html;charset=utf-8,B";
     executeScriptInMainWorld(code);
     ASSERT_TRUE(verifyActivities(""));
     executeScriptInIsolatedWorld(code);
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.cpp b/third_party/WebKit/Source/wtf/TypeTraits.cpp
index 5f09783..718fa94 100644
--- a/third_party/WebKit/Source/wtf/TypeTraits.cpp
+++ b/third_party/WebKit/Source/wtf/TypeTraits.cpp
@@ -114,12 +114,6 @@
 static_assert(!IsConvertibleToInteger<volatile char*>::value, "volatile char* should not be convertible to integer");
 static_assert(!IsConvertibleToInteger<IsConvertibleToInteger<bool>>::value, "struct should not be convertible to integer");
 
-static_assert((IsPointerConvertible<int, int>::Value), "pointers to the same type should be convertible");
-static_assert((!IsPointerConvertible<int, unsigned>::Value), "int pointers should not be convertible to unsigned pointers");
-static_assert((IsPointerConvertible<int, const int>::Value), "int pointers should be convertible to const int pointers");
-static_assert((!IsPointerConvertible<const int, int>::Value), "const int* should not be convertible to int*");
-static_assert((IsPointerConvertible<int, volatile int>::Value), "int* should be convertible to volatile int*");
-
 static_assert((IsSameType<bool, bool>::value), "bool should be the same type as itself");
 static_assert((IsSameType<int*, int*>::value), "int* should be the same type as itself");
 static_assert((!IsSameType<int, int*>::value), "int should not be the same type as int*");
@@ -138,8 +132,6 @@
 static_assert((IsSubclassOfTemplate<TestDerivedClass, TestBaseClass>::value), "Derived class should be a subclass of template from its base");
 static_assert((IsSameType<RemoveTemplate<TestBaseClass<int>, TestBaseClass>::Type, int>::value), "RemoveTemplate should remove the template typename from the type");
 static_assert((IsSameType<RemoveTemplate<int, TestBaseClass>::Type, int>::value), "RemoveTemplate should not alter non-template types");
-static_assert((IsPointerConvertible<TestDerivedClass, TestBaseClass<int>>::Value), "Derived class pointers should be convertible to base class pointers");
-static_assert((!IsPointerConvertible<TestBaseClass<int>, TestDerivedClass>::Value), "Base class pointers should not be convertible to derived class pointers");
 
 typedef int IntArray[];
 typedef int IntArraySized[4];
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.h b/third_party/WebKit/Source/wtf/TypeTraits.h
index f91e998..c4a8ab85 100644
--- a/third_party/WebKit/Source/wtf/TypeTraits.h
+++ b/third_party/WebKit/Source/wtf/TypeTraits.h
@@ -23,6 +23,7 @@
 #define TypeTraits_h
 
 #include <cstddef>
+#include <type_traits>
 #include <utility>
 
 #include "wtf/Compiler.h"
@@ -100,20 +101,6 @@
     static const bool value = std::is_integral<T>::value || IsConvertibleToDouble<!std::is_integral<T>::value, T>::value;
 };
 
-template <typename From, typename To> class IsPointerConvertible {
-    typedef char YesType;
-    struct NoType {
-        char padding[8];
-    };
-
-    static YesType convertCheck(To* x);
-    static NoType convertCheck(...);
-public:
-    enum {
-        Value = (sizeof(YesType) == sizeof(convertCheck(static_cast<From*>(0))))
-    };
-};
-
 template <typename T, typename U> struct IsSameType {
     static const bool value = false;
 };
@@ -191,10 +178,34 @@
     static const bool value = __is_polymorphic(T);
 };
 
+#if COMPILER(MSVC) && !COMPILER(CLANG)
+// FIXME: MSVC bug workaround. Remove once MSVC STL is fixed.
+// C++ 2011 Spec (ISO/IEC 14882:2011(E)) 20.9.6.2 Table 51 states that
+// the template parameters shall be a complete type if they are different types.
+// However, MSVC checks for type completeness even if they are the same type.
+// Here, we use a template specialization for same type case to allow incomplete
+// types.
+
+template <typename T, typename U> class IsBaseOf {
+public:
+    static const bool value = std::is_base_of<T, U>::value;
+};
+
+template <typename T> class IsBaseOf<T, T> {
+public:
+    static const bool value = true;
+};
+
 #define EnsurePtrConvertibleArgDecl(From, To) \
-    typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type = true
+    typename std::enable_if<WTF::IsBaseOf<To, From>::value>::type* = nullptr
 #define EnsurePtrConvertibleArgDefn(From, To) \
-    typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type
+    typename std::enable_if<WTF::IsBaseOf<To, From>::value>::type*
+#else
+#define EnsurePtrConvertibleArgDecl(From, To) \
+    typename std::enable_if<std::is_base_of<To, From>::value>::type* = nullptr
+#define EnsurePtrConvertibleArgDefn(From, To) \
+    typename std::enable_if<std::is_base_of<To, From>::value>::type*
+#endif
 
 } // namespace WTF
 
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h
index 97daeda..37f94f0 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h
@@ -41,6 +41,7 @@
         ErrorTypeActivate,
         ErrorTypeDisabled,
         ErrorTypeInstall,
+        ErrorTypeNavigation,
         ErrorTypeNetwork,
         ErrorTypeNotFound,
         ErrorTypeSecurity,
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index c9e30e3..8d87bd2 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://www.webrtc.org
 Version: unknown
-Revision: 10864
+Revision: 10903
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/third_party/openh264/BUILD.gn b/third_party/openh264/BUILD.gn
new file mode 100644
index 0000000..5819a1c
--- /dev/null
+++ b/third_party/openh264/BUILD.gn
@@ -0,0 +1,75 @@
+# Copyright 2015 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("//third_party/openh264/openh264_args.gni")
+
+assert(use_openh264)
+
+# Import source and include variables from openh264.gypi.
+openh264_gypi_values = exec_script("//build/gypi_to_gn.py",
+                                   [ rebase_path("openh264.gypi") ],
+                                   "scope")
+
+# Config shared by all openh264 targets.
+config("config") {
+  cflags = []
+  defines = []
+
+  # Compiler warnings to ignore.
+  if (!is_win) {
+    # GCC flags
+    cflags += [
+      "-Wno-header-hygiene",
+      "-Wno-unused-value",
+    ]
+  }
+
+  # Platform-specific defines.
+  if (is_android) {
+    # Android NDK is necessary for its cpufeatures and this define is what
+    # OpenH264 code uses to check if it should be used.
+    defines += [ "ANDROID_NDK" ]
+  }
+}
+
+source_set("common") {
+  sources = openh264_gypi_values.openh264_common_sources
+  include_dirs = openh264_gypi_values.openh264_common_includes
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+  configs += [ ":config" ]
+  deps = []
+  if (is_android) {
+    deps += [
+      # Defines "android_get/setCpu..." functions. The original OpenH264 build
+      # files replaces these using macros for "wels_..." versions of the same
+      # functions. We do not have access to these and use the <cpu-features.h>
+      # ones instead.
+      "//third_party/android_tools:cpu_features",
+    ]
+  }
+}
+
+source_set("processing") {
+  sources = openh264_gypi_values.openh264_processing_sources
+  include_dirs = openh264_gypi_values.openh264_processing_includes
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+  configs += [ ":config" ]
+  deps = [
+    ":common",
+  ]
+}
+
+source_set("encoder") {
+  sources = openh264_gypi_values.openh264_encoder_sources
+  include_dirs = openh264_gypi_values.openh264_encoder_includes
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+  configs += [ ":config" ]
+  deps = [
+    ":common",
+    ":processing",
+  ]
+}
diff --git a/third_party/openh264/DEPS b/third_party/openh264/DEPS
deleted file mode 100644
index d2f34d2d..0000000
--- a/third_party/openh264/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  '+testing',
-]
diff --git a/third_party/openh264/openh264.gyp b/third_party/openh264/openh264.gyp
new file mode 100644
index 0000000..c14c0dc
--- /dev/null
+++ b/third_party/openh264/openh264.gyp
@@ -0,0 +1,107 @@
+# Copyright 2015 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.
+
+{
+  'includes': [
+    'openh264_args.gypi',
+  ],
+  'conditions': [
+    ['use_openh264==1', {
+      # Settings shared by all openh264 targets.
+      'target_defaults': {
+        'variables': {
+          'chromium_code': 0,
+          'conditions': [
+            ['OS!="win"', {
+              # GCC flags
+              'openh264_cflags_add': [
+                '-Wno-unused-value',
+              ],
+              'openh264_cflags_remove': [
+                '-Wheader-hygiene',
+              ],
+            },{
+              # Windows uses 'msvs_disabled_warnings' instead, for MSVC flags.
+              'openh264_cflags_add': [],
+              'openh264_cflags_remove': [],
+            }],
+          ],
+        },
+        'cflags': [ '<@(openh264_cflags_add)' ],
+        'cflags!': [ '<@(openh264_cflags_remove)' ],
+        'xcode_settings': {
+          'WARNING_CFLAGS': [ '<@(openh264_cflags_add)' ],
+          'WARNING_CFLAGS!': [ '<@(openh264_cflags_remove)' ],
+        },
+        'msvs_disabled_warnings': [
+          4324,  # structure was padded
+          4245,  # signed/unsigned mismatch
+          4701,  # uninitialized variable used
+          4702,  # unreachable code
+        ],
+
+        # Platform-specific defines.
+        'conditions': [
+          ['OS=="android"', {
+            'defines': [
+              # Android NDK is necessary for its cpufeatures and this define is
+              # what OpenH264 code uses to check if it should be used.
+              'ANDROID_NDK',
+            ],
+          }],
+        ],
+      },
+      'includes': [
+        'openh264.gypi',
+      ],
+      'targets': [
+        {
+          'target_name': 'openh264_common',
+          'type': 'static_library',
+          'conditions': [
+            ['OS=="android"', {
+              'dependencies': [
+                # Defines "android_get/setCpu..." functions. The original
+                # OpenH264 build files replaces these using macros for
+                # "wels_..." versions of the same functions. We do not have
+                # access to these and use the <cpu-features.h> ones instead.
+                '<(DEPTH)/build/android/ndk.gyp:cpu_features',
+              ],
+            }],
+          ],
+          'include_dirs+': [ '<@(openh264_common_includes)' ],
+          'sources': [ '<@(openh264_common_sources)' ],
+        },
+        {
+          'target_name': 'openh264_processing',
+          'type': 'static_library',
+          'dependencies': [
+            'openh264_common',
+          ],
+          'include_dirs+': [ '<@(openh264_processing_includes)' ],
+          'sources': [ '<@(openh264_processing_sources)' ],
+        },
+        {
+          'target_name': 'openh264_encoder',
+          'type': 'static_library',
+          'dependencies': [
+            'openh264_common',
+            'openh264_processing',
+          ],
+          'include_dirs+': [ '<@(openh264_encoder_includes)' ],
+          'sources': [ '<@(openh264_encoder_sources)' ],
+        },
+      ],
+    },{
+      # Building without OpenH264. Defining a dummy target because every build
+      # file needs to have at least one target.
+      'targets': [
+        {
+          'target_name': 'openh264_dummy_target',
+          'type': 'none',
+        }
+      ],
+    }],
+  ],
+}
diff --git a/third_party/openh264/openh264.gypi b/third_party/openh264/openh264.gypi
new file mode 100644
index 0000000..d9ff98da
--- /dev/null
+++ b/third_party/openh264/openh264.gypi
@@ -0,0 +1,264 @@
+# Copyright 2015 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.
+
+{
+  'variables': {
+    'openh264_common_includes': [
+      'src/codec/api/svc',
+      'src/codec/common/inc',
+      'src/codec/common/src',
+    ],
+    'openh264_common_sources': [
+      'src/codec/common/inc/WelsThreadLib.h',
+      'src/codec/common/inc/copy_mb.h',
+      'src/codec/common/inc/cpu.h',
+      'src/codec/common/inc/cpu_core.h',
+      'src/codec/common/inc/crt_util_safe_x.h',
+      'src/codec/common/inc/deblocking_common.h',
+      'src/codec/common/inc/expand_pic.h',
+      'src/codec/common/inc/golomb_common.h',
+      'src/codec/common/inc/intra_pred_common.h',
+      'src/codec/common/inc/ls_defines.h',
+      'src/codec/common/inc/macros.h',
+      'src/codec/common/inc/mc.h',
+      'src/codec/common/inc/measure_time.h',
+      'src/codec/common/inc/memory_align.h',
+      'src/codec/common/inc/sad_common.h',
+      'src/codec/common/inc/typedefs.h',
+      'src/codec/common/inc/utils.h',
+      'src/codec/common/inc/version.h',
+      'src/codec/common/inc/welsCodecTrace.h',
+      'src/codec/common/inc/wels_common_defs.h',
+      'src/codec/common/inc/wels_const_common.h',
+      'src/codec/common/src/WelsThreadLib.cpp',
+      'src/codec/common/src/common_tables.cpp',
+      'src/codec/common/src/copy_mb.cpp',
+      'src/codec/common/src/cpu.cpp',
+      'src/codec/common/src/crt_util_safe_x.cpp',
+      'src/codec/common/src/deblocking_common.cpp',
+      'src/codec/common/src/expand_pic.cpp',
+      'src/codec/common/src/intra_pred_common.cpp',
+      'src/codec/common/src/mc.cpp',
+      'src/codec/common/src/memory_align.cpp',
+      'src/codec/common/src/sad_common.cpp',
+      'src/codec/common/src/utils.cpp',
+      'src/codec/common/src/welsCodecTrace.cpp',
+    ],
+    # TODO(hbos): compile with *_asm_* sources
+    'openh264_common_sources_asm_x86': [
+      'src/codec/common/src/x86/cpuid.asm',
+      'src/codec/common/src/x86/deblock.asm',
+      'src/codec/common/src/x86/expand_picture.asm',
+      'src/codec/common/src/x86/intra_pred_com.asm',
+      'src/codec/common/src/x86/mb_copy.asm',
+      'src/codec/common/src/x86/mc_chroma.asm',
+      'src/codec/common/src/x86/mc_luma.asm',
+      'src/codec/common/src/x86/satd_sad.asm',
+      'src/codec/common/src/x86/vaa.asm',
+    ],
+    'openh264_common_sources_asm_arm': [
+      'src/codec/common/src/arm/copy_mb_neon.S',
+      'src/codec/common/src/arm/deblocking_neon.S',
+      'src/codec/common/src/arm/expand_picture_neon.S',
+      'src/codec/common/src/arm/intra_pred_common_neon.S',
+      'src/codec/common/src/arm/mc_neon.S',
+    ],
+    'openh264_common_sources_asm_arm64': [
+      'src/codec/common/src/arm64/copy_mb_aarch64_neon.S',
+      'src/codec/common/src/arm64/deblocking_aarch64_neon.S',
+      'src/codec/common/src/arm64/expand_picture_aarch64_neon.S',
+      'src/codec/common/src/arm64/intra_pred_common_aarch64_neon.S',
+      'src/codec/common/src/arm64/mc_aarch64_neon.S',
+    ],
+
+    'openh264_processing_includes': [
+      'src/codec/api/svc',
+      'src/codec/common/inc',
+      'src/codec/common/src',
+      'src/codec/processing/interface',
+      'src/codec/processing/interface/',
+      'src/codec/processing/src/adaptivequantization',
+      'src/codec/processing/src/backgrounddetection',
+      'src/codec/processing/src/common',
+      'src/codec/processing/src/complexityanalysis',
+      'src/codec/processing/src/denoise',
+      'src/codec/processing/src/downsample',
+      'src/codec/processing/src/imagerotate',
+      'src/codec/processing/src/scenechangedetection',
+      'src/codec/processing/src/scrolldetection',
+      'src/codec/processing/src/vaacalc',
+    ],
+    'openh264_processing_sources': [
+      'src/codec/processing/interface/IWelsVP.h',
+      'src/codec/processing/src/adaptivequantization/AdaptiveQuantization.cpp',
+      'src/codec/processing/src/adaptivequantization/AdaptiveQuantization.h',
+      'src/codec/processing/src/backgrounddetection/BackgroundDetection.cpp',
+      'src/codec/processing/src/backgrounddetection/BackgroundDetection.h',
+      'src/codec/processing/src/common/WelsFrameWork.cpp',
+      'src/codec/processing/src/common/WelsFrameWork.h',
+      'src/codec/processing/src/common/WelsFrameWorkEx.cpp',
+      'src/codec/processing/src/common/common.h',
+      'src/codec/processing/src/common/memory.cpp',
+      'src/codec/processing/src/common/memory.h',
+      'src/codec/processing/src/common/resource.h',
+      'src/codec/processing/src/common/typedef.h',
+      'src/codec/processing/src/common/util.h',
+      'src/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp',
+      'src/codec/processing/src/complexityanalysis/ComplexityAnalysis.h',
+      'src/codec/processing/src/denoise/denoise.cpp',
+      'src/codec/processing/src/denoise/denoise.h',
+      'src/codec/processing/src/denoise/denoise_filter.cpp',
+      'src/codec/processing/src/downsample/downsample.cpp',
+      'src/codec/processing/src/downsample/downsample.h',
+      'src/codec/processing/src/downsample/downsamplefuncs.cpp',
+      'src/codec/processing/src/imagerotate/imagerotate.cpp',
+      'src/codec/processing/src/imagerotate/imagerotate.h',
+      'src/codec/processing/src/imagerotate/imagerotatefuncs.cpp',
+      'src/codec/processing/src/scenechangedetection/SceneChangeDetection.cpp',
+      'src/codec/processing/src/scenechangedetection/SceneChangeDetection.h',
+      'src/codec/processing/src/scrolldetection/ScrollDetection.cpp',
+      'src/codec/processing/src/scrolldetection/ScrollDetection.h',
+      'src/codec/processing/src/scrolldetection/ScrollDetectionFuncs.cpp',
+      'src/codec/processing/src/scrolldetection/ScrollDetectionFuncs.h',
+      'src/codec/processing/src/vaacalc/vaacalcfuncs.cpp',
+      'src/codec/processing/src/vaacalc/vaacalculation.cpp',
+      'src/codec/processing/src/vaacalc/vaacalculation.h',
+    ],
+    # TODO(hbos): compile with *_asm_* sources
+    'openh264_processing_sources_asm_x86': [
+      'src/codec/processing/src/x86/denoisefilter.asm',
+      'src/codec/processing/src/x86/downsample_bilinear.asm',
+      'src/codec/processing/src/x86/vaa.asm',
+    ],
+    'openh264_processing_sources_asm_arm': [
+      'src/codec/processing/src/arm/adaptive_quantization.S',
+      'src/codec/processing/src/arm/down_sample_neon.S',
+      'src/codec/processing/src/arm/pixel_sad_neon.S',
+      'src/codec/processing/src/arm/vaa_calc_neon.S',
+    ],
+    'openh264_processing_sources_asm_arm64': [
+      'src/codec/processing/src/arm64/adaptive_quantization_aarch64_neon.S',
+      'src/codec/processing/src/arm64/down_sample_aarch64_neon.S',
+      'src/codec/processing/src/arm64/pixel_sad_aarch64_neon.S',
+      'src/codec/processing/src/arm64/vaa_calc_aarch64_neon.S',
+    ],
+
+    'openh264_encoder_includes': [
+      'src/codec/api/svc',
+      'src/codec/common/inc',
+      'src/codec/common/src',
+      'src/codec/encoder/core/inc',
+      'src/codec/encoder/core/src',
+      'src/codec/encoder/plus/inc',
+      'src/codec/encoder/plus/src',
+      'src/codec/processing/interface/',
+    ],
+    'openh264_encoder_sources': [
+      'src/codec/encoder/core/inc/as264_common.h',
+      'src/codec/encoder/core/inc/au_set.h',
+      'src/codec/encoder/core/inc/deblocking.h',
+      'src/codec/encoder/core/inc/decode_mb_aux.h',
+      'src/codec/encoder/core/inc/dq_map.h',
+      'src/codec/encoder/core/inc/encode_mb_aux.h',
+      'src/codec/encoder/core/inc/encoder.h',
+      'src/codec/encoder/core/inc/encoder_context.h',
+      'src/codec/encoder/core/inc/extern.h',
+      'src/codec/encoder/core/inc/get_intra_predictor.h',
+      'src/codec/encoder/core/inc/mb_cache.h',
+      'src/codec/encoder/core/inc/md.h',
+      'src/codec/encoder/core/inc/mt_defs.h',
+      'src/codec/encoder/core/inc/mv_pred.h',
+      'src/codec/encoder/core/inc/nal_encap.h',
+      'src/codec/encoder/core/inc/param_svc.h',
+      'src/codec/encoder/core/inc/parameter_sets.h',
+      'src/codec/encoder/core/inc/picture.h',
+      'src/codec/encoder/core/inc/picture_handle.h',
+      'src/codec/encoder/core/inc/property.h',
+      'src/codec/encoder/core/inc/rc.h',
+      'src/codec/encoder/core/inc/ref_list_mgr_svc.h',
+      'src/codec/encoder/core/inc/sample.h',
+      'src/codec/encoder/core/inc/set_mb_syn_cabac.h',
+      'src/codec/encoder/core/inc/set_mb_syn_cavlc.h',
+      'src/codec/encoder/core/inc/slice.h',
+      'src/codec/encoder/core/inc/slice_multi_threading.h',
+      'src/codec/encoder/core/inc/stat.h',
+      'src/codec/encoder/core/inc/svc_base_layer_md.h',
+      'src/codec/encoder/core/inc/svc_enc_frame.h',
+      'src/codec/encoder/core/inc/svc_enc_golomb.h',
+      'src/codec/encoder/core/inc/svc_enc_macroblock.h',
+      'src/codec/encoder/core/inc/svc_enc_slice_segment.h',
+      'src/codec/encoder/core/inc/svc_encode_mb.h',
+      'src/codec/encoder/core/inc/svc_encode_slice.h',
+      'src/codec/encoder/core/inc/svc_mode_decision.h',
+      'src/codec/encoder/core/inc/svc_motion_estimate.h',
+      'src/codec/encoder/core/inc/svc_set_mb_syn.h',
+      'src/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h',
+      'src/codec/encoder/core/inc/vlc_encoder.h',
+      'src/codec/encoder/core/inc/wels_common_basis.h',
+      'src/codec/encoder/core/inc/wels_const.h',
+      'src/codec/encoder/core/inc/wels_func_ptr_def.h',
+      'src/codec/encoder/core/inc/wels_preprocess.h',
+      'src/codec/encoder/core/inc/wels_transpose_matrix.h',
+      'src/codec/encoder/core/src/au_set.cpp',
+      'src/codec/encoder/core/src/deblocking.cpp',
+      'src/codec/encoder/core/src/decode_mb_aux.cpp',
+      'src/codec/encoder/core/src/encode_mb_aux.cpp',
+      'src/codec/encoder/core/src/encoder.cpp',
+      'src/codec/encoder/core/src/encoder_data_tables.cpp',
+      'src/codec/encoder/core/src/encoder_ext.cpp',
+      'src/codec/encoder/core/src/get_intra_predictor.cpp',
+      'src/codec/encoder/core/src/md.cpp',
+      'src/codec/encoder/core/src/mv_pred.cpp',
+      'src/codec/encoder/core/src/nal_encap.cpp',
+      'src/codec/encoder/core/src/picture_handle.cpp',
+      'src/codec/encoder/core/src/property.cpp',
+      'src/codec/encoder/core/src/ratectl.cpp',
+      'src/codec/encoder/core/src/ref_list_mgr_svc.cpp',
+      'src/codec/encoder/core/src/sample.cpp',
+      'src/codec/encoder/core/src/set_mb_syn_cabac.cpp',
+      'src/codec/encoder/core/src/set_mb_syn_cavlc.cpp',
+      'src/codec/encoder/core/src/slice_multi_threading.cpp',
+      'src/codec/encoder/core/src/svc_base_layer_md.cpp',
+      'src/codec/encoder/core/src/svc_enc_slice_segment.cpp',
+      'src/codec/encoder/core/src/svc_encode_mb.cpp',
+      'src/codec/encoder/core/src/svc_encode_slice.cpp',
+      'src/codec/encoder/core/src/svc_mode_decision.cpp',
+      'src/codec/encoder/core/src/svc_motion_estimate.cpp',
+      'src/codec/encoder/core/src/svc_set_mb_syn_cabac.cpp',
+      'src/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp',
+      'src/codec/encoder/core/src/wels_preprocess.cpp',
+      'src/codec/encoder/plus/inc/welsEncoderExt.h',
+      'src/codec/encoder/plus/src/welsEncoderExt.cpp',
+      # Note: Purposefully excluded: 'src/codec/encoder/plus/src/DllEntry.cpp',
+      # This file is not built by the OpenH264 original build files.
+    ],
+    # TODO(hbos): compile with *_asm_* sources
+    'openh264_encoder_sources_asm_x86': [
+      'src/codec/encoder/core/x86/coeff.asm',
+      'src/codec/encoder/core/x86/dct.asm',
+      'src/codec/encoder/core/x86/intra_pred.asm',
+      'src/codec/encoder/core/x86/matrix_transpose.asm',
+      'src/codec/encoder/core/x86/memzero.asm',
+      'src/codec/encoder/core/x86/quant.asm',
+      'src/codec/encoder/core/x86/sample_sc.asm',
+      'src/codec/encoder/core/x86/score.asm',
+    ],
+    'openh264_encoder_sources_asm_arm': [
+      'src/codec/encoder/core/arm/intra_pred_neon.S',
+      'src/codec/encoder/core/arm/intra_pred_sad_3_opt_neon.S',
+      'src/codec/encoder/core/arm/memory_neon.S',
+      'src/codec/encoder/core/arm/pixel_neon.S',
+      'src/codec/encoder/core/arm/reconstruct_neon.S',
+      'src/codec/encoder/core/arm/svc_motion_estimation.S',
+    ],
+    'openh264_encoder_sources_asm_arm64': [
+      'src/codec/encoder/core/arm64/intra_pred_aarch64_neon.S',
+      'src/codec/encoder/core/arm64/intra_pred_sad_3_opt_aarch64_neon.S',
+      'src/codec/encoder/core/arm64/memory_aarch64_neon.S',
+      'src/codec/encoder/core/arm64/pixel_aarch64_neon.S',
+      'src/codec/encoder/core/arm64/reconstruct_aarch64_neon.S',
+      'src/codec/encoder/core/arm64/svc_motion_estimation_aarch64_neon.S',
+    ],
+  },
+}
diff --git a/third_party/openh264/openh264_args.gni b/third_party/openh264/openh264_args.gni
new file mode 100644
index 0000000..b7558fbd
--- /dev/null
+++ b/third_party/openh264/openh264_args.gni
@@ -0,0 +1,12 @@
+# Copyright 2015 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("//build/config/chrome_build.gni")
+
+declare_args() {
+  # Enable this to build OpenH264 (for encoding, not decoding).
+  # CHECK THE OPENH264 LICENSE/PATENT BEFORE BUILDING, see
+  # http://www.openh264.org/.
+  use_openh264 = false
+}
diff --git a/third_party/openh264/openh264_args.gypi b/third_party/openh264/openh264_args.gypi
new file mode 100644
index 0000000..676bce51
--- /dev/null
+++ b/third_party/openh264/openh264_args.gypi
@@ -0,0 +1,12 @@
+# Copyright 2015 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.
+
+{
+  'variables': {
+    # Enable this to build OpenH264 (for encoding, not decoding).
+    # CHECK THE OPENH264 LICENSE/PATENT BEFORE BUILDING, see
+    # http://www.openh264.org/.
+    'use_openh264%': 0,
+  },
+}
diff --git a/tools/perf/benchmarks/service_worker.py b/tools/perf/benchmarks/service_worker.py
index 3ced276..1b464fc8 100644
--- a/tools/perf/benchmarks/service_worker.py
+++ b/tools/perf/benchmarks/service_worker.py
@@ -8,7 +8,6 @@
 
 from core import perf_benchmark
 
-from telemetry import benchmark
 from telemetry.core import util
 from telemetry.page import action_runner
 from telemetry.page import page_test
@@ -95,12 +94,6 @@
     self._speed_index = speedindex.SpeedIndexMetric()
     self._page_open_times = collections.defaultdict(int)
 
-  # TODO(falken): Remove when reference build rolls. crbug.com/458538
-  def CustomizeBrowserOptions(self, options):
-    options.AppendExtraBrowserArgs([
-        '--enable-experimental-web-platform-features'
-      ])
-
   def WillNavigateToPage(self, page, tab):
     self._timeline_controller.SetUp(page, tab)
     self._timeline_controller.Start(tab)
@@ -176,9 +169,6 @@
     return 'service_worker.service_worker'
 
 
-# The reference build is disabled. crbug.com/442752
-# TODO(horo): Enable after the reference build newer than M39 will be rolled.
-@benchmark.Disabled('reference')
 class ServiceWorkerMicroBenchmarkPerfTest(perf_benchmark.PerfBenchmark):
   """This test is a microbenchmark of service worker.
 
diff --git a/tools/perf/page_sets/service_worker_micro_benchmark.py b/tools/perf/page_sets/service_worker_micro_benchmark.py
index dc8fa52..c1e9758b 100644
--- a/tools/perf/page_sets/service_worker_micro_benchmark.py
+++ b/tools/perf/page_sets/service_worker_micro_benchmark.py
@@ -26,12 +26,10 @@
         cloud_storage_bucket=story.PUBLIC_BUCKET)
 
     # pylint: disable=line-too-long
-    # The code of localhost:8091 is placed in
-    # https://github.com/coonsta/Service-Worker-Performance
-    # but currently the following is used:
-    # https://github.com/amiq11/Service-Worker-Performance/tree/follow_spec_and_many_registration
-    # (rev: 3238098ea0225f53dab2f69f7406db8a2712dbf9)
-    # This will be merged into the main repository.
+    # The latest code of localhost:8091 is from:
+    # https://github.com/horo-t/Service-Worker-Performance/tree/fix-flakyness
+    # (rev: 0cc35c2398526665399ca99fe53147ff81101408)
+    # TODO(falken): House the code in GoogleChrome's GitHub repository.
     # pylint: enable=C0301
     # Why: to measure performance of many concurrent fetches
     self.AddStory(ServiceWorkerBenchmarkPage(
diff --git a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
index fcf19420..757d6b9 100644
--- a/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
+++ b/tools/valgrind/gtest_exclude/content_browsertests.gtest-drmemory.txt
@@ -66,6 +66,3 @@
 
 # https://crbug.com/536881
 IndexedDBBrowserTest.DiskFullOnCommit
-
-# https://crbug.com/562406
-WebRtcMediaRecorderTest.MediaRecorderStartWithTimeSlice
diff --git a/ui/file_manager/audio_player/elements/audio_player.css b/ui/file_manager/audio_player/elements/audio_player.css
index bc6d7aa..614c701 100644
--- a/ui/file_manager/audio_player/elements/audio_player.css
+++ b/ui/file_manager/audio_player/elements/audio_player.css
@@ -2,6 +2,14 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
+track-list {
+  bottom: 96px;  /* Room for the control bar. */
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+}
+
 control-panel {
   bottom: 0;
   left: 0;
diff --git a/ui/file_manager/audio_player/elements/audio_player.js b/ui/file_manager/audio_player/elements/audio_player.js
index df97719..917168d 100644
--- a/ui/file_manager/audio_player/elements/audio_player.js
+++ b/ui/file_manager/audio_player/elements/audio_player.js
@@ -29,7 +29,7 @@
      */
     shuffle: {
       type: Boolean,
-      observer: 'shuffleChanged'
+      notify: true
     },
 
     /**
@@ -37,7 +37,7 @@
      */
     repeat: {
       type: Boolean,
-      observer: 'repeatChanged'
+      notify: true
     },
 
     /**
@@ -45,7 +45,7 @@
      */
     volume: {
       type: Number,
-      observer: 'volumeChanged'
+      notify: true
     },
 
     /**
@@ -53,7 +53,7 @@
      */
     expanded: {
       type: Boolean,
-      observer: 'expandedChanged'
+      notify: true
     },
 
     /**
@@ -65,16 +65,6 @@
     },
 
     /**
-     * Model object of the Audio Player.
-     * @type {AudioPlayerModel}
-     */
-    model: {
-      type: Object,
-      value: null,
-      observer: 'modelChanged'
-    },
-
-    /**
      * URL of the current track. (exposed publicly for tests)
      */
     currenttrackurl: {
@@ -104,41 +94,6 @@
   wasPlayingOnDragStart_: false,
 
   /**
-   * Handles change event for shuffle mode.
-   * @param {boolean} shuffle
-   */
-  shuffleChanged: function(shuffle) {
-    if (this.model)
-      this.model.shuffle = shuffle;
-  },
-
-  /**
-   * Handles change event for repeat mode.
-   * @param {boolean} repeat
-   */
-  repeatChanged: function(repeat) {
-    if (this.model)
-      this.model.repeat = repeat;
-  },
-
-  /**
-   * Handles change event for audio volume.
-   * @param {number} volume
-   */
-  volumeChanged: function(volume) {
-    if (this.model)
-      this.model.volume = volume;
-  },
-
-  /**
-   * Handles change event for expanded state of track list.
-   */
-  expandedChanged: function(expanded) {
-    if (this.model)
-      this.model.expanded = expanded;
-  },
-
-  /**
    * Initializes an element. This method is called automatically when the
    * element is ready.
    */
@@ -215,21 +170,6 @@
   },
 
   /**
-   * Invoked when the model changed.
-   * @param {AudioPlayerModel} newModel New model.
-   * @param {AudioPlayerModel} oldModel Old model.
-   */
-  modelChanged: function(newModel, oldModel) {
-    // Setting up the UI
-    if (newModel !== oldModel && newModel) {
-      this.shuffle = newModel.shuffle;
-      this.repeat = newModel.repeat;
-      this.volume = newModel.volume;
-      this.expanded = newModel.expanded;
-    }
-  },
-
-  /**
    * Invoked when time is changed.
    * @param {number} newValue new time (in ms).
    * @param {number} oldValue old time (in ms).
diff --git a/ui/file_manager/audio_player/elements/track_list.css b/ui/file_manager/audio_player/elements/track_list.css
index a2f31a29..c04ad559 100644
--- a/ui/file_manager/audio_player/elements/track_list.css
+++ b/ui/file_manager/audio_player/elements/track_list.css
@@ -5,19 +5,14 @@
 :host {
   align-items: center;
   background: rgb(245, 245, 245);
-  bottom: 72px;  /* Room for the controls bar. */
   color: rgb(51, 51, 51);
   cursor: default;
   display: flex;
   flex-direction: column;
   font-size: 10pt;
   justify-content: flex-start;
-  left: 0;
   overflow-x: hidden;
   overflow-y: auto;
-  position: absolute;
-  right: 0;
-  top: 0;
 }
 
 /* Track item. */
diff --git a/ui/file_manager/audio_player/elements/track_list.js b/ui/file_manager/audio_player/elements/track_list.js
index d1a030e4..e04b727b 100644
--- a/ui/file_manager/audio_player/elements/track_list.js
+++ b/ui/file_manager/audio_player/elements/track_list.js
@@ -56,26 +56,9 @@
      * element is ready.
      */
     ready: function() {
-      this.observeTrackList();
-
       window.addEventListener('resize', this.onWindowResize_.bind(this));
     },
 
-    observeTrackList: function() {
-      // Unobserve the previous track list.
-      if (this.unobserveTrackList_)
-        this.unobserveTrackList_();
-
-      // Observe the new track list.
-      var observer = this.tracksValueChanged_.bind(this);
-      Array.observe(this.tracks, observer);
-
-      // Set the function to unobserve it.
-      this.unobserveTrackList_ = function(tracks, observer) {
-        Array.unobserve(tracks, observer);
-      }.bind(null, this.tracks, observer);
-    },
-
     /**
      * Play order of the tracks. Each value is the index of 'this.tracks'.
      * @type {Array<number>}
@@ -130,9 +113,6 @@
       // Note: Sometimes both oldValue and newValue are null though the actual
       // values are not null. Maybe it's a bug of Polymer.
 
-      // Re-register the observer of 'this.tracks'.
-      this.observeTrackList();
-
       if (this.tracks.length !== 0) {
         // Restore the active track.
         if (this.currentTrackIndex !== -1 &&
@@ -149,17 +129,6 @@
     },
 
     /**
-     * Invoked when the value in the 'tracks' is changed.
-     * @param {Array<Object>} changes The detail of the change.
-     */
-    tracksValueChanged_: function(changes) {
-      if (this.tracks.length === 0)
-        this.currentTrackIndex = -1;
-      else
-        this.set('tracks.' + this.currentTrackIndex + '.active', true);
-    },
-
-    /**
      * Invoked when the track element is clicked.
      * @param {Event} event Click event.
      */
diff --git a/ui/file_manager/audio_player/js/audio_player.js b/ui/file_manager/audio_player/js/audio_player.js
index f07bb0d4..f1a1a4a 100644
--- a/ui/file_manager/audio_player/js/audio_player.js
+++ b/ui/file_manager/audio_player/js/audio_player.js
@@ -19,19 +19,6 @@
   this.metadataModel_ = MetadataModel.create(this.volumeManager_);
   this.selectedEntry_ = null;
   this.invalidTracks_ = {};
-
-  this.model_ = new AudioPlayerModel();
-  Object.observe(this.model_, function(changes) {
-    for (var i = 0; i < changes.length; i++) {
-      var change = changes[i];
-      if (change.name == 'expanded' &&
-          (change.type == 'add' || change.type == 'update')) {
-        this.onModelExpandedChanged(change.oldValue, change.object.expanded);
-        break;
-      }
-    }
-  }.bind(this));
-
   this.entries_ = [];
   this.currentTrackIndex_ = -1;
   this.playlistGeneration_ = 0;
@@ -48,10 +35,34 @@
 
   this.player_ =
     /** @type {AudioPlayerElement} */ (document.querySelector('audio-player'));
-  // TODO(yoshiki): Move tracks into the model.
   this.player_.tracks = [];
-  this.model_.initialize(function() {
-    this.player_.model = this.model_;
+
+  // Restore the saved state from local storage, and update the local storage
+  // if the states are changed.
+  var STORAGE_PREFIX = 'audioplayer-';
+  var KEYS_TO_SAVE_STATES = ['shuffle', 'repeat', 'volume', 'expanded'];
+  var storageKeys = KEYS_TO_SAVE_STATES.map(a => STORAGE_PREFIX + a);
+  chrome.storage.local.get(storageKeys, function(results) {
+    // Update the UI by loaded state.
+    for (var storageKey in results) {
+      var key = storageKey.substr(STORAGE_PREFIX.length);
+      this.player_[key] = results[storageKey];
+    }
+    // Start listening to UI changes to write back the states to local storage.
+    for (var i = 0; i < KEYS_TO_SAVE_STATES.length; i++) {
+      this.player_.addEventListener(
+          KEYS_TO_SAVE_STATES[i] + '-changed',
+          function(storageKey, event) {
+            var objectToBeSaved = {};
+            objectToBeSaved[storageKey] = event.detail.value;
+            chrome.storage.local.set(objectToBeSaved);
+          }.bind(this, storageKeys[i]));
+    }
+  }.bind(this));
+
+  // Update the window size when UI's 'expanded' state is changed.
+  this.player_.addEventListener('expanded-changed', function(event) {
+    this.onExpandedChanged_(event.detail.value);
   }.bind(this));
 
   // Run asynchronously after an event of model change is delivered.
@@ -372,10 +383,10 @@
 
 /**
  * Invoked when the 'expanded' property in the model is changed.
- * @param {boolean} oldValue Old value.
  * @param {boolean} newValue New value.
+ * @private
  */
-AudioPlayer.prototype.onModelExpandedChanged = function(oldValue, newValue) {
+AudioPlayer.prototype.onExpandedChanged_ = function(newValue) {
   if (this.isExpanded_ !== null &&
       this.isExpanded_ === newValue)
     return;
diff --git a/ui/file_manager/audio_player/js/audio_player_model.js b/ui/file_manager/audio_player/js/audio_player_model.js
deleted file mode 100644
index 7bbef274..0000000
--- a/ui/file_manager/audio_player/js/audio_player_model.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * The model class for audio player.
- * @constructor
- */
-function AudioPlayerModel() {}
-
-AudioPlayerModel.prototype.initialize = function(callback) {
-  'use strict';
-
-  /**
-   * List of values to be stored into the model.
-   * @type {!Object<*>}
-   * @const
-   */
-  var VALUES =
-    /**
-     * They will be used as properties of AudioPlayerModel.
-     * @lends {AudioPlayerModel.prototype}
-     */
-    {
-      shuffle: false,
-      repeat: false,
-      volume: 100,
-      expanded: false,
-    };
-
-  /**
-   * Prefix of the stored values in the storage.
-   * @type {string}
-   */
-  var STORAGE_PREFIX = 'audioplayer-';
-
-  /**
-   * Save the values in the model into the storage.
-   * @param {AudioPlayerModel} model The model.
-   */
-  function saveModel(model) {
-    var objectToBeSaved = {};
-    for (var key in VALUES) {
-      objectToBeSaved[STORAGE_PREFIX + key] = model[key];
-    }
-
-    chrome.storage.local.set(objectToBeSaved);
-  };
-
-  /**
-   * Load the values in the model from the storage.
-   * @param {AudioPlayerModel} model The model.
-   * @param {function()} inCallback Called when the load is completed.
-   */
-  function loadModel(model, inCallback) {
-    // Restores the values from the storage
-    var objectsToBeRead = Object.keys(VALUES).
-                          map(function(a) {
-                            return STORAGE_PREFIX + a;
-                          });
-
-    chrome.storage.local.get(objectsToBeRead, function(result) {
-      for (var key in result) {
-        // Strips the prefix.
-        model[key.substr(STORAGE_PREFIX.length)] = result[key];
-      }
-      inCallback();
-    });
-  };
-
-  // Initializes values.
-  for (var key in VALUES) {
-    this[key] = VALUES[key];
-  }
-  Object.seal(this);
-
-  // Restores the values from the storage
-  var target = this;
-  loadModel(target, function() {
-    // Installs observer to watch changes of the values.
-    Object.observe(target, function(changes) {
-      saveModel(target);
-    });
-    callback();
-  });
-}
diff --git a/ui/file_manager/audio_player/js/audio_player_scripts.js b/ui/file_manager/audio_player/js/audio_player_scripts.js
index ec50fc7..d296d65 100644
--- a/ui/file_manager/audio_player/js/audio_player_scripts.js
+++ b/ui/file_manager/audio_player/js/audio_player_scripts.js
@@ -38,7 +38,6 @@
 <include src="../../file_manager/foreground/js/metadata/thumbnail_model.js">
 
 <include src="audio_player.js"/>
-<include src="audio_player_model.js"/>
 
 window.reload = reload;
 window.unload = unload;
diff --git a/ui/file_manager/audio_player/js/compiled_resources.gyp b/ui/file_manager/audio_player/js/compiled_resources.gyp
index 1902b6e..9fd6e65 100644
--- a/ui/file_manager/audio_player/js/compiled_resources.gyp
+++ b/ui/file_manager/audio_player/js/compiled_resources.gyp
@@ -90,7 +90,6 @@
           '../elements/control_panel.js',
           '../elements/track_list.js',
           '../elements/audio_player.js',
-          'audio_player_model.js',
         ],
         'externs': [
           '<(EXTERNS_DIR)/chrome_extensions.js',
@@ -101,7 +100,6 @@
           '../../externs/audio_player_foreground.js',
           '../../externs/chrome_test.js',
           '../../externs/es6_workaround.js',
-          '../../externs/es7_workaround.js',
           '../../externs/platform.js',
         ],
       },
diff --git a/ui/file_manager/externs/es7_workaround.js b/ui/file_manager/externs/es7_workaround.js
deleted file mode 100644
index 4d76e88e..0000000
--- a/ui/file_manager/externs/es7_workaround.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 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.
-
-/**
-* @fileoverview Partial definitions for ECMAScript 7. To compile Files.app, some
-*     definitions are defined in this file. They should be removed once ES7
-*     definitions are ready in closure compiler by default.
-* @externs
-*/
-
-/**
- * @param {!Object} obj
- * @param {function(!Array<!Object>)} callback
- * @param {!Array<string>=} acceptList
- */
-Object.observe = function(obj, callback, acceptList) {};
-
-/**
- * @param {!Object} obj
- * @param {function(!Array<!Object>)} callback
- */
-Object.unobserve = function(obj, callback) {};
-
-/**
- * @param {!Array} arr
- * @param {function(!Array<!Object>)} callback
- */
-Array.observe = function(arr, callback) {};
-
-/**
- * @param {!Array} arr
- * @param {function(!Array<!Object>)} callback
- */
-Array.unobserve = function(arr, callback) {};