diff --git a/BUILD.gn b/BUILD.gn
index 866b040..7903e89 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -791,7 +791,7 @@
     deps = [
       "//ipc/mojo:ipc_mojo_perftests",
       "//media/mojo:tests",
-      "//media/mojo/services:cdm_service",
+      "//media/mojo/services",
       "//mojo:tests",
     ]
   }
diff --git a/DEPS b/DEPS
index 1b3b785..aa05d1f 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'c2878e23d405e7ae77f6110602ad75ce1f6b941c',
+  'skia_revision': '4803f9715ff02b54a8ebae24167c490181d7cc3f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '16da943d395b09019159df6e013853d107b930c1',
+  'v8_revision': 'bcf6e72360119316c0d158caf4b743a7c62ac6ba',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -83,7 +83,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '7975b186d213188b50bec674a83e45ab11a90cfd',
+  'nacl_revision': '4eebc9bc011b2ea84c225a4b47068cb98790646e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling dEQP
   # and whatever else without interference from each other.
@@ -210,7 +210,7 @@
    Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '7da28c6c7c6a1387217352ce02b31754deb54d2a',
 
   'src/third_party/libjpeg_turbo':
-   Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + '414f2433e6634942b9ceea9450bdc21dcc5520cf',
+   Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + '7260e4d8b8e1e40b17f03fafdf1cd83296900f76',
 
   'src/third_party/flac':
    Var('chromium_git') + '/chromium/deps/flac.git' + '@' + '812243a85937e06102ba312c6caf8823e243b35b',
@@ -225,7 +225,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' + '@' + '671d805d1f07c3bf427797b29575480f0810d5c5', # commit position 12773
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '495f1ae055d27cfe096a2f7e47ff4a1f57724b5f', # commit position 12784
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 04201e51..fcd6803a6 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1972,7 +1972,7 @@
 
   # Allow more direct string conversions on platforms with native utf8
   # strings
-  if (is_mac || is_ios || is_chromeos) {
+  if (is_mac || is_ios || is_chromeos || is_chromecast) {
     defines = [ "SYSTEM_NATIVE_UTF8" ]
   }
 
diff --git a/build/config/arm.gni b/build/config/arm.gni
index 18f923d..d16c0d2 100644
--- a/build/config/arm.gni
+++ b/build/config/arm.gni
@@ -90,5 +90,4 @@
   # arm64 supports only "hard".
   arm_float_abi = "hard"
   arm_use_neon = true
-  arm_fpu = "cortex-a57+simd+crypto+fp+crc"
 }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 267c920f..3f82d79 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -702,9 +702,6 @@
   if (current_cpu == "arm" && !is_ios && !is_nacl) {
     cflags = [ "-mfpu=$arm_fpu" ]
     asmflags = cflags
-  } else if (current_cpu == "arm64" && !is_ios && !is_nacl) {
-    cflags = [ "-mcpu=$arm_fpu" ]
-    asmflags = cflags
   }
 }
 
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index c0c5e70..f6c3a104 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -53,9 +53,9 @@
       run_state_(WAITING_FOR_TARGET_AVAILABILITY),
       iterations_(1),
       iteration_start_(0),
-      direction_(DIRECTION_NORMAL),
+      direction_(Direction::NORMAL),
       playback_rate_(1),
-      fill_mode_(FILL_MODE_BOTH),
+      fill_mode_(FillMode::BOTH),
       needs_synchronized_start_time_(false),
       received_finished_event_(false),
       suspended_(false),
@@ -141,7 +141,7 @@
 
 bool Animation::InEffect(base::TimeTicks monotonic_time) const {
   return ConvertToActiveTime(monotonic_time) >= base::TimeDelta() ||
-         (fill_mode_ == FILL_MODE_BOTH || fill_mode_ == FILL_MODE_BACKWARDS);
+         (fill_mode_ == FillMode::BOTH || fill_mode_ == FillMode::BACKWARDS);
 }
 
 base::TimeDelta Animation::ConvertToActiveTime(
@@ -225,9 +225,9 @@
   // Check if we are running the animation in reverse direction for the current
   // iteration
   bool reverse =
-      (direction_ == DIRECTION_REVERSE) ||
-      (direction_ == DIRECTION_ALTERNATE && iteration % 2 == 1) ||
-      (direction_ == DIRECTION_ALTERNATE_REVERSE && iteration % 2 == 0);
+      (direction_ == Direction::REVERSE) ||
+      (direction_ == Direction::ALTERNATE_NORMAL && iteration % 2 == 1) ||
+      (direction_ == Direction::ALTERNATE_REVERSE && iteration % 2 == 0);
 
   // If we are running the animation in reverse direction, reverse the result
   if (reverse)
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index ba0b517..07702dc 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -45,19 +45,9 @@
     LAST_RUN_STATE = ABORTED_BUT_NEEDS_COMPLETION
   };
 
-  enum Direction {
-    DIRECTION_NORMAL,
-    DIRECTION_REVERSE,
-    DIRECTION_ALTERNATE,
-    DIRECTION_ALTERNATE_REVERSE
-  };
+  enum class Direction { NORMAL, REVERSE, ALTERNATE_NORMAL, ALTERNATE_REVERSE };
 
-  enum FillMode {
-    FILL_MODE_NONE,
-    FILL_MODE_FORWARDS,
-    FILL_MODE_BACKWARDS,
-    FILL_MODE_BOTH
-  };
+  enum class FillMode { NONE, FORWARDS, BACKWARDS, BOTH };
 
   static std::unique_ptr<Animation> Create(
       std::unique_ptr<AnimationCurve> curve,
diff --git a/cc/animation/animation_unittest.cc b/cc/animation/animation_unittest.cc
index f20e3f12..edf0f793 100644
--- a/cc/animation/animation_unittest.cc
+++ b/cc/animation/animation_unittest.cc
@@ -92,7 +92,7 @@
 
 TEST(AnimationTest, TrimTimeReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(-1));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   EXPECT_EQ(
       1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0)).InSecondsF());
   EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -109,7 +109,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateInfiniteIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(-1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -126,7 +126,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateOneIteration) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -143,7 +143,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateTwoIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -166,7 +166,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateTwoHalfIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(2.5));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -193,7 +193,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateReverseInfiniteIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(-1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -210,7 +210,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateReverseOneIteration) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -227,7 +227,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateReverseTwoIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -266,7 +266,7 @@
 TEST(AnimationTest, TrimTimeStartTimeReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
   anim->set_start_time(TicksFromSecondsF(4));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   EXPECT_EQ(
       0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF());
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(4.0))
@@ -297,7 +297,7 @@
   std::unique_ptr<Animation> anim(CreateAnimation(1));
   anim->set_time_offset(TimeDelta::FromMilliseconds(4000));
   anim->set_start_time(TicksFromSecondsF(4));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
@@ -325,7 +325,7 @@
 TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
   anim->set_time_offset(TimeDelta::FromMilliseconds(-4000));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
 
   EXPECT_EQ(
       0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0)).InSecondsF());
@@ -356,7 +356,7 @@
 
 TEST(AnimationTest, TrimTimePauseResumeReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0));
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
@@ -391,7 +391,7 @@
 
 TEST(AnimationTest, TrimTimeSuspendResumeReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   anim->SetRunState(Animation::RUNNING, TicksFromSecondsF(0.0));
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
@@ -707,7 +707,7 @@
 
 TEST(AnimationTest, TrimTimePlaybackNormalDoubleReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1, 1, -1));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
                    .InSecondsF());
   EXPECT_EQ(
@@ -722,7 +722,7 @@
 
 TEST(AnimationTest, TrimTimePlaybackFastDoubleReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(1, 4, -2));
-  anim->set_direction(Animation::DIRECTION_REVERSE);
+  anim->set_direction(Animation::Direction::REVERSE);
   EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
                    .InSecondsF());
   EXPECT_EQ(
@@ -741,7 +741,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFast) {
   std::unique_ptr<Animation> anim(CreateAnimation(2, 2, 2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -766,7 +766,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(2, 2, 2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
                      .InSecondsF());
   EXPECT_EQ(2.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
@@ -793,7 +793,7 @@
 
 TEST(AnimationTest, TrimTimeAlternateTwoIterationsPlaybackFastDoubleReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(2, 2, -2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(2.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(1.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -819,7 +819,7 @@
 TEST(AnimationTest,
      TrimTimeAlternateReverseThreeIterationsPlaybackFastAlternateReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(3, 2, -2));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE_REVERSE);
+  anim->set_direction(Animation::Direction::ALTERNATE_REVERSE);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.25))
@@ -853,7 +853,7 @@
 TEST(AnimationTest,
      TrimTimeAlternateReverseTwoIterationsPlaybackNormalAlternate) {
   std::unique_ptr<Animation> anim(CreateAnimation(2, 2, -1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.5))
@@ -897,7 +897,7 @@
 
 TEST(AnimationTest, TrimTimeIterationStartAlternate) {
   std::unique_ptr<Animation> anim(CreateAnimation(2, 1, 1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   anim->set_iteration_start(0.3);
   EXPECT_EQ(0.3, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
                      .InSecondsF());
@@ -917,7 +917,7 @@
 
 TEST(AnimationTest, TrimTimeIterationStartAlternateThreeIterations) {
   std::unique_ptr<Animation> anim(CreateAnimation(3, 1, 1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   anim->set_iteration_start(1);
   EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(-1.0))
                      .InSecondsF());
@@ -942,7 +942,7 @@
 TEST(AnimationTest,
      TrimTimeIterationStartAlternateThreeIterationsPlaybackReverse) {
   std::unique_ptr<Animation> anim(CreateAnimation(3, 1, -1));
-  anim->set_direction(Animation::DIRECTION_ALTERNATE);
+  anim->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   anim->set_iteration_start(1);
   EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(0.0))
                      .InSecondsF());
@@ -958,22 +958,22 @@
 
 TEST(AnimationTest, InEffectFillMode) {
   std::unique_ptr<Animation> anim(CreateAnimation(1));
-  anim->set_fill_mode(Animation::FILL_MODE_NONE);
+  anim->set_fill_mode(Animation::FillMode::NONE);
   EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_FORWARDS);
+  anim->set_fill_mode(Animation::FillMode::FORWARDS);
   EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_BACKWARDS);
+  anim->set_fill_mode(Animation::FillMode::BACKWARDS);
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_BOTH);
+  anim->set_fill_mode(Animation::FillMode::BOTH);
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
@@ -981,22 +981,22 @@
 
 TEST(AnimationTest, InEffectFillModePlayback) {
   std::unique_ptr<Animation> anim(CreateAnimation(1, 1, -1));
-  anim->set_fill_mode(Animation::FILL_MODE_NONE);
+  anim->set_fill_mode(Animation::FillMode::NONE);
   EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_FORWARDS);
+  anim->set_fill_mode(Animation::FillMode::FORWARDS);
   EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_BACKWARDS);
+  anim->set_fill_mode(Animation::FillMode::BACKWARDS);
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
 
-  anim->set_fill_mode(Animation::FILL_MODE_BOTH);
+  anim->set_fill_mode(Animation::FillMode::BOTH);
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
   EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc
index ed5810e..c43a0a5 100644
--- a/cc/animation/element_animations.cc
+++ b/cc/animation/element_animations.cc
@@ -512,12 +512,12 @@
 
     bool forward_direction = true;
     switch (animations_[i]->direction()) {
-      case Animation::DIRECTION_NORMAL:
-      case Animation::DIRECTION_ALTERNATE:
+      case Animation::Direction::NORMAL:
+      case Animation::Direction::ALTERNATE_NORMAL:
         forward_direction = animations_[i]->playback_rate() >= 0.0;
         break;
-      case Animation::DIRECTION_REVERSE:
-      case Animation::DIRECTION_ALTERNATE_REVERSE:
+      case Animation::Direction::REVERSE:
+      case Animation::Direction::ALTERNATE_REVERSE:
         forward_direction = animations_[i]->playback_rate() < 0.0;
         break;
     }
@@ -549,12 +549,12 @@
 
     bool forward_direction = true;
     switch (animations_[i]->direction()) {
-      case Animation::DIRECTION_NORMAL:
-      case Animation::DIRECTION_ALTERNATE:
+      case Animation::Direction::NORMAL:
+      case Animation::Direction::ALTERNATE_NORMAL:
         forward_direction = animations_[i]->playback_rate() >= 0.0;
         break;
-      case Animation::DIRECTION_REVERSE:
-      case Animation::DIRECTION_ALTERNATE_REVERSE:
+      case Animation::Direction::REVERSE:
+      case Animation::Direction::ALTERNATE_REVERSE:
         forward_direction = animations_[i]->playback_rate() < 0.0;
         break;
     }
diff --git a/cc/animation/element_animations_unittest.cc b/cc/animation/element_animations_unittest.cc
index ce755cc1..158db04 100644
--- a/cc/animation/element_animations_unittest.cc
+++ b/cc/animation/element_animations_unittest.cc
@@ -2396,7 +2396,7 @@
       Animation::Create(std::move(curve2), 2, 2, TargetProperty::TRANSFORM);
 
   // Reverse Direction
-  animation->set_direction(Animation::DIRECTION_REVERSE);
+  animation->set_direction(Animation::Direction::REVERSE);
   animation->set_affects_active_elements(false);
   animations_impl->AddAnimation(std::move(animation));
 
@@ -2589,7 +2589,7 @@
   EXPECT_GT(animation->playback_rate(), 0.0);
 
   // NORMAL direction with positive playback rate.
-  animation->set_direction(Animation::DIRECTION_NORMAL);
+  animation->set_direction(Animation::Direction::NORMAL);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(6.f, max_scale);
@@ -2598,7 +2598,7 @@
   EXPECT_EQ(6.f, max_scale);
 
   // ALTERNATE direction with positive playback rate.
-  animation->set_direction(Animation::DIRECTION_ALTERNATE);
+  animation->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(6.f, max_scale);
@@ -2607,7 +2607,7 @@
   EXPECT_EQ(6.f, max_scale);
 
   // REVERSE direction with positive playback rate.
-  animation->set_direction(Animation::DIRECTION_REVERSE);
+  animation->set_direction(Animation::Direction::REVERSE);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(3.f, max_scale);
@@ -2616,7 +2616,7 @@
   EXPECT_EQ(3.f, max_scale);
 
   // ALTERNATE reverse direction.
-  animation->set_direction(Animation::DIRECTION_REVERSE);
+  animation->set_direction(Animation::Direction::REVERSE);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(3.f, max_scale);
@@ -2627,7 +2627,7 @@
   animation->set_playback_rate(-1.0);
 
   // NORMAL direction with negative playback rate.
-  animation->set_direction(Animation::DIRECTION_NORMAL);
+  animation->set_direction(Animation::Direction::NORMAL);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(3.f, max_scale);
@@ -2636,7 +2636,7 @@
   EXPECT_EQ(3.f, max_scale);
 
   // ALTERNATE direction with negative playback rate.
-  animation->set_direction(Animation::DIRECTION_ALTERNATE);
+  animation->set_direction(Animation::Direction::ALTERNATE_NORMAL);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(3.f, max_scale);
@@ -2645,7 +2645,7 @@
   EXPECT_EQ(3.f, max_scale);
 
   // REVERSE direction with negative playback rate.
-  animation->set_direction(Animation::DIRECTION_REVERSE);
+  animation->set_direction(Animation::Direction::REVERSE);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(6.f, max_scale);
@@ -2654,7 +2654,7 @@
   EXPECT_EQ(6.f, max_scale);
 
   // ALTERNATE reverse direction with negative playback rate.
-  animation->set_direction(Animation::DIRECTION_REVERSE);
+  animation->set_direction(Animation::Direction::REVERSE);
   EXPECT_TRUE(animations_impl->MaximumTargetScale(ElementListType::PENDING,
                                                   &max_scale));
   EXPECT_EQ(6.f, max_scale);
@@ -3124,7 +3124,7 @@
   animations->GetAnimationById(animation_id)
       ->set_time_offset(base::TimeDelta::FromMilliseconds(-10000));
   animations->GetAnimationById(animation_id)
-      ->set_fill_mode(Animation::FILL_MODE_NONE);
+      ->set_fill_mode(Animation::FillMode::NONE);
 
   animations->PushPropertiesTo(animations_impl.get());
   EXPECT_TRUE(client_impl_.GetHasPotentialOpacityAnimation(
@@ -3393,7 +3393,7 @@
   std::unique_ptr<Animation> animation(CreateAnimation(
       std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
       1, TargetProperty::OPACITY));
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(TimeDelta::FromMilliseconds(-2000));
   animation->set_affects_active_elements(false);
 
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc
index ce5fb3c..b001044 100644
--- a/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/cc/animation/keyframed_animation_curve_unittest.cc
@@ -445,10 +445,10 @@
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
   const int num_steps = 36;
-  const float steps_start_offset = 1.0f;
   curve->AddKeyframe(FloatKeyframe::Create(
       base::TimeDelta(), 0.f,
-      StepsTimingFunction::Create(num_steps, steps_start_offset)));
+      StepsTimingFunction::Create(num_steps,
+                                  StepsTimingFunction::StepPosition::START)));
   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
                                            num_steps, nullptr));
 
@@ -476,10 +476,10 @@
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
   const int num_steps = 36;
-  const float steps_start_offset = 0.5f;
   curve->AddKeyframe(FloatKeyframe::Create(
       base::TimeDelta(), 0.f,
-      StepsTimingFunction::Create(num_steps, steps_start_offset)));
+      StepsTimingFunction::Create(num_steps,
+                                  StepsTimingFunction::StepPosition::MIDDLE)));
   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
                                            num_steps, nullptr));
 
@@ -508,10 +508,10 @@
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
   const int num_steps = 36;
-  const float steps_start_offset = 0.0f;
   curve->AddKeyframe(FloatKeyframe::Create(
       base::TimeDelta(), 0.f,
-      StepsTimingFunction::Create(num_steps, steps_start_offset)));
+      StepsTimingFunction::Create(num_steps,
+                                  StepsTimingFunction::StepPosition::END)));
   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
                                            num_steps, nullptr));
 
@@ -822,8 +822,10 @@
 TEST(KeyframedAnimationCurveTest, StepsTimingInputsOutsideZeroOneRange) {
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
-  curve->AddKeyframe(FloatKeyframe::Create(
-      base::TimeDelta(), 0.f, StepsTimingFunction::Create(4, 0.5f)));
+  curve->AddKeyframe(
+      FloatKeyframe::Create(base::TimeDelta(), 0.f,
+                            StepsTimingFunction::Create(
+                                4, StepsTimingFunction::StepPosition::MIDDLE)));
   curve->AddKeyframe(
       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
   // Curve timing function producing timing outputs outside of range [0,1].
diff --git a/cc/animation/timing_function.cc b/cc/animation/timing_function.cc
index 8e80f7f..494d8ef 100644
--- a/cc/animation/timing_function.cc
+++ b/cc/animation/timing_function.cc
@@ -66,16 +66,23 @@
 
 std::unique_ptr<StepsTimingFunction> StepsTimingFunction::Create(
     int steps,
-    float steps_start_offset) {
-  return base::WrapUnique(new StepsTimingFunction(steps, steps_start_offset));
+    StepPosition step_position) {
+  return base::WrapUnique(new StepsTimingFunction(steps, step_position));
 }
 
-StepsTimingFunction::StepsTimingFunction(int steps, float steps_start_offset)
-    : steps_(steps), steps_start_offset_(steps_start_offset) {
-  // Restrict it to CSS presets: step_start, step_end and step_middle.
-  // See the Web Animations specification, 3.12.4. Timing in discrete steps.
-  DCHECK(steps_start_offset_ == 0 || steps_start_offset_ == 1 ||
-         steps_start_offset_ == 0.5);
+StepsTimingFunction::StepsTimingFunction(int steps, StepPosition step_position)
+    : steps_(steps) {
+  switch (step_position) {
+    case StepPosition::START:
+      steps_start_offset_ = 1;
+      break;
+    case StepPosition::MIDDLE:
+      steps_start_offset_ = 0.5;
+      break;
+    case StepPosition::END:
+      steps_start_offset_ = 0;
+      break;
+  }
 }
 
 StepsTimingFunction::~StepsTimingFunction() {
diff --git a/cc/animation/timing_function.h b/cc/animation/timing_function.h
index 0953a39..17b9014 100644
--- a/cc/animation/timing_function.h
+++ b/cc/animation/timing_function.h
@@ -88,8 +88,12 @@
 
 class CC_EXPORT StepsTimingFunction : public TimingFunction {
  public:
-  static std::unique_ptr<StepsTimingFunction> Create(int steps,
-                                                     float steps_start_offset);
+  // Web Animations specification, 3.12.4. Timing in discrete steps.
+  enum class StepPosition { START, MIDDLE, END };
+
+  static std::unique_ptr<StepsTimingFunction> Create(
+      int steps,
+      StepPosition step_position);
   ~StepsTimingFunction() override;
 
   float GetValue(double t) const override;
@@ -99,7 +103,7 @@
   float Velocity(double time) const override;
 
  protected:
-  StepsTimingFunction(int steps, float steps_start_offset);
+  StepsTimingFunction(int steps, StepPosition step_position);
 
  private:
   int steps_;
diff --git a/cc/ipc/OWNERS b/cc/ipc/OWNERS
new file mode 100644
index 0000000..aef66cf
--- /dev/null
+++ b/cc/ipc/OWNERS
@@ -0,0 +1,8 @@
+per-file *param_traits*.*=set noparent
+per-file *param_traits*.*=dcheng@chromium.org
+per-file *param_traits*.*=inferno@chromium.org
+per-file *param_traits*.*=jln@chromium.org
+per-file *param_traits*.*=jschuh@chromium.org
+per-file *param_traits*.*=kenrb@chromium.org
+per-file *param_traits*.*=nasko@chromium.org
+per-file *param_traits*.*=tsepez@chromium.org
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index e01d5660..ca47707 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -332,19 +332,6 @@
       ValidateQuadResources(stream_video_quad);
       break;
     }
-    case VideoFrameExternalResources::IO_SURFACE: {
-      DCHECK_EQ(frame_resources_.size(), 1u);
-      if (frame_resources_.size() < 1u)
-        break;
-      IOSurfaceDrawQuad* io_surface_quad =
-          render_pass->CreateAndAppendDrawQuad<IOSurfaceDrawQuad>();
-      io_surface_quad->SetNew(shared_quad_state, quad_rect, opaque_rect,
-                              visible_quad_rect, visible_rect.size(),
-                              frame_resources_[0].id,
-                              IOSurfaceDrawQuad::UNFLIPPED);
-      ValidateQuadResources(io_surface_quad);
-      break;
-    }
 #if defined(VIDEO_HOLE)
     // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not
     // maintained by the general compositor team. Please contact the following
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index d2fb731..f0fe524 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -52,7 +52,7 @@
                      ? VideoFrameExternalResources::RGBA_RESOURCE
                      : VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE;
         case GL_TEXTURE_RECTANGLE_ARB:
-          return VideoFrameExternalResources::IO_SURFACE;
+          return VideoFrameExternalResources::RGB_RESOURCE;
         default:
           NOTREACHED();
           break;
@@ -66,7 +66,7 @@
         case GL_TEXTURE_EXTERNAL_OES:
           return VideoFrameExternalResources::YUV_RESOURCE;
         case GL_TEXTURE_RECTANGLE_ARB:
-          return VideoFrameExternalResources::IO_SURFACE;
+          return VideoFrameExternalResources::RGB_RESOURCE;
         default:
           NOTREACHED();
           break;
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h
index ca3be1a..b56597d 100644
--- a/cc/resources/video_resource_updater.h
+++ b/cc/resources/video_resource_updater.h
@@ -42,7 +42,6 @@
     RGBA_PREMULTIPLIED_RESOURCE,
     RGBA_RESOURCE,
     STREAM_TEXTURE_RESOURCE,
-    IO_SURFACE,
 
 #if defined(VIDEO_HOLE)
     // TODO(danakj): Implement this with a solid color layer instead of a video
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index 13b80ea..5d542106 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -276,8 +276,8 @@
   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
       KeyframedFloatAnimationCurve::Create());
 
-  std::unique_ptr<TimingFunction> func =
-      StepsTimingFunction::Create(num_steps, 0.5f);
+  std::unique_ptr<TimingFunction> func = StepsTimingFunction::Create(
+      num_steps, StepsTimingFunction::StepPosition::MIDDLE);
   if (duration > 0.0)
     curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), start_opacity,
                                              std::move(func)));
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 31cb627..77b1c68 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -2694,7 +2694,7 @@
   std::unique_ptr<Animation> animation = Animation::Create(
       std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1,
       TargetProperty::TRANSFORM);
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
   AddAnimationToLayerWithPlayer(grand_child->id(), timeline_impl(),
                                 std::move(animation));
@@ -8147,7 +8147,7 @@
       base::TimeDelta::FromMilliseconds(100), end_filters, nullptr));
   std::unique_ptr<Animation> animation =
       Animation::Create(std::move(curve), 0, 1, TargetProperty::FILTER);
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
 
   AddAnimationToLayerWithPlayer(child->id(), timeline_impl(),
@@ -8545,7 +8545,7 @@
   std::unique_ptr<Animation> animation = Animation::Create(
       std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)),
       animation_id, 1, TargetProperty::TRANSFORM);
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
   AddAnimationToLayerWithPlayer(child->id(), timeline(), std::move(animation));
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
@@ -8573,7 +8573,7 @@
   animation = Animation::Create(
       std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
       animation_id, 1, TargetProperty::OPACITY);
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
   AddAnimationToLayerWithExistingPlayer(child->id(), timeline(),
                                         std::move(animation));
@@ -9724,7 +9724,7 @@
   std::unique_ptr<Animation> animation = Animation::Create(
       std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
       animation_id, 1, TargetProperty::OPACITY);
-  animation->set_fill_mode(Animation::FILL_MODE_NONE);
+  animation->set_fill_mode(Animation::FillMode::NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
   Animation* animation_ptr = animation.get();
   AddAnimationToLayerWithExistingPlayer(animated->id(), timeline(),
diff --git a/chrome/VERSION b/chrome/VERSION
index 461a14a..ea3043c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=52
 MINOR=0
-BUILD=2740
+BUILD=2741
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
index e15e901..3af6f50 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -30,7 +30,6 @@
 @JNINamespace("offline_pages::android")
 public class OfflinePageBridge {
     public static final String BOOKMARK_NAMESPACE = "bookmark";
-    public static final long INVALID_OFFLINE_ID = 0;
 
     /**
      * Retrieves the OfflinePageBridge for the given profile, creating it the first time
@@ -390,13 +389,6 @@
         assert mIsNativeOfflinePageModelLoaded;
         assert webContents != null;
 
-        if (webContents.isDestroyed()) {
-            callback.onSavePageDone(SavePageResult.CONTENT_UNAVAILABLE, null, INVALID_OFFLINE_ID);
-            RecordHistogram.recordEnumeratedHistogram("OfflinePages.SavePageResult",
-                    SavePageResult.CONTENT_UNAVAILABLE, SavePageResult.RESULT_COUNT);
-            return;
-        }
-
         SavePageCallback callbackWrapper = new SavePageCallback() {
             @Override
             public void onSavePageDone(int savePageResult, String url, long offlineId) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index 91fbc71..d21273b7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -174,10 +174,15 @@
         Tab tab = getActivity().getActivityTab();
         ContextMenu menu = ContextMenuUtils.openContextMenu(this, tab, "testImage");
         assertNotNull("Context menu was not properly created", menu);
-        assertFalse("Context menu did not have window focus", getActivity().hasWindowFocus());
+        CriteriaHelper.pollUiThread(new Criteria("Context menu did not have window focus") {
+            @Override
+            public boolean isSatisfied() {
+                return !getActivity().hasWindowFocus();
+            }
+        });
 
         getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        CriteriaHelper.pollInstrumentationThread(new Criteria("Activity did not regain focus.") {
+        CriteriaHelper.pollUiThread(new Criteria("Activity did not regain focus.") {
             @Override
             public boolean isSatisfied() {
                 return getActivity().hasWindowFocus();
@@ -191,11 +196,16 @@
         Tab tab = getActivity().getActivityTab();
         ContextMenu menu = ContextMenuUtils.openContextMenu(this, tab, "testImage");
         assertNotNull("Context menu was not properly created", menu);
-        assertFalse("Context menu did not have window focus", getActivity().hasWindowFocus());
+        CriteriaHelper.pollUiThread(new Criteria("Context menu did not have window focus") {
+            @Override
+            public boolean isSatisfied() {
+                return !getActivity().hasWindowFocus();
+            }
+        });
 
         TestTouchUtils.singleClickView(getInstrumentation(), tab.getView(), 0, 0);
 
-        CriteriaHelper.pollInstrumentationThread(new Criteria("Activity did not regain focus.") {
+        CriteriaHelper.pollUiThread(new Criteria("Activity did not regain focus.") {
             @Override
             public boolean isSatisfied() {
                 return getActivity().hasWindowFocus();
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 70666d9..5826670 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -11096,9 +11096,16 @@
         Use a web service to help resolve navigation errors
       </message>
 
-      <message name="IDS_OPTIONS_SUGGEST_PREF" desc="The documentation string of the 'Use Suggest' preference">
-        Use a prediction service to help complete searches and URLs typed in the address bar or the app launcher search box
-      </message>
+      <if expr="chromeos">
+        <message name="IDS_OPTIONS_SUGGEST_PREF" desc="The documentation string of the 'Use Suggest' preference">
+          Use a prediction service to help complete searches and URLs typed in the address bar or the app launcher search box
+        </message>
+      </if>
+      <if expr="not chromeos">
+        <message name="IDS_OPTIONS_SUGGEST_PREF" desc="The documentation string of the 'Use Suggest' preference">
+          Use a prediction service to help complete searches and URLs typed in the address bar
+        </message>
+      </if>
       <message name="IDS_OPTIONS_SPELLING_PREF" desc="The documentation string of the 'Use Spelling' preference">
         Use a web service to help resolve spelling errors
       </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7c513a0..d8f9496 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -940,7 +940,7 @@
     ]
     deps += [ "//media/mojo/interfaces" ]
     if (mojo_media_host == "browser") {
-      deps += [ "//media/mojo/services:application_factory" ]
+      deps += [ "//media/mojo/services" ]
     }
   }
 
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc
index ee2bd0b..2def0ef 100644
--- a/chrome/browser/android/offline_pages/offline_page_bridge.cc
+++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -303,12 +303,15 @@
   ScopedJavaGlobalRef<jobject> j_callback_ref;
   j_callback_ref.Reset(env, j_callback_obj);
 
+  GURL url;
+  std::unique_ptr<OfflinePageArchiver> archiver;
+
   content::WebContents* web_contents =
       content::WebContents::FromJavaWebContents(j_web_contents);
-  GURL url(web_contents->GetLastCommittedURL());
-
-  std::unique_ptr<OfflinePageArchiver> archiver(
-      new OfflinePageMHTMLArchiver(web_contents));
+  if (web_contents) {
+    url = web_contents->GetLastCommittedURL();
+    archiver.reset(new OfflinePageMHTMLArchiver(web_contents));
+  }
 
   offline_pages::ClientId client_id;
   client_id.name_space = ConvertJavaStringToUTF8(env, j_namespace);
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc
index 3d064bdb..94dcb0a 100644
--- a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc
+++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc
@@ -89,6 +89,7 @@
   if (error_code == net::OK &&
       OfflinePageUtils::IsOfflinePage(
           web_contents()->GetBrowserContext(), navigation_handle->GetURL())) {
+    UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork", true);
     OfflinePageUtils::MarkPageAccessed(
         web_contents()->GetBrowserContext(), navigation_handle->GetURL());
   }
@@ -104,6 +105,7 @@
   // On a forward or back transition, don't affect the order of the nav stack.
   if (navigation_handle->GetPageTransition() ==
       ui::PAGE_TRANSITION_FORWARD_BACK) {
+    UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork", false);
     return;
   }
 
@@ -114,8 +116,10 @@
   // in this case.
   GURL offline_url = offline_pages::OfflinePageUtils::GetOfflineURLForOnlineURL(
       web_contents()->GetBrowserContext(), navigation_handle->GetURL());
-  if (!offline_url.is_valid())
+  if (!offline_url.is_valid()) {
+    UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork", false);
     return;
+  }
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 49e88a6..b107415 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -310,7 +310,7 @@
 #endif
 
 #if defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
-#include "media/mojo/services/mojo_media_application_factory.h"
+#include "media/mojo/services/mojo_media_application_factory.h"  // nogncheck
 #endif
 
 using base::FileDescriptor;
diff --git a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
index 507796c..9280941 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
+++ b/chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.cc
@@ -37,8 +37,8 @@
     "gbchcmhmhahfdphkhkmpfmihenigjmpp",  // Chrome Remote Desktop
     "cjanmonomjogheabiocdamfpknlpdehm",  // HP printer driver
     "pmnllmkmjilbojkpgplbdmckghmaocjh",  // Scan app by François Beaufort
-    "khpfeaanjngmcnplbdlpegiifgpfgdco",  // SmartCard Manager App
-    "dojmlffgommefdofbfdajjpgjgjoffjo",  // Charismathics Smart Card Middleware
+    "khpfeaanjngmcnplbdlpegiifgpfgdco",  // Smart Card Connector App
+    "haeblkpifdemlfnkogkipmghfcbonief",  // Charismathics Smart Card Middleware
 
     // Libraries:
     "aclofikceldphonlfmghmimkodjdmhck",  // Ancoris login component
diff --git a/chrome/browser/chromeos/file_manager/arc_file_tasks.cc b/chrome/browser/chromeos/file_manager/arc_file_tasks.cc
index e33ef911..8e4c9d4 100644
--- a/chrome/browser/chromeos/file_manager/arc_file_tasks.cc
+++ b/chrome/browser/chromeos/file_manager/arc_file_tasks.cc
@@ -34,6 +34,7 @@
 constexpr int kArcInstanceHelperVersionWithUrlListSupport = 4;
 constexpr base::FilePath::CharType kArcDownloadPath[] =
     FILE_PATH_LITERAL("/sdcard/Download");
+constexpr char kAppIdSeparator = '/';
 
 // Returns the Mojo interface for ARC Intent Helper, with version |minVersion|
 // or above. If the ARC bridge is not established, returns null.
@@ -83,6 +84,25 @@
   return arc::mojom::ActionType::VIEW;
 }
 
+std::string ActivityNameToAppId(const std::string& package_name,
+                                const std::string& activity_name) {
+  return package_name + kAppIdSeparator + activity_name;
+}
+
+arc::mojom::ActivityNamePtr AppIdToActivityName(const std::string& id) {
+  arc::mojom::ActivityNamePtr name = arc::mojom::ActivityName::New();
+
+  const size_t separator = id.find(kAppIdSeparator);
+  if (separator == std::string::npos) {
+    name->package_name = id;
+    name->activity_name = mojo::String();
+  } else {
+    name->package_name = id.substr(0, separator);
+    name->activity_name = id.substr(separator + 1);
+  }
+  return name;
+}
+
 // Converts the Chrome OS file path to ARC file URL.
 bool ConvertToArcUrl(const base::FilePath& path, GURL* arc_url) {
   // Obtain the primary profile. This information is required because currently
@@ -124,8 +144,9 @@
                                        base::UTF8ToUTF16(name));
     }
     result_list->push_back(FullTaskDescriptor(
-        TaskDescriptor(handler->package_name, TASK_TYPE_ARC_APP,
-                       ArcActionToString(handler->action)),
+        TaskDescriptor(
+            ActivityNameToAppId(handler->package_name, handler->activity_name),
+            TASK_TYPE_ARC_APP, ArcActionToString(handler->action)),
         name,
         GURL(""),                                        // TODO: get the icon
         false,                                           // is_default,
@@ -191,8 +212,10 @@
     url_with_type->mime_type = mime_types[i];
     urls.push_back(std::move(url_with_type));
   }
-  arc_intent_helper->HandleUrlList(std::move(urls), task.app_id,
-                                   StringToArcAction(task.action_id));
+
+  arc_intent_helper->HandleUrlList(
+      std::move(urls), AppIdToActivityName(task.app_id)->package_name,
+      StringToArcAction(task.action_id));
   return true;
 }
 
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index 1d1349c..2e0445bd 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -43,6 +43,10 @@
 #include "base/mac/scoped_nsautorelease_pool.h"
 #endif
 
+#if defined(ENABLE_PEPPER_CDMS)
+#include "chrome/browser/media/pepper_cdm_test_helper.h"
+#endif
+
 using content::BrowserThread;
 using net::URLRequestMockHTTPJob;
 
@@ -317,32 +321,17 @@
 #if defined(ENABLE_PLUGINS)
 class PepperContentSettingsSpecialCasesTest : public ContentSettingsTest {
  protected:
-  static const char kExternalClearKeyMimeType[];
-
   // Registers any CDM plugins not registered by default.
   void SetUpCommandLine(base::CommandLine* command_line) override {
 #if defined(ENABLE_PEPPER_CDMS)
-    // Platform-specific filename relative to the chrome executable.
-#if defined(OS_WIN)
-    const char kLibraryName[] = "clearkeycdmadapter.dll";
-#else  // !defined(OS_WIN)
-#if defined(OS_MACOSX)
-    const char kLibraryName[] = "clearkeycdmadapter.plugin";
-#elif defined(OS_POSIX)
-    const char kLibraryName[] = "libclearkeycdmadapter.so";
-#endif  // defined(OS_MACOSX)
-#endif  // defined(OS_WIN)
-
     // Append the switch to register the External Clear Key CDM.
-    base::FilePath::StringType pepper_plugins = BuildPepperPluginRegistration(
-        kLibraryName, "Clear Key CDM", kExternalClearKeyMimeType);
+    base::FilePath::StringType pepper_plugins = BuildPepperCdmRegistration(
+        kClearKeyCdmAdapterFileName, kClearKeyCdmPepperMimeType);
 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     // The CDM must be registered when it is a component.
     pepper_plugins.append(FILE_PATH_LITERAL(","));
-    pepper_plugins.append(
-        BuildPepperPluginRegistration(kWidevineCdmAdapterFileName,
-                                      kWidevineCdmDisplayName,
-                                      kWidevineCdmPluginMimeType));
+    pepper_plugins.append(BuildPepperCdmRegistration(
+        kWidevineCdmAdapterFileName, kWidevineCdmPluginMimeType));
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
                                      pepper_plugins);
@@ -428,41 +417,8 @@
               tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_JAVASCRIPT));
     EXPECT_FALSE(tab_settings->IsContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS));
   }
-
- private:
-  // Builds the string to pass to kRegisterPepperPlugins for a single
-  // plugin using the provided parameters and a dummy version.
-  // Multiple results may be passed to kRegisterPepperPlugins, separated by ",".
-  base::FilePath::StringType BuildPepperPluginRegistration(
-      const char* library_name,
-      const char* display_name,
-      const char* mime_type) {
-    base::FilePath plugin_dir;
-    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
-
-    base::FilePath plugin_lib = plugin_dir.AppendASCII(library_name);
-    EXPECT_TRUE(base::PathExists(plugin_lib));
-
-    base::FilePath::StringType pepper_plugin = plugin_lib.value();
-    std::string string_to_append = "#";
-    string_to_append.append(display_name);
-    string_to_append.append("#A CDM#0.1.0.0;");
-    string_to_append.append(mime_type);
-
-#if defined(OS_WIN)
-    pepper_plugin.append(base::ASCIIToUTF16(string_to_append));
-#else
-    pepper_plugin.append(string_to_append);
-#endif
-
-    return pepper_plugin;
-  }
 };
 
-const char
-PepperContentSettingsSpecialCasesTest::kExternalClearKeyMimeType[] =
-    "application/x-ppapi-clearkey-cdm";
-
 class PepperContentSettingsSpecialCasesPluginsBlockedTest
     : public PepperContentSettingsSpecialCasesTest {
  public:
@@ -496,7 +452,7 @@
       ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS,
                                  CONTENT_SETTING_ALLOW);
 
-  RunLoadPepperPluginTest(kExternalClearKeyMimeType, true);
+  RunLoadPepperPluginTest(kClearKeyCdmPepperMimeType, true);
 }
 #endif  // defined(ENABLE_PEPPER_CDMS)
 
@@ -507,7 +463,7 @@
 // The plugin successfully loaded above is blocked.
 IN_PROC_BROWSER_TEST_F(PepperContentSettingsSpecialCasesPluginsBlockedTest,
                        Normal) {
-  RunLoadPepperPluginTest(kExternalClearKeyMimeType, false);
+  RunLoadPepperPluginTest(kClearKeyCdmPepperMimeType, false);
 }
 
 #if defined(WIDEVINE_CDM_AVAILABLE) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index ffcf367..4704227 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -23,21 +23,11 @@
 #include "base/android/build_info.h"
 #endif
 
-#include "widevine_cdm_version.h"  //  In SHARED_INTERMEDIATE_DIR.
-
 #if defined(ENABLE_PEPPER_CDMS)
-// Platform-specific filename relative to the chrome executable.
-const char kClearKeyCdmAdapterFileName[] =
-#if defined(OS_MACOSX)
-    "clearkeycdmadapter.plugin";
-#elif defined(OS_WIN)
-    "clearkeycdmadapter.dll";
-#elif defined(OS_POSIX)
-    "libclearkeycdmadapter.so";
+#include "chrome/browser/media/pepper_cdm_test_helper.h"
 #endif
 
-const char kClearKeyCdmPluginMimeType[] = "application/x-ppapi-clearkey-cdm";
-#endif  // defined(ENABLE_PEPPER_CDMS)
+#include "widevine_cdm_version.h"  //  In SHARED_INTERMEDIATE_DIR.
 
 // Available key systems.
 const char kClearKeyKeySystem[] = "org.w3.clearkey";
@@ -108,7 +98,7 @@
 // Base class for encrypted media tests.
 class EncryptedMediaTestBase : public MediaBrowserTest {
  public:
-  EncryptedMediaTestBase() : is_pepper_cdm_registered_(false) {}
+  EncryptedMediaTestBase() {}
 
   bool IsExternalClearKey(const std::string& key_system) {
     if (key_system == kExternalClearKeyKeySystem)
@@ -261,11 +251,13 @@
 
 #if defined(ENABLE_PEPPER_CDMS)
     if (IsExternalClearKey(key_system)) {
-      RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName, key_system);
+      RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName,
+                        GetPepperType(key_system));
     }
 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
     else if (IsWidevine(key_system)) {  // NOLINT
-      RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName, key_system);
+      RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName,
+                        GetPepperType(key_system));
     }
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
 #endif  // defined(ENABLE_PEPPER_CDMS)
@@ -273,33 +265,10 @@
 
  private:
 #if defined(ENABLE_PEPPER_CDMS)
-  void RegisterPepperCdm(base::CommandLine* command_line,
-                         const std::string& adapter_name,
-                         const std::string& key_system) {
-    DCHECK(!is_pepper_cdm_registered_)
-        << "RegisterPepperCdm() can only be called once.";
-    is_pepper_cdm_registered_ = true;
-
-    // Append the switch to register the Clear Key CDM Adapter.
-    base::FilePath plugin_dir;
-    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
-    base::FilePath plugin_lib = plugin_dir.AppendASCII(adapter_name);
-    EXPECT_TRUE(base::PathExists(plugin_lib)) << plugin_lib.value();
-    base::FilePath::StringType pepper_plugin = plugin_lib.value();
-    pepper_plugin.append(FILE_PATH_LITERAL("#CDM#0.1.0.0;"));
-#if defined(OS_WIN)
-    pepper_plugin.append(base::ASCIIToUTF16(GetPepperType(key_system)));
-#else
-    pepper_plugin.append(GetPepperType(key_system));
-#endif
-    command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
-                                     pepper_plugin);
-  }
-
   // Adapted from key_systems.cc.
   std::string GetPepperType(const std::string& key_system) {
     if (IsExternalClearKey(key_system))
-      return kClearKeyCdmPluginMimeType;
+      return kClearKeyCdmPepperMimeType;
 #if defined(WIDEVINE_CDM_AVAILABLE)
     if (IsWidevine(key_system))
       return kWidevineCdmPluginMimeType;
@@ -309,8 +278,6 @@
     return "";
   }
 #endif  // defined(ENABLE_PEPPER_CDMS)
-
-  bool is_pepper_cdm_registered_;
 };
 
 #if defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
index d59b992c..974c341d 100644
--- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -27,12 +27,16 @@
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "url/gurl.h"
 
-#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
+#if defined(ENABLE_PEPPER_CDMS)
+#include "chrome/browser/media/pepper_cdm_test_helper.h"
+#endif
 
 #if defined(OS_ANDROID)
 #error This file needs to be updated to run on Android.
 #endif
 
+#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
+
 namespace chrome {
 
 namespace {
@@ -83,8 +87,8 @@
 // Expectations for Widevine.
 // Note: Widevine is not available on platforms using components because
 // RegisterPepperCdm() cannot set the codecs.
-// TODO(ddorwin): Enable these tests after we have the ability to use the CUS
-// in these tests. See http://crbug.com/356833.
+// TODO(xhwang): Enable these tests after we have the ability to use the
+// manifest in these tests. See http://crbug.com/586634
 #if defined(WIDEVINE_CDM_AVAILABLE) && !defined(WIDEVINE_CDM_IS_COMPONENT)
 #define EXPECT_WV_SUCCESS EXPECT_SUCCESS
 #define EXPECT_WV_PROPRIETARY EXPECT_PROPRIETARY
@@ -100,7 +104,7 @@
 
 class EncryptedMediaSupportedTypesTest : public InProcessBrowserTest {
  protected:
-  EncryptedMediaSupportedTypesTest() : is_pepper_cdm_registered_(false) {
+  EncryptedMediaSupportedTypesTest() {
     audio_webm_codecs_.push_back("opus");
     audio_webm_codecs_.push_back("vorbis");
 
@@ -147,32 +151,6 @@
   }
   const CodecVector& invalid_codecs() const { return invalid_codecs_; }
 
-  // Update the command line to load |adapter_name| for
-  // |pepper_type_for_key_system|.
-  void RegisterPepperCdm(base::CommandLine* command_line,
-                         const std::string& adapter_name,
-                         const std::string& pepper_type_for_key_system,
-                         bool expect_adapter_exists = true) {
-    DCHECK(!is_pepper_cdm_registered_)
-        << "RegisterPepperCdm() can only be called once.";
-    is_pepper_cdm_registered_ = true;
-
-    // Append the switch to register the appropriate adapter.
-    base::FilePath plugin_dir;
-    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
-    base::FilePath plugin_lib = plugin_dir.AppendASCII(adapter_name);
-    EXPECT_EQ(expect_adapter_exists, base::PathExists(plugin_lib));
-    base::FilePath::StringType pepper_plugin = plugin_lib.value();
-    pepper_plugin.append(FILE_PATH_LITERAL("#CDM#0.1.0.0;"));
-#if defined(OS_WIN)
-    pepper_plugin.append(base::ASCIIToUTF16(pepper_type_for_key_system));
-#else
-    pepper_plugin.append(pepper_type_for_key_system);
-#endif
-    command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
-                                     pepper_plugin);
-  }
-
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
 
@@ -266,8 +244,6 @@
   CodecVector video_mp4_codecs_;
   CodecVector video_mp4_hi10p_codecs_;
   CodecVector invalid_codecs_;
-
-  bool is_pepper_cdm_registered_;
 };
 
 // For ClearKey, nothing additional is required.
@@ -282,19 +258,8 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-
-    // Platform-specific filename relative to the chrome executable.
-    const char adapter_file_name[] =
-#if defined(OS_MACOSX)
-        "clearkeycdmadapter.plugin";
-#elif defined(OS_WIN)
-        "clearkeycdmadapter.dll";
-#elif defined(OS_POSIX)
-        "libclearkeycdmadapter.so";
-#endif
-
-    const std::string pepper_name("application/x-ppapi-clearkey-cdm");
-    RegisterPepperCdm(command_line, adapter_file_name, pepper_name);
+    RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName,
+                      kClearKeyCdmPepperMimeType);
   }
 #endif  // defined(ENABLE_PEPPER_CDMS)
 };
@@ -313,10 +278,8 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-    RegisterPepperCdm(command_line,
-                      "clearkeycdmadapterwrongname.dll",
-                      "application/x-ppapi-clearkey-cdm",
-                      false);
+    RegisterPepperCdm(command_line, "clearkeycdmadapterwrongname.dll",
+                      kClearKeyCdmPepperMimeType, false);
   }
 };
 
@@ -326,10 +289,8 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line);
-    RegisterPepperCdm(command_line,
-                      "widevinecdmadapterwrongname.dll",
-                      "application/x-ppapi-widevine-cdm",
-                      false);
+    RegisterPepperCdm(command_line, "widevinecdmadapterwrongname.dll",
+                      "application/x-ppapi-widevine-cdm", false);
   }
 };
 #endif  // defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/browser/media/pepper_cdm_test_helper.cc b/chrome/browser/media/pepper_cdm_test_helper.cc
new file mode 100644
index 0000000..0fd101c
--- /dev/null
+++ b/chrome/browser/media/pepper_cdm_test_helper.cc
@@ -0,0 +1,58 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media/pepper_cdm_test_helper.h"
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/content_switches.h"
+
+#include "widevine_cdm_version.h"  //  In SHARED_INTERMEDIATE_DIR.
+
+const char kClearKeyCdmAdapterFileName[] =
+#if defined(OS_MACOSX)
+    "clearkeycdmadapter.plugin";
+#elif defined(OS_WIN)
+    "clearkeycdmadapter.dll";
+#elif defined(OS_POSIX)
+    "libclearkeycdmadapter.so";
+#endif
+
+const char kClearKeyCdmPepperMimeType[] = "application/x-ppapi-clearkey-cdm";
+
+base::FilePath::StringType BuildPepperCdmRegistration(
+    const std::string& adapter_file_name,
+    const std::string& mime_type,
+    bool expect_adapter_exists) {
+  base::FilePath adapter_path;
+  PathService::Get(base::DIR_MODULE, &adapter_path);
+  adapter_path = adapter_path.AppendASCII(adapter_file_name);
+  DCHECK_EQ(expect_adapter_exists, base::PathExists(adapter_path));
+
+  base::FilePath::StringType pepper_cdm_registration = adapter_path.value();
+  pepper_cdm_registration.append(FILE_PATH_LITERAL("#CDM#0.1.0.0;"));
+
+#if defined(OS_WIN)
+  pepper_cdm_registration.append(base::ASCIIToUTF16(mime_type));
+#else
+  pepper_cdm_registration.append(mime_type);
+#endif
+
+  return pepper_cdm_registration;
+}
+
+void RegisterPepperCdm(base::CommandLine* command_line,
+                       const std::string& adapter_file_name,
+                       const std::string& mime_type,
+                       bool expect_adapter_exists) {
+  base::FilePath::StringType pepper_cdm_registration =
+      BuildPepperCdmRegistration(adapter_file_name, mime_type,
+                                 expect_adapter_exists);
+
+  // Append the switch to register the CDM Adapter.
+  command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
+                                   pepper_cdm_registration);
+}
diff --git a/chrome/browser/media/pepper_cdm_test_helper.h b/chrome/browser/media/pepper_cdm_test_helper.h
new file mode 100644
index 0000000..cfff76f
--- /dev/null
+++ b/chrome/browser/media/pepper_cdm_test_helper.h
@@ -0,0 +1,37 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MEDIA_PEPPER_CDM_TEST_HELPER_H_
+#define CHROME_BROWSER_MEDIA_PEPPER_CDM_TEST_HELPER_H_
+
+#include <string>
+
+#include "base/files/file_path.h"
+
+namespace base {
+class CommandLine;
+}
+
+// Platform-specific filename relative to kClearKeyCdmBaseDirectory.
+extern const char kClearKeyCdmAdapterFileName[];
+
+// Pepper type for Clear Key CDM.
+extern const char kClearKeyCdmPepperMimeType[];
+
+// Builds the string to pass to kRegisterPepperPlugins for a single
+// CDM using the provided parameters and a dummy version.
+// Multiple results may be passed to kRegisterPepperPlugins, separated by ",".
+// The CDM adapter should be located in DIR_MODULE.
+base::FilePath::StringType BuildPepperCdmRegistration(
+    const std::string& adapter_file_name,
+    const std::string& mime_type,
+    bool expect_adapter_exists = true);
+
+// Registers pepper CDM in |command_line|.
+void RegisterPepperCdm(base::CommandLine* command_line,
+                       const std::string& adapter_file_name,
+                       const std::string& mime_type,
+                       bool expect_adapter_exists = true);
+
+#endif  // CHROME_BROWSER_MEDIA_PEPPER_CDM_TEST_HELPER_H_
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html
index 3f42a73..9a7294f 100644
--- a/chrome/browser/resources/md_history/app.html
+++ b/chrome/browser/resources/md_history/app.html
@@ -38,14 +38,20 @@
         background: var(--md-toolbar-color);
       }
     </style>
-    <history-toolbar id="toolbar"></history-toolbar>
+    <history-toolbar id="toolbar" searching="[[queryState_.querying]]"
+        search-term="{{queryState_.searchTerm}}"
+        query-start-time="[[queryState_.queryStartTime]]"
+        query-end-time="[[queryState_.queryEndTime]]">
+    </history-toolbar>
 
     <div id="main-container">
       <history-side-bar id="history-side-bar" selected-page="{{selectedPage}}">
       </history-side-bar>
       <iron-pages id="content" attr-for-selected="id"
           selected="{{selectedPage}}">
-        <history-list id="history-list"></history-list>
+        <history-list id="history-list" querying="[[queryState_.querying]]"
+            searched-term="{{queryState_.info.term}}">
+        </history-list>
         <history-synced-device-manager id="history-synced-device-manager">
         </history-synced-device-manager>
       </iron-pages>
diff --git a/chrome/browser/resources/md_history/app.js b/chrome/browser/resources/md_history/app.js
index 98a5f64..d58fcfd 100644
--- a/chrome/browser/resources/md_history/app.js
+++ b/chrome/browser/resources/md_history/app.js
@@ -2,6 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+/**
+ * @typedef {{querying: boolean,
+ *            searchTerm: string,
+ *            results: ?Array<!HistoryEntry>,
+ *            info: ?HistoryQuery}}
+ */
+var QueryState;
+
 Polymer({
   is: 'history-app',
 
@@ -10,15 +18,34 @@
     selectedPage: {
       type: String,
       value: 'history-list'
-    }
+    },
+
+    /** @type {!QueryState} */
+    queryState_: {
+      type: Object,
+      value: function() {
+        return {
+          // A query is initiated by page load.
+          querying: true,
+          searchTerm: '',
+          results: null,
+          info: null,
+        };
+      }
+    },
   },
 
+  observers: [
+    'searchTermChanged_(queryState_.searchTerm)',
+  ],
+
   // TODO(calamity): Replace these event listeners with data bound properties.
   listeners: {
     'history-checkbox-select': 'checkboxSelected',
     'unselect-all': 'unselectAll',
     'delete-selected': 'deleteSelected',
-    'search-changed': 'searchChanged',
+    'search-domain': 'searchDomain_',
+    'load-more-history': 'loadMoreHistory_',
   },
 
   ready: function() {
@@ -60,16 +87,8 @@
     /** @type {HistoryListElement} */(this.$['history-list']).deleteSelected();
   },
 
-  /**
-   * When the search is changed refresh the results from the backend.
-   * Ensures that the search bar is updated with the new search term.
-   * @param {{detail: {search: string}}} e
-   */
-  searchChanged: function(e) {
-    this.$.toolbar.setSearchTerm(e.detail.search);
-    /** @type {HistoryListElement} */(this.$['history-list']).setLoading();
-    /** @type {HistoryToolbarElement} */(this.$.toolbar).searching = true;
-    chrome.send('queryHistory', [e.detail.search, 0, 0, 0, RESULTS_PER_PAGE]);
+  loadMoreHistory_: function() {
+    this.queryHistory(true);
   },
 
   /**
@@ -78,15 +97,39 @@
    * @param {!Array<HistoryEntry>} results A list of results.
    */
   historyResult: function(info, results) {
+    this.set('queryState_.querying', false);
+    this.set('queryState_.results', results);
+    this.set('queryState_.info', info);
+
     var list = /** @type {HistoryListElement} */(this.$['history-list']);
-    list.addNewResults(results, info.term);
-    /** @type {HistoryToolbarElement} */(this.$.toolbar).searching = false;
+    list.addNewResults(results);
     if (info.finished)
       list.disableResultLoading();
+  },
 
-    var toolbar = /** @type {HistoryToolbarElement} */(this.$.toolbar);
-    toolbar.queryStartTime = info.queryStartTime;
-    toolbar.queryEndTime = info.queryEndTime;
+  /**
+   * Fired when the user presses 'More from this site'.
+   * @param {{detail: {domain: string}}} e
+   */
+  searchDomain_: function(e) {
+    this.$.toolbar.setSearchTerm(e.detail.domain);
+  },
+
+  searchTermChanged_: function() {
+    this.queryHistory(false);
+  },
+
+  queryHistory: function(incremental) {
+    var lastVisitTime = 0;
+    if (incremental) {
+      var lastVisit = this.queryState_.results.slice(-1)[0];
+      lastVisitTime = lastVisit ? lastVisit.time : 0;
+    }
+
+    this.set('queryState_.querying', true);
+    chrome.send(
+        'queryHistory',
+        [this.queryState_.searchTerm, 0, 0, lastVisitTime, RESULTS_PER_PAGE]);
   },
 
   /**
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html
index 9dfd9b7..e68c8d9 100644
--- a/chrome/browser/resources/md_history/history_list.html
+++ b/chrome/browser/resources/md_history/history_list.html
@@ -34,7 +34,7 @@
     </style>
     <div id="no-results" class="centered-message"
         hidden$="{{hasResults(historyData.length)}}">
-      {{noResultsMessage_(searchTerm, loading_)}}
+      {{noResultsMessage_(searchedTerm, querying)}}
     </div>
     <iron-list items="{{historyData}}" as="item" id="infinite-list"
         hidden$="{{!hasResults(historyData.length)}}">
@@ -45,7 +45,7 @@
             is-card-start="[[isCardStart_(item, index, historyData.length)]]"
             is-card-end="[[isCardEnd_(item, index, historyData.length)]]"
             has-time-gap="[[needsTimeGap_(item, index, historyData.length)]]"
-            search-term="[[searchTerm]]"
+            search-term="[[searchedTerm]]"
             number-of-items="[[historyData.length]]">
         </history-item>
       </template>
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js
index edf88b19..bce530e 100644
--- a/chrome/browser/resources/md_history/history_list.js
+++ b/chrome/browser/resources/md_history/history_list.js
@@ -6,31 +6,22 @@
   is: 'history-list',
 
   properties: {
-    // An array of history entries in reverse chronological order.
-    historyData: {
-      type: Array
-    },
-
-    // The time of access of the last history item in historyData.
-    lastVisitedTime: {
-      type: Number,
-      value: 0
-    },
-
-    searchTerm: {
+    // The search term for the current query. Set when the query returns.
+    searchedTerm: {
       type: String,
-      value: ''
+      value: '',
     },
 
-    // True if there is a pending request to the backend.
-    loading_: {
-      type: Boolean,
-      value: true
-    },
+    lastSearchedTerm_: String,
+
+    querying: Boolean,
+
+    // An array of history entries in reverse chronological order.
+    historyData: Array,
 
     resultLoadingDisabled_: {
       type: Boolean,
-      value: false
+      value: false,
     },
   },
 
@@ -49,13 +40,6 @@
   },
 
   /**
-   * Mark the page as currently loading new data from the back-end.
-   */
-  setLoading: function() {
-    this.loading_ = true;
-  },
-
-  /**
    * Opens the overflow menu unless the menu is already open and the same button
    * is pressed.
    * @param {{detail: {item: !HistoryEntry, target: !HTMLElement}}} e
@@ -70,7 +54,7 @@
   /** @private */
   onMoreFromSiteTap_: function() {
     var menu = /** @type {CrSharedMenuElement} */(this.$.sharedMenu);
-    this.fire('search-changed', {search: menu.itemData.domain});
+    this.fire('search-domain', {domain: menu.itemData.domain});
     menu.closeMenu();
   },
 
@@ -100,18 +84,16 @@
    * Adds the newly updated history results into historyData. Adds new fields
    * for each result.
    * @param {!Array<!HistoryEntry>} historyResults The new history results.
-   * @param {string} searchTerm Search query used to find these results.
    */
-  addNewResults: function(historyResults, searchTerm) {
-    this.loading_ = false;
+  addNewResults: function(historyResults) {
     /** @type {IronScrollThresholdElement} */(this.$['scroll-threshold'])
         .clearTriggers();
 
-    if (this.searchTerm != searchTerm) {
+    if (this.lastSearchedTerm_ != this.searchedTerm) {
       this.resultLoadingDisabled_ = false;
       if (this.historyData)
         this.splice('historyData', 0, this.historyData.length);
-      this.searchTerm = searchTerm;
+      this.lastSearchedTerm_ = this.searchedTerm;
     }
 
     if (historyResults.length == 0)
@@ -127,7 +109,8 @@
       // Sets the default values for these fields to prevent undefined types.
       results[i].selected = false;
       results[i].readableTimestamp =
-          searchTerm == '' ? results[i].dateTimeOfDay : results[i].dateShort;
+          this.searchedTerm == '' ?
+              results[i].dateTimeOfDay : results[i].dateShort;
 
       if (results[i].dateRelativeDay != currentDate) {
         currentDate = results[i].dateRelativeDay;
@@ -144,8 +127,6 @@
       // initialized correctly.
       this.set('historyData', results);
     }
-
-    this.lastVisitedTime = this.historyData[this.historyData.length - 1].time;
   },
 
   /**
@@ -220,12 +201,10 @@
    * @private
    */
   loadMoreData_: function() {
-    if (this.resultLoadingDisabled_ || this.loading_)
+    if (this.resultLoadingDisabled_ || this.querying)
       return;
 
-    this.loading_ = true;
-    chrome.send('queryHistory',
-        [this.searchTerm, 0, 0, this.lastVisitedTime, RESULTS_PER_PAGE]);
+    this.fire('load-more-history');
   },
 
   /**
@@ -244,7 +223,7 @@
     var currentItem = this.historyData[index];
     var nextItem = this.historyData[index + 1];
 
-    if (this.searchTerm)
+    if (this.searchedTerm)
       return currentItem.dateShort != nextItem.dateShort;
 
     return currentItem.time - nextItem.time > BROWSING_GAP_TIME &&
@@ -255,10 +234,10 @@
     return historyDataLength > 0;
   },
 
-  noResultsMessage_: function(searchTerm, isLoading) {
+  noResultsMessage_: function(searchedTerm, isLoading) {
     if (isLoading)
       return '';
-    var messageId = searchTerm !== '' ? 'noSearchResults' : 'noResults';
+    var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults';
     return loadTimeData.getString(messageId);
   },
 
diff --git a/chrome/browser/resources/md_history/history_toolbar.js b/chrome/browser/resources/md_history/history_toolbar.js
index d534186..356866d0 100644
--- a/chrome/browser/resources/md_history/history_toolbar.js
+++ b/chrome/browser/resources/md_history/history_toolbar.js
@@ -40,7 +40,7 @@
     // as the user types.
     searchTerm: {
       type: String,
-      value: ''
+      notify: true,
     },
 
     // True if waiting on the search backend.
@@ -86,6 +86,7 @@
   setSearchTerm: function(search) {
     if (this.searchTerm == search)
       return;
+
     this.searchTerm = search;
     var searchField = /** @type {SearchField} */(this.$['search-input']);
     searchField.showAndFocus().then(function(showing) {
@@ -97,10 +98,8 @@
    * If the search term has changed reload for the new search.
    */
   onSearch: function(searchTerm) {
-    if (searchTerm != this.searchTerm) {
+    if (searchTerm != this.searchTerm)
       this.searchTerm = searchTerm;
-      this.fire('search-changed', {search: searchTerm});
-    }
   },
 
   attached: function() {
diff --git a/chrome/browser/ui/app_list/app_list_service_disabled.cc b/chrome/browser/ui/app_list/app_list_service_disabled.cc
index a54dd7e9..56c87a7 100644
--- a/chrome/browser/ui/app_list/app_list_service_disabled.cc
+++ b/chrome/browser/ui/app_list/app_list_service_disabled.cc
@@ -5,8 +5,30 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/singleton.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
 
+#if defined(TOOLKIT_VIEWS)
+#include "base/command_line.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_attributes_entry.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_navigator_params.h"
+#include "chrome/browser/ui/user_manager.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
+#include "components/signin/core/common/profile_management_switches.h"
+#include "ui/base/page_transition_types.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include "chrome/browser/ui/app_list/app_list_service_disabled_mac.h"
+#endif
+
 namespace {
 
 class AppListServiceDisabled : public AppListService {
@@ -57,6 +79,41 @@
   DISALLOW_COPY_AND_ASSIGN(AppListServiceDisabled);
 };
 
+#if defined(TOOLKIT_VIEWS)
+bool IsProfileSignedOut(Profile* profile) {
+  // The signed out status only makes sense at the moment in the context of the
+  // --new-profile-management flag.
+  if (!switches::IsNewProfileManagement())
+    return false;
+  ProfileAttributesEntry* entry;
+  bool has_entry =
+      g_browser_process->profile_manager()
+          ->GetProfileAttributesStorage()
+          .GetProfileAttributesWithPath(profile->GetPath(), &entry);
+  return has_entry && entry->IsSigninRequired();
+}
+
+// Opens a Chrome browser tab at chrome://apps.
+void OpenAppsPage(Profile* fallback_profile) {
+  Browser* browser = chrome::FindLastActive();
+  Profile* app_list_profile = browser ? browser->profile() : fallback_profile;
+  app_list_profile = app_list_profile->GetOriginalProfile();
+
+  if (IsProfileSignedOut(app_list_profile) ||
+      app_list_profile->IsSystemProfile() ||
+      app_list_profile->IsGuestSession()) {
+    UserManager::Show(base::FilePath(), profiles::USER_MANAGER_NO_TUTORIAL,
+                      profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
+    return;
+  }
+
+  chrome::NavigateParams params(app_list_profile,
+                                GURL(chrome::kChromeUIAppsURL),
+                                ui::PAGE_TRANSITION_AUTO_BOOKMARK);
+  chrome::Navigate(&params);
+}
+#endif
+
 }  // namespace
 
 // static
@@ -66,7 +123,11 @@
 
 // static
 void AppListService::InitAll(Profile* initial_profile,
-                             const base::FilePath& profile_path) {}
+                             const base::FilePath& profile_path) {
+#if defined(OS_MACOSX)
+  InitAppsPageLegacyShimHandler(&OpenAppsPage);
+#endif
+}
 
 // static
 void AppListService::RegisterPrefs(PrefRegistrySimple* registry) {}
@@ -75,5 +136,13 @@
 bool AppListService::HandleLaunchCommandLine(
     const base::CommandLine& command_line,
     Profile* launch_profile) {
+#if defined(TOOLKIT_VIEWS)
+  if (!command_line.HasSwitch(switches::kShowAppList))
+    return false;
+
+  OpenAppsPage(launch_profile);
+  return true;
+#else
   return false;
+#endif
 }
diff --git a/chrome/browser/ui/app_list/app_list_service_disabled_mac.h b/chrome/browser/ui/app_list/app_list_service_disabled_mac.h
new file mode 100644
index 0000000..9a3fdea
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_service_disabled_mac.h
@@ -0,0 +1,15 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_DISABLED_MAC_H_
+#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_DISABLED_MAC_H_
+
+class Profile;
+
+// Register the handler to accept connections from the old app_list shim, and
+// perform |action|; e.g. to open chrome://apps rather than the deleted App
+// Launcher UI.
+void InitAppsPageLegacyShimHandler(void (*action)(Profile*));
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_DISABLED_MAC_H_
diff --git a/chrome/browser/ui/app_list/app_list_service_disabled_mac.mm b/chrome/browser/ui/app_list/app_list_service_disabled_mac.mm
new file mode 100644
index 0000000..6589eb5
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_service_disabled_mac.mm
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/app_list/app_list_service_disabled_mac.h"
+
+#include "base/compiler_specific.h"
+#import "base/mac/foundation_util.h"
+#import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/apps/app_shim/app_shim_handler_mac.h"
+#include "chrome/common/mac/app_mode_common.h"
+
+namespace {
+
+// Stub handler for the old app_list shim that opens chrome://apps when a copy
+// of the App Launcher .app bundle created with Chrome < m52 tries to connect.
+class AppsPageShimHandler : public apps::AppShimHandler {
+ public:
+  explicit AppsPageShimHandler(void (*action)(Profile*)) : action_(action) {}
+
+ private:
+  // AppShimHandler:
+  void OnShimLaunch(apps::AppShimHandler::Host* host,
+                    apps::AppShimLaunchType launch_type,
+                    const std::vector<base::FilePath>& files) override {
+    AppController* controller =
+        base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
+    action_([controller lastProfile]);
+
+    // Always close the shim process immediately.
+    host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_DUPLICATE_HOST);
+  }
+  void OnShimClose(apps::AppShimHandler::Host* host) override {}
+  void OnShimFocus(apps::AppShimHandler::Host* host,
+                   apps::AppShimFocusType focus_type,
+                   const std::vector<base::FilePath>& files) override {}
+  void OnShimSetHidden(apps::AppShimHandler::Host* host, bool hidden) override {
+  }
+  void OnShimQuit(apps::AppShimHandler::Host* host) override {}
+
+  void (*action_)(Profile*);
+
+  DISALLOW_COPY_AND_ASSIGN(AppsPageShimHandler);
+};
+
+}  // namespace
+
+void InitAppsPageLegacyShimHandler(void (*action)(Profile*)) {
+  static AppsPageShimHandler* handler = nullptr;
+  if (!handler) {
+    handler = new AppsPageShimHandler(action);
+    apps::AppShimHandler::RegisterHandler(app_mode::kAppListModeId, handler);
+  }
+}
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index f9e54f0d..0ff86c0 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -1576,7 +1576,8 @@
 
 // Simiulate browser window width change and ensure that the bookmark buttons
 // that should be visible are visible.
-TEST_F(BookmarkBarControllerTest, LastBookmarkResizeBehavior) {
+// Appears to fail on Mac 10.11 bot on the waterfall; http://crbug.com/612640.
+TEST_F(BookmarkBarControllerTest, DISABLED_LastBookmarkResizeBehavior) {
   // Hide the apps shortcut.
   profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowAppsShortcutInBookmarkBar, false);
diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
index 93b8160..ccf799c2 100644
--- a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
+++ b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
@@ -145,11 +145,6 @@
     if (!args->GetString(1, &language))
       return;
     translate_prefs->UnblockLanguage(language);
-  } else if (pref_name == "language_blacklist") {
-    std::string language;
-    if (!args->GetString(1, &language))
-      return;
-    translate_prefs->RemoveLanguageFromLegacyBlacklist(language);
   } else if (pref_name == "site_blacklist") {
     std::string site;
     if (!args->GetString(1, &site))
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index b4d858c..e6382cff 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2683,7 +2683,10 @@
     ],
     # Used when the app list is disabled.
     'chrome_browser_ui_non_app_list_sources': [
+      'browser/ui/app_list/app_list_service.h',
       'browser/ui/app_list/app_list_service_disabled.cc',
+      'browser/ui/app_list/app_list_service_disabled_mac.h',
+      'browser/ui/app_list/app_list_service_disabled_mac.mm',
     ],
     'chrome_browser_ui_extensions_sources': [
       'browser/ui/extensions/accelerator_priority.cc',
diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi
index 985f40d..38755ae 100644
--- a/chrome/chrome_dll_bundle.gypi
+++ b/chrome/chrome_dll_bundle.gypi
@@ -132,9 +132,9 @@
       ],
     },
     {
-      # This file is used by the component installer.
-      # It is not a complete plugin on its own.
-      'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Internet Plug-Ins/',
+      # The adapter is not a complete library on its own. It needs the Widevine
+      # CDM to work.
+      'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Libraries/',
       'files': [],
       'conditions': [
         ['branding == "Chrome"', {
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index c69f3971..658e79ee 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2671,6 +2671,10 @@
           'sources': [ '<@(chrome_browser_tests_supervised_user_sources)' ],
         }],
         ['enable_pepper_cdms==1', {
+          'sources' : [
+            'browser/media/pepper_cdm_test_helper.cc',
+            'browser/media/pepper_cdm_test_helper.h',
+          ],
           'dependencies': [
             # Runtime dependencies.
             '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index cde69313..f4e119db 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -375,7 +375,7 @@
     // In the component case, this is the source adapter. Otherwise, it is the
     // actual Pepper module that gets loaded.
     case chrome::FILE_WIDEVINE_CDM_ADAPTER:
-      if (!GetInternalPluginsDirectory(&cur))
+      if (!GetComponentDirectory(&cur))
         return false;
       cur = cur.AppendASCII(kWidevineCdmAdapterFileName);
       break;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index a1a4f74..3bbf49e 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1351,6 +1351,11 @@
               "//chrome")
     }
     if (enable_pepper_cdms) {
+      sources += [
+        "../browser/media/pepper_cdm_test_helper.cc",
+        "../browser/media/pepper_cdm_test_helper.h",
+      ]
+
       # Runtime dependencies.
       data_deps += [
         "//media/cdm/ppapi:clearkeycdmadapter",
diff --git a/chrome/test/data/webui/md_history/history_item_test.js b/chrome/test/data/webui/md_history/history_item_test.js
index 8b69fac..a620f4e 100644
--- a/chrome/test/data/webui/md_history/history_item_test.js
+++ b/chrome/test/data/webui/md_history/history_item_test.js
@@ -22,13 +22,13 @@
 
         SEARCH_HISTORY_RESULTS = [
           createSearchEntry('2016-03-16', "http://www.google.com"),
-          createSearchEntry('2016-03-14', "http://calendar.google.com"),
-          createSearchEntry('2016-03-14', "http://mail.google.com")
+          createSearchEntry('2016-03-14 11:00', "http://calendar.google.com"),
+          createSearchEntry('2016-03-14 10:00', "http://mail.google.com")
         ];
       });
 
       test('basic separator insertion', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
         flush(function() {
           // Check that the correct number of time gaps are inserted.
           var items =
@@ -46,7 +46,8 @@
       });
 
       test('separator insertion for search', function(done) {
-        element.addNewResults(SEARCH_HISTORY_RESULTS, 'search');
+        element.addNewResults(SEARCH_HISTORY_RESULTS);
+        element.searchedTerm = 'search';
         flush(function() {
           var items =
               Polymer.dom(element.root).querySelectorAll('history-item');
@@ -60,7 +61,7 @@
       });
 
       test('separator insertion after deletion', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
         flush(function() {
           var items =
               Polymer.dom(element.root).querySelectorAll('history-item');
@@ -81,6 +82,7 @@
 
       teardown(function() {
         element.historyData = [];
+        element.searchedTerm = '';
       });
     });
   }
diff --git a/chrome/test/data/webui/md_history/history_list_test.js b/chrome/test/data/webui/md_history/history_list_test.js
index 8b35227..53eac5d 100644
--- a/chrome/test/data/webui/md_history/history_list_test.js
+++ b/chrome/test/data/webui/md_history/history_list_test.js
@@ -30,7 +30,7 @@
       });
 
       test('cancelling selection of multiple items', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
         flush(function() {
           var items = Polymer.dom(element.root)
               .querySelectorAll('history-item');
@@ -62,7 +62,7 @@
       });
 
       test('setting first and last items', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
 
         flush(function() {
           var items =
@@ -80,8 +80,8 @@
       });
 
       test('updating history results', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
-        element.addNewResults(ADDITIONAL_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
+        element.addNewResults(ADDITIONAL_RESULTS);
 
         flush(function() {
           var items =
@@ -100,8 +100,8 @@
       });
 
       test('deleting multiple items from view', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
-        element.addNewResults(ADDITIONAL_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
+        element.addNewResults(ADDITIONAL_RESULTS);
         flush(function() {
           items = Polymer.dom(element.root).querySelectorAll('history-item');
 
@@ -134,8 +134,8 @@
 
       test('search results display with correct item title', function(done) {
         element.addNewResults(
-            [createHistoryEntry('2016-03-15', 'https://www.google.com')],
-            'Google');
+            [createHistoryEntry('2016-03-15', 'https://www.google.com')]);
+        element.searchedTerm = 'Google';
 
         flush(function() {
           var item = element.$$('history-item');
@@ -154,13 +154,13 @@
       });
 
       test('correct display message when no history available', function(done) {
-        element.addNewResults([], '');
+        element.addNewResults([]);
 
         flush(function() {
           assertFalse(element.$['no-results'].hidden);
           assertTrue(element.$['infinite-list'].hidden);
 
-          element.addNewResults(TEST_HISTORY_RESULTS, '');
+          element.addNewResults(TEST_HISTORY_RESULTS);
 
           flush(function() {
             assertTrue(element.$['no-results'].hidden);
@@ -172,6 +172,7 @@
 
       teardown(function() {
         element.historyData = [];
+        element.searchedTerm = '';
         registerMessageCallback('removeVisits', this, undefined);
       });
     });
diff --git a/chrome/test/data/webui/md_history/history_supervised_user_test.js b/chrome/test/data/webui/md_history/history_supervised_user_test.js
index 05122e64..a7c23ae2 100644
--- a/chrome/test/data/webui/md_history/history_supervised_user_test.js
+++ b/chrome/test/data/webui/md_history/history_supervised_user_test.js
@@ -17,7 +17,7 @@
       });
 
       setup(function() {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
       });
 
       test('checkboxes disabled for supervised user', function(done) {
@@ -45,6 +45,7 @@
 
       teardown(function() {
         element.historyData = [];
+        element.searchedTerm = '';
       });
     });
   }
diff --git a/chrome/test/data/webui/md_history/history_toolbar_test.js b/chrome/test/data/webui/md_history/history_toolbar_test.js
index cb07582..b2c9cb02 100644
--- a/chrome/test/data/webui/md_history/history_toolbar_test.js
+++ b/chrome/test/data/webui/md_history/history_toolbar_test.js
@@ -17,7 +17,7 @@
       });
 
       test('selecting checkbox causes toolbar to change', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, '');
+        element.addNewResults(TEST_HISTORY_RESULTS);
 
         flush(function() {
           var item = element.$$('history-item');
@@ -53,7 +53,7 @@
 
       test('more from this site sends and sets correct data', function(done) {
         registerMessageCallback('queryHistory', this, function (info) {
-          assertEquals(info[0], 'example.com');
+          assertEquals('example.com', info[0]);
           flush(function() {
             assertEquals(toolbar.$$('#search-input').$$('#search-input').value,
                 'example.com');
@@ -67,6 +67,7 @@
 
       teardown(function() {
         element.historyData = [];
+        element.searchedTerm = '';
         registerMessageCallback('queryHistory', this, undefined);
         toolbar.count = 0;
       });
diff --git a/chromecast/browser/media/BUILD.gn b/chromecast/browser/media/BUILD.gn
index 401e9a2d..73c812f 100644
--- a/chromecast/browser/media/BUILD.gn
+++ b/chromecast/browser/media/BUILD.gn
@@ -32,7 +32,7 @@
   if (mojo_media_host == "browser") {
     public_deps = [
       "//media/mojo/interfaces",
-      "//media/mojo/services:application",
+      "//media/mojo/services",
       "//services/shell/public/cpp",
     ]
   }
diff --git a/components/offline_pages/offline_page_model.cc b/components/offline_pages/offline_page_model.cc
index 3472066e..e71da4d 100644
--- a/components/offline_pages/offline_page_model.cc
+++ b/components/offline_pages/offline_page_model.cc
@@ -104,6 +104,18 @@
   CHECK(base::CreateDirectory(archives_dir));
 }
 
+std::string AddHistogramSuffix(const ClientId& client_id,
+                               const char* histogram_name) {
+  if (client_id.name_space.empty()) {
+    NOTREACHED();
+    return histogram_name;
+  }
+  std::string adjusted_histogram_name(histogram_name);
+  adjusted_histogram_name += ".";
+  adjusted_histogram_name += client_id.name_space;
+  return adjusted_histogram_name;
+}
+
 }  // namespace
 
 // static
@@ -150,12 +162,18 @@
 
   // Skip saving the page that is not intended to be saved, like local file
   // page.
-  if (!CanSavePage(url)) {
-    InformSavePageDone(callback, SavePageResult::SKIPPED, kInvalidOfflineId);
+  if (url.is_valid() && !CanSavePage(url)) {
+    InformSavePageDone(callback, SavePageResult::SKIPPED, client_id,
+                       kInvalidOfflineId);
     return;
   }
 
-  DCHECK(archiver.get());
+  // The web contents is not available if archiver is not created and passed.
+  if (!archiver.get()) {
+    InformSavePageDone(callback, SavePageResult::CONTENT_UNAVAILABLE, client_id,
+                       kInvalidOfflineId);
+    return;
+  }
 
   int64_t offline_id = GenerateOfflineId();
 
@@ -182,17 +200,16 @@
   base::TimeDelta time_since_last_accessed =
       now - offline_page_item.last_access_time;
 
-  // The last access time was set to same as creation time when the page was
-  // created.
-  if (offline_page_item.creation_time == offline_page_item.last_access_time) {
-    UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.FirstOpenSinceCreated",
-                                time_since_last_accessed.InMinutes(), 1,
-                                kMaxOpenedPageHistogramBucket.InMinutes(), 50);
-  } else {
-    UMA_HISTOGRAM_CUSTOM_COUNTS("OfflinePages.OpenSinceLastOpen",
-                                time_since_last_accessed.InMinutes(), 1,
-                                kMaxOpenedPageHistogramBucket.InMinutes(), 50);
-  }
+  // When the access account is still zero, the page is opened for the first
+  // time since its creation.
+  UMA_HISTOGRAM_CUSTOM_COUNTS(
+      AddHistogramSuffix(
+          offline_page_item.client_id,
+          (offline_page_item.access_count == 0) ?
+              "OfflinePages.FirstOpenSinceCreated" :
+              "OfflinePages.OpenSinceLastOpen").c_str(),
+      time_since_last_accessed.InMinutes(), 1,
+      kMaxOpenedPageHistogramBucket.InMinutes(), 50);
 
   offline_page_item.last_access_time = now;
   offline_page_item.access_count++;
@@ -560,14 +577,14 @@
     // TODO(fgorski): We have created an archive for a wrong URL. It should be
     // deleted from here, once archiver has the right functionality.
     InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED,
-                       offline_id);
+                       client_id, offline_id);
     DeletePendingArchiver(archiver);
     return;
   }
 
   if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
     SavePageResult result = ToSavePageResult(archiver_result);
-    InformSavePageDone(callback, result, offline_id);
+    InformSavePageDone(callback, result, client_id, offline_id);
     DeletePendingArchiver(archiver);
     return;
   }
@@ -589,14 +606,18 @@
     offline_pages_[offline_page.offline_id] = offline_page;
     result = SavePageResult::SUCCESS;
     UMA_HISTOGRAM_TIMES(
-        "OfflinePages.SavePageTime",
+        AddHistogramSuffix(
+            offline_page.client_id, "OfflinePages.SavePageTime").c_str(),
         base::Time::Now() - offline_page.creation_time);
     UMA_HISTOGRAM_MEMORY_KB(
-        "OfflinePages.PageSize", offline_page.file_size / 1024);
+        AddHistogramSuffix(
+            offline_page.client_id, "OfflinePages.PageSize").c_str(),
+        offline_page.file_size / 1024);
   } else {
     result = SavePageResult::STORE_FAILURE;
   }
-  InformSavePageDone(callback, result, offline_page.offline_id);
+  InformSavePageDone(callback, result, offline_page.client_id,
+                     offline_page.offline_id);
   DeletePendingArchiver(archiver);
 
   FOR_EACH_OBSERVER(Observer, observers_, OfflinePageModelChanged(this));
@@ -652,9 +673,10 @@
 
 void OfflinePageModel::InformSavePageDone(const SavePageCallback& callback,
                                           SavePageResult result,
+                                          const ClientId& client_id,
                                           int64_t offline_id) {
   UMA_HISTOGRAM_ENUMERATION(
-      "OfflinePages.SavePageResult",
+      AddHistogramSuffix(client_id, "OfflinePages.SavePageResult").c_str(),
       static_cast<int>(result),
       static_cast<int>(SavePageResult::RESULT_COUNT));
   callback.Run(result, offline_id);
@@ -695,29 +717,36 @@
     if (iter == offline_pages_.end())
       continue;
     total_size += iter->second.file_size;
+    ClientId client_id = iter->second.client_id;
     UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "OfflinePages.PageLifetime",
+        AddHistogramSuffix(client_id, "OfflinePages.PageLifetime").c_str(),
         (now - iter->second.creation_time).InMinutes(),
         1,
         base::TimeDelta::FromDays(365).InMinutes(),
         100);
     UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "OfflinePages.DeletePage.TimeSinceLastOpen",
+        AddHistogramSuffix(
+            client_id, "OfflinePages.DeletePage.TimeSinceLastOpen").c_str(),
         (now - iter->second.last_access_time).InMinutes(),
         1,
         base::TimeDelta::FromDays(365).InMinutes(),
         100);
     UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "OfflinePages.DeletePage.LastOpenToCreated",
+        AddHistogramSuffix(
+            client_id, "OfflinePages.DeletePage.LastOpenToCreated").c_str(),
         (iter->second.last_access_time - iter->second.creation_time).
             InMinutes(),
         1,
         base::TimeDelta::FromDays(365).InMinutes(),
         100);
     UMA_HISTOGRAM_MEMORY_KB(
-        "OfflinePages.DeletePage.PageSize", iter->second.file_size / 1024);
+        AddHistogramSuffix(
+            client_id, "OfflinePages.DeletePage.PageSize").c_str(),
+        iter->second.file_size / 1024);
     UMA_HISTOGRAM_COUNTS(
-        "OfflinePages.DeletePage.AccessCount", iter->second.access_count);
+        AddHistogramSuffix(
+            client_id, "OfflinePages.DeletePage.AccessCount").c_str(),
+        iter->second.access_count);
     FOR_EACH_OBSERVER(
         Observer, observers_,
         OfflinePageDeleted(iter->second.offline_id, iter->second.client_id));
diff --git a/components/offline_pages/offline_page_model.h b/components/offline_pages/offline_page_model.h
index 297c229..925cff5 100644
--- a/components/offline_pages/offline_page_model.h
+++ b/components/offline_pages/offline_page_model.h
@@ -293,6 +293,7 @@
                             bool success);
   void InformSavePageDone(const SavePageCallback& callback,
                           SavePageResult result,
+                          const ClientId& client_id,
                           int64_t offline_id);
   void DeletePendingArchiver(OfflinePageArchiver* archiver);
 
diff --git a/components/safe_browsing_db/database_manager.cc b/components/safe_browsing_db/database_manager.cc
index 2013c865..712f703 100644
--- a/components/safe_browsing_db/database_manager.cc
+++ b/components/safe_browsing_db/database_manager.cc
@@ -119,7 +119,7 @@
 void SafeBrowsingDatabaseManager::HandleGetHashesWithApisResults(
     SafeBrowsingApiCheck* check,
     const std::vector<SBFullHashResult>& full_hash_results,
-    const base::TimeDelta& negative_cache_duration) {
+    const base::Time& negative_cache_expire) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(check);
 
diff --git a/components/safe_browsing_db/database_manager.h b/components/safe_browsing_db/database_manager.h
index f560ee3..e2ae292 100644
--- a/components/safe_browsing_db/database_manager.h
+++ b/components/safe_browsing_db/database_manager.h
@@ -224,7 +224,7 @@
   virtual void HandleGetHashesWithApisResults(
       SafeBrowsingApiCheck* check,
       const std::vector<SBFullHashResult>& full_hash_results,
-      const base::TimeDelta& negative_cache_duration);
+      const base::Time& negative_cache_expire);
 
   // Created and destroyed via StartOnIOThread/StopOnIOThread.
   V4GetHashProtocolManager* v4_get_hash_protocol_manager_;
diff --git a/components/safe_browsing_db/database_manager_unittest.cc b/components/safe_browsing_db/database_manager_unittest.cc
index db8fd9c..fd2da57 100644
--- a/components/safe_browsing_db/database_manager_unittest.cc
+++ b/components/safe_browsing_db/database_manager_unittest.cc
@@ -30,7 +30,7 @@
 void InvokeFullHashCallback(
     V4GetHashProtocolManager::FullHashCallback callback,
     const std::vector<SBFullHashResult>& full_hashes) {
-  callback.Run(full_hashes, base::TimeDelta::FromMinutes(0));
+  callback.Run(full_hashes, base::Time::UnixEpoch());
 }
 
 // A TestV4GetHashProtocolManager that returns fixed responses from the
diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
index 139dc38..7135f420 100644
--- a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
+++ b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
@@ -163,7 +163,7 @@
 bool V4GetHashProtocolManager::ParseHashResponse(
     const std::string& data,
     std::vector<SBFullHashResult>* full_hashes,
-    base::TimeDelta* negative_cache_duration) {
+    base::Time* negative_cache_expire) {
   FindFullHashesResponse response;
 
   if (!response.ParseFromString(data)) {
@@ -171,11 +171,11 @@
     return false;
   }
 
-  if (response.has_negative_cache_duration()) {
-    // Seconds resolution is good enough so we ignore the nanos field.
-    *negative_cache_duration = base::TimeDelta::FromSeconds(
-        response.negative_cache_duration().seconds());
-  }
+  // negative_cache_duration should always be set.
+  DCHECK(response.has_negative_cache_duration());
+  // Seconds resolution is good enough so we ignore the nanos field.
+  *negative_cache_expire = clock_->Now() + base::TimeDelta::FromSeconds(
+      response.negative_cache_duration().seconds());
 
   if (response.has_minimum_wait_duration()) {
     // Seconds resolution is good enough so we ignore the nanos field.
@@ -313,7 +313,7 @@
       RecordGetHashResult(V4OperationResult::MIN_WAIT_DURATION_ERROR);
     }
     std::vector<SBFullHashResult> full_hashes;
-    callback.Run(full_hashes, base::TimeDelta());
+    callback.Run(full_hashes, base::Time());
     return;
   }
 
@@ -364,13 +364,13 @@
 
   const FullHashCallback& callback = it->second;
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta negative_cache_duration;
+  base::Time negative_cache_expire;
   if (status.is_success() && response_code == net::HTTP_OK) {
     RecordGetHashResult(V4OperationResult::STATUS_200);
     ResetGetHashErrors();
     std::string data;
     source->GetResponseAsString(&data);
-    if (!ParseHashResponse(data, &full_hashes, &negative_cache_duration)) {
+    if (!ParseHashResponse(data, &full_hashes, &negative_cache_expire)) {
       full_hashes.clear();
       RecordGetHashResult(V4OperationResult::PARSE_ERROR);
     }
@@ -391,7 +391,7 @@
   // Invoke the callback with full_hashes, even if there was a parse error or
   // an error response code (in which case full_hashes will be empty). The
   // caller can't be blocked indefinitely.
-  callback.Run(full_hashes, negative_cache_duration);
+  callback.Run(full_hashes, negative_cache_expire);
 
   hash_requests_.erase(it);
 }
diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager.h b/components/safe_browsing_db/v4_get_hash_protocol_manager.h
index 6e14ef63..1a9ddd8 100644
--- a/components/safe_browsing_db/v4_get_hash_protocol_manager.h
+++ b/components/safe_browsing_db/v4_get_hash_protocol_manager.h
@@ -44,9 +44,10 @@
   // Parameters:
   //   - The vector of full hash results. If empty, indicates that there
   //     were no matches, and that the resource is safe.
-  //   - The negative cache duration of the result.
+  //   - The negative cache expire time of the result. This value may be
+  //     uninitialized, and the results should not be cached in this case.
   typedef base::Callback<void(const std::vector<SBFullHashResult>&,
-                              const base::TimeDelta&)>
+                              const base::Time&)>
       FullHashCallback;
 
   ~V4GetHashProtocolManager() override;
@@ -118,13 +119,13 @@
                              ThreatType threat_type);
 
   // Parses a FindFullHashesResponse protocol buffer and fills the results in
-  // |full_hashes| and |negative_cache_duration|. |data| is a serialized
-  // FindFullHashes protocol buffer. |negative_cache_duration| is the duration
-  // to cache the response for entities that did not match the threat list.
+  // |full_hashes| and |negative_cache_expire|. |data| is a serialized
+  // FindFullHashes protocol buffer. |negative_cache_expire| is the cache expiry
+  // time of the response for entities that did not match the threat list.
   // Returns true if parsing is successful, false otherwise.
   bool ParseHashResponse(const std::string& data_base64,
                          std::vector<SBFullHashResult>* full_hashes,
-                         base::TimeDelta* negative_cache_duration);
+                         base::Time* negative_cache_expire);
 
   // Resets the gethash error counter and multiplier.
   void ResetGetHashErrors();
diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc b/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
index 2820ed4..76f4964 100644
--- a/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
+++ b/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
@@ -66,14 +66,20 @@
 
     return res_data;
   }
+
+  void SetTestClock(base::Time now, V4GetHashProtocolManager* pm) {
+    base::SimpleTestClock* clock = new base::SimpleTestClock();
+    clock->SetNow(now);
+    pm->SetClockForTests(base::WrapUnique(clock));
+  }
 };
 
 void ValidateGetV4HashResults(
     const std::vector<SBFullHashResult>& expected_full_hashes,
-    const base::TimeDelta& expected_cache_duration,
+    const base::Time& expected_cache_expire,
     const std::vector<SBFullHashResult>& full_hashes,
-    const base::TimeDelta& cache_duration) {
-  EXPECT_EQ(expected_cache_duration, cache_duration);
+    const base::Time& cache_expire) {
+  EXPECT_EQ(expected_cache_expire, cache_expire);
   ASSERT_EQ(expected_full_hashes.size(), full_hashes.size());
 
   for (unsigned int i = 0; i < expected_full_hashes.size(); ++i) {
@@ -92,11 +98,11 @@
 
   std::vector<SBPrefix> prefixes;
   std::vector<SBFullHashResult> expected_full_hashes;
-  base::TimeDelta expected_cache_duration;
+  base::Time expected_cache_expire;
 
   pm->GetFullHashesWithApis(
       prefixes, base::Bind(&ValidateGetV4HashResults, expected_full_hashes,
-                           expected_cache_duration));
+                           expected_cache_expire));
 
   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
   DCHECK(fetcher);
@@ -119,11 +125,11 @@
 
   std::vector<SBPrefix> prefixes;
   std::vector<SBFullHashResult> expected_full_hashes;
-  base::TimeDelta expected_cache_duration;
+  base::Time expected_cache_expire;
 
   pm->GetFullHashesWithApis(
       prefixes, base::Bind(&ValidateGetV4HashResults, expected_full_hashes,
-                           expected_cache_duration));
+                           expected_cache_expire));
 
   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
   DCHECK(fetcher);
@@ -143,9 +149,7 @@
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
   base::Time now = base::Time::UnixEpoch();
-  base::SimpleTestClock* clock = new base::SimpleTestClock();
-  clock->SetNow(now);
-  pm->SetClockForTests(base::WrapUnique(clock));
+  SetTestClock(now, pm.get());
 
   std::vector<SBPrefix> prefixes;
   std::vector<SBFullHashResult> expected_full_hashes;
@@ -154,11 +158,11 @@
   hash_result.metadata.api_permissions.push_back("NOTIFICATIONS");
   hash_result.cache_expire_after = now + base::TimeDelta::FromSeconds(300);
   expected_full_hashes.push_back(hash_result);
-  base::TimeDelta expected_cache_duration = base::TimeDelta::FromSeconds(600);
+  base::Time expected_cache_expire = now + base::TimeDelta::FromSeconds(600);
 
   pm->GetFullHashesWithApis(
       prefixes, base::Bind(&ValidateGetV4HashResults, expected_full_hashes,
-                           expected_cache_duration));
+                           expected_cache_expire));
 
   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
   DCHECK(fetcher);
@@ -211,9 +215,7 @@
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
   base::Time now = base::Time::UnixEpoch();
-  base::SimpleTestClock* clock = new base::SimpleTestClock();
-  clock->SetNow(now);
-  pm->SetClockForTests(base::WrapUnique(clock));
+  SetTestClock(now, pm.get());
 
   FindFullHashesResponse res;
   res.mutable_negative_cache_duration()->set_seconds(600);
@@ -235,10 +237,10 @@
   res.SerializeToString(&res_data);
 
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta cache_lifetime;
-  EXPECT_TRUE(pm->ParseHashResponse(res_data, &full_hashes, &cache_lifetime));
+  base::Time cache_expire;
+  EXPECT_TRUE(pm->ParseHashResponse(res_data, &full_hashes, &cache_expire));
 
-  EXPECT_EQ(base::TimeDelta::FromSeconds(600), cache_lifetime);
+  EXPECT_EQ(now + base::TimeDelta::FromSeconds(600), cache_expire);
   EXPECT_EQ(1ul, full_hashes.size());
   EXPECT_TRUE(SBFullHashEqual(SBFullHashForString("Everything's shiny, Cap'n."),
                               full_hashes[0].hash));
@@ -254,6 +256,9 @@
        TestParseHashResponseWrongThreatEntryType) {
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
+  base::Time now = base::Time::UnixEpoch();
+  SetTestClock(now, pm.get());
+
   FindFullHashesResponse res;
   res.mutable_negative_cache_duration()->set_seconds(600);
   res.add_matches()->set_threat_entry_type(BINARY_DIGEST);
@@ -263,10 +268,10 @@
   res.SerializeToString(&res_data);
 
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta cache_lifetime;
-  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_lifetime));
+  base::Time cache_expire;
+  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_expire));
 
-  EXPECT_EQ(base::TimeDelta::FromSeconds(600), cache_lifetime);
+  EXPECT_EQ(now + base::TimeDelta::FromSeconds(600), cache_expire);
   // There should be no hash results.
   EXPECT_EQ(0ul, full_hashes.size());
 }
@@ -276,6 +281,9 @@
        TestParseHashThreatPatternType) {
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
+  base::Time now = base::Time::UnixEpoch();
+  SetTestClock(now, pm.get());
+
   // Test social engineering pattern type.
   FindFullHashesResponse se_res;
   se_res.mutable_negative_cache_duration()->set_seconds(600);
@@ -294,10 +302,10 @@
   se_res.SerializeToString(&se_data);
 
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta cache_lifetime;
-  EXPECT_TRUE(pm->ParseHashResponse(se_data, &full_hashes, &cache_lifetime));
+  base::Time cache_expire;
+  EXPECT_TRUE(pm->ParseHashResponse(se_data, &full_hashes, &cache_expire));
 
-  EXPECT_EQ(base::TimeDelta::FromSeconds(600), cache_lifetime);
+  EXPECT_EQ(now + base::TimeDelta::FromSeconds(600), cache_expire);
   EXPECT_EQ(1ul, full_hashes.size());
   EXPECT_TRUE(SBFullHashEqual(hash_string, full_hashes[0].hash));
   EXPECT_EQ(ThreatPatternType::SOCIAL_ENGINEERING_LANDING,
@@ -320,7 +328,7 @@
   std::string pha_data;
   pha_res.SerializeToString(&pha_data);
   full_hashes.clear();
-  EXPECT_TRUE(pm->ParseHashResponse(pha_data, &full_hashes, &cache_lifetime));
+  EXPECT_TRUE(pm->ParseHashResponse(pha_data, &full_hashes, &cache_expire));
   EXPECT_EQ(1ul, full_hashes.size());
   EXPECT_TRUE(SBFullHashEqual(hash_string, full_hashes[0].hash));
   EXPECT_EQ(ThreatPatternType::MALWARE_LANDING,
@@ -343,7 +351,7 @@
   invalid_res.SerializeToString(&invalid_data);
   full_hashes.clear();
   EXPECT_FALSE(
-      pm->ParseHashResponse(invalid_data, &full_hashes, &cache_lifetime));
+      pm->ParseHashResponse(invalid_data, &full_hashes, &cache_expire));
   EXPECT_EQ(0ul, full_hashes.size());
 }
 
@@ -352,6 +360,9 @@
        TestParseHashResponseNonPermissionMetadata) {
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
+  base::Time now = base::Time::UnixEpoch();
+  SetTestClock(now, pm.get());
+
   FindFullHashesResponse res;
   res.mutable_negative_cache_duration()->set_seconds(600);
   ThreatMatch* m = res.add_matches();
@@ -370,10 +381,10 @@
   res.SerializeToString(&res_data);
 
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta cache_lifetime;
-  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_lifetime));
+  base::Time cache_expire;
+  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_expire));
 
-  EXPECT_EQ(base::TimeDelta::FromSeconds(600), cache_lifetime);
+  EXPECT_EQ(now + base::TimeDelta::FromSeconds(600), cache_expire);
   EXPECT_EQ(0ul, full_hashes.size());
 }
 
@@ -382,6 +393,7 @@
   std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
 
   FindFullHashesResponse res;
+  res.mutable_negative_cache_duration()->set_seconds(600);
   ThreatMatch* m1 = res.add_matches();
   m1->set_threat_type(API_ABUSE);
   m1->set_platform_type(CHROME_PLATFORM);
@@ -400,8 +412,8 @@
   res.SerializeToString(&res_data);
 
   std::vector<SBFullHashResult> full_hashes;
-  base::TimeDelta cache_lifetime;
-  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_lifetime));
+  base::Time cache_expire;
+  EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_expire));
 }
 
 }  // namespace safe_browsing
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index 6d334ad..d5ca450 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -36,34 +36,15 @@
 const char TranslatePrefs::kPrefTranslateTooOftenDeniedForLanguage[] =
     "translate_too_often_denied_for_language";
 
-// This property is deprecated but there is still some usages. Don't use this
-// for new code.
-static const char kPrefTranslateLanguageBlacklist[] =
-    "translate_language_blacklist";
-
 // The below properties used to be used but now are deprecated. Don't use them
 // since an old profile might have some values there.
 //
 // * translate_last_denied_time
 // * translate_too_often_denied
+// * translate_language_blacklist
 
 namespace {
 
-void GetBlacklistedLanguages(const PrefService* prefs,
-                             std::vector<std::string>* languages) {
-  DCHECK(languages);
-  DCHECK(languages->empty());
-
-  const char* key = kPrefTranslateLanguageBlacklist;
-  const base::ListValue* list = prefs->GetList(key);
-  for (base::ListValue::const_iterator it = list->begin(); it != list->end();
-       ++it) {
-    std::string lang;
-    (*it)->GetAsString(&lang);
-    languages->push_back(lang);
-  }
-}
-
 // Expands language codes to make these more suitable for Accept-Language.
 // Example: ['en-US', 'ja', 'en-CA'] => ['en-US', 'en', 'ja', 'en-CA'].
 // 'en' won't appear twice as this function eliminates duplicates.
@@ -218,11 +199,6 @@
   RemoveValueFromBlacklist(kPrefTranslateBlockedLanguages, original_language);
 }
 
-void TranslatePrefs::RemoveLanguageFromLegacyBlacklist(
-    const std::string& original_language) {
-  RemoveValueFromBlacklist(kPrefTranslateLanguageBlacklist, original_language);
-}
-
 bool TranslatePrefs::IsSiteBlacklisted(const std::string& site) const {
   return IsValueBlacklisted(kPrefTranslateSiteBlacklist, site);
 }
@@ -475,8 +451,6 @@
 // static
 void TranslatePrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterListPref(kPrefTranslateLanguageBlacklist,
-                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
   registry->RegisterListPref(kPrefTranslateSiteBlacklist,
                              user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
   registry->RegisterDictionaryPref(
@@ -539,99 +513,6 @@
       }
     }
   }
-
-  // Get the union of the blacklist and the Accept languages, and set this to
-  // the new language set 'translate_blocked_languages'. This is used for the
-  // settings UI for Translate and configration to determine which langauage
-  // should be translated instead of the blacklist. The blacklist is no longer
-  // used after launching the settings UI.
-  // After that, Set 'translate_languages_not_translate' to Accept languages to
-  // enable settings for users.
-  bool merged = user_prefs->HasPrefPath(kPrefTranslateBlockedLanguages);
-
-  if (!merged) {
-    std::vector<std::string> blacklisted_languages;
-    GetBlacklistedLanguages(user_prefs, &blacklisted_languages);
-
-    std::vector<std::string> accept_languages =
-        base::SplitString(user_prefs->GetString(accept_languages_pref), ",",
-                          base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
-    std::vector<std::string> blocked_languages;
-    CreateBlockedLanguages(&blocked_languages, blacklisted_languages,
-                           accept_languages);
-
-    // Create the new preference kPrefTranslateBlockedLanguages.
-    {
-      base::ListValue blocked_languages_list;
-      for (std::vector<std::string>::const_iterator it =
-               blocked_languages.begin();
-           it != blocked_languages.end(); ++it) {
-        blocked_languages_list.Append(new base::StringValue(*it));
-      }
-      ListPrefUpdate update(user_prefs, kPrefTranslateBlockedLanguages);
-      base::ListValue* list = update.Get();
-      DCHECK(list != NULL);
-      list->Swap(&blocked_languages_list);
-    }
-
-    // Update kAcceptLanguages
-    for (std::vector<std::string>::const_iterator it =
-             blocked_languages.begin();
-         it != blocked_languages.end(); ++it) {
-      std::string lang = *it;
-      translate::ToChromeLanguageSynonym(&lang);
-      bool not_found =
-          std::find(accept_languages.begin(), accept_languages.end(), lang) ==
-          accept_languages.end();
-      if (not_found)
-        accept_languages.push_back(lang);
-    }
-
-    std::string new_accept_languages_str =
-        base::JoinString(accept_languages, ",");
-    user_prefs->SetString(accept_languages_pref, new_accept_languages_str);
-  }
-}
-
-// static
-void TranslatePrefs::CreateBlockedLanguages(
-    std::vector<std::string>* blocked_languages,
-    const std::vector<std::string>& blacklisted_languages,
-    const std::vector<std::string>& accept_languages) {
-  DCHECK(blocked_languages);
-  DCHECK(blocked_languages->empty());
-
-  std::set<std::string> result;
-
-  for (std::vector<std::string>::const_iterator it =
-           blacklisted_languages.begin();
-       it != blacklisted_languages.end(); ++it) {
-    result.insert(*it);
-  }
-
-  const std::string& app_locale =
-      TranslateDownloadManager::GetInstance()->application_locale();
-  std::string ui_lang = TranslateDownloadManager::GetLanguageCode(app_locale);
-  bool is_ui_english =
-      ui_lang == "en" ||
-      base::StartsWith(ui_lang, "en-", base::CompareCase::INSENSITIVE_ASCII);
-
-  for (std::vector<std::string>::const_iterator it = accept_languages.begin();
-       it != accept_languages.end(); ++it) {
-    std::string lang = *it;
-    translate::ToTranslateLanguageSynonym(&lang);
-
-    // Regarding http://crbug.com/36182, even though English exists in Accept
-    // language list, English could be translated on non-English locale.
-    if (lang == "en" && !is_ui_english)
-      continue;
-
-    result.insert(lang);
-  }
-
-  blocked_languages->insert(blocked_languages->begin(), result.begin(),
-                            result.end());
 }
 
 bool TranslatePrefs::IsValueInList(const base::ListValue* list,
diff --git a/components/translate/core/browser/translate_prefs.h b/components/translate/core/browser/translate_prefs.h
index 65c3bef..8c803a5e 100644
--- a/components/translate/core/browser/translate_prefs.h
+++ b/components/translate/core/browser/translate_prefs.h
@@ -99,10 +99,6 @@
   void BlockLanguage(const std::string& original_language);
   void UnblockLanguage(const std::string& original_language);
 
-  // Removes a language from the old blacklist. Only used internally for
-  // diagnostics. Don't use this if there is no special reason.
-  void RemoveLanguageFromLegacyBlacklist(const std::string& original_language);
-
   bool IsSiteBlacklisted(const std::string& site) const;
   void BlacklistSite(const std::string& site);
   void RemoveSiteFromBlacklist(const std::string& site);
@@ -167,9 +163,6 @@
 
  private:
   friend class TranslatePrefsTest;
-  FRIEND_TEST_ALL_PREFIXES(TranslatePrefsTest, CreateBlockedLanguages);
-  FRIEND_TEST_ALL_PREFIXES(TranslatePrefsTest,
-                           CreateBlockedLanguagesNonEnglishUI);
 
   // Merges two language sets to migrate to the language setting UI.
   static void CreateBlockedLanguages(
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc
index 2f94192..881718d 100644
--- a/components/translate/core/browser/translate_prefs_unittest.cc
+++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -24,107 +24,6 @@
 
 namespace translate {
 
-TEST(TranslatePrefsTest, CreateBlockedLanguages) {
-  TranslateDownloadManager::GetInstance()->set_application_locale("en");
-  std::vector<std::string> blacklisted_languages;
-  blacklisted_languages.push_back("en");
-  blacklisted_languages.push_back("fr");
-  // Hebrew: synonym to 'he'
-  blacklisted_languages.push_back("iw");
-  // Haitian is not used as Accept-Language
-  blacklisted_languages.push_back("ht");
-
-  std::vector<std::string> accept_languages;
-  accept_languages.push_back("en");
-  // The subcode (IT) will be ignored when merging, except for Chinese.
-  accept_languages.push_back("it-IT");
-  accept_languages.push_back("ja");
-  // Filippino: synonym to 'tl'
-  accept_languages.push_back("fil");
-  // General Chinese is not used as Translate language, but not filtered
-  // when merging.
-  accept_languages.push_back("zh");
-  // Chinese with a sub code is acceptable for the blocked-language list.
-  accept_languages.push_back("zh-TW");
-
-  std::vector<std::string> blocked_languages;
-
-  TranslatePrefs::CreateBlockedLanguages(
-      &blocked_languages, blacklisted_languages, accept_languages);
-
-  // The order of the elements cannot be determined.
-  std::vector<std::string> expected;
-  expected.push_back("en");
-  expected.push_back("fr");
-  expected.push_back("iw");
-  expected.push_back("ht");
-  expected.push_back("it");
-  expected.push_back("ja");
-  expected.push_back("tl");
-  expected.push_back("zh");
-  expected.push_back("zh-TW");
-
-  EXPECT_EQ(expected.size(), blocked_languages.size());
-  for (std::vector<std::string>::const_iterator it = expected.begin();
-       it != expected.end(); ++it) {
-    EXPECT_NE(blocked_languages.end(), std::find(blocked_languages.begin(),
-                                                 blocked_languages.end(), *it));
-  }
-}
-
-TEST(TranslatePrefsTest, CreateBlockedLanguagesNonEnglishUI) {
-  std::vector<std::string> blacklisted_languages;
-  blacklisted_languages.push_back("fr");
-
-  std::vector<std::string> accept_languages;
-  accept_languages.push_back("en");
-  accept_languages.push_back("ja");
-  accept_languages.push_back("zh");
-
-  // Run in an English locale.
-  {
-    TranslateDownloadManager::GetInstance()->set_application_locale("en");
-    std::vector<std::string> blocked_languages;
-    TranslatePrefs::CreateBlockedLanguages(
-        &blocked_languages, blacklisted_languages, accept_languages);
-    std::vector<std::string> expected;
-    expected.push_back("en");
-    expected.push_back("fr");
-    expected.push_back("ja");
-    expected.push_back("zh");
-
-    EXPECT_EQ(expected.size(), blocked_languages.size());
-    for (std::vector<std::string>::const_iterator it = expected.begin();
-         it != expected.end(); ++it) {
-      EXPECT_NE(
-          blocked_languages.end(),
-          std::find(blocked_languages.begin(), blocked_languages.end(), *it));
-    }
-  }
-
-  // Run in a Japanese locale.
-  // English should not be included in the result even though Accept Languages
-  // has English because the UI is not English.
-  {
-    TranslateDownloadManager::GetInstance()->set_application_locale("ja");
-    std::vector<std::string> blocked_languages;
-    TranslatePrefs::CreateBlockedLanguages(
-        &blocked_languages, blacklisted_languages, accept_languages);
-    std::vector<std::string> expected;
-    expected.push_back("fr");
-    expected.push_back("ja");
-    expected.push_back("zh");
-
-    EXPECT_EQ(expected.size(), blocked_languages.size());
-    for (std::vector<std::string>::const_iterator it = expected.begin();
-         it != expected.end(); ++it) {
-      EXPECT_NE(
-          blocked_languages.end(),
-          std::find(blocked_languages.begin(), blocked_languages.end(), *it));
-    }
-  }
-}
-
 class TranslatePrefTest : public testing::Test {
  protected:
   TranslatePrefTest() : prefs_(new user_prefs::TestingPrefServiceSyncable()) {
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index be6ff78..e756228 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -288,27 +288,12 @@
   ReloadInternal(check_for_repost, RELOAD);
 }
 void NavigationControllerImpl::ReloadToRefreshContent(bool check_for_repost) {
+  ReloadType type = RELOAD;
   if (base::FeatureList::IsEnabled(
         features::kNonValidatingReloadOnRefreshContent)) {
-    // Cause this reload to behave like NAVIGATION_TYPE_SAME_PAGE (e.g., enter
-    // in the omnibox), so that the main resource is cache-validated but all
-    // other resources use the cache as much as possible.  This requires
-    // navigating to the current URL in a new pending entry.
-    // TODO(toyoshim): Introduce a new ReloadType for this behavior if it
-    // becomes the default.
-    NavigationEntryImpl* last_committed = GetLastCommittedEntry();
-
-    // If the last committed entry does not exist, or a repost check dialog is
-    // really needed, use a standard reload instead.
-    if (last_committed &&
-        !(check_for_repost && last_committed->GetHasPostData())) {
-      LoadURL(last_committed->GetURL(), last_committed->GetReferrer(),
-              last_committed->GetTransitionType(),
-              last_committed->extra_headers());
-      return;
-    }
+    type = RELOAD_MAIN_RESOURCE;
   }
-  ReloadInternal(check_for_repost, RELOAD);
+  ReloadInternal(check_for_repost, type);
 }
 void NavigationControllerImpl::ReloadBypassingCache(bool check_for_repost) {
   ReloadInternal(check_for_repost, RELOAD_BYPASSING_CACHE);
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 27cdaea5..cfcdbb0 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -52,14 +52,16 @@
     BrowserContext* browser_context, const NavigationEntryImpl& entry,
     NavigationController::ReloadType reload_type) {
   switch (reload_type) {
-    case NavigationControllerImpl::RELOAD:
+    case NavigationController::RELOAD:
       return FrameMsg_Navigate_Type::RELOAD;
-    case NavigationControllerImpl::RELOAD_BYPASSING_CACHE:
-    case NavigationControllerImpl::RELOAD_DISABLE_LOFI_MODE:
+    case NavigationController::RELOAD_MAIN_RESOURCE:
+      return FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE;
+    case NavigationController::RELOAD_BYPASSING_CACHE:
+    case NavigationController::RELOAD_DISABLE_LOFI_MODE:
       return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE;
-    case NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL:
+    case NavigationController::RELOAD_ORIGINAL_REQUEST_URL:
       return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
-    case NavigationControllerImpl::NO_RELOAD:
+    case NavigationController::NO_RELOAD:
       break;  // Fall through to rest of function.
   }
 
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS
index 7c094d6..188bb2b 100644
--- a/content/browser/loader/DEPS
+++ b/content/browser/loader/DEPS
@@ -29,6 +29,7 @@
 
     # TODO: To be replaced by mojo.
     "+content/common/resource_messages.h",
+    "+content/common/resource_request_completion_status.h",
     "+content/common/view_messages.h",
   ],
   "async_revalidation_driver\.(cc|h)": [
@@ -61,6 +62,7 @@
 
     # TODO: To be replaced by mojo.
     "+content/common/resource_messages.h",
+    "+content/common/resource_request.h",
   ],
   "resource_buffer.*\.(cc|h)": [
     "-content",
@@ -175,6 +177,8 @@
 
     # TODO: To be replaced by mojo.
     "+content/common/resource_messages.h",
+    "+content/common/resource_request.h",
+    "+content/common/resource_request_completion_status.h",
     "+content/common/view_messages.h",
   ],
   "resource_handler\.(cc|h)": [
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc
index 78e0dab..cfeeb45 100644
--- a/content/browser/loader/async_resource_handler.cc
+++ b/content/browser/loader/async_resource_handler.cc
@@ -25,6 +25,7 @@
 #include "content/browser/loader/resource_request_info_impl.h"
 #include "content/browser/resource_context_impl.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request_completion_status.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/common/content_features.h"
@@ -523,7 +524,7 @@
     error_code = net::ERR_FAILED;
   }
 
-  ResourceMsg_RequestCompleteData request_complete_data;
+  ResourceRequestCompletionStatus request_complete_data;
   request_complete_data.error_code = error_code;
   request_complete_data.was_ignored_by_handler = was_ignored_by_handler;
   request_complete_data.exists_in_cache = request()->response_info().was_cached;
diff --git a/content/browser/loader/async_revalidation_manager.cc b/content/browser/loader/async_revalidation_manager.cc
index 4b364023..6b417ab 100644
--- a/content/browser/loader/async_revalidation_manager.cc
+++ b/content/browser/loader/async_revalidation_manager.cc
@@ -13,6 +13,7 @@
 #include "content/browser/loader/resource_request_info_impl.h"
 #include "content/browser/loader/resource_scheduler.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
 #include "content/public/browser/resource_throttle.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_transaction_factory.h"
@@ -164,7 +165,7 @@
 }
 
 bool AsyncRevalidationManager::QualifiesForAsyncRevalidation(
-    const ResourceHostMsg_Request& request) {
+    const ResourceRequest& request) {
   if (request.load_flags &
       (net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
        net::LOAD_VALIDATE_CACHE | net::LOAD_PREFERRING_CACHE |
diff --git a/content/browser/loader/async_revalidation_manager.h b/content/browser/loader/async_revalidation_manager.h
index e866b4ab..cf6f6c5 100644
--- a/content/browser/loader/async_revalidation_manager.h
+++ b/content/browser/loader/async_revalidation_manager.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 
 class GURL;
-struct ResourceHostMsg_Request;
 
 namespace net {
 class URLRequest;
@@ -24,6 +23,7 @@
 class AsyncRevalidationDriver;
 class ResourceContext;
 class ResourceScheduler;
+struct ResourceRequest;
 
 // One instance of this class manages all active AsyncRevalidationDriver objects
 // for all profiles. It is created by and owned by
@@ -44,8 +44,7 @@
   void CancelAsyncRevalidationsForResourceContext(
       ResourceContext* resource_context);
 
-  static bool QualifiesForAsyncRevalidation(
-      const ResourceHostMsg_Request& request);
+  static bool QualifiesForAsyncRevalidation(const ResourceRequest& request);
 
  private:
   // The key of the map of pending async revalidations. This key has a distinct
diff --git a/content/browser/loader/async_revalidation_manager_unittest.cc b/content/browser/loader/async_revalidation_manager_unittest.cc
index 09a7092..f299ad5 100644
--- a/content/browser/loader/async_revalidation_manager_unittest.cc
+++ b/content/browser/loader/async_revalidation_manager_unittest.cc
@@ -21,6 +21,7 @@
 #include "content/browser/loader/resource_message_filter.h"
 #include "content/common/child_process_host_impl.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/common/appcache_info.h"
 #include "content/public/common/process_type.h"
@@ -240,10 +241,10 @@
   DISALLOW_COPY_AND_ASSIGN(BlackholeFilter);
 };
 
-ResourceHostMsg_Request CreateResourceRequest(const char* method,
-                                              ResourceType type,
-                                              const GURL& url) {
-  ResourceHostMsg_Request request;
+ResourceRequest CreateResourceRequest(const char* method,
+                                      ResourceType type,
+                                      const GURL& url) {
+  ResourceRequest request;
   request.method = std::string(method);
   request.url = url;
   request.first_party_for_cookies = url;  // Bypass third-party cookie blocking.
@@ -301,7 +302,7 @@
   // Creates a request using the current test object as the filter and
   // SubResource as the resource type.
   void MakeTestRequest(int render_view_id, int request_id, const GURL& url) {
-    ResourceHostMsg_Request request =
+    ResourceRequest request =
         CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
     ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
     host_.OnMessageReceived(msg, filter_.get());
@@ -337,7 +338,7 @@
 TEST_F(AsyncRevalidationManagerTest, AsyncRevalidationNotSupportedForPOST) {
   SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
   // Create POST request.
-  ResourceHostMsg_Request request = CreateResourceRequest(
+  ResourceRequest request = CreateResourceRequest(
       "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php"));
   ResourceHostMsg_RequestResource msg(0, 1, request);
   host_.OnMessageReceived(msg, filter_.get());
diff --git a/content/browser/loader/reload_cache_control_browsertest.cc b/content/browser/loader/reload_cache_control_browsertest.cc
new file mode 100644
index 0000000..94ae06d
--- /dev/null
+++ b/content/browser/loader/reload_cache_control_browsertest.cc
@@ -0,0 +1,109 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_path.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+using net::test_server::HttpRequest;
+using net::test_server::HttpResponse;
+
+const char kReloadTestPath[] = "/loader/reload.html";
+const char kReloadImagePath[] = "/loader/empty16x16.png";
+
+const char kNoCacheControl[] = "";
+const char kMaxAgeCacheControl[] = "max-age=0";
+const char kNoCacheCacheControl[] = "no-cache";
+
+struct RequestLog {
+  std::string relative_url;
+  std::string cache_control;
+};
+
+class ReloadCacheControlBrowserTest : public ContentBrowserTest {
+ protected:
+  ReloadCacheControlBrowserTest() = default;
+  ~ReloadCacheControlBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    // ContentBrowserTest creates embedded_test_server instance with
+    // a registered HandleFileRequest for "content/test/data".
+    // Because the handler is registered as the first handler, MonitorHandler
+    // is needed to capture all requests.
+    embedded_test_server()->RegisterRequestMonitor(base::Bind(
+        &ReloadCacheControlBrowserTest::MonitorRequestHandler, this));
+
+    ASSERT_TRUE(embedded_test_server()->Start());
+  }
+
+ protected:
+  std::vector<RequestLog> request_log_;
+
+ private:
+  void MonitorRequestHandler(const HttpRequest& request) {
+    RequestLog log;
+    log.relative_url = request.relative_url;
+    auto cache_control = request.headers.find("Cache-Control");
+    log.cache_control = cache_control == request.headers.end()
+                            ? kNoCacheControl
+                            : cache_control->second;
+    request_log_.push_back(log);
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(ReloadCacheControlBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, NormalReload) {
+  GURL url(embedded_test_server()->GetURL(kReloadTestPath));
+
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  ReloadBlockUntilNavigationsComplete(shell(), 1);
+
+  ASSERT_EQ(4UL, request_log_.size());
+  EXPECT_EQ(kReloadTestPath, request_log_[0].relative_url);
+  EXPECT_EQ(kNoCacheControl, request_log_[0].cache_control);
+  EXPECT_EQ(kReloadImagePath, request_log_[1].relative_url);
+  EXPECT_EQ(kNoCacheControl, request_log_[1].cache_control);
+
+  EXPECT_EQ(kReloadTestPath, request_log_[2].relative_url);
+  EXPECT_EQ(kMaxAgeCacheControl, request_log_[2].cache_control);
+  EXPECT_EQ(kReloadImagePath, request_log_[3].relative_url);
+  EXPECT_EQ(kMaxAgeCacheControl, request_log_[3].cache_control);
+}
+
+IN_PROC_BROWSER_TEST_F(ReloadCacheControlBrowserTest, BypassingReload) {
+  GURL url(embedded_test_server()->GetURL(kReloadTestPath));
+
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  ReloadBypassingCacheBlockUntilNavigationsComplete(shell(), 1);
+
+  ASSERT_EQ(4UL, request_log_.size());
+  EXPECT_EQ(kReloadTestPath, request_log_[0].relative_url);
+  EXPECT_EQ(kNoCacheControl, request_log_[0].cache_control);
+  EXPECT_EQ(kReloadImagePath, request_log_[1].relative_url);
+  EXPECT_EQ(kNoCacheControl, request_log_[1].cache_control);
+
+  EXPECT_EQ(kReloadTestPath, request_log_[2].relative_url);
+  EXPECT_EQ(kNoCacheCacheControl, request_log_[2].cache_control);
+  EXPECT_EQ(kReloadImagePath, request_log_[3].relative_url);
+  EXPECT_EQ(kNoCacheCacheControl, request_log_[3].cache_control);
+}
+
+}  // namespace
+
+}  // namespace content
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index c3392079..cb64dc8 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -75,6 +75,8 @@
 #include "content/common/navigation_params.h"
 #include "content/common/net/url_request_service_worker_data.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
+#include "content/common/resource_request_completion_status.h"
 #include "content/common/site_isolation_policy.h"
 #include "content/common/ssl_status_serialization.h"
 #include "content/common/view_messages.h"
@@ -235,7 +237,7 @@
     filter->Send(sync_result);
   } else {
     // Tell the renderer that this request was disallowed.
-    ResourceMsg_RequestCompleteData request_complete_data;
+    ResourceRequestCompletionStatus request_complete_data;
     request_complete_data.error_code = net::ERR_ABORTED;
     request_complete_data.was_ignored_by_handler = false;
     request_complete_data.exists_in_cache = false;
@@ -294,7 +296,7 @@
 // if the renderer is attempting to upload an unauthorized file.
 bool ShouldServiceRequest(int process_type,
                           int child_id,
-                          const ResourceHostMsg_Request& request_data,
+                          const ResourceRequest& request_data,
                           const net::HttpRequestHeaders& headers,
                           ResourceMessageFilter* filter,
                           ResourceContext* resource_context) {
@@ -1215,7 +1217,7 @@
 void ResourceDispatcherHostImpl::OnRequestResource(
     int routing_id,
     int request_id,
-    const ResourceHostMsg_Request& request_data) {
+    const ResourceRequest& request_data) {
   // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
   tracked_objects::ScopedTracker tracking_profile(
       FROM_HERE_WITH_EXPLICIT_FUNCTION(
@@ -1247,10 +1249,9 @@
 //
 // If sync_result is non-null, then a SyncLoad reply will be generated, else
 // a normal asynchronous set of response messages will be generated.
-void ResourceDispatcherHostImpl::OnSyncLoad(
-    int request_id,
-    const ResourceHostMsg_Request& request_data,
-    IPC::Message* sync_result) {
+void ResourceDispatcherHostImpl::OnSyncLoad(int request_id,
+                                            const ResourceRequest& request_data,
+                                            IPC::Message* sync_result) {
   BeginRequest(request_id, request_data, sync_result,
                sync_result->routing_id());
 }
@@ -1273,7 +1274,7 @@
     int child_id,
     int route_id,
     int request_id,
-    const ResourceHostMsg_Request& request_data,
+    const ResourceRequest& request_data,
     LoaderMap::iterator iter) {
   ResourceRequestInfoImpl* info = iter->second->GetRequestInfo();
   GlobalFrameRoutingId old_routing_id(request_data.transferred_request_child_id,
@@ -1365,7 +1366,7 @@
 
 void ResourceDispatcherHostImpl::BeginRequest(
     int request_id,
-    const ResourceHostMsg_Request& request_data,
+    const ResourceRequest& request_data,
     IPC::Message* sync_result,  // only valid for sync
     int route_id) {
   int process_type = filter_->process_type();
@@ -1635,7 +1636,7 @@
 std::unique_ptr<ResourceHandler>
 ResourceDispatcherHostImpl::CreateResourceHandler(
     net::URLRequest* request,
-    const ResourceHostMsg_Request& request_data,
+    const ResourceRequest& request_data,
     IPC::Message* sync_result,
     int route_id,
     int process_type,
@@ -2647,7 +2648,7 @@
 }
 
 int ResourceDispatcherHostImpl::BuildLoadFlagsForRequest(
-    const ResourceHostMsg_Request& request_data,
+    const ResourceRequest& request_data,
     int child_id,
     bool is_sync_load) {
   int load_flags = request_data.load_flags;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index 086f39b..3d960fa 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -47,7 +47,6 @@
 #include "net/url_request/url_request.h"
 
 class ResourceHandler;
-struct ResourceHostMsg_Request;
 
 namespace base {
 class FilePath;
@@ -80,6 +79,7 @@
 struct DownloadSaveInfo;
 struct NavigationRequestInfo;
 struct Referrer;
+struct ResourceRequest;
 
 // This class is responsible for notifying the IO thread (specifically, the
 // ResourceDispatcherHostImpl) of frame events. It has an interace for callers
@@ -465,9 +465,9 @@
 
   void OnRequestResource(int routing_id,
                          int request_id,
-                         const ResourceHostMsg_Request& request_data);
+                         const ResourceRequest& request_data);
   void OnSyncLoad(int request_id,
-                  const ResourceHostMsg_Request& request_data,
+                  const ResourceRequest& request_data,
                   IPC::Message* sync_result);
 
   bool IsRequestIDInUse(const GlobalRequestID& id) const;
@@ -477,19 +477,19 @@
   void UpdateRequestForTransfer(int child_id,
                                 int route_id,
                                 int request_id,
-                                const ResourceHostMsg_Request& request_data,
+                                const ResourceRequest& request_data,
                                 LoaderMap::iterator iter);
 
   void BeginRequest(int request_id,
-                    const ResourceHostMsg_Request& request_data,
+                    const ResourceRequest& request_data,
                     IPC::Message* sync_result,  // only valid for sync
-                    int route_id);  // only valid for async
+                    int route_id);              // only valid for async
 
   // Creates a ResourceHandler to be used by BeginRequest() for normal resource
   // loading.
   std::unique_ptr<ResourceHandler> CreateResourceHandler(
       net::URLRequest* request,
-      const ResourceHostMsg_Request& request_data,
+      const ResourceRequest& request_data,
       IPC::Message* sync_result,
       int route_id,
       int process_type,
@@ -553,7 +553,7 @@
   void UnregisterResourceMessageDelegate(const GlobalRequestID& id,
                                          ResourceMessageDelegate* delegate);
 
-  int BuildLoadFlagsForRequest(const ResourceHostMsg_Request& request_data,
+  int BuildLoadFlagsForRequest(const ResourceRequest& request_data,
                                int child_id,
                                bool is_sync_load);
 
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index e115042..4667dd6 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -37,6 +37,7 @@
 #include "content/common/child_process_host_impl.h"
 #include "content/common/navigation_params.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
 #include "content/common/ssl_status_serialization.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/global_request_id.h"
@@ -149,10 +150,10 @@
   return request_id;
 }
 
-static ResourceHostMsg_Request CreateResourceRequest(const char* method,
-                                                     ResourceType type,
-                                                     const GURL& url) {
-  ResourceHostMsg_Request request;
+static ResourceRequest CreateResourceRequest(const char* method,
+                                             ResourceType type,
+                                             const GURL& url) {
+  ResourceRequest request;
   request.method = std::string(method);
   request.url = url;
   request.first_party_for_cookies = url;  // bypass third-party cookie blocking
@@ -1214,7 +1215,7 @@
     int request_id,
     const GURL& url,
     ResourceType type) {
-  ResourceHostMsg_Request request = CreateResourceRequest("GET", type, url);
+  ResourceRequest request = CreateResourceRequest("GET", type, url);
   request.render_frame_id = render_frame_id;
   ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
   host_.OnMessageReceived(msg, filter_.get());
@@ -1227,8 +1228,7 @@
     int request_id,
     const GURL& url,
     ResourceType type) {
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", type, url);
+  ResourceRequest request = CreateResourceRequest("GET", type, url);
   ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
   host_.OnMessageReceived(msg, filter);
   KickOffRequest();
@@ -1245,7 +1245,7 @@
     MakeWebContentsAssociatedTestRequestWithResourceType(int request_id,
                                                          const GURL& url,
                                                          ResourceType type) {
-  ResourceHostMsg_Request request = CreateResourceRequest("GET", type, url);
+  ResourceRequest request = CreateResourceRequest("GET", type, url);
   request.origin_pid = web_contents_->GetRenderProcessHost()->GetID();
   request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID();
   ResourceHostMsg_RequestResource msg(web_contents_->GetRoutingID(), request_id,
@@ -1267,7 +1267,7 @@
     int render_frame_id,
     int request_id,
     net::RequestPriority priority) {
-  ResourceHostMsg_Request request = CreateResourceRequest(
+  ResourceRequest request = CreateResourceRequest(
       "GET", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/priority"));
   request.render_frame_id = render_frame_id;
   request.priority = priority;
@@ -1578,9 +1578,9 @@
 // load.
 TEST_P(ResourceDispatcherHostTest, DeletedFilterDetached) {
   // test_url_1's data is available synchronously, so use 2 and 3.
-  ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
+  ResourceRequest request_prefetch = CreateResourceRequest(
       "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());
-  ResourceHostMsg_Request request_ping = CreateResourceRequest(
+  ResourceRequest request_ping = CreateResourceRequest(
       "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3());
 
   ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
@@ -1629,7 +1629,7 @@
 // If the filter has disappeared (original process dies) then detachable
 // resources should continue to load, even when redirected.
 TEST_P(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
-  ResourceHostMsg_Request request = CreateResourceRequest(
+  ResourceRequest request = CreateResourceRequest(
       "GET", RESOURCE_TYPE_PREFETCH,
       net::URLRequestTestJob::test_url_redirect_to_url_2());
 
@@ -2785,9 +2785,8 @@
   int new_render_view_id = 1;
   int new_request_id = 2;
 
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://other.com/blech"));
+  ResourceRequest request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://other.com/blech"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = request_id;
 
@@ -2865,7 +2864,7 @@
   int new_render_view_id = 1;
   int new_request_id = 2;
 
-  ResourceHostMsg_Request request = CreateResourceRequest(
+  ResourceRequest request = CreateResourceRequest(
       "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("https://example.com/blech"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = request_id;
@@ -2953,9 +2952,8 @@
   // Transfer the first request.
   int new_render_view_id = 1;
   int new_request_id = 5;
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://example.com/blah"));
+  ResourceRequest request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://example.com/blah"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = request_id;
 
@@ -2966,9 +2964,8 @@
 
   // Transfer the second request.
   int new_second_request_id = 6;
-  ResourceHostMsg_Request second_request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://example.com/foo"));
+  ResourceRequest second_request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://example.com/foo"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = second_request_id;
 
@@ -3042,9 +3039,8 @@
   int new_render_view_id = 1;
   int new_request_id = 2;
 
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://other.com/blech"));
+  ResourceRequest request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://other.com/blech"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = request_id;
 
@@ -3094,9 +3090,8 @@
     scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
     first_child_id = first_filter->child_id();
 
-    ResourceHostMsg_Request first_request =
-        CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                              GURL("http://example.com/blah"));
+    ResourceRequest first_request = CreateResourceRequest(
+        "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://example.com/blah"));
 
     ResourceHostMsg_RequestResource first_request_msg(
         render_view_id, request_id, first_request);
@@ -3130,9 +3125,8 @@
   int new_render_view_id = 1;
   int new_request_id = 2;
 
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://other.com/blech"));
+  ResourceRequest request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://other.com/blech"));
   request.transferred_request_child_id = first_child_id;
   request.transferred_request_request_id = request_id;
 
@@ -3213,9 +3207,8 @@
   int new_render_view_id = 1;
   int new_request_id = 2;
 
-  ResourceHostMsg_Request request =
-      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
-                            GURL("http://other.com/blech"));
+  ResourceRequest request = CreateResourceRequest(
+      "GET", RESOURCE_TYPE_MAIN_FRAME, GURL("http://other.com/blech"));
   request.transferred_request_child_id = filter_->child_id();
   request.transferred_request_request_id = request_id;
 
@@ -3520,7 +3513,7 @@
 
 TEST_P(ResourceDispatcherHostTest, DownloadToFile) {
   // Make a request which downloads to file.
-  ResourceHostMsg_Request request = CreateResourceRequest(
+  ResourceRequest request = CreateResourceRequest(
       "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
   request.download_to_file = true;
   ResourceHostMsg_RequestResource request_msg(0, 1, request);
diff --git a/content/browser/loader/resource_message_filter.h b/content/browser/loader/resource_message_filter.h
index 7047aa64..86979b3 100644
--- a/content/browser/loader/resource_message_filter.h
+++ b/content/browser/loader/resource_message_filter.h
@@ -14,8 +14,6 @@
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/common/resource_type.h"
 
-struct ResourceHostMsg_Request;
-
 namespace storage {
 class FileSystemContext;
 }  // namespace storage
diff --git a/content/browser/media/capture/image_capture_impl.cc b/content/browser/media/capture/image_capture_impl.cc
index 1722a4f..7a22bc9f 100644
--- a/content/browser/media/capture/image_capture_impl.cc
+++ b/content/browser/media/capture/image_capture_impl.cc
@@ -60,6 +60,18 @@
 
 ImageCaptureImpl::~ImageCaptureImpl() {}
 
+void ImageCaptureImpl::GetCapabilities(
+    const mojo::String& source_id,
+    const GetCapabilitiesCallback& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  blink::mojom::PhotoCapabilitiesPtr empty_capabilities =
+      blink::mojom::PhotoCapabilities::New();
+  empty_capabilities->zoom = blink::mojom::Range::New();
+  callback.Run(std::move(empty_capabilities));
+}
+
+
 void ImageCaptureImpl::TakePhoto(const mojo::String& source_id,
                                  const TakePhotoCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/media/capture/image_capture_impl.h b/content/browser/media/capture/image_capture_impl.h
index eef6732..8ca23da 100644
--- a/content/browser/media/capture/image_capture_impl.h
+++ b/content/browser/media/capture/image_capture_impl.h
@@ -18,6 +18,9 @@
       mojo::InterfaceRequest<blink::mojom::ImageCapture> request);
   ~ImageCaptureImpl() override;
 
+  void GetCapabilities(const mojo::String& source_id,
+                       const GetCapabilitiesCallback& callback) override;
+
   void TakePhoto(const mojo::String& source_id,
                  const TakePhotoCallback& callback) override;
 
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 07e84bb..e225045 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -18,6 +18,7 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/frame_messages.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
@@ -106,8 +107,8 @@
   return next_rfh->render_view_host();
 }
 
-ResourceHostMsg_Request CreateXHRRequest(const char* url) {
-  ResourceHostMsg_Request request;
+ResourceRequest CreateXHRRequest(const char* url) {
+  ResourceRequest request;
   request.method = "GET";
   request.url = GURL(url);
   request.referrer_policy = blink::WebReferrerPolicyDefault;
@@ -126,9 +127,8 @@
   return request;
 }
 
-ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) {
-  ResourceHostMsg_Request request =
-      CreateXHRRequest("http://bar.com/simple_page.html");
+ResourceRequest CreateXHRRequestWithOrigin(const char* origin) {
+  ResourceRequest request = CreateXHRRequest("http://bar.com/simple_page.html");
   request.first_party_for_cookies = GURL(origin);
   request.headers = base::StringPrintf("Origin: %s\r\n", origin);
   return request;
@@ -148,7 +148,7 @@
   // blocks indefinitely, which is good because the request stays alive and the
   // test can try to reuse the request id without a race.
   const char* blocking_url = net::URLRequestSlowDownloadJob::kUnknownSizeUrl;
-  ResourceHostMsg_Request request(CreateXHRRequest(blocking_url));
+  ResourceRequest request(CreateXHRRequest(blocking_url));
 
   // Use the same request id twice.
   RenderProcessHostWatcher process_killed(
@@ -414,13 +414,12 @@
 // Renderer processes should not be able to spoof Origin HTTP headers.
 IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
   // Create a set of IPC messages with various Origin headers.
-  ResourceHostMsg_Request chrome_origin_msg(
+  ResourceRequest chrome_origin_msg(
       CreateXHRRequestWithOrigin("chrome://settings"));
-  ResourceHostMsg_Request embedder_isolated_origin_msg(
+  ResourceRequest embedder_isolated_origin_msg(
       CreateXHRRequestWithOrigin("https://isolated.bar.com"));
-  ResourceHostMsg_Request invalid_origin_msg(
-      CreateXHRRequestWithOrigin("invalidurl"));
-  ResourceHostMsg_Request invalid_scheme_origin_msg(
+  ResourceRequest invalid_origin_msg(CreateXHRRequestWithOrigin("invalidurl"));
+  ResourceRequest invalid_scheme_origin_msg(
       CreateXHRRequestWithOrigin("fake-scheme://foo"));
 
   GURL web_url("http://foo.com/simple_page.html");
@@ -443,7 +442,7 @@
   // Web processes cannot make XHRs with URLs that the content embedder expects
   // to have process isolation.  Ideally this would test chrome-extension://
   // URLs for Chrome Apps, but those can't be tested inside content/ and the
-  // ResourceHostMsg_Request IPC can't be created in a test outside content/.
+  // ResourceRequest IPC can't be created in a test outside content/.
   NavigateToURL(shell(), web_url);
   {
     // Set up a ContentBrowserClient that simulates an app URL in a non-app
diff --git a/content/child/request_extra_data.h b/content/child/request_extra_data.h
index 5bb859e..eb80fac5 100644
--- a/content/child/request_extra_data.h
+++ b/content/child/request_extra_data.h
@@ -20,7 +20,7 @@
 namespace content {
 
 // Can be used by callers to store extra data on every ResourceRequest
-// which will be incorporated into the ResourceHostMsg_Request message
+// which will be incorporated into the ResourceHostMsg_RequestResource message
 // sent by ResourceDispatcher.
 class CONTENT_EXPORT RequestExtraData
     : public NON_EXPORTED_BASE(blink::WebURLRequest::ExtraData) {
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index 9cd7011..2a615e72 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -31,6 +31,8 @@
 #include "content/common/inter_process_time_ticks_converter.h"
 #include "content/common/navigation_params.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
+#include "content/common/resource_request_completion_status.h"
 #include "content/public/child/fixed_received_data.h"
 #include "content/public/child/request_peer.h"
 #include "content/public/child/resource_dispatcher_delegate.h"
@@ -341,7 +343,7 @@
 
 void ResourceDispatcher::OnRequestComplete(
     int request_id,
-    const ResourceMsg_RequestCompleteData& request_complete_data) {
+    const ResourceRequestCompletionStatus& request_complete_data) {
   TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete");
 
   PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
@@ -542,7 +544,7 @@
 void ResourceDispatcher::StartSync(const RequestInfo& request_info,
                                    ResourceRequestBody* request_body,
                                    SyncLoadResponse* response) {
-  std::unique_ptr<ResourceHostMsg_Request> request =
+  std::unique_ptr<ResourceRequest> request =
       CreateRequest(request_info, request_body, NULL);
 
   SyncLoadResult result;
@@ -574,7 +576,7 @@
                                    ResourceRequestBody* request_body,
                                    std::unique_ptr<RequestPeer> peer) {
   GURL frame_origin;
-  std::unique_ptr<ResourceHostMsg_Request> request =
+  std::unique_ptr<ResourceRequest> request =
       CreateRequest(request_info, request_body, &frame_origin);
 
   // Compute a unique request_id for this renderer process.
@@ -730,11 +732,11 @@
   }
 }
 
-std::unique_ptr<ResourceHostMsg_Request> ResourceDispatcher::CreateRequest(
+std::unique_ptr<ResourceRequest> ResourceDispatcher::CreateRequest(
     const RequestInfo& request_info,
     ResourceRequestBody* request_body,
     GURL* frame_origin) {
-  std::unique_ptr<ResourceHostMsg_Request> request(new ResourceHostMsg_Request);
+  std::unique_ptr<ResourceRequest> request(new ResourceRequest);
   request->method = request_info.method;
   request->url = request_info.url;
   request->first_party_for_cookies = request_info.first_party_for_cookies;
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h
index c676e695..17c80e416 100644
--- a/content/child/resource_dispatcher.h
+++ b/content/child/resource_dispatcher.h
@@ -28,9 +28,6 @@
 #include "net/base/request_priority.h"
 #include "url/gurl.h"
 
-struct ResourceHostMsg_Request;
-struct ResourceMsg_RequestCompleteData;
-
 namespace net {
 struct RedirectInfo;
 }
@@ -42,6 +39,8 @@
 class ResourceSchedulingFilter;
 struct ResourceResponseInfo;
 struct RequestInfo;
+struct ResourceRequest;
+struct ResourceRequestCompletionStatus;
 struct ResourceResponseHead;
 class SharedMemoryReceivedDataFactory;
 struct SiteIsolationResponseMetaData;
@@ -187,7 +186,7 @@
   void OnDownloadedData(int request_id, int data_len, int encoded_data_length);
   void OnRequestComplete(
       int request_id,
-      const ResourceMsg_RequestCompleteData& request_complete_data);
+      const ResourceRequestCompletionStatus& request_complete_data);
 
   // Dispatch the message to one of the message response handlers.
   void DispatchMessage(const IPC::Message& message);
@@ -223,7 +222,7 @@
   // for use on deferred message queues that are no longer needed.
   static void ReleaseResourcesInMessageQueue(MessageQueue* queue);
 
-  std::unique_ptr<ResourceHostMsg_Request> CreateRequest(
+  std::unique_ptr<ResourceRequest> CreateRequest(
       const RequestInfo& request_info,
       ResourceRequestBody* request_body,
       GURL* frame_origin);
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc
index 1a7d58f..b250ca4 100644
--- a/content/child/resource_dispatcher_unittest.cc
+++ b/content/child/resource_dispatcher_unittest.cc
@@ -23,6 +23,8 @@
 #include "content/child/request_info.h"
 #include "content/common/appcache_interfaces.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
+#include "content/common/resource_request_completion_status.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/child/fixed_received_data.h"
 #include "content/public/child/request_peer.h"
@@ -172,7 +174,7 @@
       ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
       return -1;
     }
-    ResourceHostMsg_Request request = base::get<2>(params);
+    ResourceRequest request = base::get<2>(params);
     EXPECT_EQ(kTestPageUrl, request.url.spec());
     message_queue_.erase(message_queue_.begin());
     return base::get<1>(params);
@@ -283,7 +285,7 @@
   }
 
   void NotifyRequestComplete(int request_id, size_t total_size) {
-    ResourceMsg_RequestCompleteData request_complete_data;
+    ResourceRequestCompletionStatus request_complete_data;
     request_complete_data.error_code = net::OK;
     request_complete_data.was_ignored_by_handler = false;
     request_complete_data.exists_in_cache = false;
diff --git a/content/common/frame_message_enums.h b/content/common/frame_message_enums.h
index 27e98433c..bbb973ad6 100644
--- a/content/common/frame_message_enums.h
+++ b/content/common/frame_message_enums.h
@@ -13,6 +13,9 @@
     // Reload the page, validating cache entries.
     RELOAD,
 
+    // Reload the page, validating only cache entry for the main resource.
+    RELOAD_MAIN_RESOURCE,
+
     // Reload the page, bypassing any cache entries.
     RELOAD_BYPASSING_CACHE,
 
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index 3471b4b..c74a4e810 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -14,7 +14,9 @@
 #include "base/process/process.h"
 #include "content/common/content_param_traits_macros.h"
 #include "content/common/navigation_params.h"
+#include "content/common/resource_request.h"
 #include "content/common/resource_request_body.h"
+#include "content/common/resource_request_completion_status.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/common/common_param_traits.h"
 #include "content/public/common/resource_response.h"
@@ -196,170 +198,59 @@
 
 IPC_ENUM_TRAITS_MAX_VALUE(net::ct::SCTVerifyStatus, net::ct::SCT_STATUS_MAX)
 
-// Parameters for a resource request.
-IPC_STRUCT_BEGIN(ResourceHostMsg_Request)
-  // The request method: GET, POST, etc.
-  IPC_STRUCT_MEMBER(std::string, method)
-
-  // The requested URL.
-  IPC_STRUCT_MEMBER(GURL, url)
-
-  // Usually the URL of the document in the top-level window, which may be
-  // checked by the third-party cookie blocking policy. Leaving it empty may
-  // lead to undesired cookie blocking. Third-party cookie blocking can be
-  // bypassed by setting first_party_for_cookies = url, but this should ideally
-  // only be done if there really is no way to determine the correct value.
-  IPC_STRUCT_MEMBER(GURL, first_party_for_cookies)
-
-  // The origin of the context which initiated the request, which will be used
-  // for cookie checks like 'First-Party-Only'.
-  IPC_STRUCT_MEMBER(url::Origin, request_initiator)
-
-  // The referrer to use (may be empty).
-  IPC_STRUCT_MEMBER(GURL, referrer)
-
-  // The referrer policy to use.
-  IPC_STRUCT_MEMBER(blink::WebReferrerPolicy, referrer_policy)
-
-  // The frame's visiblity state.
-  IPC_STRUCT_MEMBER(blink::WebPageVisibilityState, visiblity_state)
-
-  // Additional HTTP request headers.
-  IPC_STRUCT_MEMBER(std::string, headers)
-
-  // net::URLRequest load flags (0 by default).
-  IPC_STRUCT_MEMBER(int, load_flags)
-
-  // Process ID from which this request originated, or zero if it originated
-  // in the renderer itself.
-  // If kDirectNPAPIRequests isn't specified, then plugin requests get routed
-  // through the renderer and and this holds the pid of the plugin process.
-  // Otherwise this holds the render_process_id of the view that has the plugin.
-  IPC_STRUCT_MEMBER(int, origin_pid)
-
-  // What this resource load is for (main frame, sub-frame, sub-resource,
-  // object).
-  IPC_STRUCT_MEMBER(content::ResourceType, resource_type)
-
-  // The priority of this request.
-  IPC_STRUCT_MEMBER(net::RequestPriority, priority)
-
-  // Used by plugin->browser requests to get the correct net::URLRequestContext.
-  IPC_STRUCT_MEMBER(uint32_t, request_context)
-
-  // Indicates which frame (or worker context) the request is being loaded into,
-  // or kAppCacheNoHostId.
-  IPC_STRUCT_MEMBER(int, appcache_host_id)
-
-  // True if corresponding AppCache group should be resetted.
-  IPC_STRUCT_MEMBER(bool, should_reset_appcache)
-
-  // Indicates which frame (or worker context) the request is being loaded into,
-  // or kInvalidServiceWorkerProviderId.
-  IPC_STRUCT_MEMBER(int, service_worker_provider_id)
-
-  // True if the request originated from a Service Worker, e.g. due to a
-  // fetch() in the Service Worker script.
-  IPC_STRUCT_MEMBER(bool, originated_from_service_worker)
-
-  // True if the request should not be handled by the ServiceWorker.
-  IPC_STRUCT_MEMBER(bool, skip_service_worker)
-
-  // The request mode passed to the ServiceWorker.
-  IPC_STRUCT_MEMBER(content::FetchRequestMode, fetch_request_mode)
-
-  // The credentials mode passed to the ServiceWorker.
-  IPC_STRUCT_MEMBER(content::FetchCredentialsMode, fetch_credentials_mode)
-
-  // The redirect mode used in Fetch API.
-  IPC_STRUCT_MEMBER(content::FetchRedirectMode, fetch_redirect_mode)
-
-  // The request context passed to the ServiceWorker.
-  IPC_STRUCT_MEMBER(content::RequestContextType, fetch_request_context_type)
-
-  // The frame type passed to the ServiceWorker.
-  IPC_STRUCT_MEMBER(content::RequestContextFrameType, fetch_frame_type)
-
-  // Optional resource request body (may be null).
-  IPC_STRUCT_MEMBER(scoped_refptr<content::ResourceRequestBody>,
-                    request_body)
-
-  IPC_STRUCT_MEMBER(bool, download_to_file)
-
-  // True if the request was user initiated.
-  IPC_STRUCT_MEMBER(bool, has_user_gesture)
-
-  // True if load timing data should be collected for request.
-  IPC_STRUCT_MEMBER(bool, enable_load_timing)
-
-  // True if upload progress should be available for request.
-  IPC_STRUCT_MEMBER(bool, enable_upload_progress)
-
-  // True if login prompts for this request should be supressed.
-  IPC_STRUCT_MEMBER(bool, do_not_prompt_for_login)
-
-  // The routing id of the RenderFrame.
-  IPC_STRUCT_MEMBER(int, render_frame_id)
-
-  // True if |frame_id| is the main frame of a RenderView.
-  IPC_STRUCT_MEMBER(bool, is_main_frame)
-
-  // True if |parent_render_frame_id| is the main frame of a RenderView.
-  IPC_STRUCT_MEMBER(bool, parent_is_main_frame)
-
-  // Identifies the parent frame of the frame that sent the request.
-  // -1 if unknown / invalid.
-  IPC_STRUCT_MEMBER(int, parent_render_frame_id)
-
-  IPC_STRUCT_MEMBER(ui::PageTransition, transition_type)
-
-  // For navigations, whether this navigation should replace the current session
-  // history entry on commit.
-  IPC_STRUCT_MEMBER(bool, should_replace_current_entry)
-
-  // The following two members identify a previous request that has been
-  // created before this navigation has been transferred to a new render view.
-  // This serves the purpose of recycling the old request.
-  // Unless this refers to a transferred navigation, these values are -1 and -1.
-  IPC_STRUCT_MEMBER(int, transferred_request_child_id)
-  IPC_STRUCT_MEMBER(int, transferred_request_request_id)
-
-  // Whether or not we should allow the URL to download.
-  IPC_STRUCT_MEMBER(bool, allow_download)
-
-  // Whether to intercept headers to pass back to the renderer.
-  IPC_STRUCT_MEMBER(bool, report_raw_headers)
-
-  // Whether or not to request a LoFi version of the resource or let the browser
-  // decide.
-  IPC_STRUCT_MEMBER(content::LoFiState, lofi_state)
-
-  // PlzNavigate: the stream url associated with a navigation. Used to get
-  // access to the body of the response that has already been fetched by the
-  // browser.
-  IPC_STRUCT_MEMBER(GURL, resource_body_stream_url)
-IPC_STRUCT_END()
+IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequest)
+  IPC_STRUCT_TRAITS_MEMBER(method)
+  IPC_STRUCT_TRAITS_MEMBER(url)
+  IPC_STRUCT_TRAITS_MEMBER(first_party_for_cookies)
+  IPC_STRUCT_TRAITS_MEMBER(request_initiator)
+  IPC_STRUCT_TRAITS_MEMBER(referrer)
+  IPC_STRUCT_TRAITS_MEMBER(referrer_policy)
+  IPC_STRUCT_TRAITS_MEMBER(visiblity_state)
+  IPC_STRUCT_TRAITS_MEMBER(headers)
+  IPC_STRUCT_TRAITS_MEMBER(load_flags)
+  IPC_STRUCT_TRAITS_MEMBER(origin_pid)
+  IPC_STRUCT_TRAITS_MEMBER(resource_type)
+  IPC_STRUCT_TRAITS_MEMBER(priority)
+  IPC_STRUCT_TRAITS_MEMBER(request_context)
+  IPC_STRUCT_TRAITS_MEMBER(appcache_host_id)
+  IPC_STRUCT_TRAITS_MEMBER(should_reset_appcache)
+  IPC_STRUCT_TRAITS_MEMBER(service_worker_provider_id)
+  IPC_STRUCT_TRAITS_MEMBER(originated_from_service_worker)
+  IPC_STRUCT_TRAITS_MEMBER(skip_service_worker)
+  IPC_STRUCT_TRAITS_MEMBER(fetch_request_mode)
+  IPC_STRUCT_TRAITS_MEMBER(fetch_credentials_mode)
+  IPC_STRUCT_TRAITS_MEMBER(fetch_redirect_mode)
+  IPC_STRUCT_TRAITS_MEMBER(fetch_request_context_type)
+  IPC_STRUCT_TRAITS_MEMBER(fetch_frame_type)
+  IPC_STRUCT_TRAITS_MEMBER(request_body)
+  IPC_STRUCT_TRAITS_MEMBER(download_to_file)
+  IPC_STRUCT_TRAITS_MEMBER(has_user_gesture)
+  IPC_STRUCT_TRAITS_MEMBER(enable_load_timing)
+  IPC_STRUCT_TRAITS_MEMBER(enable_upload_progress)
+  IPC_STRUCT_TRAITS_MEMBER(do_not_prompt_for_login)
+  IPC_STRUCT_TRAITS_MEMBER(render_frame_id)
+  IPC_STRUCT_TRAITS_MEMBER(is_main_frame)
+  IPC_STRUCT_TRAITS_MEMBER(parent_is_main_frame)
+  IPC_STRUCT_TRAITS_MEMBER(parent_render_frame_id)
+  IPC_STRUCT_TRAITS_MEMBER(transition_type)
+  IPC_STRUCT_TRAITS_MEMBER(should_replace_current_entry)
+  IPC_STRUCT_TRAITS_MEMBER(transferred_request_child_id)
+  IPC_STRUCT_TRAITS_MEMBER(transferred_request_request_id)
+  IPC_STRUCT_TRAITS_MEMBER(allow_download)
+  IPC_STRUCT_TRAITS_MEMBER(report_raw_headers)
+  IPC_STRUCT_TRAITS_MEMBER(lofi_state)
+  IPC_STRUCT_TRAITS_MEMBER(resource_body_stream_url)
+IPC_STRUCT_TRAITS_END()
 
 // Parameters for a ResourceMsg_RequestComplete
-IPC_STRUCT_BEGIN(ResourceMsg_RequestCompleteData)
-  // The error code.
-  IPC_STRUCT_MEMBER(int, error_code)
-
-  // Was ignored by the request handler.
-  IPC_STRUCT_MEMBER(bool, was_ignored_by_handler)
-
-  // A copy of the data requested exists in the cache.
-  IPC_STRUCT_MEMBER(bool, exists_in_cache)
-
-  // Serialized security info; see content/common/ssl_status_serialization.h.
-  IPC_STRUCT_MEMBER(std::string, security_info)
-
-  // Time the request completed.
-  IPC_STRUCT_MEMBER(base::TimeTicks, completion_time)
-
-  // Total amount of data received from the network.
-  IPC_STRUCT_MEMBER(int64_t, encoded_data_length)
-IPC_STRUCT_END()
+IPC_STRUCT_TRAITS_BEGIN(content::ResourceRequestCompletionStatus)
+  IPC_STRUCT_TRAITS_MEMBER(error_code)
+  IPC_STRUCT_TRAITS_MEMBER(was_ignored_by_handler)
+  IPC_STRUCT_TRAITS_MEMBER(exists_in_cache)
+  IPC_STRUCT_TRAITS_MEMBER(security_info)
+  IPC_STRUCT_TRAITS_MEMBER(completion_time)
+  IPC_STRUCT_TRAITS_MEMBER(encoded_data_length)
+IPC_STRUCT_TRAITS_END()
 
 // Resource messages sent from the browser to the renderer.
 
@@ -432,15 +323,15 @@
 // Sent when the request has been completed.
 IPC_MESSAGE_CONTROL2(ResourceMsg_RequestComplete,
                      int /* request_id */,
-                     ResourceMsg_RequestCompleteData)
+                     content::ResourceRequestCompletionStatus)
 
 // Resource messages sent from the renderer to the browser.
 
 // Makes a resource request via the browser.
 IPC_MESSAGE_CONTROL3(ResourceHostMsg_RequestResource,
-                    int /* routing_id */,
-                    int /* request_id */,
-                    ResourceHostMsg_Request)
+                     int /* routing_id */,
+                     int /* request_id */,
+                     content::ResourceRequest)
 
 // Cancels a resource request with the ID given as the parameter.
 IPC_MESSAGE_CONTROL1(ResourceHostMsg_CancelRequest,
@@ -454,7 +345,7 @@
 // Makes a synchronous resource request via the browser.
 IPC_SYNC_MESSAGE_ROUTED2_1(ResourceHostMsg_SyncLoad,
                            int /* request_id */,
-                           ResourceHostMsg_Request,
+                           content::ResourceRequest,
                            content::SyncLoadResult)
 
 // Sent when the renderer process is done processing a DataReceived
diff --git a/content/common/resource_request.cc b/content/common/resource_request.cc
new file mode 100644
index 0000000..54f4598
--- /dev/null
+++ b/content/common/resource_request.cc
@@ -0,0 +1,13 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/resource_request.h"
+
+namespace content {
+
+ResourceRequest::ResourceRequest() {}
+ResourceRequest::ResourceRequest(const ResourceRequest& request) = default;
+ResourceRequest::~ResourceRequest() {}
+
+}  // namespace content
diff --git a/content/common/resource_request.h b/content/common/resource_request.h
new file mode 100644
index 0000000..d59dbf7
--- /dev/null
+++ b/content/common/resource_request.h
@@ -0,0 +1,177 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_RESOURCE_REQUEST_H_
+#define CONTENT_COMMON_RESOURCE_REQUEST_H_
+
+#include <stdint.h>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
+#include "content/common/navigation_params.h"
+#include "content/common/resource_request_body.h"
+#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/appcache_info.h"
+#include "content/public/common/request_context_frame_type.h"
+#include "content/public/common/request_context_type.h"
+#include "content/public/common/resource_type.h"
+#include "net/base/request_priority.h"
+#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
+#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
+#include "ui/base/page_transition_types.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+struct CONTENT_EXPORT ResourceRequest {
+  ResourceRequest();
+  ResourceRequest(const ResourceRequest& request);
+  ~ResourceRequest();
+
+  // The request method: GET, POST, etc.
+  std::string method;
+
+  // The requested URL.
+  GURL url;
+
+  // Usually the URL of the document in the top-level window, which may be
+  // checked by the third-party cookie blocking policy. Leaving it empty may
+  // lead to undesired cookie blocking. Third-party cookie blocking can be
+  // bypassed by setting first_party_for_cookies = url, but this should ideally
+  // only be done if there really is no way to determine the correct value.
+  GURL first_party_for_cookies;
+
+  // The origin of the context which initiated the request, which will be used
+  // for cookie checks like 'First-Party-Only'.
+  url::Origin request_initiator;
+
+  // The referrer to use (may be empty).
+  GURL referrer;
+
+  // The referrer policy to use.
+  blink::WebReferrerPolicy referrer_policy = blink::WebReferrerPolicyAlways;
+
+  // The frame's visiblity state.
+  blink::WebPageVisibilityState visiblity_state =
+      blink::WebPageVisibilityStateVisible;
+
+  // Additional HTTP request headers.
+  std::string headers;
+
+  // net::URLRequest load flags (0 by default).
+  int load_flags = 0;
+
+  // Process ID from which this request originated, or zero if it originated
+  // in the renderer itself.
+  int origin_pid = 0;
+
+  // What this resource load is for (main frame, sub-frame, sub-resource,
+  // object).
+  ResourceType resource_type = RESOURCE_TYPE_MAIN_FRAME;
+
+  // The priority of this request.
+  net::RequestPriority priority = net::IDLE;
+
+  // Used by plugin->browser requests to get the correct net::URLRequestContext.
+  uint32_t request_context = 0;
+
+  // Indicates which frame (or worker context) the request is being loaded into,
+  // or kAppCacheNoHostId.
+  int appcache_host_id = kAppCacheNoHostId;
+
+  // True if corresponding AppCache group should be resetted.
+  bool should_reset_appcache = false;
+
+  // Indicates which frame (or worker context) the request is being loaded into,
+  // or kInvalidServiceWorkerProviderId.
+  int service_worker_provider_id = kInvalidServiceWorkerProviderId;
+
+  // True if the request originated from a Service Worker, e.g. due to a
+  // fetch() in the Service Worker script.
+  bool originated_from_service_worker = false;
+
+  // True if the request should not be handled by the ServiceWorker.
+  bool skip_service_worker = false;
+
+  // The request mode passed to the ServiceWorker.
+  FetchRequestMode fetch_request_mode = FETCH_REQUEST_MODE_SAME_ORIGIN;
+
+  // The credentials mode passed to the ServiceWorker.
+  FetchCredentialsMode fetch_credentials_mode = FETCH_CREDENTIALS_MODE_OMIT;
+
+  // The redirect mode used in Fetch API.
+  FetchRedirectMode fetch_redirect_mode = FetchRedirectMode::FOLLOW_MODE;
+
+  // The request context passed to the ServiceWorker.
+  RequestContextType fetch_request_context_type =
+      REQUEST_CONTEXT_TYPE_UNSPECIFIED;
+
+  // The frame type passed to the ServiceWorker.
+  RequestContextFrameType fetch_frame_type =
+      REQUEST_CONTEXT_FRAME_TYPE_AUXILIARY;
+
+  // Optional resource request body (may be null).
+  scoped_refptr<ResourceRequestBody> request_body;
+
+  bool download_to_file = false;
+
+  // True if the request was user initiated.
+  bool has_user_gesture = false;
+
+  // True if load timing data should be collected for request.
+  bool enable_load_timing = false;
+
+  // True if upload progress should be available for request.
+  bool enable_upload_progress = false;
+
+  // True if login prompts for this request should be supressed.
+  bool do_not_prompt_for_login = false;
+
+  // The routing id of the RenderFrame.
+  int render_frame_id = 0;
+
+  // True if |frame_id| is the main frame of a RenderView.
+  bool is_main_frame = false;
+
+  // True if |parent_render_frame_id| is the main frame of a RenderView.
+  bool parent_is_main_frame = false;
+
+  // Identifies the parent frame of the frame that sent the request.
+  // -1 if unknown / invalid.
+  int parent_render_frame_id = -1;
+
+  ui::PageTransition transition_type = ui::PAGE_TRANSITION_LINK;
+
+  // For navigations, whether this navigation should replace the current session
+  // history entry on commit.
+  bool should_replace_current_entry = false;
+
+  // The following two members identify a previous request that has been
+  // created before this navigation has been transferred to a new render view.
+  // This serves the purpose of recycling the old request.
+  // Unless this refers to a transferred navigation, these values are -1 and -1.
+  int transferred_request_child_id = -1;
+  int transferred_request_request_id = -1;
+
+  // Whether or not we should allow the URL to download.
+  bool allow_download = false;
+
+  // Whether to intercept headers to pass back to the renderer.
+  bool report_raw_headers = false;
+
+  // Whether or not to request a LoFi version of the resource or let the browser
+  // decide.
+  LoFiState lofi_state = LOFI_UNSPECIFIED;
+
+  // PlzNavigate: the stream url associated with a navigation. Used to get
+  // access to the body of the response that has already been fetched by the
+  // browser.
+  GURL resource_body_stream_url;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_RESOURCE_REQUEST_H_
diff --git a/content/common/resource_request_completion_status.cc b/content/common/resource_request_completion_status.cc
new file mode 100644
index 0000000..4f2c850
--- /dev/null
+++ b/content/common/resource_request_completion_status.cc
@@ -0,0 +1,14 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/resource_request_completion_status.h"
+
+namespace content {
+
+ResourceRequestCompletionStatus::ResourceRequestCompletionStatus() {}
+ResourceRequestCompletionStatus::ResourceRequestCompletionStatus(
+    const ResourceRequestCompletionStatus& status) = default;
+ResourceRequestCompletionStatus::~ResourceRequestCompletionStatus() {}
+
+}  // namespace content
diff --git a/content/common/resource_request_completion_status.h b/content/common/resource_request_completion_status.h
new file mode 100644
index 0000000..766c0ea
--- /dev/null
+++ b/content/common/resource_request_completion_status.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_RESOURCE_REQUEST_COMPLETION_STATUS_H_
+#define CONTENT_COMMON_RESOURCE_REQUEST_COMPLETION_STATUS_H_
+
+#include <stdint.h>
+#include <string>
+
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+struct CONTENT_EXPORT ResourceRequestCompletionStatus {
+  ResourceRequestCompletionStatus();
+  ResourceRequestCompletionStatus(
+      const ResourceRequestCompletionStatus& status);
+  ~ResourceRequestCompletionStatus();
+
+  // The error code.
+  int error_code = 0;
+
+  // Was ignored by the request handler.
+  bool was_ignored_by_handler = false;
+
+  // A copy of the data requested exists in the cache.
+  bool exists_in_cache = false;
+
+  // Serialized security info; see content/common/ssl_status_serialization.h.
+  std::string security_info;
+
+  // Time the request completed.
+  base::TimeTicks completion_time;
+
+  // Total amount of data received from the network.
+  int64_t encoded_data_length = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_RESOURCE_REQUEST_COMPLETION_STATUS_H_
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 0fa1c31..e9e6e813 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -475,8 +475,12 @@
       'common/resize_params.h',
       'common/resource_messages.cc',
       'common/resource_messages.h',
+      'common/resource_request.cc',
+      'common/resource_request.h',
       'common/resource_request_body.cc',
       'common/resource_request_body.h',
+      'common/resource_request_completion_status.cc',
+      'common/resource_request_completion_status.h',
       'common/sandbox_init_mac.cc',
       'common/sandbox_init_mac.h',
       'common/sandbox_init_win.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 8b5c2a4c..d8a7ea96 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -234,6 +234,7 @@
       'browser/loader/async_resource_handler_browsertest.cc',
       'browser/loader/async_revalidation_manager_browsertest.cc',
       'browser/loader/cross_site_resource_handler_browsertest.cc',
+      'browser/loader/reload_cache_control_browsertest.cc',
       'browser/loader/resource_dispatcher_host_browsertest.cc',
       'browser/manifest/manifest_browsertest.cc',
       'browser/media/encrypted_media_browsertest.cc',
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn
index 1b3aa77..593136e 100644
--- a/content/gpu/BUILD.gn
+++ b/content/gpu/BUILD.gn
@@ -57,7 +57,6 @@
     "//ipc",
     "//media/gpu",
     "//media/gpu/ipc/service",
-    "//media/mojo/services:application_factory",
     "//services/shell/public/interfaces",
     "//skia",
     "//ui/events/ipc",
@@ -67,7 +66,7 @@
   ]
 
   if (mojo_media_host == "gpu") {
-    deps += [ "//media/mojo/services:application_factory" ]
+    deps += [ "//media/mojo/services" ]
     if (is_android) {
       deps += [ "//media/base/android" ]
     }
diff --git a/content/gpu/gpu_process_control_impl.cc b/content/gpu/gpu_process_control_impl.cc
index 0ecc58b6..832ae7d 100644
--- a/content/gpu/gpu_process_control_impl.cc
+++ b/content/gpu/gpu_process_control_impl.cc
@@ -8,7 +8,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "content/public/common/content_client.h"
-#include "media/mojo/services/mojo_media_application_factory.h"
+#include "media/mojo/services/mojo_media_application_factory.h"  // nogncheck
 #if defined(OS_ANDROID)
 #include "media/base/android/media_client_android.h"
 #endif
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h
index 6e6c2e4..e3673d1 100644
--- a/content/public/browser/navigation_controller.h
+++ b/content/public/browser/navigation_controller.h
@@ -49,6 +49,7 @@
   enum ReloadType {
     NO_RELOAD,                   // Normal load, restore, or history navigation.
     RELOAD,                      // Normal (cache-validating) reload.
+    RELOAD_MAIN_RESOURCE,        // Reload validating only the main resource.
     RELOAD_BYPASSING_CACHE,      // Reload bypassing the cache (shift-reload).
     RELOAD_ORIGINAL_REQUEST_URL, // Reload using the original request URL.
     RELOAD_DISABLE_LOFI_MODE     // Reload with Lo-Fi mode disabled.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 66f0880..95fc49d 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -56,7 +56,7 @@
 // Non-validating reload on reload-to-refresh-content (e.g. pull-to-refresh).
 // See https://crbug.com/558829
 const base::Feature kNonValidatingReloadOnRefreshContent{
-    "NonValidatingReloadOnRefreshContent",
+    "NonValidatingReloadOnRefreshContentV2",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
 // An experiment to optimize resource loading IPC for small resources.
diff --git a/content/public/common/mojo_application_info.cc b/content/public/common/mojo_application_info.cc
index 4c2c534..8bb3856 100644
--- a/content/public/common/mojo_application_info.cc
+++ b/content/public/common/mojo_application_info.cc
@@ -5,6 +5,7 @@
 #include "content/public/common/mojo_application_info.h"
 
 #include "base/callback.h"
+#include "services/shell/public/cpp/shell_client.h"
 
 namespace content {
 
diff --git a/content/public/common/mojo_application_info.h b/content/public/common/mojo_application_info.h
index b5bcc44..f412aa6d 100644
--- a/content/public/common/mojo_application_info.h
+++ b/content/public/common/mojo_application_info.h
@@ -7,14 +7,14 @@
 
 #include <memory>
 
-#include "base/callback_forward.h"
+#include "base/callback.h"
 #include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "services/shell/public/cpp/shell_client.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}  // namespace base
+namespace shell {
+class ShellClient;
+}
 
 namespace content {
 
diff --git a/content/public/test/content_browser_test_utils.cc b/content/public/test/content_browser_test_utils.cc
index dab6f727..daa8e09 100644
--- a/content/public/test/content_browser_test_utils.cc
+++ b/content/public/test/content_browser_test_utils.cc
@@ -53,6 +53,17 @@
   same_tab_observer.Wait();
 }
 
+void ReloadBypassingCacheBlockUntilNavigationsComplete(
+    Shell* window,
+    int number_of_navigations) {
+  WaitForLoadStop(window->web_contents());
+  TestNavigationObserver same_tab_observer(window->web_contents(),
+                                           number_of_navigations);
+
+  window->ReloadBypassingCache();
+  same_tab_observer.Wait();
+}
+
 void LoadDataWithBaseURL(Shell* window,
                          const GURL& url,
                          const std::string& data,
diff --git a/content/public/test/content_browser_test_utils.h b/content/public/test/content_browser_test_utils.h
index 19a00349..47b2c07 100644
--- a/content/public/test/content_browser_test_utils.h
+++ b/content/public/test/content_browser_test_utils.h
@@ -69,6 +69,12 @@
 void ReloadBlockUntilNavigationsComplete(Shell* window,
                                          int number_of_navigations);
 
+// Reloads |window| with bypassing cache flag, and blocks until the given number
+// of navigations finishes.
+void ReloadBypassingCacheBlockUntilNavigationsComplete(
+    Shell* window,
+    int number_of_navigations);
+
 // Wait until an application modal dialog is requested.
 void WaitForAppModalDialog(Shell* window);
 
diff --git a/content/renderer/media/media_stream_video_source.h b/content/renderer/media/media_stream_video_source.h
index 0ad206a..550adea20 100644
--- a/content/renderer/media/media_stream_video_source.h
+++ b/content/renderer/media/media_stream_video_source.h
@@ -98,6 +98,10 @@
 
   const media::VideoCaptureFormat* GetCurrentFormat() const;
 
+  base::WeakPtr<MediaStreamVideoSource> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
+  }
+
  protected:
   void DoStopSource() override;
 
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index 413bebaf..74893dc 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -229,7 +229,7 @@
           new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(),
                                                     enabled)),
       constraints_(constraints),
-      source_(source) {
+      source_(source->GetWeakPtr()) {
   DCHECK(!constraints.isNull());
   source->AddTrack(this,
                    base::Bind(
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index 9547c3d..e74e3bc 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -86,10 +86,8 @@
 
   const blink::WebMediaConstraints constraints_;
 
-  // Weak ref to the source this tracks is connected to.  |source_| is owned
-  // by the blink::WebMediaStreamSource and is guaranteed to outlive the
-  // track.
-  MediaStreamVideoSource* source_;
+  // Weak ref to the source this tracks is connected to.
+  base::WeakPtr<MediaStreamVideoSource> source_;
 
   // This is used for tracking if all connected video sinks are secure.
   SecureDisplayLinkTracker<MediaStreamVideoSink> secure_tracker_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index bcb7499..61a3eb8b 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -608,9 +608,39 @@
 }
 
 bool IsReload(FrameMsg_Navigate_Type::Value navigation_type) {
-  return navigation_type == FrameMsg_Navigate_Type::RELOAD ||
-         navigation_type == FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE ||
-         navigation_type == FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
+  switch (navigation_type) {
+    case FrameMsg_Navigate_Type::RELOAD:
+    case FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE:
+    case FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE:
+    case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
+      return true;
+    case FrameMsg_Navigate_Type::RESTORE:
+    case FrameMsg_Navigate_Type::RESTORE_WITH_POST:
+    case FrameMsg_Navigate_Type::NORMAL:
+      return false;
+  }
+  NOTREACHED();
+  return false;
+}
+
+WebFrameLoadType ReloadFrameLoadTypeFor(
+    FrameMsg_Navigate_Type::Value navigation_type) {
+  switch (navigation_type) {
+    case FrameMsg_Navigate_Type::RELOAD:
+    case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
+      return WebFrameLoadType::Reload;
+    case FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE:
+      return WebFrameLoadType::ReloadMainResource;
+    case FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE:
+      return WebFrameLoadType::ReloadBypassingCache;
+    case FrameMsg_Navigate_Type::RESTORE:
+    case FrameMsg_Navigate_Type::RESTORE_WITH_POST:
+    case FrameMsg_Navigate_Type::NORMAL:
+      NOTREACHED();
+      return WebFrameLoadType::Standard;
+  }
+  NOTREACHED();
+  return WebFrameLoadType::Standard;
 }
 
 RenderFrameImpl::CreateRenderFrameImplFunction g_create_render_frame_impl =
@@ -5320,10 +5350,7 @@
   // corresponds to a back/forward navigation event. Update the parameters
   // depending on the navigation type.
   if (is_reload) {
-    bool bypass_cache = (common_params.navigation_type ==
-                         FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE);
-    load_type = bypass_cache ? WebFrameLoadType::ReloadBypassingCache
-                             : WebFrameLoadType::Reload;
+    load_type = ReloadFrameLoadTypeFor(common_params.navigation_type);
 
     if (!browser_side_navigation) {
       const GURL override_url =
diff --git a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
index 0a6c159..a3556c1 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
+++ b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_vector.h"
 #include "content/common/resource_messages.h"
+#include "content/common/resource_request.h"
 #include "content/test/fake_renderer_scheduler.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -126,7 +127,7 @@
   bool FlushScheduled() { return throttler_->flush_scheduled(); }
 
   bool RequestResource() {
-    ResourceHostMsg_Request request;
+    ResourceRequest request;
     request.download_to_file = true;
     return throttler_->Send(new ResourceHostMsg_RequestResource(
         kRoutingId, ++last_request_id_, request));
@@ -135,7 +136,7 @@
   bool RequestResourceSync() {
     SyncLoadResult result;
     return throttler_->Send(new ResourceHostMsg_SyncLoad(
-        kRoutingId, ++last_request_id_, ResourceHostMsg_Request(), &result));
+        kRoutingId, ++last_request_id_, ResourceRequest(), &result));
   }
 
   void RequestResourcesUntilThrottled() {
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index dc04ca3..bf7ee55c 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -233,7 +233,6 @@
     "//gpu",
     "//ipc",
     "//media",
-    "//media/mojo/services:application_factory",
     "//net",
     "//net:net_resources",
     "//skia",
@@ -266,7 +265,7 @@
     ]
   }
   if (mojo_media_host == "browser") {
-    deps += [ "//media/mojo/services:application_factory" ]
+    deps += [ "//media/mojo/services" ]
   }
 
   if (is_win) {
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc
index 8110174..12b17d23 100644
--- a/content/shell/browser/shell.cc
+++ b/content/shell/browser/shell.cc
@@ -264,6 +264,11 @@
   web_contents_->Focus();
 }
 
+void Shell::ReloadBypassingCache() {
+  web_contents_->GetController().ReloadBypassingCache(false);
+  web_contents_->Focus();
+}
+
 void Shell::Stop() {
   web_contents_->Stop();
   web_contents_->Focus();
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h
index fb791a4..59125cf2 100644
--- a/content/shell/browser/shell.h
+++ b/content/shell/browser/shell.h
@@ -71,6 +71,7 @@
 #endif
   void GoBackOrForward(int offset);
   void Reload();
+  void ReloadBypassingCache();
   void Stop();
   void UpdateNavigationControls(bool to_different_document);
   void Close();
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 2057cdc8..9d83b18 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -60,7 +60,7 @@
 #endif
 
 #if defined(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
-#include "media/mojo/services/mojo_media_application_factory.h"
+#include "media/mojo/services/mojo_media_application_factory.h"  // nogncheck
 #endif
 
 namespace content {
diff --git a/content/test/data/loader/empty16x16.png b/content/test/data/loader/empty16x16.png
new file mode 100644
index 0000000..6648a69
--- /dev/null
+++ b/content/test/data/loader/empty16x16.png
Binary files differ
diff --git a/content/test/data/loader/reload.html b/content/test/data/loader/reload.html
new file mode 100644
index 0000000..cd8bded
--- /dev/null
+++ b/content/test/data/loader/reload.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<img src="empty16x16.png">
+</body>
+</html>
diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn
index 1c3334b..957fb43f 100644
--- a/content/utility/BUILD.gn
+++ b/content/utility/BUILD.gn
@@ -25,7 +25,6 @@
     "//content/public/child:child_sources",
     "//content/public/common:common_sources",
     "//courgette:courgette_lib",
-    "//media/mojo/services:application_factory",
     "//mojo/common",
     "//mojo/public/cpp/bindings",
     "//services/shell",
@@ -37,7 +36,7 @@
   ]
 
   if (mojo_media_host == "utility") {
-    deps += [ "//media/mojo/services:application_factory" ]
+    deps += [ "//media/mojo/services" ]
   }
 }
 
diff --git a/content/utility/utility_process_control_impl.cc b/content/utility/utility_process_control_impl.cc
index ea89450..76e4f5a 100644
--- a/content/utility/utility_process_control_impl.cc
+++ b/content/utility/utility_process_control_impl.cc
@@ -11,7 +11,7 @@
 #include "content/utility/utility_thread_impl.h"
 
 #if defined(ENABLE_MOJO_MEDIA_IN_UTILITY_PROCESS)
-#include "media/mojo/services/mojo_media_application_factory.h"
+#include "media/mojo/services/mojo_media_application_factory.h"  // nogncheck
 #endif
 
 namespace content {
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.cc b/device/bluetooth/bluez/bluetooth_device_bluez.cc
index c835899a..9ed6bf1c 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.cc
@@ -155,16 +155,9 @@
       weak_ptr_factory_(this) {
   bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()->AddObserver(
       this);
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
 
-  // Add all known GATT services.
-  const std::vector<dbus::ObjectPath> gatt_services =
-      bluez::BluezDBusManager::Get()
-          ->GetBluetoothGattServiceClient()
-          ->GetServices();
-  for (std::vector<dbus::ObjectPath>::const_iterator it = gatt_services.begin();
-       it != gatt_services.end(); ++it) {
-    GattServiceAdded(*it);
-  }
+  InitializeGattServiceMap();
 }
 
 BluetoothDeviceBlueZ::~BluetoothDeviceBlueZ() {
@@ -172,12 +165,14 @@
       ->GetBluetoothGattServiceClient()
       ->RemoveObserver(this);
 
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(
+      this);
   // Copy the GATT services list here and clear the original so that when we
   // send GattServiceRemoved(), GetGattServices() returns no services.
   GattServiceMap gatt_services_swapped;
   gatt_services_swapped.swap(gatt_services_);
   for (const auto& iter : gatt_services_swapped) {
-    DCHECK(adapter_);
+    DCHECK(adapter());
     adapter()->NotifyGattServiceRemoved(
         static_cast<BluetoothRemoteGattServiceBlueZ*>(iter.second));
   }
@@ -553,6 +548,30 @@
   return static_cast<BluetoothAdapterBlueZ*>(adapter_);
 }
 
+void BluetoothDeviceBlueZ::DevicePropertyChanged(
+    const dbus::ObjectPath& object_path,
+    const std::string& property_name) {
+  if (object_path != object_path_)
+    return;
+
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+          object_path);
+  DCHECK(properties);
+
+  if (property_name == properties->services_resolved.name() &&
+      properties->services_resolved.value()) {
+    VLOG(3) << "All services were discovered for device: "
+            << object_path.value();
+
+    for (const auto iter : newly_discovered_gatt_services_) {
+      adapter()->NotifyGattDiscoveryComplete(
+          static_cast<BluetoothRemoteGattService*>(iter));
+    }
+    newly_discovered_gatt_services_.clear();
+  }
+}
+
 void BluetoothDeviceBlueZ::GattServiceAdded(
     const dbus::ObjectPath& object_path) {
   if (GetGattService(object_path.value())) {
@@ -575,12 +594,15 @@
   BluetoothRemoteGattServiceBlueZ* service =
       new BluetoothRemoteGattServiceBlueZ(adapter(), this, object_path);
 
+  newly_discovered_gatt_services_.push_back(
+      static_cast<BluetoothRemoteGattServiceBlueZ*>(service));
+
   gatt_services_.set(service->GetIdentifier(),
                      std::unique_ptr<BluetoothRemoteGattService>(service));
   DCHECK(service->object_path() == object_path);
   DCHECK(service->GetUUID().IsValid());
 
-  DCHECK(adapter_);
+  DCHECK(adapter());
   adapter()->NotifyGattServiceAdded(service);
 }
 
@@ -604,10 +626,37 @@
   std::unique_ptr<BluetoothRemoteGattService> scoped_service =
       gatt_services_.take_and_erase(iter->first);
 
-  DCHECK(adapter_);
+  DCHECK(adapter());
   adapter()->NotifyGattServiceRemoved(service);
 }
 
+void BluetoothDeviceBlueZ::InitializeGattServiceMap() {
+  DCHECK(gatt_services_.empty());
+
+  if (!IsGattServicesDiscoveryComplete()) {
+    VLOG(2) << "Gatt services have not been fully resolved for device "
+            << object_path_.value();
+    return;
+  }
+
+  VLOG(3) << "Initializing the list of GATT services associated with device "
+          << object_path_.value();
+
+  // Add all known GATT services associated with the device.
+  const std::vector<dbus::ObjectPath> gatt_services =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetServices();
+  for (const auto& it : gatt_services)
+    GattServiceAdded(it);
+
+  // Notify on the discovery complete for each service which is found in the
+  // first discovery.
+  DCHECK(adapter());
+  for (const auto& iter : gatt_services_)
+    adapter()->NotifyGattDiscoveryComplete(iter.second);
+}
+
 void BluetoothDeviceBlueZ::OnGetConnInfo(const ConnectionInfoCallback& callback,
                                          int16_t rssi,
                                          int16_t transmit_power,
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.h b/device/bluetooth/bluez/bluetooth_device_bluez.h
index 293c2466..a7576a58 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.h
@@ -38,6 +38,7 @@
 // thread.
 class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceBlueZ
     : public device::BluetoothDevice,
+      public bluez::BluetoothDeviceClient::Observer,
       public bluez::BluetoothGattServiceClient::Observer {
  public:
   // BluetoothDevice override
@@ -124,10 +125,19 @@
       scoped_refptr<device::BluetoothSocketThread> socket_thread);
   ~BluetoothDeviceBlueZ() override;
 
-  // bluez::BluetoothGattServiceClient::Observer overrides.
+  // bluez::BluetoothDeviceClient::Observer overrides
+  void DevicePropertyChanged(const dbus::ObjectPath& object_path,
+                             const std::string& property_name) override;
+
+  // bluez::BluetoothGattServiceClient::Observer overrides
   void GattServiceAdded(const dbus::ObjectPath& object_path) override;
   void GattServiceRemoved(const dbus::ObjectPath& object_path) override;
 
+  // Called by the constructor to initialize the map of GATT services associated
+  // with this device and to invoke NotifyGattDiscoveryComplete() with each
+  // cached service.
+  void InitializeGattServiceMap();
+
   // Called by dbus:: on completion of the D-Bus method call to get the
   // connection attributes of the current connection to the device.
   void OnGetConnInfo(const ConnectionInfoCallback& callback,
@@ -206,6 +216,13 @@
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
   scoped_refptr<device::BluetoothSocketThread> socket_thread_;
 
+  // This vector temporarily caches the newly added services for later
+  // notification of discovery complete. Once DevicePropertyChange is invoked
+  // with a toggle of ServicesResolved property, the
+  // NotifyGattDiscoveryComplete() will be called with each service once.
+  std::vector<device::BluetoothRemoteGattService*>
+      newly_discovered_gatt_services_;
+
   // During pairing this is set to an object that we don't own, but on which
   // we can make method calls to request, display or confirm PIN Codes and
   // Passkeys. Generally it is the object that owns this one.
diff --git a/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
index ce7087e..1c1c110 100644
--- a/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
@@ -325,6 +325,7 @@
   observer.last_gatt_service_id().clear();
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
+
   EXPECT_EQ(2, observer.gatt_service_added_count());
   EXPECT_EQ(1, observer.gatt_service_removed_count());
   EXPECT_FALSE(observer.last_gatt_service_id().empty());
@@ -359,6 +360,62 @@
                       bluez::FakeBluetoothDeviceClient::kLowEnergyAddress));
 }
 
+TEST_F(BluetoothGattBlueZTest, DiscoveryCompleteForCachedGattService) {
+  // This tests if the notifications on service discovered complete are invoked
+  // with the cached services and added to the GATT service map of |device|.
+  TestBluetoothAdapterObserver observer(adapter_);
+
+  // Create the device and pre-expose the fake Heart Rate service. This will
+  // synchronously expose characteristics.
+  fake_bluetooth_device_client_->CreateDevice(
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kCachedLowEnergyPath));
+  BluetoothDevice* device =
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
+  ASSERT_TRUE(device);
+
+  device::BluetoothRemoteGattService* service = device->GetGattServices()[0];
+  EXPECT_EQ(1u, device->GetGattServices().size());
+  EXPECT_EQ(1, observer.gatt_discovery_complete_count());
+  EXPECT_EQ(device, service->GetDevice());
+  EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
+  EXPECT_EQ(3U, service->GetCharacteristics().size());
+}
+
+TEST_F(BluetoothGattBlueZTest, DiscoveryCompleteForNewGattService) {
+  TestBluetoothAdapterObserver observer(adapter_);
+
+  // This tests the discovery complete notification on a newly-added GATT
+  // service.
+  fake_bluetooth_device_client_->CreateDevice(
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
+  BluetoothDevice* device =
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
+  ASSERT_TRUE(device);
+
+  EXPECT_EQ(0u, device->GetGattServices().size());
+  EXPECT_EQ(0, observer.gatt_discovery_complete_count());
+
+  // Expose the fake Heart Rate service. This will asynchronously expose
+  // characteristics.
+  fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
+
+  // Run the message loop so that the characteristics/descriptors appear.
+  base::MessageLoop::current()->Run();
+
+  // The discovery completed event of a newly-added GATT service should not be
+  // fired until ServicesResolved property becomes true. And the new service
+  // will be added immediately to the GATT service map of |device|.
+  BluetoothRemoteGattService* service = device->GetGattServices()[0];
+  EXPECT_EQ(1u, device->GetGattServices().size());
+  EXPECT_EQ(1, observer.gatt_discovery_complete_count());
+  EXPECT_EQ(device, service->GetDevice());
+  EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
+  EXPECT_EQ(3U, service->GetCharacteristics().size());
+}
+
 TEST_F(BluetoothGattBlueZTest, ServicesDiscovered) {
   // Create a fake LE device. We store the device pointer here because this is a
   // test. It's unsafe to do this in production as the device might get deleted.
@@ -378,9 +435,8 @@
   // Expose the fake Heart Rate Service.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
-  // Notify that all services have been discovered.
-  properties->services_resolved.ReplaceValue(true);
-
+  // Run the message loop so that the characteristics/descriptors appear.
+  base::MessageLoop::current()->Run();
   EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
   EXPECT_EQ(1u, device->GetGattServices().size());
   EXPECT_EQ(device, observer.last_device());
@@ -412,7 +468,8 @@
   // Verify that service discovery can be done again:
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
-  properties->services_resolved.ReplaceValue(true);
+  // Run the message loop so that the characteristics/descriptors appear.
+  base::MessageLoop::current()->Run();
   EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
   EXPECT_EQ(1u, device->GetGattServices().size());
 }
diff --git a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.cc b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.cc
index 6031388..50786999 100644
--- a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.cc
@@ -22,7 +22,6 @@
     const dbus::ObjectPath& object_path)
     : BluetoothGattServiceBlueZ(adapter, object_path),
       device_(device),
-      discovery_complete_(false),
       weak_ptr_factory_(this) {
   VLOG(1) << "Creating remote GATT service with identifier: "
           << object_path.value();
@@ -118,7 +117,7 @@
   // Don't send service changed unless we know that all characteristics have
   // already been discovered. This is to prevent spammy events before sending
   // out the first Gatt
-  if (!discovery_complete_)
+  if (!device_->IsGattServicesDiscoveryComplete())
     return;
 
   DCHECK(GetAdapter());
diff --git a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
index 46192a7..e194392 100644
--- a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
@@ -6,6 +6,7 @@
 #define DEVICE_BLUETOOTH_BLUEZ_BLUETOOTH_REMOTE_GATT_SERVICE_BLUEZ_H_
 
 #include <stdint.h>
+
 #include <map>
 #include <string>
 #include <vector>
@@ -111,10 +112,6 @@
   // characteristics by identifier.
   CharacteristicMap characteristics_;
 
-  // Indicates whether or not the characteristics of this service are known to
-  // have been discovered.
-  bool discovery_complete_;
-
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothRemoteGattServiceBlueZ> weak_ptr_factory_;
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
index dda98de..391ad91 100644
--- a/device/bluetooth/dbus/fake_bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
@@ -218,6 +218,15 @@
 const uint32_t
     FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceClass = 0x7a020c;
 
+const char FakeBluetoothDeviceClient::kCachedLowEnergyPath[] =
+    "/fake/hci0/devF";
+const char FakeBluetoothDeviceClient::kCachedLowEnergyAddress[] =
+    "02:A5:11:0D:15:40";
+const char FakeBluetoothDeviceClient::kCachedLowEnergyName[] =
+    "Bluetooth 4.0 Heart Rate Monitor";
+const uint32_t FakeBluetoothDeviceClient::kCachedLowEnergyClass =
+    0x000918;  // Major class "Health", Minor class "Heart/Pulse Rate Monitor."
+
 FakeBluetoothDeviceClient::Properties::Properties(
     const PropertyChangedCallback& callback)
     : BluetoothDeviceClient::Properties(
@@ -698,12 +707,32 @@
     properties->paired.ReplaceValue(false);
     properties->name.ReplaceValue("Connected Pairable Device");
     properties->alias.ReplaceValue(kConnectedTrustedNotPairedDeviceName);
+  } else if (device_path == dbus::ObjectPath(kCachedLowEnergyPath)) {
+    properties->address.ReplaceValue(kLowEnergyAddress);
+    properties->bluetooth_class.ReplaceValue(kLowEnergyClass);
+    properties->name.ReplaceValue("Heart Rate Monitor");
+    properties->alias.ReplaceValue(kLowEnergyName);
+    properties->alias.ReplaceValue(kLowEnergyName);
+    properties->services_resolved.ReplaceValue(false);
+
+    std::vector<std::string> uuids;
+    uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID);
+    properties->uuids.ReplaceValue(uuids);
   } else {
     NOTREACHED();
   }
 
   properties_map_.insert(std::make_pair(device_path, std::move(properties)));
   device_list_.push_back(device_path);
+
+  // After the new properties| is added to the map, expose the heart rate
+  // service to emulate the device with cached GATT services.
+  if (device_path == dbus::ObjectPath(kCachedLowEnergyPath)) {
+    static_cast<FakeBluetoothGattServiceClient*>(
+        bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient())
+        ->ExposeHeartRateServiceWithoutDelay(device_path);
+  }
+
   FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                     DeviceAdded(device_path));
 }
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.h b/device/bluetooth/dbus/fake_bluetooth_device_client.h
index 7479bd7..ea2f949b 100644
--- a/device/bluetooth/dbus/fake_bluetooth_device_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.h
@@ -249,6 +249,11 @@
   static const char kConnectedTrustedNotPairedDeviceName[];
   static const uint32_t kConnectedTrustedNotPairedDeviceClass;
 
+  static const char kCachedLowEnergyPath[];
+  static const char kCachedLowEnergyAddress[];
+  static const char kCachedLowEnergyName[];
+  static const uint32_t kCachedLowEnergyClass;
+
  private:
   // Property callback passed when we create Properties* structures.
   void OnPropertyChanged(const dbus::ObjectPath& object_path,
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
index cc080118..12daa95 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
@@ -10,17 +10,12 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace bluez {
 
-namespace {
-
-const int kExposeCharacteristicsDelayIntervalMs = 100;
-
-}  // namespace
-
 // static
 const char FakeBluetoothGattServiceClient::kHeartRateServicePathComponent[] =
     "service0000";
@@ -105,12 +100,17 @@
 
   NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_));
 
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(
           &FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics,
-          weak_ptr_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(kExposeCharacteristicsDelayIntervalMs));
+          weak_ptr_factory_.GetWeakPtr()));
+
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &FakeBluetoothGattServiceClient::ToggleServicesResolvedProperty,
+          weak_ptr_factory_.GetWeakPtr(), device_path, true));
 }
 
 void FakeBluetoothGattServiceClient::HideHeartRateService() {
@@ -134,6 +134,33 @@
   heart_rate_service_path_.clear();
 }
 
+void FakeBluetoothGattServiceClient::ExposeHeartRateServiceWithoutDelay(
+    const dbus::ObjectPath& device_path) {
+  if (IsHeartRateVisible()) {
+    DCHECK(!heart_rate_service_path_.empty());
+    VLOG(1) << "Fake Heart Rate Service already exposed.";
+    return;
+  }
+  VLOG(2) << "Exposing fake Heart Rate Service.";
+  heart_rate_service_path_ =
+      device_path.value() + "/" + kHeartRateServicePathComponent;
+  heart_rate_service_properties_.reset(new Properties(base::Bind(
+      &FakeBluetoothGattServiceClient::OnPropertyChanged,
+      base::Unretained(this), dbus::ObjectPath(heart_rate_service_path_))));
+  heart_rate_service_properties_->uuid.ReplaceValue(kHeartRateServiceUUID);
+  heart_rate_service_properties_->device.ReplaceValue(device_path);
+  heart_rate_service_properties_->primary.ReplaceValue(true);
+
+  NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_));
+
+  static_cast<FakeBluetoothGattCharacteristicClient*>(
+      bluez::BluezDBusManager::Get()->GetBluetoothGattCharacteristicClient())
+      ->ExposeHeartRateCharacteristics(
+          dbus::ObjectPath(heart_rate_service_path_));
+
+  ToggleServicesResolvedProperty(device_path, true);
+}
+
 bool FakeBluetoothGattServiceClient::IsHeartRateVisible() const {
   return !!heart_rate_service_properties_.get();
 }
@@ -179,4 +206,17 @@
       dbus::ObjectPath(heart_rate_service_path_));
 }
 
+void FakeBluetoothGattServiceClient::ToggleServicesResolvedProperty(
+    const dbus::ObjectPath& object_path,
+    bool resolved) {
+  DCHECK(object_path.IsValid());
+
+  VLOG(2) << "Toggle the ServicesResolved property to " << resolved
+          << " of device " << object_path.value();
+  FakeBluetoothDeviceClient* device = static_cast<FakeBluetoothDeviceClient*>(
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
+  // Notify on service discovery complete.
+  device->GetProperties(object_path)->services_resolved.ReplaceValue(true);
+}
+
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
index 41dbf7e..d56a35527 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
@@ -55,6 +55,11 @@
   void ExposeHeartRateService(const dbus::ObjectPath& device_path);
   void HideHeartRateService();
 
+  // Makes a service visible for device with object path |device_path| without
+  // delay. Note that only one instance of a specific service is simulated at a
+  // time, if the service is already visible.
+  void ExposeHeartRateServiceWithoutDelay(const dbus::ObjectPath& device_path);
+
   // Returns whether or not the Heart Rate Service is visible.
   bool IsHeartRateVisible() const;
 
@@ -85,6 +90,11 @@
   // time this method is called, then it does nothing.
   void ExposeHeartRateCharacteristics();
 
+  // Toggles the ServicesResolved property for the device with |object_path|.
+  // This should be done after a service is fully discovered.
+  void ToggleServicesResolvedProperty(const dbus::ObjectPath& object_path,
+                                      bool resolved);
+
   // Static properties we return. As long as a service is exposed, this will be
   // non-null. Otherwise it will be null.
   std::unique_ptr<Properties> heart_rate_service_properties_;
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 2597078..b3c55e74 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -523,6 +523,7 @@
     "filters/h264_parser_unittest.cc",
     "filters/ivf_parser_unittest.cc",
     "filters/jpeg_parser_unittest.cc",
+    "filters/memory_data_source_unittest.cc",
     "filters/pipeline_controller_unittest.cc",
     "filters/source_buffer_stream_unittest.cc",
     "filters/video_cadence_estimator_unittest.cc",
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 00386d9..856f9f5 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -221,8 +221,11 @@
       ]
     }
 
+    # TODO(xhwang): This is needed for AVDA to access the CDM directly.
+    # Remove this dependency after VDAs are also running as part of the mojo
+    # media application. See http://crbug.com/522298
     if (mojo_media_host == "gpu") {
-      deps += [ "//media/mojo/services:cdm_service" ]
+      deps += [ "//media/mojo/services" ]
     }
   }
 
diff --git a/media/gpu/gpu_video_decode_accelerator_factory_impl.cc b/media/gpu/gpu_video_decode_accelerator_factory_impl.cc
index 1fa50d9..0a1a883 100644
--- a/media/gpu/gpu_video_decode_accelerator_factory_impl.cc
+++ b/media/gpu/gpu_video_decode_accelerator_factory_impl.cc
@@ -69,13 +69,13 @@
   if (gpu_preferences.disable_accelerated_video_decode)
     return gpu::VideoDecodeAcceleratorCapabilities();
 
-// Query VDAs for their capabilities and construct a set of supported
-// profiles for current platform. This must be done in the same order as in
-// CreateVDA(), as we currently preserve additional capabilities (such as
-// resolutions supported) only for the first VDA supporting the given codec
-// profile (instead of calculating a superset).
-// TODO(posciak,henryhsu): improve this so that we choose a superset of
-// resolutions and other supported profile parameters.
+  // Query VDAs for their capabilities and construct a set of supported
+  // profiles for current platform. This must be done in the same order as in
+  // CreateVDA(), as we currently preserve additional capabilities (such as
+  // resolutions supported) only for the first VDA supporting the given codec
+  // profile (instead of calculating a superset).
+  // TODO(posciak,henryhsu): improve this so that we choose a superset of
+  // resolutions and other supported profile parameters.
 #if defined(OS_WIN)
   capabilities.supported_profiles =
       DXVAVideoDecodeAccelerator::GetSupportedProfiles();
diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc
index 91a1d497..a10f536 100644
--- a/media/gpu/h264_decoder.cc
+++ b/media/gpu/h264_decoder.cc
@@ -643,8 +643,8 @@
       default:
         // May be recoverable.
         DVLOG(1) << "Invalid modification_of_pic_nums_idc="
-                 << list_mod->modification_of_pic_nums_idc << " in position "
-                 << i;
+                 << list_mod->modification_of_pic_nums_idc
+                 << " in position " << i;
         break;
     }
 
@@ -669,8 +669,8 @@
   }
 
   DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_)
-      << "Outputting out of order, likely a broken stream: " << last_output_poc_
-      << " -> " << pic->pic_order_cnt;
+      << "Outputting out of order, likely a broken stream: "
+      << last_output_poc_ << " -> " << pic->pic_order_cnt;
   last_output_poc_ = pic->pic_order_cnt;
 
   DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt;
@@ -1319,7 +1319,7 @@
         // We can't resume from a non-IDR slice.
         if (state_ != kDecoding)
           break;
-      // else fallthrough
+        // else fallthrough
       case media::H264NALU::kIDRSlice: {
         // TODO(posciak): the IDR may require an SPS that we don't have
         // available. For now we'd fail if that happens, but ideally we'd like
diff --git a/media/gpu/ipc/service/gpu_video_encode_accelerator.cc b/media/gpu/ipc/service/gpu_video_encode_accelerator.cc
index 3287d7b..62a8539 100644
--- a/media/gpu/ipc/service/gpu_video_encode_accelerator.cc
+++ b/media/gpu/ipc/service/gpu_video_encode_accelerator.cc
@@ -79,8 +79,7 @@
     media::VideoCodecProfile output_profile,
     uint32_t initial_bitrate) {
   DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): "
-              "input_format="
-           << input_format
+           << "input_format=" << input_format
            << ", input_visible_size=" << input_visible_size.ToString()
            << ", output_profile=" << output_profile
            << ", initial_bitrate=" << initial_bitrate;
@@ -96,8 +95,8 @@
       input_visible_size.height() > media::limits::kMaxDimension ||
       input_visible_size.GetArea() > media::limits::kMaxCanvas) {
     DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
-                   "input_visible_size "
-                << input_visible_size.ToString() << " too large";
+                << "input_visible_size " << input_visible_size.ToString()
+                << " too large";
     return false;
   }
 
@@ -270,8 +269,7 @@
 
   if (params.frame_id < 0) {
     DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): invalid "
-                   "frame_id="
-                << params.frame_id;
+                << "frame_id=" << params.frame_id;
     NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
     return;
   }
@@ -318,8 +316,9 @@
 
 void GpuVideoEncodeAccelerator::OnEncode2(
     const AcceleratedVideoEncoderMsg_Encode_Params2& params) {
-  DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode2: frame_id = "
-           << params.frame_id << ", size=" << params.size.ToString()
+  DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode2: "
+           << "frame_id = " << params.frame_id
+           << ", size=" << params.size.ToString()
            << ", force_keyframe=" << params.force_keyframe
            << ", handle type=" << params.gpu_memory_buffer_handles[0].type;
   // Encoding GpuMemoryBuffer backed frames is not supported.
@@ -331,21 +330,18 @@
     base::SharedMemoryHandle buffer_handle,
     uint32_t buffer_size) {
   DVLOG(3) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
-              "buffer_id="
-           << buffer_id << ", buffer_size=" << buffer_size;
+           << "buffer_id=" << buffer_id << ", buffer_size=" << buffer_size;
   if (!encoder_)
     return;
   if (buffer_id < 0) {
     DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
-                   "invalid buffer_id="
-                << buffer_id;
+                << "invalid buffer_id=" << buffer_id;
     NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
     return;
   }
   if (buffer_size < output_buffer_size_) {
     DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
-                   "buffer too small for buffer_id="
-                << buffer_id;
+                << "buffer too small for buffer_id=" << buffer_id;
     NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
     return;
   }
@@ -362,8 +358,7 @@
     uint32_t bitrate,
     uint32_t framerate) {
   DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): "
-              "bitrate="
-           << bitrate << ", framerate=" << framerate;
+           << "bitrate=" << bitrate << ", framerate=" << framerate;
   if (!encoder_)
     return;
   encoder_->RequestEncodingParametersChange(bitrate, framerate);
diff --git a/media/gpu/jpeg_decode_accelerator_unittest.cc b/media/gpu/jpeg_decode_accelerator_unittest.cc
index 6a0cd78d..5c68851 100644
--- a/media/gpu/jpeg_decode_accelerator_unittest.cc
+++ b/media/gpu/jpeg_decode_accelerator_unittest.cc
@@ -177,8 +177,7 @@
     SetState(CS_DECODE_PASS);
   } else {
     LOG(ERROR) << "The mean absolute difference between software and hardware "
-                  "decode is "
-               << difference;
+               << "decode is " << difference;
     SetState(CS_ERROR);
   }
 }
@@ -255,10 +254,15 @@
                                           image_file->data_str.size());
   scoped_refptr<media::VideoFrame> out_frame_ =
       media::VideoFrame::WrapExternalSharedMemory(
-          media::PIXEL_FORMAT_I420, image_file->visible_size,
-          gfx::Rect(image_file->visible_size), image_file->visible_size,
-          static_cast<uint8_t*>(hw_out_shm_->memory()), image_file->output_size,
-          hw_out_shm_->handle(), 0, base::TimeDelta());
+          media::PIXEL_FORMAT_I420,
+          image_file->visible_size,
+          gfx::Rect(image_file->visible_size),
+          image_file->visible_size,
+          static_cast<uint8_t*>(hw_out_shm_->memory()),
+          image_file->output_size,
+          hw_out_shm_->handle(),
+          0,
+          base::TimeDelta());
   LOG_ASSERT(out_frame_.get());
   decoder_->Decode(bitstream_buffer, out_frame_);
 }
@@ -282,11 +286,21 @@
   int uv_plane_stride = yplane_stride / 2;
 
   if (libyuv::ConvertToI420(
-          static_cast<uint8_t*>(in_shm_->memory()), image_file->data_str.size(),
-          yplane, yplane_stride, uplane, uv_plane_stride, vplane,
-          uv_plane_stride, 0, 0, image_file->visible_size.width(),
-          image_file->visible_size.height(), image_file->visible_size.width(),
-          image_file->visible_size.height(), libyuv::kRotate0,
+          static_cast<uint8_t*>(in_shm_->memory()),
+          image_file->data_str.size(),
+          yplane,
+          yplane_stride,
+          uplane,
+          uv_plane_stride,
+          vplane,
+          uv_plane_stride,
+          0,
+          0,
+          image_file->visible_size.width(),
+          image_file->visible_size.height(),
+          image_file->visible_size.width(),
+          image_file->visible_size.height(),
+          libyuv::kRotate0,
           libyuv::FOURCC_MJPG) != 0) {
     LOG(ERROR) << "Software decode " << image_file->filename << " failed.";
     return false;
diff --git a/media/gpu/rendering_helper.cc b/media/gpu/rendering_helper.cc
index 30b1a1e..ac998cf 100644
--- a/media/gpu/rendering_helper.cc
+++ b/media/gpu/rendering_helper.cc
@@ -212,10 +212,14 @@
 
 void RenderingHelper::Setup() {
 #if defined(OS_WIN)
-  window_ = CreateWindowEx(
-      0, L"Static", L"VideoDecodeAcceleratorTest",
-      WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, GetSystemMetrics(SM_CXSCREEN),
-      GetSystemMetrics(SM_CYSCREEN), NULL, NULL, NULL, NULL);
+  window_ = CreateWindowEx(0,
+                           L"Static",
+                           L"VideoDecodeAcceleratorTest",
+                           WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+                           0, 0,
+                           GetSystemMetrics(SM_CXSCREEN),
+                           GetSystemMetrics(SM_CYSCREEN),
+                           NULL, NULL, NULL, NULL);
 #elif defined(USE_X11)
   Display* display = gfx::GetXDisplay();
   Screen* screen = DefaultScreenOfDisplay(display);
@@ -229,11 +233,17 @@
   window_attributes.override_redirect = true;
   int depth = DefaultDepth(display, DefaultScreen(display));
 
-  window_ = XCreateWindow(
-      display, DefaultRootWindow(display), 0, 0, XWidthOfScreen(screen),
-      XHeightOfScreen(screen), 0 /* border width */, depth,
-      CopyFromParent /* class */, CopyFromParent /* visual */,
-      (CWBackPixel | CWOverrideRedirect), &window_attributes);
+  window_ = XCreateWindow(display,
+                          DefaultRootWindow(display),
+                          0, 0,
+                          XWidthOfScreen(screen),
+                          XHeightOfScreen(screen),
+                          0 /* border width */,
+                          depth,
+                          CopyFromParent /* class */,
+                          CopyFromParent /* visual */,
+                          (CWBackPixel | CWOverrideRedirect),
+                          &window_attributes);
   XStoreName(display, window_, "VideoDecodeAcceleratorTest");
   XSelectInput(display, window_, ExposureMask);
   XMapWindow(display, window_);
@@ -358,9 +368,14 @@
     glGenFramebuffersEXT(1, &thumbnails_fbo_id_);
     glGenTextures(1, &thumbnails_texture_id_);
     glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, thumbnails_fbo_size_.width(),
-                 thumbnails_fbo_size_.height(), 0, GL_RGB,
-                 GL_UNSIGNED_SHORT_5_6_5, NULL);
+    glTexImage2D(GL_TEXTURE_2D,
+                 0,
+                 GL_RGB,
+                 thumbnails_fbo_size_.width(), thumbnails_fbo_size_.height(),
+                 0,
+                 GL_RGB,
+                 GL_UNSIGNED_SHORT_5_6_5,
+                 NULL);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -419,8 +434,11 @@
       "}\n";
 #else
   static const char kFragmentShader[] =
-      STRINGIZE(varying vec2 interp_tc; uniform sampler2D tex;
-                void main() { gl_FragColor = texture2D(tex, interp_tc); });
+      STRINGIZE(varying vec2 interp_tc;
+                uniform sampler2D tex;
+                void main() {
+                  gl_FragColor = texture2D(tex, interp_tc);
+                });
 #endif
   program_ = glCreateProgram();
   CreateShader(program_, GL_VERTEX_SHADER, kVertexShader,
@@ -491,8 +509,13 @@
       new GLubyte[screen_size_.GetArea() * 2]());
   glGenTextures(1, &texture_id);
   glBindTexture(GL_TEXTURE_2D, texture_id);
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_size_.width(),
-               screen_size_.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+  glTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGB,
+               screen_size_.width(), screen_size_.height(),
+               0,
+               GL_RGB,
+               GL_UNSIGNED_SHORT_5_6_5,
                emptyData.get());
   for (int i = 0; i < warm_up_iterations; ++i) {
     RenderTexture(GL_TEXTURE_2D, texture_id);
@@ -541,8 +564,14 @@
   glGenTextures(1, texture_id);
   glBindTexture(texture_target, *texture_id);
   if (texture_target == GL_TEXTURE_2D) {
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
-                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    glTexImage2D(GL_TEXTURE_2D,
+                 0,
+                 GL_RGBA,
+                 size.width(), size.height(),
+                 0,
+                 GL_RGBA,
+                 GL_UNSIGNED_BYTE,
+                 NULL);
   }
   glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -657,8 +686,10 @@
   glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
   // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support.
-  glReadPixels(0, 0, thumbnails_fbo_size_.width(),
-               thumbnails_fbo_size_.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+  glReadPixels(0, 0,
+               thumbnails_fbo_size_.width(), thumbnails_fbo_size_.height(),
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
                &rgba[0]);
   glBindFramebufferEXT(GL_FRAMEBUFFER,
                        gl_surface_->GetBackingFrameBufferObject());
diff --git a/media/gpu/v4l2_device.cc b/media/gpu/v4l2_device.cc
index d80989d..a291104 100644
--- a/media/gpu/v4l2_device.cc
+++ b/media/gpu/v4l2_device.cc
@@ -242,14 +242,14 @@
   if (max_resolution->IsEmpty()) {
     max_resolution->SetSize(1920, 1088);
     LOG(ERROR) << "GetSupportedResolution failed to get maximum resolution for "
-               << "fourcc " << std::hex << pixelformat << ", fall back to "
-               << max_resolution->ToString();
+               << "fourcc " << std::hex << pixelformat
+               << ", fall back to " << max_resolution->ToString();
   }
   if (min_resolution->IsEmpty()) {
     min_resolution->SetSize(16, 16);
     LOG(ERROR) << "GetSupportedResolution failed to get minimum resolution for "
-               << "fourcc " << std::hex << pixelformat << ", fall back to "
-               << min_resolution->ToString();
+               << "fourcc " << std::hex << pixelformat
+               << ", fall back to " << min_resolution->ToString();
   }
 }
 
diff --git a/media/gpu/v4l2_image_processor.cc b/media/gpu/v4l2_image_processor.cc
index c4df4e1b..22c8696 100644
--- a/media/gpu/v4l2_image_processor.cc
+++ b/media/gpu/v4l2_image_processor.cc
@@ -136,8 +136,7 @@
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
     LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
-                  "caps check failed: 0x"
-               << std::hex << caps.capabilities;
+               << "caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
diff --git a/media/gpu/v4l2_jpeg_decode_accelerator.cc b/media/gpu/v4l2_jpeg_decode_accelerator.cc
index 3abfbc84..e8f4cc6 100644
--- a/media/gpu/v4l2_jpeg_decode_accelerator.cc
+++ b/media/gpu/v4l2_jpeg_decode_accelerator.cc
@@ -568,10 +568,12 @@
                               base::Unretained(this)));
   }
 
-  DVLOG(2) << __func__ << ": buffer counts: INPUT[" << input_jobs_.size()
-           << "] => DEVICE[" << free_input_buffers_.size() << "/"
-           << input_buffer_map_.size() << "->" << free_output_buffers_.size()
-           << "/" << output_buffer_map_.size() << "]";
+  DVLOG(2) << __func__ << ": buffer counts: INPUT["
+           << input_jobs_.size() << "] => DEVICE["
+           << free_input_buffers_.size() << "/"
+           << input_buffer_map_.size() << "->"
+           << free_output_buffers_.size() << "/"
+           << output_buffer_map_.size() << "]";
 }
 
 void V4L2JpegDecodeAccelerator::EnqueueInput() {
@@ -626,12 +628,18 @@
   size_t dst_v_stride = dst_frame->stride(media::VideoFrame::kVPlane);
 
   // If the source format is I420, ConvertToI420 will simply copy the frame.
-  if (libyuv::ConvertToI420(
-          static_cast<uint8_t*>(const_cast<void*>(src_addr)), src_size, dst_y,
-          dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride, 0, 0,
-          src_coded_size.width(), src_coded_size.height(),
-          dst_frame->coded_size().width(), dst_frame->coded_size().height(),
-          libyuv::kRotate0, src_pixelformat)) {
+  if (libyuv::ConvertToI420(static_cast<uint8_t*>(const_cast<void*>(src_addr)),
+                            src_size,
+                            dst_y, dst_y_stride,
+                            dst_u, dst_u_stride,
+                            dst_v, dst_v_stride,
+                            0, 0,
+                            src_coded_size.width(),
+                            src_coded_size.height(),
+                            dst_frame->coded_size().width(),
+                            dst_frame->coded_size().height(),
+                            libyuv::kRotate0,
+                            src_pixelformat)) {
     LOG(ERROR) << "ConvertToI420 failed. Source format: " << src_pixelformat;
     return false;
   }
diff --git a/media/gpu/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2_slice_video_decode_accelerator.cc
index 1b4cce7b..d27a3b1e 100644
--- a/media/gpu/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2_slice_video_decode_accelerator.cc
@@ -513,8 +513,7 @@
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
     LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
-                  ", caps check failed: 0x"
-               << std::hex << caps.capabilities;
+               << ", caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -698,8 +697,10 @@
     buffer.m.planes = planes;
     buffer.length = input_planes_count_;
     IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
-    void* address = device_->Mmap(nullptr, buffer.m.planes[0].length,
-                                  PROT_READ | PROT_WRITE, MAP_SHARED,
+    void* address = device_->Mmap(nullptr,
+                                  buffer.m.planes[0].length,
+                                  PROT_READ | PROT_WRITE,
+                                  MAP_SHARED,
                                   buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
       PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
@@ -858,11 +859,13 @@
 
   DVLOGF(2) << "buffer counts: "
             << "INPUT[" << decoder_input_queue_.size() << "]"
-            << " => DEVICE[" << free_input_buffers_.size() << "+"
-            << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
-            << "]->[" << free_output_buffers_.size() << "+"
-            << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
-            << "]"
+            << " => DEVICE["
+            << free_input_buffers_.size() << "+"
+            << input_buffer_queued_count_ << "/"
+            << input_buffer_map_.size() << "]->["
+            << free_output_buffers_.size() << "+"
+            << output_buffer_queued_count_ << "/"
+            << output_buffer_map_.size() << "]"
             << " => DISPLAYQ[" << decoder_display_queue_.size() << "]"
             << " => CLIENT[" << surfaces_at_display_.size() << "]";
 }
@@ -952,8 +955,8 @@
     DCHECK(output_record.at_device);
     output_record.at_device = false;
     output_buffer_queued_count_--;
-    DVLOGF(3) << "Dequeued output=" << dqbuf.index << " count "
-              << output_buffer_queued_count_;
+    DVLOGF(3) << "Dequeued output=" << dqbuf.index
+              << " count " << output_buffer_queued_count_;
 
     V4L2DecodeSurfaceByOutputId::iterator it =
         surfaces_at_device_.find(dqbuf.index);
@@ -1504,8 +1507,8 @@
 
   if (buffers.size() < req_buffer_count) {
     DLOG(ERROR) << "Failed to provide requested picture buffers. "
-                << "(Got " << buffers.size() << ", requested "
-                << req_buffer_count << ")";
+                << "(Got " << buffers.size()
+                << ", requested " << req_buffer_count << ")";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -2060,19 +2063,12 @@
   struct v4l2_ctrl_h264_sps v4l2_sps;
   memset(&v4l2_sps, 0, sizeof(v4l2_sps));
   v4l2_sps.constraint_set_flags =
-      sps->constraint_set0_flag
-          ? V4L2_H264_SPS_CONSTRAINT_SET0_FLAG
-          : 0 | sps->constraint_set1_flag
-                ? V4L2_H264_SPS_CONSTRAINT_SET1_FLAG
-                : 0 | sps->constraint_set2_flag
-                      ? V4L2_H264_SPS_CONSTRAINT_SET2_FLAG
-                      : 0 | sps->constraint_set3_flag
-                            ? V4L2_H264_SPS_CONSTRAINT_SET3_FLAG
-                            : 0 | sps->constraint_set4_flag
-                                  ? V4L2_H264_SPS_CONSTRAINT_SET4_FLAG
-                                  : 0 | sps->constraint_set5_flag
-                                        ? V4L2_H264_SPS_CONSTRAINT_SET5_FLAG
-                                        : 0;
+      (sps->constraint_set0_flag ? V4L2_H264_SPS_CONSTRAINT_SET0_FLAG : 0) |
+      (sps->constraint_set1_flag ? V4L2_H264_SPS_CONSTRAINT_SET1_FLAG : 0) |
+      (sps->constraint_set2_flag ? V4L2_H264_SPS_CONSTRAINT_SET2_FLAG : 0) |
+      (sps->constraint_set3_flag ? V4L2_H264_SPS_CONSTRAINT_SET3_FLAG : 0) |
+      (sps->constraint_set4_flag ? V4L2_H264_SPS_CONSTRAINT_SET4_FLAG : 0) |
+      (sps->constraint_set5_flag ? V4L2_H264_SPS_CONSTRAINT_SET5_FLAG : 0);
 #define SPS_TO_V4L2SPS(a) v4l2_sps.a = sps->a
   SPS_TO_V4L2SPS(profile_idc);
   SPS_TO_V4L2SPS(level_idc);
diff --git a/media/gpu/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2_video_decode_accelerator.cc
index 480151a..410cd6c 100644
--- a/media/gpu/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2_video_decode_accelerator.cc
@@ -258,8 +258,7 @@
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
     LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
-                  ", caps check failed: 0x"
-               << std::hex << caps.capabilities;
+               << ", caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -326,8 +325,8 @@
 
   if (buffers.size() < req_buffer_count) {
     LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
-                  " buffers. (Got "
-               << buffers.size() << ", requested " << req_buffer_count << ")";
+               << " buffers. (Got " << buffers.size()
+               << ", requested " << req_buffer_count << ")";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -1011,13 +1010,16 @@
                             base::Unretained(this), poll_device));
 
   DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
-           << decoder_input_queue_.size() << "->" << input_ready_queue_.size()
-           << "] => DEVICE[" << free_input_buffers_.size() << "+"
-           << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
-           << "->" << free_output_buffers_.size() << "+"
-           << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
-           << "] => PROCESSOR[" << image_processor_bitstream_buffer_ids_.size()
-           << "] => CLIENT[" << decoder_frames_at_client_ << "]";
+           << decoder_input_queue_.size() << "->"
+           << input_ready_queue_.size() << "] => DEVICE["
+           << free_input_buffers_.size() << "+"
+           << input_buffer_queued_count_ << "/"
+           << input_buffer_map_.size() << "->"
+           << free_output_buffers_.size() << "+"
+           << output_buffer_queued_count_ << "/"
+           << output_buffer_map_.size() << "] => PROCESSOR["
+           << image_processor_bitstream_buffer_ids_.size() << "] => CLIENT["
+           << decoder_frames_at_client_ << "]";
 
   ScheduleDecodeBufferTaskIfNeeded();
   if (resolution_change_pending)
@@ -1869,9 +1871,11 @@
     buffer.m.planes = planes;
     buffer.length = 1;
     IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
-    void* address =
-        device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
-                      MAP_SHARED, buffer.m.planes[0].m.mem_offset);
+    void* address = device_->Mmap(NULL,
+                                  buffer.m.planes[0].length,
+                                  PROT_READ | PROT_WRITE,
+                                  MAP_SHARED,
+                                  buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
       PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
       return false;
diff --git a/media/gpu/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2_video_encode_accelerator.cc
index 202a50203..c6bcc29 100644
--- a/media/gpu/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2_video_encode_accelerator.cc
@@ -132,8 +132,7 @@
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
     LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
-                  "caps check failed: 0x"
-               << std::hex << caps.capabilities;
+               << "caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -514,12 +513,15 @@
       FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
                             base::Unretained(this), poll_device));
 
-  DVLOG(2) << __func__ << ": buffer counts: ENC[" << encoder_input_queue_.size()
-           << "] => DEVICE[" << free_input_buffers_.size() << "+"
-           << input_buffer_queued_count_ << "/" << input_buffer_map_.size()
-           << "->" << free_output_buffers_.size() << "+"
-           << output_buffer_queued_count_ << "/" << output_buffer_map_.size()
-           << "] => OUT[" << encoder_output_queue_.size() << "]";
+  DVLOG(2) << __func__ << ": buffer counts: ENC["
+           << encoder_input_queue_.size() << "] => DEVICE["
+           << free_input_buffers_.size() << "+"
+           << input_buffer_queued_count_ << "/"
+           << input_buffer_map_.size() << "->"
+           << free_output_buffers_.size() << "+"
+           << output_buffer_queued_count_ << "/"
+           << output_buffer_map_.size() << "] => OUT["
+           << encoder_output_queue_.size() << "]";
 }
 
 void V4L2VideoEncodeAccelerator::Enqueue() {
@@ -658,8 +660,8 @@
     }
 
     DVLOG(3) << "Dequeue(): returning "
-                "bitstream_buffer_id="
-             << output_record.buffer_ref->id << ", size=" << output_size
+             << "bitstream_buffer_id=" << output_record.buffer_ref->id
+             << ", size=" << output_size
              << ", key_frame=" << key_frame;
     child_task_runner_->PostTask(
         FROM_HERE,
@@ -1197,9 +1199,11 @@
     buffer.m.planes = planes;
     buffer.length = arraysize(planes);
     IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
-    void* address =
-        device_->Mmap(NULL, buffer.m.planes[0].length, PROT_READ | PROT_WRITE,
-                      MAP_SHARED, buffer.m.planes[0].m.mem_offset);
+    void* address = device_->Mmap(NULL,
+                                  buffer.m.planes[0].length,
+                                  PROT_READ | PROT_WRITE,
+                                  MAP_SHARED,
+                                  buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
       PLOG(ERROR) << "CreateOutputBuffers(): mmap() failed";
       return false;
diff --git a/media/gpu/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi_video_decode_accelerator.cc
index e07b4a5..cbf1796 100644
--- a/media/gpu/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi_video_decode_accelerator.cc
@@ -412,8 +412,8 @@
   // Notify the client a picture is ready to be displayed.
   ++num_frames_at_client_;
   TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
-  DVLOG(4) << "Notifying output picture id " << output_id << " for input "
-           << input_id << " is ready";
+  DVLOG(4) << "Notifying output picture id " << output_id
+           << " for input " << input_id << " is ready";
   // TODO(posciak): Use visible size from decoder here instead
   // (crbug.com/402760). Passing (0, 0) results in the client using the
   // visible size extracted from the container instead.
@@ -503,7 +503,7 @@
       // already queued up. Otherwise will stop decoding.
       if (input_buffers_.empty())
         return false;
-    // else fallthrough
+      // else fallthrough
     case kDecoding:
     case kIdle:
       DCHECK(!input_buffers_.empty());
@@ -710,7 +710,7 @@
       break;
 
     case kDecoding:
-    // Decoder already running, fallthrough.
+      // Decoder already running, fallthrough.
     case kResetting:
       // When resetting, allow accumulating bitstream buffers, so that
       // the client can queue after-seek-buffers while we are finishing with
@@ -744,11 +744,10 @@
   while (!output_buffers_.empty())
     output_buffers_.pop();
 
-  RETURN_AND_NOTIFY_ON_FAILURE(buffers.size() >= requested_num_pics_,
-                               "Got an invalid number of picture buffers. (Got "
-                                   << buffers.size() << ", requested "
-                                   << requested_num_pics_ << ")",
-                               INVALID_ARGUMENT, );
+  RETURN_AND_NOTIFY_ON_FAILURE(
+      buffers.size() >= requested_num_pics_,
+      "Got an invalid number of picture buffers. (Got " << buffers.size()
+      << ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, );
   DCHECK(requested_pic_size_ == buffers[0].size());
 
   std::vector<VASurfaceID> va_surface_ids;
diff --git a/media/gpu/vaapi_wrapper.cc b/media/gpu/vaapi_wrapper.cc
index 72edc67..df9af81 100644
--- a/media/gpu/vaapi_wrapper.cc
+++ b/media/gpu/vaapi_wrapper.cc
@@ -844,9 +844,12 @@
   VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
 
   // Put the data into an X Pixmap.
-  va_res = vaPutSurface(va_display_, va_surface_id, x_pixmap, 0, 0,
-                        dest_size.width(), dest_size.height(), 0, 0,
-                        dest_size.width(), dest_size.height(), NULL, 0, 0);
+  va_res = vaPutSurface(va_display_,
+                        va_surface_id,
+                        x_pixmap,
+                        0, 0, dest_size.width(), dest_size.height(),
+                        0, 0, dest_size.width(), dest_size.height(),
+                        NULL, 0, 0);
   VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
   return true;
 }
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc
index 2b9d46c3..f9f27118 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -1257,8 +1257,8 @@
   if (state == expected_state)
     return;
   ASSERT_TRUE(client->decoder_deleted())
-      << "Decoder not deleted but Wait() returned " << state << ", instead of "
-      << expected_state;
+      << "Decoder not deleted but Wait() returned " << state
+      << ", instead of " << expected_state;
 }
 
 // We assert a minimal number of concurrent decoders we expect to succeed.
@@ -1318,13 +1318,23 @@
       delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse;
     }
 
-    GLRenderingVDAClient* client = new GLRenderingVDAClient(
-        index, &rendering_helper_, note, video_file->data_str,
-        num_in_flight_decodes, num_play_throughs,
-        video_file->reset_after_frame_num, delete_decoder_state,
-        video_file->width, video_file->height, video_file->profile,
-        g_fake_decoder, suppress_rendering, delay_after_frame_num, 0,
-        render_as_thumbnails);
+    GLRenderingVDAClient* client =
+        new GLRenderingVDAClient(index,
+                                 &rendering_helper_,
+                                 note,
+                                 video_file->data_str,
+                                 num_in_flight_decodes,
+                                 num_play_throughs,
+                                 video_file->reset_after_frame_num,
+                                 delete_decoder_state,
+                                 video_file->width,
+                                 video_file->height,
+                                 video_file->profile,
+                                 g_fake_decoder,
+                                 suppress_rendering,
+                                 delay_after_frame_num,
+                                 0,
+                                 render_as_thumbnails);
 
     clients[index] = client;
     helper_params.window_sizes.push_back(
@@ -1430,10 +1440,13 @@
     if (match == golden_md5s.end()) {
       // Convert raw RGB into PNG for export.
       std::vector<unsigned char> png;
-      gfx::PNGCodec::Encode(&rgb[0], gfx::PNGCodec::FORMAT_RGB,
+      gfx::PNGCodec::Encode(&rgb[0],
+                            gfx::PNGCodec::FORMAT_RGB,
                             kThumbnailsPageSize,
-                            kThumbnailsPageSize.width() * 3, true,
-                            std::vector<gfx::PNGCodec::Comment>(), &png);
+                            kThumbnailsPageSize.width() * 3,
+                            true,
+                            std::vector<gfx::PNGCodec::Comment>(),
+                            &png);
 
       LOG(ERROR) << "Unknown thumbnails MD5: " << md5_string;
 
@@ -1596,13 +1609,23 @@
 
   ClientStateNotification<ClientState>* note =
       new ClientStateNotification<ClientState>();
-  GLRenderingVDAClient* client = new GLRenderingVDAClient(
-      0, &rendering_helper_, note, test_video_files_[0]->data_str, 1, 1,
-      test_video_files_[0]->reset_after_frame_num, CS_RESET,
-      test_video_files_[0]->width, test_video_files_[0]->height,
-      test_video_files_[0]->profile, g_fake_decoder, true,
-      std::numeric_limits<int>::max(), kWebRtcDecodeCallsPerSecond,
-      false /* render_as_thumbnail */);
+  GLRenderingVDAClient* client =
+    new GLRenderingVDAClient(0,
+                             &rendering_helper_,
+                             note,
+                             test_video_files_[0]->data_str,
+                             1,
+                             1,
+                             test_video_files_[0]->reset_after_frame_num,
+                             CS_RESET,
+                             test_video_files_[0]->width,
+                             test_video_files_[0]->height,
+                             test_video_files_[0]->profile,
+                             g_fake_decoder,
+                             true,
+                             std::numeric_limits<int>::max(),
+                             kWebRtcDecodeCallsPerSecond,
+                             false /* render_as_thumbnail */);
   helper_params.window_sizes.push_back(
       gfx::Size(test_video_files_[0]->width, test_video_files_[0]->height));
   InitializeRenderingHelper(helper_params);
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc
index 0cfbfaa..2d7440b 100644
--- a/media/gpu/video_encode_accelerator_unittest.cc
+++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -1527,8 +1527,8 @@
   unsigned int bitrate = encoded_stream_size_since_last_check_ * 8 *
                          current_framerate_ / num_frames_since_last_check_;
   DVLOG(1) << "Current chunk's bitrate: " << bitrate
-           << " (expected: " << current_requested_bitrate_ << " @ "
-           << current_framerate_ << " FPS,"
+           << " (expected: " << current_requested_bitrate_
+           << " @ " << current_framerate_ << " FPS,"
            << " num frames in chunk: " << num_frames_since_last_check_;
 
   num_frames_since_last_check_ = 0;
diff --git a/media/mojo/BUILD.gn b/media/mojo/BUILD.gn
index 02c6ffc1..a7361d7 100644
--- a/media/mojo/BUILD.gn
+++ b/media/mojo/BUILD.gn
@@ -25,7 +25,7 @@
     "//media/base:test_support",
     "//media/mojo/common",
     "//media/mojo/interfaces",
-    "//media/mojo/services:cdm_service",
+    "//media/mojo/services",
     "//mojo/edk/system",
     "//mojo/edk/test:run_all_unittests",
     "//testing/gmock",
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index ae82fad..738b4d92 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -84,19 +84,14 @@
   ]
 }
 
-source_set("cdm_service") {
-  deps = [
-    "//base",
-    "//media",
-    "//media/mojo/common",
-    "//media/mojo/interfaces",
-    "//mojo/common",
-    "//mojo/public/c/system:for_component",
-    "//services/shell/public/interfaces",
-    "//url",
-  ]
+component("services") {
+  output_name = "media_mojo_services"
 
   sources = [
+    "demuxer_stream_provider_shim.cc",
+    "demuxer_stream_provider_shim.h",
+    "mojo_audio_decoder_service.cc",
+    "mojo_audio_decoder_service.h",
     "mojo_cdm_allocator.cc",
     "mojo_cdm_allocator.h",
     "mojo_cdm_promise.cc",
@@ -107,7 +102,39 @@
     "mojo_cdm_service_context.h",
     "mojo_decryptor_service.cc",
     "mojo_decryptor_service.h",
+    "mojo_demuxer_stream_adapter.cc",
+    "mojo_demuxer_stream_adapter.h",
+    "mojo_media_application.cc",
+    "mojo_media_application.h",
+    "mojo_media_application_factory.cc",
+    "mojo_media_application_factory.h",
+    "mojo_media_client.cc",
+    "mojo_media_client.h",
+    "mojo_renderer_service.cc",
+    "mojo_renderer_service.h",
     "mojo_type_trait.h",
+    "service_factory_impl.cc",
+    "service_factory_impl.h",
+  ]
+
+  defines = [ "MEDIA_MOJO_IMPLEMENTATION" ]
+
+  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+  public_configs = [ ":mojo_media_config" ]
+
+  deps = [
+    "//base",
+    "//media",
+    "//media:shared_memory_support",
+    "//media/mojo/common",
+    "//media/mojo/interfaces",
+    "//mojo/common",
+    "//mojo/public/c/system:for_component",
+    "//services/shell/public/cpp",
+    "//services/shell/public/cpp:sources",
+    "//services/shell/public/interfaces",
+    "//url",
   ]
 
   if (is_android) {
@@ -117,93 +144,8 @@
     ]
   }
 
-  # TODO(xhwang): Needed because targets can depend on cdm_service directly,
-  # which is a bit hacky since we need to access CdmService directly
-  # from C++ code (AVDA). In the future we'll make those decoders part of
-  # MojoMediaApplication, then we won't need this.
-  public_configs = [ ":mojo_media_config" ]
-
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-}
-
-source_set("audio_decoder_service") {
-  sources = [
-    "mojo_audio_decoder_service.cc",
-    "mojo_audio_decoder_service.h",
-  ]
-
-  deps = [
-    ":cdm_service",
-    "//base",
-    "//media",
-    "//media:shared_memory_support",
-    "//media/mojo/common",
-    "//media/mojo/interfaces",
-    "//mojo/common",
-  ]
-}
-
-source_set("renderer_service") {
-  sources = [
-    "demuxer_stream_provider_shim.cc",
-    "demuxer_stream_provider_shim.h",
-    "mojo_demuxer_stream_adapter.cc",
-    "mojo_demuxer_stream_adapter.h",
-    "mojo_renderer_service.cc",
-    "mojo_renderer_service.h",
-  ]
-
-  deps = [
-    ":cdm_service",
-    "//base",
-    "//media",
-    "//media:shared_memory_support",
-    "//media/mojo/common",
-    "//media/mojo/interfaces",
-    "//mojo/common",
-  ]
-}
-
-source_set("application") {
-  sources = [
-    "mojo_media_application.cc",
-    "mojo_media_application.h",
-    "mojo_media_client.cc",
-    "mojo_media_client.h",
-    "service_factory_impl.cc",
-    "service_factory_impl.h",
-  ]
-
-  public_configs = [ ":mojo_media_config" ]
-
-  deps = [
-    ":audio_decoder_service",
-    ":cdm_service",
-    ":renderer_service",
-    "//base",
-    "//media",
-    "//media/mojo/interfaces",
-    "//services/shell/public/cpp",
-  ]
-}
-
-source_set("application_factory") {
-  sources = [
-    "mojo_media_application_factory.cc",
-    "mojo_media_application_factory.h",
-  ]
-
-  public_configs = [ ":mojo_media_config" ]
-
-  deps = [
-    ":application",
-    "//base",
-    "//media",
-    "//services/shell/public/cpp:sources",
-  ]
-
   if (enable_test_mojo_media_client) {
-    defines = [ "ENABLE_TEST_MOJO_MEDIA_CLIENT" ]
+    defines += [ "ENABLE_TEST_MOJO_MEDIA_CLIENT" ]
     sources += [
       "test_mojo_media_client.cc",
       "test_mojo_media_client.h",
@@ -231,7 +173,7 @@
   ]
 
   deps = [
-    ":application",
+    ":services",
     "//base",
     "//media",
     "//mojo/logging",
diff --git a/media/mojo/services/media_mojo_export.h b/media/mojo/services/media_mojo_export.h
new file mode 100644
index 0000000..01be7be
--- /dev/null
+++ b/media/mojo/services/media_mojo_export.h
@@ -0,0 +1,32 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_MOJO_MEDIA_MOJO_EXPORT_H_
+#define MEDIA_MOJO_MEDIA_MOJO_EXPORT_H_
+
+// Define MEDIA_MOJO_EXPORT so that functionality implemented by the
+// media/mojo module can be exported to consumers.
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(MEDIA_MOJO_IMPLEMENTATION)
+#define MEDIA_MOJO_EXPORT __declspec(dllexport)
+#else
+#define MEDIA_MOJO_EXPORT __declspec(dllimport)
+#endif  // defined(MEDIA_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(MEDIA_MOJO_IMPLEMENTATION)
+#define MEDIA_MOJO_EXPORT __attribute__((visibility("default")))
+#else
+#define MEDIA_MOJO_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define MEDIA_MOJO_EXPORT
+#endif
+
+#endif  // MEDIA_MOJO_MEDIA_MOJO_EXPORT_H_
diff --git a/media/mojo/services/mojo_cdm_allocator.h b/media/mojo/services/mojo_cdm_allocator.h
index c2e3549..407fe5d 100644
--- a/media/mojo/services/mojo_cdm_allocator.h
+++ b/media/mojo/services/mojo_cdm_allocator.h
@@ -15,13 +15,14 @@
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "media/cdm/cdm_allocator.h"
+#include "media/mojo/services/media_mojo_export.h"
 #include "mojo/public/cpp/system/buffer.h"
 
 namespace media {
 
 // This is a CdmAllocator that creates buffers using mojo shared memory.
 // The internal logic is similar to ppapi_cdm_buffer.cc.
-class MojoCdmAllocator : public CdmAllocator {
+class MEDIA_MOJO_EXPORT MojoCdmAllocator : public CdmAllocator {
  public:
   MojoCdmAllocator();
   ~MojoCdmAllocator() final;
diff --git a/media/mojo/services/mojo_cdm_service.h b/media/mojo/services/mojo_cdm_service.h
index e2c7c658..04a6f4d 100644
--- a/media/mojo/services/mojo_cdm_service.h
+++ b/media/mojo/services/mojo_cdm_service.h
@@ -15,6 +15,7 @@
 #include "base/memory/weak_ptr.h"
 #include "media/base/media_keys.h"
 #include "media/mojo/interfaces/content_decryption_module.mojom.h"
+#include "media/mojo/services/media_mojo_export.h"
 #include "media/mojo/services/mojo_cdm_promise.h"
 #include "media/mojo/services/mojo_cdm_service_context.h"
 #include "media/mojo/services/mojo_decryptor_service.h"
@@ -36,7 +37,7 @@
   // render frame the caller is associated with. In the future, we should move
   // all out-of-process media players into the MojoMediaApplicaiton so that we
   // can use MojoCdmServiceContext (per render frame) to get the CDM.
-  static scoped_refptr<MediaKeys> LegacyGetCdm(int cdm_id);
+  static scoped_refptr<MediaKeys> MEDIA_MOJO_EXPORT LegacyGetCdm(int cdm_id);
 
   // Constructs a MojoCdmService and strongly binds it to the |request|.
   MojoCdmService(
diff --git a/media/mojo/services/mojo_media_application.h b/media/mojo/services/mojo_media_application.h
index 3b9ae553..2b81824f 100644
--- a/media/mojo/services/mojo_media_application.h
+++ b/media/mojo/services/mojo_media_application.h
@@ -10,8 +10,10 @@
 #include <memory>
 
 #include "base/callback.h"
+#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "media/mojo/interfaces/service_factory.mojom.h"
+#include "media/mojo/services/media_mojo_export.h"
 #include "services/shell/public/cpp/interface_factory.h"
 #include "services/shell/public/cpp/shell_client.h"
 #include "services/shell/public/cpp/shell_connection_ref.h"
@@ -22,9 +24,9 @@
 class MediaLog;
 class MojoMediaClient;
 
-class MojoMediaApplication
-    : public shell::ShellClient,
-      public shell::InterfaceFactory<mojom::ServiceFactory> {
+class MEDIA_MOJO_EXPORT MojoMediaApplication
+    : public NON_EXPORTED_BASE(shell::ShellClient),
+      public NON_EXPORTED_BASE(shell::InterfaceFactory<mojom::ServiceFactory>) {
  public:
   MojoMediaApplication(std::unique_ptr<MojoMediaClient> mojo_media_client,
                        const base::Closure& quit_closure);
diff --git a/media/mojo/services/mojo_media_application_factory.h b/media/mojo/services/mojo_media_application_factory.h
index e366f44..ead4f7a 100644
--- a/media/mojo/services/mojo_media_application_factory.h
+++ b/media/mojo/services/mojo_media_application_factory.h
@@ -8,13 +8,14 @@
 #include <memory>
 
 #include "base/callback_forward.h"
+#include "media/mojo/services/media_mojo_export.h"
 #include "services/shell/public/cpp/shell_client.h"
 
 namespace media {
 
 // Creates a MojoMediaApplication instance using the default MojoMediaClient.
-std::unique_ptr<shell::ShellClient> CreateMojoMediaApplication(
-    const base::Closure& quit_closure);
+std::unique_ptr<shell::ShellClient> MEDIA_MOJO_EXPORT
+CreateMojoMediaApplication(const base::Closure& quit_closure);
 
 }  // namespace media
 
diff --git a/media/mojo/services/mojo_media_client.h b/media/mojo/services/mojo_media_client.h
index d64c06c..010ce9a3 100644
--- a/media/mojo/services/mojo_media_client.h
+++ b/media/mojo/services/mojo_media_client.h
@@ -13,6 +13,7 @@
 #include "media/base/media_log.h"
 #include "media/base/renderer_factory.h"
 #include "media/base/video_renderer_sink.h"
+#include "media/mojo/services/media_mojo_export.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -26,7 +27,7 @@
 
 namespace media {
 
-class MojoMediaClient {
+class MEDIA_MOJO_EXPORT MojoMediaClient {
  public:
   virtual ~MojoMediaClient();
 
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn
index 7d6365d..435f4860 100644
--- a/media/test/BUILD.gn
+++ b/media/test/BUILD.gn
@@ -103,8 +103,8 @@
       "//media/audio:test_support",
       "//media/base:test_support",
       "//media/mojo/interfaces",
+      "//media/mojo/services",
       "//media/mojo/services:proxy",
-      "//media/mojo/services:renderer_service",
       "//services/shell/public/cpp:shell_test_support",
       "//testing/gtest",
       "//ui/gfx:test_support",
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index cc85d0f8..d3fe5282 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -600,9 +600,6 @@
       output_format_, mailbox_holders, release_mailbox_callback, coded_size,
       gfx::Rect(visible_size), video_frame->natural_size(),
       video_frame->timestamp());
-  if (frame &&
-      video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY))
-    frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true);
 
   if (!frame) {
     release_mailbox_callback.Run(gpu::SyncToken());
@@ -610,6 +607,22 @@
     return;
   }
 
+  bool allow_overlay = false;
+  switch (output_format_) {
+    case PIXEL_FORMAT_I420:
+      allow_overlay =
+          video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY);
+      break;
+    case PIXEL_FORMAT_NV12:
+    case PIXEL_FORMAT_UYVY:
+      allow_overlay = true;
+      break;
+    default:
+      break;
+  }
+  frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY,
+                                allow_overlay);
+
   base::TimeTicks render_time;
   if (video_frame->metadata()->GetTimeTicks(VideoFrameMetadata::REFERENCE_TIME,
                                             &render_time)) {
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc
index 59714e33..c93ff0c 100644
--- a/net/test/embedded_test_server/embedded_test_server.cc
+++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -170,6 +170,9 @@
                                        std::unique_ptr<HttpRequest> request) {
   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
 
+  for (const auto& monitor : request_monitors_)
+    monitor.Run(*request);
+
   std::unique_ptr<HttpResponse> response;
 
   for (const auto& handler : request_handlers_) {
@@ -284,15 +287,22 @@
 
 void EmbeddedTestServer::RegisterRequestHandler(
     const HandleRequestCallback& callback) {
-  // TODO(svaldez): Add check to prevent RegisterHandler from being called
-  // after the server has started. https://crbug.com/546060
+  // TODO(svaldez): Add check to prevent RegisterRequestHandler from being
+  // called after the server has started. https://crbug.com/546060
   request_handlers_.push_back(callback);
 }
 
+void EmbeddedTestServer::RegisterRequestMonitor(
+    const MonitorRequestCallback& callback) {
+  // TODO(svaldez): Add check to prevent RegisterRequestMonitor from being
+  // called after the server has started. https://crbug.com/546060
+  request_monitors_.push_back(callback);
+}
+
 void EmbeddedTestServer::RegisterDefaultHandler(
     const HandleRequestCallback& callback) {
-  // TODO(svaldez): Add check to prevent RegisterHandler from being called
-  // after the server has started. https://crbug.com/546060
+  // TODO(svaldez): Add check to prevent RegisterDefaultHandler from being
+  // called after the server has started. https://crbug.com/546060
   default_request_handlers_.push_back(callback);
 }
 
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h
index e3065c0..3b9e253b 100644
--- a/net/test/embedded_test_server/embedded_test_server.h
+++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -117,6 +117,8 @@
   typedef base::Callback<std::unique_ptr<HttpResponse>(
       const HttpRequest& request)>
       HandleRequestCallback;
+  typedef base::Callback<void(const HttpRequest& request)>
+      MonitorRequestCallback;
 
   // Creates a http test server. Start() must be called to start the server.
   // |type| indicates the protocol type of the server (HTTP/HTTPS).
@@ -207,6 +209,11 @@
   // on UI thread.
   void RegisterRequestHandler(const HandleRequestCallback& callback);
 
+  // Adds request monitors. The |callback| is called before any handlers are
+  // called, but can not respond it. This is useful to monitor requests that
+  // will be handled by other request handlers.
+  void RegisterRequestMonitor(const MonitorRequestCallback& callback);
+
   // Adds default handlers, including those added by AddDefaultHandlers, to be
   // tried after all other user-specified handlers have been tried.
   void RegisterDefaultHandler(const HandleRequestCallback& callback);
@@ -274,8 +281,9 @@
   // Owns the HttpConnection objects.
   std::map<StreamSocket*, HttpConnection*> connections_;
 
-  // Vector of registered and default request handlers.
+  // Vector of registered and default request handlers and monitors.
   std::vector<HandleRequestCallback> request_handlers_;
+  std::vector<MonitorRequestCallback> request_monitors_;
   std::vector<HandleRequestCallback> default_request_handlers_;
 
   base::ThreadChecker thread_checker_;
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index a68d8e3b0..fdeae40 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -1182,6 +1182,10 @@
         "test": "gpu_unittests"
       },
       {
+        "args": [
+          "--shard-timeout",
+          "240"
+        ],
         "test": "ipc_tests"
       },
       {
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/cached-change-row-border-width-expected.txt b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/cached-change-row-border-width-expected.txt
index c0f45c9..31e7e12 100644
--- a/third_party/WebKit/LayoutTests/fast/table/border-collapsing/cached-change-row-border-width-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/table/border-collapsing/cached-change-row-border-width-expected.txt
@@ -8,26 +8,41 @@
       "paintInvalidations": [
         {
           "object": "LayoutTableCell TD",
-          "rect": [8, 8, 56, 54],
+          "rect": [8, 8, 60, 54],
           "reason": "forced by layout"
         },
         {
           "object": "LayoutTableCell TD",
-          "rect": [8, 58, 56, 53],
+          "rect": [8, 58, 60, 53],
           "reason": "location change"
         },
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 109, 56, 2],
+          "rect": [8, 109, 60, 2],
           "reason": "incremental"
         },
         {
           "object": "LayoutTable TABLE",
-          "rect": [8, 110, 56, 1],
+          "rect": [8, 110, 60, 1],
           "reason": "incremental"
         },
         {
           "object": "LayoutTableSection TBODY",
+          "rect": [10, 10, 56, 100],
+          "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTableRow TR",
+          "rect": [10, 60, 56, 50],
+          "reason": "bounds change"
+        },
+        {
+          "object": "LayoutTableRow TR id='row'",
+          "rect": [10, 10, 56, 50],
+          "reason": "style change"
+        },
+        {
+          "object": "LayoutTableSection TBODY",
           "rect": [9, 9, 54, 100],
           "reason": "bounds change"
         },
@@ -42,19 +57,14 @@
           "reason": "style change"
         },
         {
-          "object": "LayoutTableSection TBODY",
-          "rect": [10, 10, 52, 100],
-          "reason": "bounds change"
+          "object": "LayoutTable TABLE",
+          "rect": [62, 8, 6, 103],
+          "reason": "incremental"
         },
         {
-          "object": "LayoutTableRow TR",
-          "rect": [10, 60, 52, 50],
-          "reason": "bounds change"
-        },
-        {
-          "object": "LayoutTableRow TR id='row'",
-          "rect": [10, 10, 52, 50],
-          "reason": "style change"
+          "object": "LayoutTable TABLE",
+          "rect": [64, 8, 4, 103],
+          "reason": "incremental"
         },
         {
           "object": "LayoutTableCell TD",
diff --git a/third_party/WebKit/LayoutTests/fast/table/change-row-border-width-expected.txt b/third_party/WebKit/LayoutTests/fast/table/change-row-border-width-expected.txt
new file mode 100644
index 0000000..d0472cec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/table/change-row-border-width-expected.txt
@@ -0,0 +1,2 @@
+There should be a square with a 4px blue border.
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/table/change-row-border-width.html b/third_party/WebKit/LayoutTests/fast/table/change-row-border-width.html
new file mode 100644
index 0000000..c8043a59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/table/change-row-border-width.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<style>
+    td {
+        width: 50px;
+        height: 50px;
+        padding: 0px;
+    }
+</style>
+<script src="../../resources/check-layout.js"></script>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<script type="text/javascript">
+    runAfterLayoutAndPaint(function() {
+        document.getElementById("row").style.borderWidth = "4px";
+        checkLayout("table");
+    }, true);
+</script>
+There should be a square with a 4px blue border.
+<table style="border-collapse:collapse" data-expected-width=58 data-expected-height=58>
+    <tr style="border:18px solid lightblue" id="row">
+        <td />
+    </tr>
+</table>
diff --git a/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash-expected.txt
new file mode 100644
index 0000000..e7c7dca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash-expected.txt
@@ -0,0 +1 @@
+ï²· PASS: did not crash.
diff --git a/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash.html b/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash.html
new file mode 100644
index 0000000..f30bc13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/text/vertical-spacing-crash.html
@@ -0,0 +1,13 @@
+<style>
+* { writing-mode: vertical-lr; letter-spacing: 1;}
+</style>
+
+<body>
+&#xfcb7;
+PASS: did not crash.
+  <script>
+    if (window.testRunner)
+      testRunner.dumpAsText();
+  </script>
+</body>
+
diff --git a/third_party/WebKit/LayoutTests/imagecapture/photocapabilities.html b/third_party/WebKit/LayoutTests/imagecapture/photocapabilities.html
new file mode 100644
index 0000000..2281a12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imagecapture/photocapabilities.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/mojo-helpers.js"></script>
+<script src="resources/mock-imagecapture.js"></script>
+<body>
+<canvas id='canvas' width=10 height=10/>
+</body>
+<script>
+
+// This test verifies that ImageCapture retrieves PhotoCapabilities on
+// construction, with a mock Mojo interface implementation.
+
+async_test(function(t) {
+  var canvas = document.getElementById('canvas');
+  var context = canvas.getContext("2d");
+  context.fillStyle = "red";
+  context.fillRect(0, 0, 10, 10);
+  var stream = canvas.captureStream();
+
+  var capturer;
+  mockImageCaptureReady
+    .then(mock => {
+      capturer = new ImageCapture(stream.getVideoTracks()[0]);
+      return mock;
+    })
+    .catch(error => {
+      assert_unreached("Error creating MockImageCapture: " + error);
+    })
+    .then(mock => {
+      // ImageCapture retrieves the capabilities on construction. Wait for that.
+      return mock.waitForGetCapabilities();
+    })
+    .then(expected_capabilities => {
+      assert_true(capturer.photoCapabilities instanceof PhotoCapabilities);
+
+      assert_true(capturer.photoCapabilities.zoom
+                      instanceof MediaSettingsRange);
+      assert_equals(expected_capabilities.zoom.max,
+                    capturer.photoCapabilities.zoom.max);
+      assert_equals(expected_capabilities.zoom.min,
+                    capturer.photoCapabilities.zoom.min);
+      assert_equals(expected_capabilities.zoom.initial,
+                    capturer.photoCapabilities.zoom.initial);
+
+      t.done();
+    });
+}, 'exercises the retrieval of Capabilities on ImageCapture API construction');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imagecapture/resources/mock-imagecapture.js b/third_party/WebKit/LayoutTests/imagecapture/resources/mock-imagecapture.js
index ae788164..f1b01777 100644
--- a/third_party/WebKit/LayoutTests/imagecapture/resources/mock-imagecapture.js
+++ b/third_party/WebKit/LayoutTests/imagecapture/resources/mock-imagecapture.js
@@ -13,6 +13,7 @@
       serviceRegistry.addServiceOverrideForTesting(
           imageCapture.ImageCapture.name,
           pipe => this.bindToPipe(pipe));
+      this.getCapabilitiesCallback_  = null;
     }
 
     bindToPipe(pipe) {
@@ -21,10 +22,28 @@
       bindings.StubBindings(this.stub_).delegate = this;
     }
 
-    takePhoto(sourceid) {
+    getCapabilities(source_id) {
+      const response =
+          { capabilities : { zoom : { min : 0, max : 10, initial : 5 } } };
+      if (this.getCapabilitiesCallback_) {
+        // Give the time needed for the Mojo response to ripple back to Blink.
+        setTimeout(this.getCapabilitiesCallback_, 0, response.capabilities);
+        //this.getCapabilitiesCallback_(response.capabilities)
+      }
+      return Promise.resolve(response);
+    }
+
+    takePhoto(source_id) {
       return Promise.resolve({ mime_type : 'image/cat',
                                data : "(,,,)=(^.^)=(,,,)" });
     }
+
+    waitForGetCapabilities() {
+      return new Promise((resolve,reject) => {
+         this.getCapabilitiesCallback_ = resolve;
+      });
+    }
+
   }
   return new MockImageCapture();
 });
diff --git a/third_party/WebKit/LayoutTests/imagecapture/takephoto.html b/third_party/WebKit/LayoutTests/imagecapture/takephoto.html
index d3dc1f7..144d9c2 100644
--- a/third_party/WebKit/LayoutTests/imagecapture/takephoto.html
+++ b/third_party/WebKit/LayoutTests/imagecapture/takephoto.html
@@ -19,20 +19,21 @@
   var stream = canvas.captureStream();
 
   mockImageCaptureReady
-    .then((mock) => {
-      var capturer = new ImageCapture(stream.getVideoTracks()[0]);
-
-      capturer.takePhoto()
-        .then(blob => {
-            assert_true(blob.size > 0);
-            t.done();
-        })
-        .catch(error => {
-            assert_unreached("Error during takePhoto(): " + error);
-        });
+    .then(mock => {
+      return new ImageCapture(stream.getVideoTracks()[0]);
     })
     .catch(error => {
       assert_unreached("Error creating MockImageCapture: " + error);
+    })
+    .then(capturer => {
+      return capturer.takePhoto();
+    })
+    .then(blob => {
+        assert_true(blob.size > 0);
+        t.done();
+    })
+    .catch(error => {
+        assert_unreached("Error during takePhoto(): " + error);
     });
 }, 'exercises the ImageCapture API takePhoto()');
 
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 151ea1d..f493e96 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -774,6 +774,7 @@
     setter oncomplete
     setter onerror
 global object
+    attribute StorageManager
     attribute console
     attribute internals
     getter caches
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index aabe1c5f6..0b9c9690 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1,3 +1,4 @@
+CONSOLE ERROR: The 'DurableStorage' feature is currently enabled in limited trials. Please see https://bit.ly/OriginTrials for information on enabling a trial for your site.
 CONSOLE WARNING: 'webkitIDBTransaction' is deprecated. Please use 'IDBTransaction' instead.
 CONSOLE WARNING: 'webkitIDBRequest' is deprecated. Please use 'IDBRequest' instead.
 CONSOLE WARNING: 'webkitIDBObjectStore' is deprecated. Please use 'IDBObjectStore' instead.
@@ -850,6 +851,7 @@
 [Worker]     setter oncomplete
 [Worker]     setter onerror
 [Worker] [GLOBAL OBJECT]
+[Worker]     attribute StorageManager
 [Worker]     attribute console
 [Worker]     attribute internals
 [Worker]     getter caches
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 59500d5..5cbe1dd 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -10,6 +10,7 @@
 CONSOLE WARNING: 'webkitIDBDatabase' is deprecated. Please use 'IDBDatabase' instead.
 CONSOLE WARNING: 'webkitIDBCursor' is deprecated. Please use 'IDBCursor' instead.
 CONSOLE WARNING: 'webkitIndexedDB' is deprecated. Please use 'indexedDB' instead.
+CONSOLE ERROR: The 'DurableStorage' feature is currently enabled in limited trials. Please see https://bit.ly/OriginTrials for information on enabling a trial for your site.
 CONSOLE WARNING: 'webkitURL' is deprecated. Please use 'URL' instead.
 This test documents all interface attributes and methods on the global window object and element instances.
 
@@ -6452,6 +6453,7 @@
     setter username
 [GLOBAL OBJECT]
     attribute GCController
+    attribute StorageManager
     attribute accessibilityController
     attribute applicationCache
     attribute caches
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index 30df7f6..d05e575 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -842,6 +842,7 @@
 [Worker]     setter oncomplete
 [Worker]     setter onerror
 [Worker] [GLOBAL OBJECT]
+[Worker]     attribute StorageManager
 [Worker]     attribute console
 [Worker]     attribute internals
 [Worker]     getter caches
diff --git a/third_party/WebKit/LayoutTests/web-animations-api/animations-responsive-fontSize.html b/third_party/WebKit/LayoutTests/web-animations-api/animations-responsive-fontSize.html
index 7a070a46..9f794fd 100644
--- a/third_party/WebKit/LayoutTests/web-animations-api/animations-responsive-fontSize.html
+++ b/third_party/WebKit/LayoutTests/web-animations-api/animations-responsive-fontSize.html
@@ -39,4 +39,34 @@
     assert_not_equals(getComputedStyle(element).fontSize, fontSize);
 }, 'Relative font size smaller responsive to style changes');
 
+test(function() {
+    var keyframes = [
+        {fontSize: 'medium'},
+        {fontSize: 'medium'}
+    ];
+
+    container.style.fontFamily = 'cursive';
+    var player = element.animate(keyframes, 10);
+    player.pause();
+    player.currentTime = 5;
+    fontSize = getComputedStyle(element).fontSize;
+    container.style.fontFamily = 'monospace';
+    assert_not_equals(getComputedStyle(element).fontSize, fontSize);
+}, 'Font size medium responsive to style changes');
+
+test(function() {
+    var keyframes = [
+        {fontSize: 'initial'},
+        {fontSize: 'initial'}
+    ];
+
+    container.style.fontFamily = 'monospace';
+    var player = element.animate(keyframes, 10);
+    player.pause();
+    player.currentTime = 5;
+    fontSize = getComputedStyle(element).fontSize;
+    container.style.fontFamily = 'serif';
+    assert_not_equals(getComputedStyle(element).fontSize, fontSize);
+}, 'Font size initial responsive to style changes');
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index e682d60..00f71e4 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3410,6 +3410,7 @@
     method transferFromImageBitmap
 interface ImageCapture
     attribute @@toStringTag
+    getter photoCapabilities
     getter videoStreamTrack
     method constructor
     method grabFrame
@@ -3685,6 +3686,12 @@
     setter onresume
     setter onstart
     setter onstop
+interface MediaSettingsRange
+    attribute @@toStringTag
+    getter initial
+    getter max
+    getter min
+    method constructor
 interface MediaSource : EventTarget
     static method isTypeSupported
     attribute @@toStringTag
@@ -4295,6 +4302,11 @@
     attribute @@toStringTag
     getter length
     method constructor
+interface PhotoCapabilities
+    attribute @@toStringTag
+    getter zoom
+    method constructor
+    setter zoom
 interface Plugin
     attribute @@toStringTag
     getter description
diff --git a/third_party/WebKit/PRESUBMIT.py b/third_party/WebKit/PRESUBMIT.py
index 75dde66..f0a4cb0 100644
--- a/third_party/WebKit/PRESUBMIT.py
+++ b/third_party/WebKit/PRESUBMIT.py
@@ -235,7 +235,8 @@
     """Checks that Blink uses Chromium namespaces only in permitted code."""
     # This list is not exhaustive, but covers likely ones.
     chromium_namespaces = ["base", "cc", "content", "gfx", "net", "ui"]
-    chromium_classes = ["scoped_refptr"]
+    chromium_forbidden_classes = ["scoped_refptr"]
+    chromium_allowed_classes = ["gfx::CubicBezier"]
 
     def source_file_filter(path):
         return input_api.FilterSourceFile(path,
@@ -245,13 +246,29 @@
     comment_re = input_api.re.compile(r'^\s*//')
     result = []
     for namespace in chromium_namespaces:
-        namespace_re = input_api.re.compile(r'\b{0}::|^\s*using namespace {0};|^\s*namespace {0} \{{'.format(input_api.re.escape(namespace)))
+        namespace_re = input_api.re.compile(r'\b{0}::([A-Za-z_][A-Za-z0-9_]*)'.format(input_api.re.escape(namespace)))
+
+        def uses_namespace_outside_comments(line):
+            if comment_re.search(line):
+                return False
+            re_result = namespace_re.search(line)
+            if not re_result:
+                return False
+            parsed_class_name = namespace + "::" + re_result.group(1)
+            return not (parsed_class_name in chromium_allowed_classes)
+
+        errors = input_api.canned_checks._FindNewViolationsOfRule(lambda _, line: not uses_namespace_outside_comments(line),
+                                                                  input_api, source_file_filter)
+        if errors:
+            result += [output_api.PresubmitError('Do not use Chromium class from namespace {} inside Blink core:\n{}'.format(namespace, '\n'.join(errors)))]
+    for namespace in chromium_namespaces:
+        namespace_re = input_api.re.compile(r'^\s*using namespace {0};|^\s*namespace {0} \{{'.format(input_api.re.escape(namespace)))
         uses_namespace_outside_comments = lambda line: namespace_re.search(line) and not comment_re.search(line)
         errors = input_api.canned_checks._FindNewViolationsOfRule(lambda _, line: not uses_namespace_outside_comments(line),
                                                                   input_api, source_file_filter)
         if errors:
             result += [output_api.PresubmitError('Do not use Chromium namespace {} inside Blink core:\n{}'.format(namespace, '\n'.join(errors)))]
-    for class_name in chromium_classes:
+    for class_name in chromium_forbidden_classes:
         class_re = input_api.re.compile(r'\b{0}\b'.format(input_api.re.escape(class_name)))
         uses_class_outside_comments = lambda line: class_re.search(line) and not comment_re.search(line)
         errors = input_api.canned_checks._FindNewViolationsOfRule(lambda _, line: not uses_class_outside_comments(line),
diff --git a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp
index 0aabc32d..90d31e6 100644
--- a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp
@@ -67,7 +67,7 @@
     return InterpolationValue(BasicShapeInterpolationFunctions::createNeutralValue(*underlying.nonInterpolableValue), nonInterpolableValue);
 }
 
-InterpolationValue CSSBasicShapeInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSBasicShapeInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return BasicShapeInterpolationFunctions::maybeConvertBasicShape(
         BasicShapePropertyFunctions::getInitialBasicShape(cssProperty()), 1);
diff --git a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h
index 5532322..e46cb49 100644
--- a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
index c32c70a7..e3247cc 100644
--- a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
@@ -173,7 +173,7 @@
     return convertBorderImageLengthBox(zeroBox, 1);
 }
 
-InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return convertBorderImageLengthBox(BorderImageLengthBoxPropertyFunctions::getInitialBorderImageLengthBox(cssProperty()), 1);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h
index e7496c1..c98ad69 100644
--- a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp
index e27f941..898dd59 100644
--- a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp
@@ -175,7 +175,7 @@
     return createClipValue(neutralBox, 1);
 }
 
-InterpolationValue CSSClipInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSClipInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return nullptr;
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h
index c12f6aa..37a76e9 100644
--- a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h
@@ -24,7 +24,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp
index e8c09fa5..c12d010 100644
--- a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp
@@ -161,7 +161,7 @@
     return convertStyleColorPair(StyleColor(Color::transparent), StyleColor(Color::transparent));
 }
 
-InterpolationValue CSSColorInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSColorInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     const StyleColor initialColor = ColorPropertyFunctions::getInitialColor(cssProperty());
     return convertStyleColorPair(initialColor, initialColor);
diff --git a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h
index 4420d364..02f60d8 100644
--- a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h
@@ -30,7 +30,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue convertStyleColorPair(const StyleColor&, const StyleColor&) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp
index f7bee75..ac54530 100644
--- a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp
@@ -89,7 +89,7 @@
     return InterpolationValue(underlying.interpolableValue->cloneAndZero(), &nonInterpolableList);
 }
 
-InterpolationValue CSSFilterListInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSFilterListInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     return convertFilterList(FilterListPropertyFunctions::getInitialFilterList(cssProperty()), 1);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h
index 01fcc2b..64dd993 100644
--- a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
index 76581ae..b409ffc 100644
--- a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
@@ -14,6 +14,25 @@
 
 namespace {
 
+class IsMonospaceChecker : public InterpolationType::ConversionChecker {
+public:
+    static PassOwnPtr<IsMonospaceChecker> create(bool isMonospace)
+    {
+        return adoptPtr(new IsMonospaceChecker(isMonospace));
+    }
+private:
+    IsMonospaceChecker(bool isMonospace)
+        : m_isMonospace(isMonospace)
+    { }
+
+    bool isValid(const InterpolationEnvironment& environment, const InterpolationValue&) const final
+    {
+        return m_isMonospace == environment.state().style()->getFontDescription().isMonospace();
+    }
+
+    const bool m_isMonospace;
+};
+
 class InheritedFontSizeChecker : public InterpolationType::ConversionChecker {
 public:
     static PassOwnPtr<InheritedFontSizeChecker> create(const FontDescription::Size& inheritedFontSize)
@@ -39,18 +58,19 @@
     return InterpolationValue(CSSLengthInterpolationType::createInterpolablePixels(size));
 }
 
-InterpolationValue maybeConvertKeyword(CSSValueID valueID, const StyleResolverState& state, InterpolationType::ConversionCheckers* conversionCheckers)
+InterpolationValue maybeConvertKeyword(CSSValueID valueID, const StyleResolverState& state, InterpolationType::ConversionCheckers& conversionCheckers)
 {
     if (FontSize::isValidValueID(valueID)) {
-        // TODO(alancutter): Be responsive to changes in isMonospace().
-        return convertFontSize(state.fontBuilder().fontSizeForKeyword(FontSize::keywordSize(valueID), state.style()->getFontDescription().isMonospace()));
+        bool isMonospace = state.style()->getFontDescription().isMonospace();
+        conversionCheckers.append(IsMonospaceChecker::create(isMonospace));
+        return convertFontSize(state.fontBuilder().fontSizeForKeyword(FontSize::keywordSize(valueID), isMonospace));
     }
 
     if (valueID != CSSValueSmaller && valueID != CSSValueLarger)
         return nullptr;
 
     const FontDescription::Size& inheritedFontSize = state.parentFontDescription().getSize();
-    conversionCheckers->append(InheritedFontSizeChecker::create(inheritedFontSize));
+    conversionCheckers.append(InheritedFontSizeChecker::create(inheritedFontSize));
     if (valueID == CSSValueSmaller)
         return convertFontSize(FontDescription::smallerSize(inheritedFontSize).value);
     return convertFontSize(FontDescription::largerSize(inheritedFontSize).value);
@@ -63,9 +83,9 @@
     return InterpolationValue(CSSLengthInterpolationType::createNeutralInterpolableValue());
 }
 
-InterpolationValue CSSFontSizeInterpolationType::maybeConvertInitial(const StyleResolverState& state) const
+InterpolationValue CSSFontSizeInterpolationType::maybeConvertInitial(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
 {
-    return maybeConvertKeyword(FontSize::initialValueID(), state, nullptr);
+    return maybeConvertKeyword(FontSize::initialValueID(), state, conversionCheckers);
 }
 
 InterpolationValue CSSFontSizeInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
@@ -84,7 +104,7 @@
     if (!value.isPrimitiveValue() || !toCSSPrimitiveValue(value).isValueID())
         return nullptr;
 
-    return maybeConvertKeyword(toCSSPrimitiveValue(value).getValueID(), state, &conversionCheckers);
+    return maybeConvertKeyword(toCSSPrimitiveValue(value).getValueID(), state, conversionCheckers);
 }
 
 InterpolationValue CSSFontSizeInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
diff --git a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h
index 38f9579..16a4256 100644
--- a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp
index bdf58ba7..cbc644c 100644
--- a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp
@@ -85,7 +85,7 @@
     return InterpolationValue(InterpolableNumber::create(0));
 }
 
-InterpolationValue CSSFontWeightInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSFontWeightInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     return createFontWeightValue(FontWeightNormal);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h
index f64209b..619e3e5 100644
--- a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h
@@ -24,7 +24,7 @@
 private:
     InterpolationValue createFontWeightValue(FontWeight) const;
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
index f7e5536..60a9a0a3 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
@@ -142,7 +142,7 @@
     return InterpolationValue(underlying.clone());
 }
 
-InterpolationValue CSSImageInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSImageInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     return maybeConvertStyleImage(ImagePropertyFunctions::getInitialStyleImage(cssProperty()), true);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h
index 7ec928b..bec9804d 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h
@@ -31,7 +31,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp
index 22d1ed50..e5c80b8 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp
@@ -41,7 +41,7 @@
     return underlying.clone();
 }
 
-InterpolationValue CSSImageListInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSImageListInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     StyleImageList initialImageList;
     ImageListPropertyFunctions::getInitialImageList(cssProperty(), initialImageList);
diff --git a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h
index 3f350d9b..33c619b 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h
@@ -24,7 +24,7 @@
     InterpolationValue maybeConvertStyleImageList(const StyleImageList&) const;
 
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp
index 28e27340..76890c03 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp
@@ -158,7 +158,7 @@
     return convertImageSlice(ImageSlice(zeroBox, underlyingTypes.fill), 1);
 }
 
-InterpolationValue CSSImageSliceInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSImageSliceInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     return convertImageSlice(ImageSlicePropertyFunctions::getInitialImageSlice(cssProperty()), 1);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h
index 337457b..eea100dd 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
index 51af4ea..1868fd8 100644
--- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
@@ -54,7 +54,7 @@
     }
 
     if (value->isInitialValue() || (value->isUnsetValue() && !CSSPropertyMetadata::isInheritedProperty(cssProperty())))
-        return maybeConvertInitial(environment.state());
+        return maybeConvertInitial(environment.state(), conversionCheckers);
 
     if (value->isInheritedValue() || (value->isUnsetValue() && CSSPropertyMetadata::isInheritedProperty(cssProperty())))
         return maybeConvertInherit(environment.state(), conversionCheckers);
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h
index f607015..6edfcb5 100644
--- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h
@@ -21,7 +21,7 @@
 
     InterpolationValue maybeConvertSingle(const PropertySpecificKeyframe&, const InterpolationEnvironment&, const InterpolationValue& underlying, ConversionCheckers&) const override;
     virtual InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const = 0;
-    virtual InterpolationValue maybeConvertInitial(const StyleResolverState&) const = 0;
+    virtual InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const = 0;
     virtual InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const = 0;
     virtual InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const = 0;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp
index 4ee4984..a2c4cc050 100644
--- a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp
@@ -174,7 +174,7 @@
     return InterpolationValue(createNeutralInterpolableValue());
 }
 
-InterpolationValue CSSLengthInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSLengthInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     Length initialLength;
     if (!LengthPropertyFunctions::getInitialLength(cssProperty(), initialLength))
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h
index 655443e..84f9b94 100644
--- a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h
@@ -36,7 +36,7 @@
     float effectiveZoom(const ComputedStyle&) const;
 
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp
index 62b4bd40..890cb13 100644
--- a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp
@@ -43,7 +43,7 @@
     });
 }
 
-InterpolationValue CSSLengthListInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSLengthListInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     Vector<Length> initialLengthList;
     if (!LengthListPropertyFunctions::getInitialLengthList(cssProperty(), initialLengthList))
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h
index 2acc226..d470b7f8 100644
--- a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h
@@ -21,7 +21,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     virtual InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.cpp
index 34cf81d3..4f50495 100644
--- a/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.cpp
@@ -91,7 +91,7 @@
     return convertMotionRotation(StyleMotionRotation(0, underlyingRotationType));
 }
 
-InterpolationValue CSSMotionRotationInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSMotionRotationInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     return convertMotionRotation(StyleMotionRotation(0, MotionRotationAuto));
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.h
index 4f51bbf..2fd12d5b 100644
--- a/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSMotionRotationInterpolationType.h
@@ -23,7 +23,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
     PairwiseInterpolationValue maybeMergeSingles(InterpolationValue&& start, InterpolationValue&& end) const final;
diff --git a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp
index fe5b328..debdf1e 100644
--- a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp
@@ -45,7 +45,7 @@
     return createNumberValue(0);
 }
 
-InterpolationValue CSSNumberInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSNumberInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     double initialNumber;
     if (!NumberPropertyFunctions::getInitialNumber(cssProperty(), initialNumber))
diff --git a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h
index fed02a47..573b8d33 100644
--- a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h
@@ -21,7 +21,7 @@
 private:
     InterpolationValue createNumberValue(double number) const;
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp
index 2dcae1b..33fb0e1 100644
--- a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp
@@ -15,7 +15,7 @@
     return InterpolationValue(CSSColorInterpolationType::createInterpolableColor(Color::transparent));
 }
 
-InterpolationValue CSSPaintInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSPaintInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers& conversionCheckers) const
 {
     StyleColor initialColor;
     if (!PaintPropertyFunctions::getInitialColor(cssProperty(), initialColor))
diff --git a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h
index fcab1101d..b49799b 100644
--- a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h
@@ -20,7 +20,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp
index 97c3e9c..03c87db 100644
--- a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp
@@ -31,7 +31,7 @@
     return PathInterpolationFunctions::maybeConvertNeutral(underlying, conversionCheckers);
 }
 
-InterpolationValue CSSPathInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSPathInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return PathInterpolationFunctions::convertValue(nullptr);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h
index a97a0761..6337fceb 100644
--- a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h
@@ -20,7 +20,7 @@
 
 protected:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertUnderlyingValue(const InterpolationEnvironment&) const final;
diff --git a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp
index 6b7b83b6b..c060bcad 100644
--- a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp
@@ -116,7 +116,7 @@
     return convertRotation(Rotation());
 }
 
-InterpolationValue CSSRotateInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSRotateInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return convertRotation(getRotation(ComputedStyle::initialStyle()));
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h
index c00b873..10ef2aa 100644
--- a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h
@@ -25,7 +25,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp
index bbb48a1a..8ee7a3cf 100644
--- a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp
@@ -122,7 +122,7 @@
     return InterpolationValue(Scale(1, 1, 1).createInterpolableValue());
 }
 
-InterpolationValue CSSScaleInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSScaleInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return InterpolationValue(Scale(1, 1, 1).createInterpolableValue());
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h
index 6120d7d..76bbd9f6 100644
--- a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h
@@ -24,7 +24,7 @@
 private:
     InterpolationValue maybeConvertSingle(const PropertySpecificKeyframe&, const InterpolationEnvironment&, const InterpolationValue& underlying, ConversionCheckers&) const final;
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
     PairwiseInterpolationValue maybeMergeSingles(InterpolationValue&&, InterpolationValue&&) const final;
diff --git a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp
index 66410cf7..2f2efc0 100644
--- a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp
@@ -34,7 +34,7 @@
     return createNeutralValue();
 }
 
-InterpolationValue CSSShadowListInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSShadowListInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return convertShadowList(ShadowListPropertyFunctions::getInitialShadowList(cssProperty()), 1);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h
index 54d10c4..0fea639 100644
--- a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h
@@ -26,7 +26,7 @@
     InterpolationValue createNeutralValue() const;
 
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
     PairwiseInterpolationValue maybeMergeSingles(InterpolationValue&& start, InterpolationValue&& end) const final;
diff --git a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp
index 5aac056..4cf925d 100644
--- a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp
@@ -117,7 +117,7 @@
     return createValue(Length(0, Fixed), mode, 1);
 }
 
-InterpolationValue CSSTextIndentInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSTextIndentInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     IndentMode mode(ComputedStyle::initialTextIndentLine(), ComputedStyle::initialTextIndentType());
     return createValue(ComputedStyle::initialTextIndent(), mode, 1);
diff --git a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h
index 22b7e07..6747e81 100644
--- a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h
@@ -24,7 +24,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp
index 445dee2..b44eb40 100644
--- a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp
@@ -131,7 +131,7 @@
     return convertTransform(EmptyTransformOperations());
 }
 
-InterpolationValue CSSTransformInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSTransformInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return convertTransform(ComputedStyle::initialStyle().transform());
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h
index 93f9c9a..daa23d98 100644
--- a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h
@@ -25,7 +25,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 };
diff --git a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp
index fc8810a..1f8b305 100644
--- a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp
@@ -75,7 +75,7 @@
     return createNeutralValue();
 }
 
-InterpolationValue CSSTranslateInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSTranslateInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return createNeutralValue();
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h
index bac02ce..97ba9fd 100644
--- a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h
@@ -22,7 +22,7 @@
 
 private:
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
index 6293ca6..4c3c926 100644
--- a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
@@ -30,10 +30,10 @@
     }
 
     // As we override CSSInterpolationType::maybeConvertSingle, these are never called.
-    InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final { ASSERT_NOT_REACHED(); return nullptr; }
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final { ASSERT_NOT_REACHED(); return nullptr; }
-    InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final { ASSERT_NOT_REACHED(); return nullptr; }
-    InterpolationValue maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const final { ASSERT_NOT_REACHED(); return nullptr; }
+    InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final { NOTREACHED(); return nullptr; }
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final { NOTREACHED(); return nullptr; }
+    InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final { NOTREACHED(); return nullptr; }
+    InterpolationValue maybeConvertValue(const CSSValue& value, const StyleResolverState&, ConversionCheckers&) const final { NOTREACHED(); return nullptr; }
 
     void composite(UnderlyingValueOwner& underlyingValueOwner, double underlyingFraction, const InterpolationValue& value, double interpolationFraction) const final
     {
diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
index c18d072..f620da1 100644
--- a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
@@ -109,7 +109,7 @@
     return createVisibilityValue(underlyingVisibility);
 }
 
-InterpolationValue CSSVisibilityInterpolationType::maybeConvertInitial(const StyleResolverState&) const
+InterpolationValue CSSVisibilityInterpolationType::maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const
 {
     return createVisibilityValue(VISIBLE);
 }
diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h
index daf1b39..c3cdea7 100644
--- a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h
@@ -26,7 +26,7 @@
 private:
     InterpolationValue createVisibilityValue(EVisibility) const;
     InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
-    InterpolationValue maybeConvertInitial(const StyleResolverState&) const final;
+    InterpolationValue maybeConvertInitial(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final;
     InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const final;
 
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
index a080cd2..ce8ff42d 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -491,28 +491,6 @@
     }
 }
 
-void getStepsTimingFunctionParameters(const TimingFunction& timingFunction, int& outSteps, float& outStepsStartOffset)
-{
-    const StepsTimingFunction& steps = toStepsTimingFunction(timingFunction);
-
-    outSteps = steps.numberOfSteps();
-    switch (steps.getStepAtPosition()) {
-    case StepsTimingFunction::Start:
-        outStepsStartOffset = 1;
-        break;
-    case StepsTimingFunction::Middle:
-        outStepsStartOffset = 0.5;
-        break;
-    case StepsTimingFunction::End:
-        outStepsStartOffset = 0;
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        outStepsStartOffset = 0;
-        break;
-    }
-}
-
 template<typename PlatformAnimationCurveType, typename PlatformAnimationKeyframeType>
 void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const PlatformAnimationKeyframeType& keyframe, const TimingFunction* timingFunction)
 {
@@ -541,11 +519,8 @@
     }
 
     case TimingFunction::kStepsFunction: {
-        int steps;
-        float stepsStartOffset;
-        getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffset);
-
-        curve.add(keyframe, steps, stepsStartOffset);
+        const StepsTimingFunction& steps = toStepsTimingFunction(*timingFunction);
+        curve.add(keyframe, steps.numberOfSteps(), steps.getStepPosition());
         break;
     }
 
@@ -582,11 +557,8 @@
     }
 
     case TimingFunction::kStepsFunction: {
-        int steps;
-        float stepsStartOffset;
-        getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffset);
-
-        curve.setStepsTimingFunction(steps, stepsStartOffset);
+        const StepsTimingFunction& steps = toStepsTimingFunction(*timingFunction);
+        curve.setStepsTimingFunction(steps.numberOfSteps(), steps.getStepPosition());
         break;
     }
 
@@ -711,16 +683,16 @@
 
         switch (compositorTiming.direction) {
         case Timing::PlaybackDirectionNormal:
-            animation->setDirection(CompositorAnimation::DirectionNormal);
+            animation->setDirection(CompositorAnimation::Direction::NORMAL);
             break;
         case Timing::PlaybackDirectionReverse:
-            animation->setDirection(CompositorAnimation::DirectionReverse);
+            animation->setDirection(CompositorAnimation::Direction::REVERSE);
             break;
         case Timing::PlaybackDirectionAlternate:
-            animation->setDirection(CompositorAnimation::DirectionAlternate);
+            animation->setDirection(CompositorAnimation::Direction::ALTERNATE_NORMAL);
             break;
         case Timing::PlaybackDirectionAlternateReverse:
-            animation->setDirection(CompositorAnimation::DirectionAlternateReverse);
+            animation->setDirection(CompositorAnimation::Direction::ALTERNATE_REVERSE);
             break;
         default:
             ASSERT_NOT_REACHED();
@@ -729,16 +701,16 @@
 
         switch (compositorTiming.fillMode) {
         case Timing::FillModeNone:
-            animation->setFillMode(CompositorAnimation::FillModeNone);
+            animation->setFillMode(CompositorAnimation::FillMode::NONE);
             break;
         case Timing::FillModeForwards:
-            animation->setFillMode(CompositorAnimation::FillModeForwards);
+            animation->setFillMode(CompositorAnimation::FillMode::FORWARDS);
             break;
         case Timing::FillModeBackwards:
-            animation->setFillMode(CompositorAnimation::FillModeBackwards);
+            animation->setFillMode(CompositorAnimation::FillMode::BACKWARDS);
             break;
         case Timing::FillModeBoth:
-            animation->setFillMode(CompositorAnimation::FillModeBoth);
+            animation->setFillMode(CompositorAnimation::FillMode::BOTH);
             break;
         default:
             ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
index 3d15b50..2cc8b87 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -96,7 +96,7 @@
         m_linearTimingFunction = LinearTimingFunction::shared();
         m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
         m_cubicCustomTimingFunction = CubicBezierTimingFunction::create(1, 2, 3, 4);
-        m_stepTimingFunction = StepsTimingFunction::create(1, StepsTimingFunction::End);
+        m_stepTimingFunction = StepsTimingFunction::create(1, StepsTimingFunction::StepPosition::END);
 
         m_timing = createCompositableTiming();
         m_compositorTiming = CompositorAnimationsImpl::CompositorTiming();
@@ -676,7 +676,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -721,7 +721,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -773,7 +773,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionAlternate));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::ALTERNATE_NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(2.0));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -820,7 +820,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(-3.25));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -877,7 +877,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionAlternate));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::ALTERNATE_NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -935,7 +935,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionAlternateReverse));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::ALTERNATE_REVERSE));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -983,7 +983,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(3.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionAlternateReverse));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::ALTERNATE_REVERSE));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -1028,7 +1028,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(-3));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
@@ -1073,9 +1073,9 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setFillMode(CompositorAnimation::FillModeNone));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setFillMode(CompositorAnimation::FillMode::NONE));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
         .Times(1)
@@ -1118,9 +1118,9 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setFillMode(CompositorAnimation::FillModeNone));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setFillMode(CompositorAnimation::FillMode::NONE));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
         .Times(1)
@@ -1164,7 +1164,7 @@
 
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
-    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::DirectionNormal));
+    usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(CompositorAnimation::Direction::NORMAL));
     usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setPlaybackRate(1));
 
     EXPECT_CALL(*mockAnimationPtr, delete_())
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
index d9f9830..580c937 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
@@ -99,12 +99,12 @@
     MOCK_METHOD1_T(add, void(const KeyframeType&));
     MOCK_METHOD2_T(add, void(const KeyframeType&, CompositorAnimationCurve::TimingFunctionType));
     MOCK_METHOD5_T(add, void(const KeyframeType&, double, double, double, double));
-    MOCK_METHOD3_T(add, void(const KeyframeType&, int steps, float stepsStartOffset));
+    MOCK_METHOD3_T(add, void(const KeyframeType&, int steps, StepsTimingFunction::StepPosition));
 
     MOCK_METHOD0(setLinearTimingFunction, void());
     MOCK_METHOD4(setCubicBezierTimingFunction, void(double, double, double, double));
     MOCK_METHOD1(setCubicBezierTimingFunction, void(CompositorAnimationCurve::TimingFunctionType));
-    MOCK_METHOD2(setStepsTimingFunction, void(int, float));
+    MOCK_METHOD2(setStepsTimingFunction, void(int, StepsTimingFunction::StepPosition));
 
     MOCK_CONST_METHOD1_T(getValue, float(double)); // Only on CompositorFloatAnimationCurve, but can't hurt to have here.
 
diff --git a/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp b/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp
index eb455410..698e567 100644
--- a/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp
+++ b/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp
@@ -183,7 +183,7 @@
     EXPECT_EQ(12, calculateTransformedTime(1, 20, 12, timing));
 
     // PlaybackDirectionForwards with timing function
-    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::End);
+    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::END);
     EXPECT_EQ(10, calculateTransformedTime(0, 20, 12, timing));
     EXPECT_EQ(10, calculateTransformedTime(1, 20, 12, timing));
 
@@ -194,7 +194,7 @@
     EXPECT_EQ(8, calculateTransformedTime(1, 20, 12, timing));
 
     // PlaybackDirectionReverse with timing function
-    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::End);
+    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::END);
     EXPECT_EQ(5, calculateTransformedTime(0, 20, 12, timing));
     EXPECT_EQ(5, calculateTransformedTime(1, 20, 12, timing));
 
diff --git a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
index 42c8abf..ea312229 100644
--- a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
+++ b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
@@ -202,19 +202,19 @@
     EXPECT_TRUE(success);
     EXPECT_EQ(*LinearTimingFunction::shared(), *applyTimingInputString("easing", "linear", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Start), *applyTimingInputString("easing", "step-start", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START), *applyTimingInputString("easing", "step-start", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Middle), *applyTimingInputString("easing", "step-middle", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::MIDDLE), *applyTimingInputString("easing", "step-middle", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::End), *applyTimingInputString("easing", "step-end", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END), *applyTimingInputString("easing", "step-end", success).timingFunction);
     EXPECT_TRUE(success);
     EXPECT_EQ(*CubicBezierTimingFunction::create(1, 1, 0.3, 0.3), *applyTimingInputString("easing", "cubic-bezier(1, 1, 0.3, 0.3)", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::create(3, StepsTimingFunction::Start), *applyTimingInputString("easing", "steps(3, start)", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(3, StepsTimingFunction::StepPosition::START), *applyTimingInputString("easing", "steps(3, start)", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::Middle), *applyTimingInputString("easing", "steps(5, middle)", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::MIDDLE), *applyTimingInputString("easing", "steps(5, middle)", success).timingFunction);
     EXPECT_TRUE(success);
-    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::End), *applyTimingInputString("easing", "steps(5, end)", success).timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::END), *applyTimingInputString("easing", "steps(5, end)", success).timingFunction);
     EXPECT_TRUE(success);
 
     applyTimingInputString("easing", "", success);
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 1ff02bde..2dc4fa81 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -1490,6 +1490,8 @@
             'editing/SelectionController.h',
             'editing/SelectionEditor.cpp',
             'editing/SelectionEditor.h',
+            'editing/SelectionModifier.cpp',
+            'editing/SelectionModifier.h',
             'editing/SelectionType.h',
             'editing/SurroundingText.cpp',
             'editing/SurroundingText.h',
diff --git a/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp b/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
index 3fa1eea..bfdb36d 100644
--- a/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
@@ -45,28 +45,24 @@
 
 String CSSStepsTimingFunctionValue::customCSSText() const
 {
-    String stepAtPositionString;
-    switch (m_stepAtPosition) {
-    case StepsTimingFunction::Start:
-        stepAtPositionString = "start";
+    String stepPositionString;
+    switch (m_stepPosition) {
+    case StepsTimingFunction::StepPosition::START:
+        stepPositionString = "start";
         break;
-    case StepsTimingFunction::Middle:
-        stepAtPositionString = "middle";
+    case StepsTimingFunction::StepPosition::MIDDLE:
+        stepPositionString = "middle";
         break;
-    case StepsTimingFunction::End:
-        stepAtPositionString = "end";
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        stepAtPositionString = "end";
+    case StepsTimingFunction::StepPosition::END:
+        stepPositionString = "end";
         break;
     }
-    return "steps(" + String::number(m_steps) + ", " + stepAtPositionString + ')';
+    return "steps(" + String::number(m_steps) + ", " + stepPositionString + ')';
 }
 
 bool CSSStepsTimingFunctionValue::equals(const CSSStepsTimingFunctionValue& other) const
 {
-    return m_steps == other.m_steps && m_stepAtPosition == other.m_stepAtPosition;
+    return m_steps == other.m_steps && m_stepPosition == other.m_stepPosition;
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h b/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
index 4115442..b3036afa 100644
--- a/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
+++ b/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
@@ -70,13 +70,13 @@
 
 class CSSStepsTimingFunctionValue : public CSSValue {
 public:
-    static CSSStepsTimingFunctionValue* create(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
+    static CSSStepsTimingFunctionValue* create(int steps, StepsTimingFunction::StepPosition stepPosition)
     {
-        return new CSSStepsTimingFunctionValue(steps, stepAtPosition);
+        return new CSSStepsTimingFunctionValue(steps, stepPosition);
     }
 
     int numberOfSteps() const { return m_steps; }
-    StepsTimingFunction::StepAtPosition getStepAtPosition() const { return m_stepAtPosition; }
+    StepsTimingFunction::StepPosition getStepPosition() const { return m_stepPosition; }
 
     String customCSSText() const;
 
@@ -85,15 +85,15 @@
     DEFINE_INLINE_TRACE_AFTER_DISPATCH() { CSSValue::traceAfterDispatch(visitor); }
 
 private:
-    CSSStepsTimingFunctionValue(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
+    CSSStepsTimingFunctionValue(int steps, StepsTimingFunction::StepPosition stepPosition)
         : CSSValue(StepsTimingFunctionClass)
         , m_steps(steps)
-        , m_stepAtPosition(stepAtPosition)
+        , m_stepPosition(stepPosition)
     {
     }
 
     int m_steps;
-    StepsTimingFunction::StepAtPosition m_stepAtPosition;
+    StepsTimingFunction::StepPosition m_stepPosition;
 };
 
 DEFINE_CSS_VALUE_TYPE_CASTS(CSSStepsTimingFunctionValue, isStepsTimingFunctionValue());
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 6f6d9465..3f719fe 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -1070,13 +1070,13 @@
     case TimingFunction::kStepsFunction:
         {
             const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction);
-            StepsTimingFunction::StepAtPosition position = stepsTimingFunction->getStepAtPosition();
+            StepsTimingFunction::StepPosition position = stepsTimingFunction->getStepPosition();
             int steps = stepsTimingFunction->numberOfSteps();
-            ASSERT(position == StepsTimingFunction::Start || position == StepsTimingFunction::End);
+            DCHECK(position == StepsTimingFunction::StepPosition::START || position == StepsTimingFunction::StepPosition::END);
 
             if (steps > 1)
                 return CSSStepsTimingFunctionValue::create(steps, position);
-            CSSValueID valueId = position == StepsTimingFunction::Start ? CSSValueStepStart : CSSValueStepEnd;
+            CSSValueID valueId = position == StepsTimingFunction::StepPosition::START ? CSSValueStepStart : CSSValueStepEnd;
             return cssValuePool().createIdentifierValue(valueId);
         }
 
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 6562558..d3e9794 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1183,19 +1183,19 @@
     if (!steps)
         return nullptr;
 
-    StepsTimingFunction::StepAtPosition position = StepsTimingFunction::End;
+    StepsTimingFunction::StepPosition position = StepsTimingFunction::StepPosition::END;
     if (consumeCommaIncludingWhitespace(args)) {
         switch (args.consumeIncludingWhitespace().id()) {
         case CSSValueMiddle:
             if (!RuntimeEnabledFeatures::webAnimationsAPIEnabled())
                 return nullptr;
-            position = StepsTimingFunction::Middle;
+            position = StepsTimingFunction::StepPosition::MIDDLE;
             break;
         case CSSValueStart:
-            position = StepsTimingFunction::Start;
+            position = StepsTimingFunction::StepPosition::START;
             break;
         case CSSValueEnd:
-            position = StepsTimingFunction::End;
+            position = StepsTimingFunction::StepPosition::END;
             break;
         default:
             return nullptr;
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp b/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
index a08e364..bec29ee3 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
@@ -396,13 +396,13 @@
         case CSSValueEaseInOut:
             return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
         case CSSValueStepStart:
-            return StepsTimingFunction::preset(StepsTimingFunction::Start);
+            return StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
         case CSSValueStepMiddle:
             if (allowStepMiddle)
-                return StepsTimingFunction::preset(StepsTimingFunction::Middle);
+                return StepsTimingFunction::preset(StepsTimingFunction::StepPosition::MIDDLE);
             return CSSTimingData::initialTimingFunction();
         case CSSValueStepEnd:
-            return StepsTimingFunction::preset(StepsTimingFunction::End);
+            return StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
         default:
             ASSERT_NOT_REACHED();
             return CSSTimingData::initialTimingFunction();
@@ -418,9 +418,9 @@
         return CSSTimingData::initialTimingFunction();
 
     const CSSStepsTimingFunctionValue& stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
-    if (stepsTimingFunction.getStepAtPosition() == StepsTimingFunction::Middle && !allowStepMiddle)
+    if (stepsTimingFunction.getStepPosition() == StepsTimingFunction::StepPosition::MIDDLE && !allowStepMiddle)
         return CSSTimingData::initialTimingFunction();
-    return StepsTimingFunction::create(stepsTimingFunction.numberOfSteps(), stepsTimingFunction.getStepAtPosition());
+    return StepsTimingFunction::create(stepsTimingFunction.numberOfSteps(), stepsTimingFunction.getStepPosition());
 }
 
 void CSSToStyleMap::mapNinePieceImage(StyleResolverState& state, CSSPropertyID property, const CSSValue& value, NinePieceImage& image)
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 9939c9e..0db7245 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -1935,7 +1935,7 @@
     // beginFrame? This will catch the first layout in a page that does lots
     // of layout thrashing even though that layout might not be followed by
     // a paint for many seconds.
-    if (isRenderingReady() && body() && !styleEngine().hasPendingSheets()) {
+    if (isRenderingReady() && body() && !styleEngine().hasPendingScriptBlockingSheets()) {
         if (!m_documentTiming.firstLayout())
             m_documentTiming.markFirstLayout();
     }
@@ -1977,7 +1977,7 @@
 {
     StyleEngine::IgnoringPendingStylesheet ignoring(styleEngine());
 
-    if (styleEngine().hasPendingSheets()) {
+    if (styleEngine().hasPendingScriptBlockingSheets()) {
         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
         // Our assumption is that it would be dangerous to try to stop it a second time, after page
         // content has already been loaded and displayed with accurate style information. (Our
@@ -3031,7 +3031,7 @@
 
 void Document::didLoadAllImports()
 {
-    if (!haveStylesheetsLoaded())
+    if (!haveScriptBlockingStylesheetsLoaded())
         return;
     if (!importLoader())
         styleResolverMayHaveChanged();
@@ -3453,7 +3453,7 @@
 {
     styleEngine().resolverChanged(hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate);
 
-    if (didLayoutWithPendingStylesheets() && !styleEngine().hasPendingSheets()) {
+    if (didLayoutWithPendingStylesheets() && !styleEngine().hasPendingScriptBlockingSheets()) {
         // We need to manually repaint because we avoid doing all repaints in layout or style
         // recalc while sheets are still loading to avoid FOUC.
         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
@@ -5670,16 +5670,16 @@
     }
 }
 
-bool Document::haveStylesheetsLoaded() const
+bool Document::haveScriptBlockingStylesheetsLoaded() const
 {
-    return m_styleEngine->haveStylesheetsLoaded();
+    return m_styleEngine->haveScriptBlockingStylesheetsLoaded();
 }
 
 bool Document::haveRenderBlockingStylesheetsLoaded() const
 {
     if (RuntimeEnabledFeatures::cssInBodyDoesNotBlockPaintEnabled())
         return m_styleEngine->haveRenderBlockingStylesheetsLoaded();
-    return m_styleEngine->haveStylesheetsLoaded();
+    return m_styleEngine->haveScriptBlockingStylesheetsLoaded();
 }
 
 Locale& Document::getCachedLocale(const AtomicString& locale)
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 673206c..6130657 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -374,7 +374,7 @@
     bool sawElementsInKnownNamespaces() const { return m_sawElementsInKnownNamespaces; }
 
     bool isRenderingReady() const { return haveImportsLoaded() && haveRenderBlockingStylesheetsLoaded(); }
-    bool isScriptExecutionReady() const { return haveImportsLoaded() && haveStylesheetsLoaded(); }
+    bool isScriptExecutionReady() const { return haveImportsLoaded() && haveScriptBlockingStylesheetsLoaded(); }
 
     // This is a DOM function.
     StyleSheetList& styleSheets();
@@ -1155,7 +1155,7 @@
     void clearFocusedElementSoon();
     void clearFocusedElementTimerFired(Timer<Document>*);
 
-    bool haveStylesheetsLoaded() const;
+    bool haveScriptBlockingStylesheetsLoaded() const;
     bool haveRenderBlockingStylesheetsLoaded() const;
     void styleResolverMayHaveChanged();
 
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
index 5efdd12..5b241d1 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -133,7 +133,7 @@
 
 void StyleEngine::addPendingSheet(StyleEngineContext &context)
 {
-    m_pendingStylesheets++;
+    m_pendingScriptBlockingStylesheets++;
 
     context.addingPendingSheet(document());
     if (context.addedPendingSheetBeforeBody())
@@ -154,10 +154,10 @@
     }
 
     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
-    DCHECK_GT(m_pendingStylesheets, 0);
+    DCHECK_GT(m_pendingScriptBlockingStylesheets, 0);
 
-    m_pendingStylesheets--;
-    if (m_pendingStylesheets)
+    m_pendingScriptBlockingStylesheets--;
+    if (m_pendingScriptBlockingStylesheets)
         return;
 
     document().didRemoveAllPendingStylesheet();
@@ -427,7 +427,7 @@
 
 bool StyleEngine::shouldClearResolver() const
 {
-    return !m_didCalculateResolver && !haveStylesheetsLoaded();
+    return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded();
 }
 
 void StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h
index cd4c207..02bc8e13 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.h
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -102,9 +102,9 @@
     void addPendingSheet(StyleEngineContext&);
     void removePendingSheet(Node* styleSheetCandidateNode, const StyleEngineContext&);
 
-    bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
+    bool hasPendingScriptBlockingSheets() const { return m_pendingScriptBlockingStylesheets > 0; }
     bool hasPendingRenderBlockingSheets() const { return m_pendingRenderBlockingStylesheets > 0; }
-    bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
+    bool haveScriptBlockingStylesheetsLoaded() const { return !hasPendingScriptBlockingSheets() || m_ignorePendingStylesheets; }
     bool haveRenderBlockingStylesheetsLoaded() const { return !hasPendingRenderBlockingSheets() || m_ignorePendingStylesheets; }
     bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; }
 
@@ -225,7 +225,7 @@
     // Sheets loaded using the @import directive are not included in this count.
     // We use this count of pending sheets to detect when we can begin attaching
     // elements and when it is safe to execute scripts.
-    int m_pendingStylesheets = 0;
+    int m_pendingScriptBlockingStylesheets = 0;
     int m_pendingRenderBlockingStylesheets = 0;
 
     HeapVector<Member<CSSStyleSheet>> m_injectedAuthorStyleSheets;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index e19f7cf..aa0b479 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -45,6 +45,7 @@
 #include "core/editing/RenderedPosition.h"
 #include "core/editing/SelectionController.h"
 #include "core/editing/SelectionEditor.h"
+#include "core/editing/SelectionModifier.h"
 #include "core/editing/TextAffinity.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/commands/TypingCommand.h"
@@ -96,6 +97,7 @@
     , m_pendingSelection(PendingSelection::create(*this))
     , m_selectionEditor(SelectionEditor::create(*this))
     , m_granularity(CharacterGranularity)
+    , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
     , m_previousCaretVisibility(CaretVisibility::Hidden)
     , m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired)
     , m_caretRectDirty(true)
@@ -340,7 +342,7 @@
 
     // Always clear the x position used for vertical arrow navigation.
     // It will be restored by the vertical arrow navigation code if necessary.
-    m_selectionEditor->resetXPosForVerticalArrowNavigation();
+    m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
     // This may dispatch a synchronous focus-related events.
     selectFrameElementInParentIfFullySelected();
     notifyLayoutObjectOfSelectionChange(userTriggered);
@@ -598,10 +600,33 @@
     updateAppearance();
 }
 
+static DispatchEventResult dispatchSelectStart(const VisibleSelection& selection)
+{
+    Node* selectStartTarget = selection.extent().computeContainerNode();
+    if (!selectStartTarget)
+        return DispatchEventResult::NotCanceled;
+
+    return selectStartTarget->dispatchEvent(Event::createCancelableBubble(EventTypeNames::selectstart));
+}
+
 bool FrameSelection::modify(EAlteration alter, SelectionDirection direction, TextGranularity granularity, EUserTriggered userTriggered)
 {
-    if (!m_selectionEditor->modify(alter, direction, granularity, userTriggered))
+    SelectionModifier selectionModifier(*frame(), selection(), m_xPosForVerticalArrowNavigation);
+    const bool modified = selectionModifier.modify(alter, direction, granularity);
+    if (userTriggered == UserTriggered
+        && selectionModifier.selection().isRange()
+        && selection().isCaret()
+        && dispatchSelectStart(selection()) != DispatchEventResult::NotCanceled) {
         return false;
+    }
+    if (!modified)
+        return false;
+
+    const SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered;
+    setSelection(selectionModifier.selection(), options);
+
+    if (granularity == LineGranularity || granularity == ParagraphGranularity)
+        m_xPosForVerticalArrowNavigation = selectionModifier.xPosForVerticalArrowNavigation();
 
     if (userTriggered == UserTriggered)
         m_granularity = CharacterGranularity;
@@ -613,9 +638,16 @@
 
 bool FrameSelection::modify(EAlteration alter, unsigned verticalDistance, VerticalDirection direction, EUserTriggered userTriggered, CursorAlignOnScroll align)
 {
-    if (!m_selectionEditor->modify(alter, verticalDistance, direction, userTriggered, align))
+    SelectionModifier selectionModifier(*frame(), selection());
+    if (!selectionModifier.modifyWithPageGranularity(alter, verticalDistance, direction))
         return false;
 
+    const SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered;
+    if (alter == AlterationMove)
+        setSelection(selectionModifier.selection(), options, align);
+    else
+        setSelection(selectionModifier.selection(), options);
+
     if (userTriggered == UserTriggered)
         m_granularity = CharacterGranularity;
 
@@ -645,22 +677,6 @@
     m_previousCaretNode.clear();
 }
 
-void FrameSelection::setStart(const VisiblePosition &pos, EUserTriggered trigger)
-{
-    if (selection().isBaseFirst())
-        setBase(pos, trigger);
-    else
-        setExtent(pos, trigger);
-}
-
-void FrameSelection::setEnd(const VisiblePosition &pos, EUserTriggered trigger)
-{
-    if (selection().isBaseFirst())
-        setExtent(pos, trigger);
-    else
-        setBase(pos, trigger);
-}
-
 void FrameSelection::setBase(const VisiblePosition &pos, EUserTriggered userTriggered)
 {
     const bool selectionHasDirection = true;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.h b/third_party/WebKit/Source/core/editing/FrameSelection.h
index 259d7df..ae3aa98 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.h
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -145,9 +145,6 @@
 
     TextGranularity granularity() const { return m_granularity; }
 
-    void setStart(const VisiblePosition &, EUserTriggered = NotUserTriggered);
-    void setEnd(const VisiblePosition &, EUserTriggered = NotUserTriggered);
-
     void setBase(const VisiblePosition&, EUserTriggered = NotUserTriggered);
     void setExtent(const VisiblePosition&, EUserTriggered = NotUserTriggered);
 
@@ -302,6 +299,7 @@
     VisiblePosition m_originalBase;
     VisiblePositionInFlatTree m_originalBaseInFlatTree;
     TextGranularity m_granularity;
+    LayoutUnit m_xPosForVerticalArrowNavigation;
 
     Member<Node> m_previousCaretNode; // The last node which painted the caret. Retained for clearing the old caret when it moves.
     LayoutRect m_previousCaretRect;
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
index e0222b1..b70bc15b 100644
--- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -28,6 +28,7 @@
 #include "core/editing/EditingUtilities.h"
 #include "core/editing/Editor.h"
 #include "core/editing/SelectionAdjuster.h"
+#include "core/editing/SelectionModifier.h"
 #include "core/events/Event.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
@@ -37,11 +38,6 @@
 
 namespace blink {
 
-static inline LayoutUnit NoXPosForVerticalArrowNavigation()
-{
-    return LayoutUnit::min();
-}
-
 static inline bool shouldAlwaysUseDirectionalSelection(LocalFrame* frame)
 {
     return !frame || frame->editor().behavior().shouldConsiderSelectionAsDirectional();
@@ -49,7 +45,6 @@
 
 SelectionEditor::SelectionEditor(FrameSelection& frameSelection)
     : m_frameSelection(frameSelection)
-    , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
     , m_observingVisibleSelection(false)
 {
 }
@@ -102,11 +97,6 @@
     SelectionAdjuster::adjustSelectionInDOMTree(&m_selection, m_selectionInFlatTree);
 }
 
-void SelectionEditor::resetXPosForVerticalArrowNavigation()
-{
-    m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
-}
-
 void SelectionEditor::setIsDirectional(bool isDirectional)
 {
     m_selection.setIsDirectional(isDirectional);
@@ -119,12 +109,14 @@
     m_selectionInFlatTree.setWithoutValidation(toPositionInFlatTree(base), toPositionInFlatTree(extent));
 }
 
-TextDirection SelectionEditor::directionOfEnclosingBlock()
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+TextDirection SelectionModifier::directionOfEnclosingBlock() const
 {
     return blink::directionOfEnclosingBlock(m_selection.extent());
 }
 
-TextDirection SelectionEditor::directionOfSelection()
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+TextDirection SelectionModifier::directionOfSelection() const
 {
     InlineBox* startBox = nullptr;
     InlineBox* endBox = nullptr;
@@ -142,7 +134,8 @@
     return directionOfEnclosingBlock();
 }
 
-void SelectionEditor::willBeModified(EAlteration alter, SelectionDirection direction)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+void SelectionModifier::willBeModified(EAlteration alter, SelectionDirection direction)
 {
     if (alter != FrameSelection::AlterationExtend)
         return;
@@ -189,10 +182,10 @@
         m_selection.setBase(end);
         m_selection.setExtent(start);
     }
-    SelectionAdjuster::adjustSelectionInFlatTree(&m_selectionInFlatTree, m_selection);
 }
 
-VisiblePosition SelectionEditor::positionForPlatform(bool isGetStart) const
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::positionForPlatform(bool isGetStart) const
 {
     Settings* settings = frame() ? frame()->settings() : nullptr;
     if (settings && settings->editingBehaviorType() == EditingMacBehavior)
@@ -205,17 +198,20 @@
     return m_selection.isBaseFirst() ? m_selection.visibleEnd() : m_selection.visibleStart();
 }
 
-VisiblePosition SelectionEditor::startForPlatform() const
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::startForPlatform() const
 {
     return positionForPlatform(true);
 }
 
-VisiblePosition SelectionEditor::endForPlatform() const
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::endForPlatform() const
 {
     return positionForPlatform(false);
 }
 
-VisiblePosition SelectionEditor::nextWordPositionForPlatform(const VisiblePosition &originalPosition)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::nextWordPositionForPlatform(const VisiblePosition &originalPosition)
 {
     VisiblePosition positionAfterCurrentWord = nextWordPosition(originalPosition);
 
@@ -235,13 +231,15 @@
     return positionAfterCurrentWord;
 }
 
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
 static void adjustPositionForUserSelectAll(VisiblePosition& pos, bool isForward)
 {
     if (Node* rootUserSelectAll = EditingStrategy::rootUserSelectAllForNode(pos.deepEquivalent().anchorNode()))
         pos = createVisiblePosition(isForward ? mostForwardCaretPosition(positionAfterNode(rootUserSelectAll), CanCrossEditingBoundary) : mostBackwardCaretPosition(positionBeforeNode(rootUserSelectAll), CanCrossEditingBoundary));
 }
 
-VisiblePosition SelectionEditor::modifyExtendingRight(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyExtendingRight(TextGranularity granularity)
 {
     VisiblePosition pos = createVisiblePosition(m_selection.extent(), m_selection.affinity());
 
@@ -283,7 +281,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyExtendingForward(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyExtendingForward(TextGranularity granularity)
 {
     VisiblePosition pos = createVisiblePosition(m_selection.extent(), m_selection.affinity());
     switch (granularity) {
@@ -323,7 +322,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyMovingRight(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyMovingRight(TextGranularity granularity)
 {
     VisiblePosition pos;
     switch (granularity) {
@@ -358,7 +358,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyMovingForward(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyMovingForward(TextGranularity granularity)
 {
     VisiblePosition pos;
     // FIXME: Stay in editable content for the less common granularities.
@@ -406,7 +407,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyExtendingLeft(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyExtendingLeft(TextGranularity granularity)
 {
     VisiblePosition pos = createVisiblePosition(m_selection.extent(), m_selection.affinity());
 
@@ -447,7 +449,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyExtendingBackward(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyExtendingBackward(TextGranularity granularity)
 {
     VisiblePosition pos = createVisiblePosition(m_selection.extent(), m_selection.affinity());
 
@@ -492,7 +495,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyMovingLeft(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyMovingLeft(TextGranularity granularity)
 {
     VisiblePosition pos;
     switch (granularity) {
@@ -527,7 +531,8 @@
     return pos;
 }
 
-VisiblePosition SelectionEditor::modifyMovingBackward(TextGranularity granularity)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+VisiblePosition SelectionModifier::modifyMovingBackward(TextGranularity granularity)
 {
     VisiblePosition pos;
     switch (granularity) {
@@ -569,22 +574,35 @@
     return pos;
 }
 
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
 static bool isBoundary(TextGranularity granularity)
 {
     return granularity == LineBoundary || granularity == ParagraphBoundary || granularity == DocumentBoundary;
 }
 
-bool SelectionEditor::modify(EAlteration alter, SelectionDirection direction, TextGranularity granularity, EUserTriggered userTriggered)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+static void setSelectionEnd(VisibleSelection* selection, const VisiblePosition& newEnd)
 {
-    if (userTriggered == UserTriggered) {
-        FrameSelection* trialFrameSelection = FrameSelection::create();
-        trialFrameSelection->setSelection(m_selection);
-        trialFrameSelection->modify(alter, direction, granularity, NotUserTriggered);
-
-        if (trialFrameSelection->selection().isRange() && m_selection.isCaret() && dispatchSelectStart() != DispatchEventResult::NotCanceled)
-            return false;
+    if (selection->isBaseFirst()) {
+        selection->setExtent(newEnd);
+        return;
     }
+    selection->setBase(newEnd);
+}
 
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+static void setSelectionStart(VisibleSelection* selection, const VisiblePosition& newStart)
+{
+    if (selection->isBaseFirst()) {
+        selection->setBase(newStart);
+        return;
+    }
+    selection->setExtent(newStart);
+}
+
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+bool SelectionModifier::modify(EAlteration alter, SelectionDirection direction, TextGranularity granularity)
+{
     willBeModified(alter, direction);
 
     bool wasRange = m_selection.isRange();
@@ -634,7 +652,7 @@
 
     switch (alter) {
     case FrameSelection::AlterationMove:
-        m_frameSelection->moveTo(position, userTriggered);
+        m_selection = VisibleSelection(position, m_selection.isDirectional());
         break;
     case FrameSelection::AlterationExtend:
 
@@ -657,13 +675,13 @@
         if (!frame() || !frame()->editor().behavior().shouldAlwaysGrowSelectionWhenExtendingToBoundary()
             || m_selection.isCaret()
             || !isBoundary(granularity)) {
-            m_frameSelection->setExtent(position, userTriggered);
+            m_selection.setExtent(position);
         } else {
             TextDirection textDirection = directionOfEnclosingBlock();
             if (direction == DirectionForward || (textDirection == LTR && direction == DirectionRight) || (textDirection == RTL && direction == DirectionLeft))
-                m_frameSelection->setEnd(position, userTriggered);
+                setSelectionEnd(&m_selection, position);
             else
-                m_frameSelection->setStart(position, userTriggered);
+                setSelectionStart(&m_selection, position);
         }
         break;
     }
@@ -674,7 +692,8 @@
     return true;
 }
 
-// FIXME: Maybe baseline would be better?
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+// TODO(yosin): Maybe baseline would be better?
 static bool absoluteCaretY(const VisiblePosition &c, int &y)
 {
     IntRect rect = absoluteCaretBoundsOf(c);
@@ -684,7 +703,8 @@
     return true;
 }
 
-bool SelectionEditor::modify(EAlteration alter, unsigned verticalDistance, VerticalDirection direction, EUserTriggered userTriggered, CursorAlignOnScroll align)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+bool SelectionModifier::modifyWithPageGranularity(EAlteration alter, unsigned verticalDistance, VerticalDirection direction)
 {
     if (!verticalDistance)
         return false;
@@ -741,10 +761,10 @@
 
     switch (alter) {
     case FrameSelection::AlterationMove:
-        m_frameSelection->moveTo(result, userTriggered, align);
+        m_selection = VisibleSelection(result, m_selection.isDirectional());
         break;
     case FrameSelection::AlterationExtend:
-        m_frameSelection->setExtent(result, userTriggered);
+        m_selection.setExtent(result);
         break;
     }
 
@@ -753,6 +773,7 @@
     return true;
 }
 
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
 // Abs x/y position of the caret ignoring transforms.
 // TODO(yosin) navigation with transforms should be smarter.
 static LayoutUnit lineDirectionPointForBlockDirectionNavigationOf(const VisiblePosition& visiblePosition)
@@ -775,7 +796,8 @@
     return LayoutUnit(containingBlock->isHorizontalWritingMode() ? caretPoint.x() : caretPoint.y());
 }
 
-LayoutUnit SelectionEditor::lineDirectionPointForBlockDirectionNavigation(EPositionType type)
+// TODO(yosin): We should move this function to "SelectionModifier.cpp".
+LayoutUnit SelectionModifier::lineDirectionPointForBlockDirectionNavigation(EPositionType type)
 {
     LayoutUnit x;
 
@@ -846,15 +868,6 @@
     return firstRangeOf(m_selection);
 }
 
-DispatchEventResult SelectionEditor::dispatchSelectStart()
-{
-    Node* selectStartTarget = m_selection.extent().computeContainerNode();
-    if (!selectStartTarget)
-        return DispatchEventResult::NotCanceled;
-
-    return selectStartTarget->dispatchEvent(Event::createCancelableBubble(EventTypeNames::selectstart));
-}
-
 void SelectionEditor::didChangeVisibleSelection()
 {
     DCHECK(m_observingVisibleSelection);
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.h b/third_party/WebKit/Source/core/editing/SelectionEditor.h
index 69fb256d..a6b9a34 100644
--- a/third_party/WebKit/Source/core/editing/SelectionEditor.h
+++ b/third_party/WebKit/Source/core/editing/SelectionEditor.h
@@ -31,15 +31,13 @@
 
 namespace blink {
 
+// TODO(yosin): We will rename |SelectionEditor| to appropriate name since
+// it is no longer have a changing selection functionality, it was moved to
+// |SelectionModifier| class.
 class SelectionEditor final : public GarbageCollectedFinalized<SelectionEditor>, public VisibleSelectionChangeObserver {
     WTF_MAKE_NONCOPYABLE(SelectionEditor);
     USING_GARBAGE_COLLECTED_MIXIN(SelectionEditor);
 public:
-    // TODO(yosin) We should move |EAlteration| and |VerticalDirection| out
-    // from |FrameSelection| class like |EUserTriggered|.
-    typedef FrameSelection::EAlteration EAlteration;
-    typedef FrameSelection::VerticalDirection VerticalDirection;
-
     static SelectionEditor* create(FrameSelection& frameSelection)
     {
         return new SelectionEditor(frameSelection);
@@ -53,9 +51,6 @@
 
     bool setSelectedRange(const EphemeralRange&, TextAffinity, SelectionDirectionalMode, FrameSelection::SetSelectionOptions);
 
-    bool modify(EAlteration, SelectionDirection, TextGranularity, EUserTriggered);
-    bool modify(EAlteration, unsigned verticalDistance, VerticalDirection, EUserTriggered, CursorAlignOnScroll);
-
     template <typename Strategy>
     const VisibleSelectionTemplate<Strategy>& visibleSelection() const;
     void setVisibleSelection(const VisibleSelection&, FrameSelection::SetSelectionOptions);
@@ -64,10 +59,6 @@
     void setIsDirectional(bool);
     void setWithoutValidation(const Position& base, const Position& extent);
 
-    void resetXPosForVerticalArrowNavigation();
-
-    void willBeModified(EAlteration, SelectionDirection);
-
     // If this FrameSelection has a logical range which is still valid, this
     // function return its clone. Otherwise, the return value from underlying
     // |VisibleSelection|'s |firstRange()| is returned.
@@ -85,37 +76,12 @@
 private:
     explicit SelectionEditor(FrameSelection&);
 
-    // TODO(yosin) We should use capitalized name for |EPositionType|.
-    enum EPositionType { START, END, BASE, EXTENT }; // NOLINT
-
     LocalFrame* frame() const;
-
-    TextDirection directionOfEnclosingBlock();
-    TextDirection directionOfSelection();
-
-    VisiblePosition positionForPlatform(bool isGetStart) const;
-    VisiblePosition startForPlatform() const;
-    VisiblePosition endForPlatform() const;
-    VisiblePosition nextWordPositionForPlatform(const VisiblePosition&);
-
-    VisiblePosition modifyExtendingRight(TextGranularity);
-    VisiblePosition modifyExtendingForward(TextGranularity);
-    VisiblePosition modifyMovingRight(TextGranularity);
-    VisiblePosition modifyMovingForward(TextGranularity);
-    VisiblePosition modifyExtendingLeft(TextGranularity);
-    VisiblePosition modifyExtendingBackward(TextGranularity);
-    VisiblePosition modifyMovingLeft(TextGranularity);
-    VisiblePosition modifyMovingBackward(TextGranularity);
-
     void startObservingVisibleSelectionChange();
     void stopObservingVisibleSelectionChangeIfNecessary();
 
-    LayoutUnit lineDirectionPointForBlockDirectionNavigation(EPositionType);
-    DispatchEventResult dispatchSelectStart();
-
     Member<FrameSelection> m_frameSelection;
 
-    LayoutUnit m_xPosForVerticalArrowNavigation;
     VisibleSelection m_selection;
     VisibleSelectionInFlatTree m_selectionInFlatTree;
     bool m_observingVisibleSelection;
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
new file mode 100644
index 0000000..7f28985
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "core/editing/SelectionModifier.h"
+
+namespace blink {
+
+LayoutUnit NoXPosForVerticalArrowNavigation()
+{
+    return LayoutUnit::min();
+}
+
+SelectionModifier::SelectionModifier(const LocalFrame& frame, const VisibleSelection& selection, LayoutUnit xPosForVerticalArrowNavigation)
+    : m_frame(const_cast<LocalFrame*>(&frame))
+    , m_selection(selection)
+    , m_xPosForVerticalArrowNavigation(xPosForVerticalArrowNavigation)
+{
+}
+
+SelectionModifier::SelectionModifier(const LocalFrame& frame, const VisibleSelection& selection)
+    : SelectionModifier(frame, selection, NoXPosForVerticalArrowNavigation())
+{
+}
+
+DEFINE_TRACE(SelectionModifier)
+{
+    visitor->trace(m_frame);
+    visitor->trace(m_selection);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifier.h b/third_party/WebKit/Source/core/editing/SelectionModifier.h
new file mode 100644
index 0000000..b7114a4
--- /dev/null
+++ b/third_party/WebKit/Source/core/editing/SelectionModifier.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SelectionModifier_h
+#define SelectionModifier_h
+
+#include "base/macros.h"
+#include "core/editing/FrameSelection.h"
+#include "platform/LayoutUnit.h"
+#include "wtf/Allocator.h"
+
+namespace blink {
+
+class SelectionModifier {
+    STACK_ALLOCATED();
+public:
+    using EAlteration = FrameSelection::EAlteration;
+    using VerticalDirection = FrameSelection::VerticalDirection;
+
+    // |frame| is used for providing settings.
+    SelectionModifier(const LocalFrame& /* frame */, const VisibleSelection&, LayoutUnit);
+    SelectionModifier(const LocalFrame&, const VisibleSelection&);
+
+    LayoutUnit xPosForVerticalArrowNavigation() const { return m_xPosForVerticalArrowNavigation; }
+    const VisibleSelection& selection() const { return m_selection; }
+
+    bool modify(EAlteration, SelectionDirection, TextGranularity);
+    bool modifyWithPageGranularity(EAlteration, unsigned verticalDistance, VerticalDirection);
+
+    DECLARE_VIRTUAL_TRACE();
+
+private:
+    // TODO(yosin): We should move |EPositionType| to "SelectionModifier.cpp",
+    // it is only used for implementing |modify()|.
+    // TODO(yosin) We should use capitalized name for |EPositionType|.
+    enum EPositionType { START, END, BASE, EXTENT }; // NOLINT
+
+    LocalFrame* frame() const { return m_frame; }
+
+    TextDirection directionOfEnclosingBlock() const;
+    TextDirection directionOfSelection() const;
+    VisiblePosition positionForPlatform(bool isGetStart) const;
+    VisiblePosition startForPlatform() const;
+    VisiblePosition endForPlatform() const;
+    LayoutUnit lineDirectionPointForBlockDirectionNavigation(EPositionType);
+    VisiblePosition modifyExtendingRight(TextGranularity);
+    VisiblePosition modifyExtendingForward(TextGranularity);
+    VisiblePosition modifyMovingRight(TextGranularity);
+    VisiblePosition modifyMovingForward(TextGranularity);
+    VisiblePosition modifyExtendingLeft(TextGranularity);
+    VisiblePosition modifyExtendingBackward(TextGranularity);
+    VisiblePosition modifyMovingLeft(TextGranularity);
+    VisiblePosition modifyMovingBackward(TextGranularity);
+    VisiblePosition nextWordPositionForPlatform(const VisiblePosition&);
+    void willBeModified(EAlteration, SelectionDirection);
+
+    Member<LocalFrame> m_frame;
+    VisibleSelection m_selection;
+    LayoutUnit m_xPosForVerticalArrowNavigation;
+
+    DISALLOW_COPY_AND_ASSIGN(SelectionModifier);
+};
+
+LayoutUnit NoXPosForVerticalArrowNavigation();
+
+} // namespace blink
+
+#endif // SelectionModifier_h
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.cpp b/third_party/WebKit/Source/core/fetch/RawResource.cpp
index 48eadab..37c225d 100644
--- a/third_party/WebKit/Source/core/fetch/RawResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/RawResource.cpp
@@ -106,20 +106,21 @@
         return;
     ASSERT(RawResourceClient::isExpectedType(c));
     RawResourceClient* client = static_cast<RawResourceClient*>(c);
+    WeakPtr<RawResourceClient> clientWeak = client->createWeakPtr();
     for (const auto& redirect : redirectChain()) {
         ResourceRequest request(redirect.m_request);
         client->redirectReceived(this, request, redirect.m_redirectResponse);
-        if (!hasClient(c))
+        if (!clientWeak || !hasClient(c))
             return;
     }
 
     if (!m_response.isNull())
         client->responseReceived(this, m_response, nullptr);
-    if (!hasClient(c))
+    if (!clientWeak || !hasClient(c))
         return;
     if (m_data)
         client->dataReceived(this, m_data->data(), m_data->size());
-    if (!hasClient(c))
+    if (!clientWeak || !hasClient(c))
         return;
     Resource::didAddClient(client);
 }
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.h b/third_party/WebKit/Source/core/fetch/RawResource.h
index 46f8cc0..84b7026 100644
--- a/third_party/WebKit/Source/core/fetch/RawResource.h
+++ b/third_party/WebKit/Source/core/fetch/RawResource.h
@@ -28,6 +28,7 @@
 #include "core/fetch/ResourceClient.h"
 #include "public/platform/WebDataConsumerHandle.h"
 #include "wtf/PassOwnPtr.h"
+#include "wtf/WeakPtr.h"
 
 namespace blink {
 class FetchRequest;
@@ -103,6 +104,9 @@
 
 class CORE_EXPORT RawResourceClient : public ResourceClient {
 public:
+    RawResourceClient()
+        : m_weakFactory(this) { }
+    WeakPtr<RawResourceClient> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
     ~RawResourceClient() override {}
     static bool isExpectedType(ResourceClient* client) { return client->getResourceClientType() == RawResourceType; }
     ResourceClientType getResourceClientType() const final { return RawResourceType; }
@@ -115,6 +119,9 @@
     virtual void redirectBlocked() {}
     virtual void dataDownloaded(Resource*, int) { }
     virtual void didReceiveResourceTiming(Resource*, const ResourceTimingInfo&) { }
+
+private:
+    WeakPtrFactory<RawResourceClient> m_weakFactory;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index ce74509..a3fd221 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1182,6 +1182,9 @@
         AudioListenerSetPosition = 1366,
         AudioListenerSetOrientation = 1367,
         IntersectionObserver_Constructor = 1368,
+        DurableStoragePersist = 1369,
+        DurableStoragePersisted = 1370,
+        DurableStorageEstimate = 1371,
 
         // Add new features immediately above this line. Don't change assigned
         // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp b/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
index d28bfd30..4a9596f0 100644
--- a/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
+++ b/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
@@ -169,7 +169,7 @@
 
 bool HTMLImportLoader::hasPendingResources() const
 {
-    return m_document && m_document->styleEngine().hasPendingSheets();
+    return m_document && m_document->styleEngine().hasPendingScriptBlockingSheets();
 }
 
 void HTMLImportLoader::didFinishLoading()
diff --git a/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp b/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
index f1ee701..52677dd8 100644
--- a/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
+++ b/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
@@ -44,7 +44,7 @@
 
 bool HTMLImportTreeRoot::hasFinishedLoading() const
 {
-    return !m_document->parsing() && m_document->styleEngine().haveStylesheetsLoaded();
+    return !m_document->parsing() && m_document->styleEngine().haveScriptBlockingStylesheetsLoaded();
 }
 
 void HTMLImportTreeRoot::stateWillChange()
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
index e29b24e..dff65e3 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -29,6 +29,7 @@
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/loader/DocumentLoader.h"
+#include "platform/Histogram.h"
 #include "public/platform/Platform.h"
 
 namespace blink {
@@ -75,6 +76,9 @@
     if (preload->resourceType() == Resource::Script || preload->resourceType() == Resource::CSSStyleSheet || preload->resourceType() == Resource::ImportResource)
         request.setCharset(preload->charset().isEmpty() ? m_document->characterSet().getString() : preload->charset());
     request.setForPreload(true);
+    int duration = static_cast<int>(1000 * (monotonicallyIncreasingTime() - preload->discoveryTime()));
+    DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDelayHistogram, ("WebCore.PreloadDelayMs", 0, 2000, 20));
+    preloadDelayHistogram.count(duration);
     m_document->loader()->startPreload(preload->resourceType(), request);
 }
 
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
index 2d23e7e7..29ddf17c 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
@@ -31,6 +31,7 @@
 #include "core/html/parser/PreloadRequest.h"
 #include "core/html/parser/ResourcePreloader.h"
 #include "core/loader/NetworkHintsInterface.h"
+#include "wtf/CurrentTime.h"
 #include "wtf/text/TextPosition.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/html/parser/PreloadRequest.h b/third_party/WebKit/Source/core/html/parser/PreloadRequest.h
index 01ba69f..cb0932d 100644
--- a/third_party/WebKit/Source/core/html/parser/PreloadRequest.h
+++ b/third_party/WebKit/Source/core/html/parser/PreloadRequest.h
@@ -33,6 +33,7 @@
     FetchRequest resourceRequest(Document*);
 
     const String& charset() const { return m_charset; }
+    double discoveryTime() const { return m_discoveryTime; }
     void setDefer(FetchRequest::DeferOption defer) { m_defer = defer; }
     void setCharset(const String& charset) { m_charset = charset.isolatedCopy(); }
     void setCrossOrigin(CrossOriginAttributeValue crossOrigin)
@@ -76,6 +77,7 @@
         , m_baseURL(baseURL.copy())
         , m_resourceType(resourceType)
         , m_crossOrigin(CrossOriginAttributeNotSet)
+        , m_discoveryTime(monotonicallyIncreasingTime())
         , m_defer(FetchRequest::NoDefer)
         , m_resourceWidth(resourceWidth)
         , m_clientHintsPreferences(clientHintsPreferences)
@@ -93,6 +95,7 @@
     String m_charset;
     Resource::Type m_resourceType;
     CrossOriginAttributeValue m_crossOrigin;
+    double m_discoveryTime;
     FetchRequest::DeferOption m_defer;
     FetchRequest::ResourceWidth m_resourceWidth;
     ClientHintsPreferences m_clientHintsPreferences;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index 8feedca..0c7365c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -81,10 +81,12 @@
             // If the border width changes on a row, we need to make sure the cells in the row know to lay out again.
             // This only happens when borders are collapsed, since they end up affecting the border sides of the cell
             // itself.
+            table->setPreferredLogicalWidthsDirty(MarkOnlyThis);
             for (LayoutBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
                 if (!childBox->isTableCell())
                     continue;
                 childBox->setChildNeedsLayout();
+                childBox->setPreferredLogicalWidthsDirty(MarkOnlyThis);
             }
         }
     }
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 2f288f4..6b54a3f2 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -104,7 +104,7 @@
     // recover if blocking of a script is leading to a page break and the user
     // reloads the page.
     const FrameLoadType loadType = document.frame()->loader().loadType();
-    const bool isReload = loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadBypassingCache || loadType == FrameLoadTypeSame;
+    const bool isReload = loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadBypassingCache || loadType == FrameLoadTypeReloadMainResource;
     if (isReload) {
         // Recording this metric since an increase in number of reloads for pages
         // where a script was blocked could be indicative of a page break.
@@ -235,7 +235,7 @@
             return WebCachePolicy::ReturnCacheDataDontLoad;
         if (!frame()->host()->overrideEncoding().isEmpty())
             return WebCachePolicy::ReturnCacheDataElseLoad;
-        if (frameLoadType == FrameLoadTypeSame || request.isConditional() || request.httpMethod() == "POST")
+        if (frameLoadType == FrameLoadTypeReloadMainResource || request.isConditional() || request.httpMethod() == "POST")
             return WebCachePolicy::ValidatingCacheData;
 
         for (Frame* f = frame(); f; f = f->tree().parent()) {
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
index 02ee60d1..784f3f29 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
@@ -413,8 +413,8 @@
     EXPECT_EQ(WebCachePolicy::ReturnCacheDataElseLoad, fetchContext->resourceRequestCachePolicy(request, Resource::MainResource, FetchRequest::NoDefer));
     document->frame()->host()->setOverrideEncoding(AtomicString());
 
-    // FrameLoadTypeSame
-    document->frame()->loader().setLoadType(FrameLoadTypeSame);
+    // FrameLoadTypeReloadMainResource
+    document->frame()->loader().setLoadType(FrameLoadTypeReloadMainResource);
     EXPECT_EQ(WebCachePolicy::ValidatingCacheData, fetchContext->resourceRequestCachePolicy(request, Resource::MainResource, FetchRequest::NoDefer));
 
     // Conditional request
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 5187a7d..20e75c7 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -137,7 +137,7 @@
 ResourceRequest FrameLoader::resourceRequestForReload(FrameLoadType frameLoadType,
     const KURL& overrideURL, ClientRedirectPolicy clientRedirectPolicy)
 {
-    ASSERT(frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadBypassingCache);
+    ASSERT(frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadMainResource || frameLoadType == FrameLoadTypeReloadBypassingCache);
     WebCachePolicy cachePolicy = frameLoadType == FrameLoadTypeReloadBypassingCache ? WebCachePolicy::BypassingCache : WebCachePolicy::ValidatingCacheData;
     if (!m_currentItem)
         return ResourceRequest();
@@ -809,7 +809,7 @@
 
     if (request.resourceRequest().url() == m_documentLoader->urlForHistory()) {
         if (!request.originDocument())
-            return FrameLoadTypeSame;
+            return FrameLoadTypeReloadMainResource;
         return request.resourceRequest().httpMethod() == HTTPNames::POST ? FrameLoadTypeStandard : FrameLoadTypeReplaceCurrentItem;
     }
 
@@ -1287,7 +1287,7 @@
     return (!isFormSubmission || equalIgnoringCase(httpMethod, HTTPNames::GET))
         && loadType != FrameLoadTypeReload
         && loadType != FrameLoadTypeReloadBypassingCache
-        && loadType != FrameLoadTypeSame
+        && loadType != FrameLoadTypeReloadMainResource
         && loadType != FrameLoadTypeBackForward
         && url.hasFragmentIdentifier()
         && equalIgnoringFragmentIdentifier(m_frame->document()->url(), url)
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h b/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
index 146d15a..c0752912 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
@@ -31,11 +31,12 @@
 
 namespace blink {
 
+// See WebFrameLoadType in public/web/WebFrameLoadType.h for details.
 enum FrameLoadType {
     FrameLoadTypeStandard,
     FrameLoadTypeBackForward,
     FrameLoadTypeReload,
-    FrameLoadTypeSame, // user loads same URL again (but not reload button)
+    FrameLoadTypeReloadMainResource,
     FrameLoadTypeReplaceCurrentItem,
     FrameLoadTypeInitialInChildFrame,
     FrameLoadTypeInitialHistoryLoad,
diff --git a/third_party/WebKit/Source/core/svg/DEPS b/third_party/WebKit/Source/core/svg/DEPS
new file mode 100644
index 0000000..709a0319
--- /dev/null
+++ b/third_party/WebKit/Source/core/svg/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+    "+ui/gfx/geometry/cubic_bezier.h",
+]
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
index 1973759..0633879 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
@@ -106,7 +106,7 @@
 }
 
 template<typename CharType>
-static bool parseKeySplinesInternal(const String& string, Vector<UnitBezier>& result)
+static bool parseKeySplinesInternal(const String& string, Vector<gfx::CubicBezier>& result)
 {
     const CharType* ptr = string.getCharacters<CharType>();
     const CharType* end = ptr + string.length();
@@ -136,13 +136,13 @@
             ptr++;
         skipOptionalSVGSpaces(ptr, end);
 
-        result.append(UnitBezier(posA, posB, posC, posD));
+        result.append(gfx::CubicBezier(posA, posB, posC, posD));
     }
 
     return ptr == end;
 }
 
-static bool parseKeySplines(const String& string, Vector<UnitBezier>& result)
+static bool parseKeySplines(const String& string, Vector<gfx::CubicBezier>& result)
 {
     result.clear();
     if (string.isEmpty())
@@ -451,11 +451,11 @@
 {
     ASSERT(getCalcMode() == CalcModeSpline);
     ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size());
-    UnitBezier bezier = m_keySplines[splineIndex];
+    gfx::CubicBezier bezier = m_keySplines[splineIndex];
     SMILTime duration = simpleDuration();
     if (!duration.isFinite())
         duration = 100.0;
-    return narrowPrecisionToFloat(bezier.solveWithEpsilon(percent, solveEpsilon(duration.value())));
+    return narrowPrecisionToFloat(bezier.SolveWithEpsilon(percent, solveEpsilon(duration.value())));
 }
 
 float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimationElement.h b/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
index 75a9507..63352d2 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
@@ -28,7 +28,7 @@
 #include "core/CoreExport.h"
 #include "core/svg/SVGAnimatedBoolean.h"
 #include "core/svg/animation/SVGSMILElement.h"
-#include "platform/animation/UnitBezier.h"
+#include "ui/gfx/geometry/cubic_bezier.h"
 #include "wtf/Functional.h"
 #include "wtf/Vector.h"
 
@@ -212,7 +212,7 @@
     // changed to use doubles.
     Vector<float> m_keyTimes;
     Vector<float> m_keyPoints;
-    Vector<UnitBezier> m_keySplines;
+    Vector<gfx::CubicBezier> m_keySplines;
     String m_lastValuesAnimationFrom;
     String m_lastValuesAnimationTo;
     bool m_hasInvalidCSSAttributeType;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js b/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
index 8812a071..56387c1 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
@@ -237,6 +237,8 @@
 {
     var checkbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Offline"), WebInspector.UIString("Force disconnected from network"), undefined, forceOffline);
     WebInspector.multitargetNetworkManager.addEventListener(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged, networkConditionsChanged);
+    checkbox.setChecked(WebInspector.multitargetNetworkManager.networkConditions() === WebInspector.NetworkManager.OfflineConditions);
+
     var lastNetworkConditions;
 
     function forceOffline()
diff --git a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
index 8143877..7099804 100644
--- a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
+++ b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
@@ -1543,3 +1543,53 @@
         return defaultValue;
     });
 }
+
+/**
+ * @param {!Map<number, ?>} other
+ * @param {function(!VALUE,?):boolean} isEqual
+ * @return {!{removed: !Array<!VALUE>, added: !Array<?>, equal: !Array<!VALUE>}}
+ * @this {Map<number, VALUE>}
+ */
+Map.prototype.diff = function(other, isEqual)
+{
+    var leftKeys = this.keysArray();
+    var rightKeys = other.keysArray();
+    leftKeys.sort((a, b) => a - b);
+    rightKeys.sort((a, b) => a - b);
+
+    var removed = [];
+    var added = [];
+    var equal = [];
+    var leftIndex = 0;
+    var rightIndex = 0;
+    while (leftIndex < leftKeys.length && rightIndex < rightKeys.length) {
+        var leftKey = leftKeys[leftIndex];
+        var rightKey = rightKeys[rightIndex];
+        if (leftKey === rightKey && isEqual(this.get(leftKey), other.get(rightKey))) {
+            equal.push(this.get(leftKey));
+            ++leftIndex;
+            ++rightIndex;
+            continue;
+        }
+        if (leftKey <= rightKey) {
+            removed.push(this.get(leftKey));
+            ++leftIndex;
+            continue;
+        }
+        added.push(other.get(rightKey));
+        ++rightIndex;
+    }
+    while (leftIndex < leftKeys.length) {
+        var leftKey = leftKeys[leftIndex++];
+        removed.push(this.get(leftKey));
+    }
+    while (rightIndex < rightKeys.length) {
+        var rightKey = rightKeys[rightIndex++];
+        added.push(other.get(rightKey));
+    }
+    return {
+        added: added,
+        removed: removed,
+        equal: equal
+    }
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
index 43df4dd..91b9242 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
@@ -116,12 +116,6 @@
         return treeElement;
     },
 
-    wasShown: function()
-    {
-        if (!this._sidebarTree.selectedTreeElement)
-            this._manifestTreeElement.select();
-    },
-
     /**
      * @override
      * @param {!WebInspector.Target} target
@@ -137,7 +131,6 @@
         if (target.resourceTreeModel.cachedResourcesLoaded())
             this._initialize();
 
-        target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
         target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._initialize, this);
         target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
         this._databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
@@ -154,7 +147,6 @@
             return;
         delete this._target;
 
-        target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
         target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._initialize, this);
         target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
         this._databaseModel.removeEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
@@ -182,19 +174,10 @@
         this.indexedDBListTreeElement._initialize();
         this.cacheStorageListTreeElement._initialize();
         this._initDefaultSelection();
-        this._initialized = true;
-    },
-
-    _loadEventFired: function()
-    {
-        this._initDefaultSelection();
     },
 
     _initDefaultSelection: function()
     {
-        if (!this._initialized)
-            return;
-
         var itemURL = this._resourcesLastSelectedItemSetting.get();
         if (itemURL) {
             var rootElement = this._sidebarTree.rootElement();
@@ -205,12 +188,7 @@
                 }
             }
         }
-
-        var mainResource = this._target.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded
-                ? this._target.resourceTreeModel.resourceForURL(this._target.resourceTreeModel.inspectedPageURL())
-                : null;
-        if (mainResource)
-            this.showResource(mainResource);
+        this._manifestTreeElement.select();
     },
 
     _resetWithFrames: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourceCodeDiff.js b/third_party/WebKit/Source/devtools/front_end/sources/SourceCodeDiff.js
index c16fb9e..752d8c4 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourceCodeDiff.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourceCodeDiff.js
@@ -14,6 +14,8 @@
     this._decorations = [];
     this._textEditor.installGutter(WebInspector.SourceCodeDiff.DiffGutterType, true);
     this._diffBaseline = this._uiSourceCode.requestOriginalContent();
+    /** @type {!Array<!WebInspector.TextEditorPositionHandle>}*/
+    this._animatedLines = [];
 }
 
 /** @type {number} */
@@ -23,14 +25,14 @@
 WebInspector.SourceCodeDiff.DiffGutterType = "CodeMirror-gutter-diff";
 
 WebInspector.SourceCodeDiff.prototype = {
-    updateWhenPossible: function()
+    updateDiffMarkersWhenPossible: function()
     {
         if (this._updateTimeout)
             clearTimeout(this._updateTimeout);
-        this._updateTimeout = setTimeout(this.updateImmediately.bind(this), WebInspector.SourceCodeDiff.UpdateTimeout);
+        this._updateTimeout = setTimeout(this.updateDiffMarkersImmediately.bind(this), WebInspector.SourceCodeDiff.UpdateTimeout);
     },
 
-    updateImmediately: function()
+    updateDiffMarkersImmediately: function()
     {
         if (this._updateTimeout)
             clearTimeout(this._updateTimeout);
@@ -39,30 +41,78 @@
     },
 
     /**
-     * @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} decorations
+     * @param {?string} oldContent
+     * @param {?string} newContent
      */
-    _installEditorDecorations: function(decorations)
+    highlightModifiedLines: function(oldContent, newContent)
     {
-        this._textEditor.operation(operation);
+        if (typeof oldContent !== "string" || typeof newContent !== "string")
+            return;
 
+        var diff = this._computeDiff(oldContent, newContent);
+        var changedLines = [];
+        for (var i = 0; i < diff.length; ++i) {
+            var diffEntry = diff[i];
+            if (diffEntry.type === WebInspector.SourceCodeDiff.GutterDecorationType.Delete)
+                continue;
+            for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber) {
+                var position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
+                if (position)
+                    changedLines.push(position);
+            }
+        }
+        this._updateHighlightedLines(changedLines);
+        this._animationTimeout = setTimeout(this._updateHighlightedLines.bind(this, []), 400); // // Keep this timeout in sync with sourcesView.css.
+    },
+
+    /**
+     * @param {!Array<!WebInspector.TextEditorPositionHandle>} newLines
+     */
+    _updateHighlightedLines: function(newLines)
+    {
+        if (this._animationTimeout)
+            clearTimeout(this._animationTimeout);
+        this._animationTimeout = null;
+        this._textEditor.operation(operation.bind(this));
+
+        /**
+         * @this {WebInspector.SourceCodeDiff}
+         */
         function operation()
         {
-            for (var decoration of decorations)
-                decoration.install();
+            toggleLines.call(this, false);
+            this._animatedLines = newLines;
+            toggleLines.call(this, true);
+        }
+
+        /**
+         * @param {boolean} value
+         * @this {WebInspector.SourceCodeDiff}
+         */
+        function toggleLines(value)
+        {
+            for (var i = 0; i < this._animatedLines.length; ++i) {
+                var location = this._animatedLines[i].resolve();
+                if (location)
+                    this._textEditor.toggleLineClass(location.lineNumber, "highlight-line-modification", value);
+            }
         }
     },
 
     /**
-     * @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} decorations
+     * @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} removed
+     * @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} added
      */
-    _removeEditorDecorations: function(decorations)
+    _updateDecorations: function(removed, added)
     {
         this._textEditor.operation(operation);
 
         function operation()
         {
-            for (var decoration of decorations)
+            for (var decoration of removed)
                 decoration.remove();
+            for (var decoration of added)
+                decoration.install();
         }
     },
 
@@ -145,23 +195,37 @@
     {
         var current = this._uiSourceCode.workingCopy();
         if (typeof current !== "string" || typeof baseline !== "string") {
-            this._removeEditorDecorations(this._decorations);
+            this._updateDecorations(this._decorations, [] /* added */);
             this._decorations = [];
             return;
         }
 
         var diff = this._computeDiff(baseline, current);
-        var updater = new WebInspector.SourceCodeDiff.DecorationUpdater(this._textEditor, this._decorations);
+
+        /** @type {!Map<number, !WebInspector.SourceCodeDiff.GutterDecoration>} */
+        var oldDecorations = new Map();
+        for (var i = 0; i < this._decorations.length; ++i) {
+            var decoration = this._decorations[i];
+            var lineNumber = decoration.lineNumber();
+            if (lineNumber === -1)
+                continue;
+            oldDecorations.set(lineNumber, decoration);
+        }
+
+        /** @type {!Map<number, !{lineNumber: number, type: !WebInspector.SourceCodeDiff.GutterDecorationType}>} */
+        var newDecorations = new Map();
         for (var i = 0; i < diff.length; ++i) {
             var diffEntry = diff[i];
             for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber)
-                updater.addDecoration(diffEntry.type, lineNumber);
+                newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry.type});
         }
-        updater.finalize();
-        this._removeEditorDecorations(updater.removed());
-        this._installEditorDecorations(updater.added());
-        this._decorations = updater.newDecorations();
-    }
+
+        var decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type);
+        var addedDecorations = decorationDiff.added.map(entry => new WebInspector.SourceCodeDiff.GutterDecoration(this._textEditor, entry.lineNumber, entry.type));
+
+        this._decorations = decorationDiff.equal.concat(addedDecorations);
+        this._updateDecorations(decorationDiff.removed, addedDecorations);
+    },
 }
 
 /** @enum {string} */
@@ -188,7 +252,7 @@
         this._className = "diff-entry-delete";
     else if (type === WebInspector.SourceCodeDiff.GutterDecorationType.Modify)
         this._className = "diff-entry-modify";
-    this._type = type;
+    this.type = type;
 }
 
 WebInspector.SourceCodeDiff.GutterDecoration.prototype = {
@@ -203,14 +267,6 @@
         return location.lineNumber;
     },
 
-    /**
-     * @return {!WebInspector.SourceCodeDiff.GutterDecorationType}
-     */
-    type: function()
-    {
-        return this._type;
-    },
-
     install: function()
     {
         var location = this._position.resolve();
@@ -231,76 +287,3 @@
         this._textEditor.toggleLineClass(location.lineNumber, this._className, false);
     }
 }
-
-/**
- * @constructor
- * @param {!WebInspector.CodeMirrorTextEditor} textEditor
- * @param {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>} decorations
- */
-WebInspector.SourceCodeDiff.DecorationUpdater = function(textEditor, decorations)
-{
-    this._textEditor = textEditor;
-    this._oldDecorations = decorations;
-    this._oldIndex = 0;
-
-    this._removed = [];
-    this._added = [];
-    this._newDecorations = [];
-}
-
-WebInspector.SourceCodeDiff.DecorationUpdater.prototype = {
-    /**
-     * @param {!WebInspector.SourceCodeDiff.GutterDecorationType} type
-     * @param {number} lineNumber
-     */
-    addDecoration: function(type, lineNumber)
-    {
-        while (this._oldIndex < this._oldDecorations.length) {
-            var decoration = this._oldDecorations[this._oldIndex];
-            var decorationLine = decoration.lineNumber();
-            if (decorationLine === lineNumber && decoration.type() === type) {
-                ++this._oldIndex;
-                this._newDecorations.push(decoration);
-                return;
-            }
-            if (decorationLine >= lineNumber)
-                break;
-
-            this._removed.push(decoration);
-            ++this._oldIndex;
-        }
-        var decoration = new WebInspector.SourceCodeDiff.GutterDecoration(this._textEditor, lineNumber, type);
-        this._added.push(decoration);
-        this._newDecorations.push(decoration);
-    },
-
-    finalize: function()
-    {
-        while (this._oldIndex < this._oldDecorations.length)
-            this._removed.push(this._oldDecorations[this._oldIndex++]);
-    },
-
-    /**
-     * @return {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>}
-     */
-    added: function()
-    {
-        return this._added;
-    },
-
-    /**
-     * @return {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>}
-     */
-    removed: function()
-    {
-        return this._removed;
-    },
-
-    /**
-     * @return {!Array<!WebInspector.SourceCodeDiff.GutterDecoration>}
-     */
-    newDecorations: function()
-    {
-        return this._newDecorations;
-    }
-}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index 6c7627f..f4bef52 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -173,8 +173,10 @@
         WebInspector.context.setFlavor(WebInspector.SourcesPanel, this);
         WebInspector.Panel.prototype.wasShown.call(this);
         var wrapper = WebInspector.SourcesPanel.WrapperView._instance;
-        if (wrapper && wrapper.isShowing())
+        if (wrapper && wrapper.isShowing()) {
             WebInspector.inspectorView.setDrawerMinimized(true);
+            WebInspector.SourcesPanel.updateResizer(this);
+        }
         this.editorView.setMainWidget(this._sourcesView);
     },
 
@@ -182,9 +184,10 @@
     {
         WebInspector.Panel.prototype.willHide.call(this);
         WebInspector.context.setFlavor(WebInspector.SourcesPanel, null);
-        if (WebInspector.SourcesPanel.WrapperView._instance && WebInspector.SourcesPanel.WrapperView._instance.isShowing()) {
+        if (WebInspector.SourcesPanel.WrapperView.isShowing()) {
             WebInspector.SourcesPanel.WrapperView._instance._showViewInWrapper();
             WebInspector.inspectorView.setDrawerMinimized(false);
+            WebInspector.SourcesPanel.updateResizer(this);
         }
     },
 
@@ -193,7 +196,7 @@
      */
     _ensureSourcesViewVisible: function()
     {
-        if (WebInspector.SourcesPanel.WrapperView._instance && WebInspector.SourcesPanel.WrapperView._instance.isShowing())
+        if (WebInspector.SourcesPanel.WrapperView.isShowing())
             return true;
         return this === WebInspector.inspectorView.setCurrentPanel(this);
     },
@@ -1095,10 +1098,7 @@
         this._splitWidget.setVertical(!vertically);
         this._splitWidget.element.classList.toggle("sources-split-view-vertical", vertically);
 
-        if (!vertically)
-            this._splitWidget.uninstallResizer(this._sourcesView.toolbarContainerElement());
-        else
-            this._splitWidget.installResizer(this._sourcesView.toolbarContainerElement());
+        WebInspector.SourcesPanel.updateResizer(this);
 
         // Create vertical box with stack.
         var vbox = new WebInspector.VBox();
@@ -1403,6 +1403,17 @@
 }
 
 /**
+ * @param {!WebInspector.SourcesPanel} panel
+ */
+WebInspector.SourcesPanel.updateResizer = function(panel)
+{
+    if (panel._splitWidget.isVertical() || (WebInspector.SourcesPanel.WrapperView.isShowing() && !WebInspector.inspectorView.isDrawerMinimized()))
+        panel._splitWidget.uninstallResizer(panel._sourcesView.toolbarContainerElement());
+    else
+        panel._splitWidget.installResizer(panel._sourcesView.toolbarContainerElement());
+}
+
+/**
  * @constructor
  * @implements {WebInspector.PanelFactory}
  */
@@ -1440,11 +1451,13 @@
             this._showViewInWrapper();
         else
             WebInspector.inspectorView.setDrawerMinimized(true);
+        WebInspector.SourcesPanel.updateResizer(WebInspector.SourcesPanel.instance());
     },
 
     willHide: function()
     {
         WebInspector.inspectorView.setDrawerMinimized(false);
+        setImmediate(() => WebInspector.SourcesPanel.updateResizer(WebInspector.SourcesPanel.instance()));
     },
 
     /**
@@ -1468,3 +1481,11 @@
 
     __proto__: WebInspector.VBox.prototype
 }
+
+/**
+ * @return {boolean}
+ */
+WebInspector.SourcesPanel.WrapperView.isShowing = function()
+{
+    return !!WebInspector.SourcesPanel.WrapperView._instance && WebInspector.SourcesPanel.WrapperView._instance.isShowing();
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
index 221c2e6..923ed29b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
@@ -164,7 +164,7 @@
     _onWorkingCopyChanged: function(event)
     {
         if (this._diff)
-            this._diff.updateWhenPossible();
+            this._diff.updateDiffMarkersWhenPossible();
         if (this._muteSourceCodeEvents)
             return;
         this._innerSetContent(this._uiSourceCode.workingCopy());
@@ -183,7 +183,7 @@
         this._textEditor.markClean();
         this._updateStyle();
         if (this._diff)
-            this._diff.updateWhenPossible();
+            this._diff.updateDiffMarkersWhenPossible();
     },
 
     _updateStyle: function()
@@ -201,9 +201,14 @@
     _innerSetContent: function(content)
     {
         this._isSettingContent = true;
-        this.setContent(content);
-        if (this._diff)
-            this._diff.updateImmediately();
+        if (this._diff) {
+            var oldContent = this._textEditor.text();
+            this.setContent(content);
+            this._diff.updateDiffMarkersImmediately();
+            this._diff.highlightModifiedLines(oldContent, content);
+        } else {
+            this.setContent(content);
+        }
         delete this._isSettingContent;
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css
index ec37608..73b654d 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css
+++ b/third_party/WebKit/Source/devtools/front_end/sources/sourcesPanel.css
@@ -97,36 +97,6 @@
     overflow: auto;
 }
 
-.source-frame-breakpoint-condition {
-    z-index: 30;
-    padding: 4px;
-    background-color: rgb(203, 226, 255);
-    border-radius: 7px;
-    border: 2px solid rgb(169, 172, 203);
-    width: 90%;
-    pointer-events: auto;
-}
-
-.source-frame-breakpoint-message {
-    background-color: transparent;
-    font-weight: normal;
-    font-size: 11px;
-    text-align: left;
-    text-shadow: none;
-    color: rgb(85, 85, 85);
-    cursor: default;
-    margin: 0 0 2px 0;
-}
-
-#source-frame-breakpoint-condition {
-    margin: 0;
-    border: 1px inset rgb(190, 190, 190) !important;
-    width: 100%;
-    box-shadow: none !important;
-    outline: none !important;
-    -webkit-user-modify: read-write;
-}
-
 .cursor-pointer {
     cursor: pointer;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/sourcesView.css b/third_party/WebKit/Source/devtools/front_end/sources/sourcesView.css
index 793e33b..d7996c4 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/sourcesView.css
+++ b/third_party/WebKit/Source/devtools/front_end/sources/sourcesView.css
@@ -57,6 +57,36 @@
     background-color: rgba(255, 225, 205, 0.40);
 }
 
+.source-frame-breakpoint-condition {
+    z-index: 30;
+    padding: 4px;
+    background-color: rgb(203, 226, 255);
+    border-radius: 7px;
+    border: 2px solid rgb(169, 172, 203);
+    width: 90%;
+    pointer-events: auto;
+}
+
+.source-frame-breakpoint-message {
+    background-color: transparent;
+    font-weight: normal;
+    font-size: 11px;
+    text-align: left;
+    text-shadow: none;
+    color: rgb(85, 85, 85);
+    cursor: default;
+    margin: 0 0 2px 0;
+}
+
+#source-frame-breakpoint-condition {
+    margin: 0;
+    border: 1px inset rgb(190, 190, 190) !important;
+    width: 100%;
+    box-shadow: none !important;
+    outline: none !important;
+    -webkit-user-modify: read-write;
+}
+
 @-webkit-keyframes source-frame-value-update-highlight-animation {
     from {
         background-color: inherit;
@@ -111,4 +141,28 @@
 
 .CodeMirror-gutter-diff {
     width: 4px;
-}
\ No newline at end of file
+}
+
+.highlight-line-modification {
+    animation: source-line-modification-background-fadeout 0.4s 0s;
+    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+.highlight-line-modification span {
+    animation: source-line-modification-foreground-fadeout 0.4s 0s;
+    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+@keyframes source-line-modification-background-fadeout {
+    from { background-color: rgba(158, 54, 153, 0.5); }
+    50% { background-color: rgba(158, 54, 153, 0.5); }
+    90% { background-color: rgba(158, 54, 153, 0); }
+    to { background-color: transparent; }
+}
+
+@keyframes source-line-modification-foreground-fadeout {
+    from { color: white; }
+    50% { color: white; }
+    90% { color: intial; }
+    to { color: intial; }
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js b/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
index 8f053313..5d278212 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
@@ -396,6 +396,14 @@
     },
 
     /**
+     * @return {boolean}
+     */
+    isDrawerMinimized: function()
+    {
+        return this._drawerSplitWidget.isSidebarMinimized();
+    },
+
+    /**
      * @override
      * @return {!Element}
      */
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
index caac1160..530a41b1 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
@@ -290,6 +290,14 @@
     },
 
     /**
+     * @return {boolean}
+     */
+    isSidebarMinimized: function()
+    {
+        return this._sidebarMinimized;
+    },
+
+    /**
      * @param {!WebInspector.Widget} sideToShow
      * @param {!WebInspector.Widget} sideToHide
      * @param {!Element} shadowToShow
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
index 7e12239..0b6a6732 100644
--- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
+++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
@@ -11,6 +11,8 @@
 #include "core/fileapi/Blob.h"
 #include "core/frame/ImageBitmap.h"
 #include "modules/EventTargetModules.h"
+#include "modules/imagecapture/MediaSettingsRange.h"
+#include "modules/imagecapture/PhotoCapabilities.h"
 #include "modules/mediastream/MediaStreamTrack.h"
 #include "platform/mojo/MojoHelper.h"
 #include "public/platform/Platform.h"
@@ -127,6 +129,7 @@
 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
     : ActiveScriptWrappable(this)
     , ContextLifecycleObserver(context)
+    , m_photoCapabilities(PhotoCapabilities::create())
     , m_streamTrack(track)
 {
     DCHECK(m_streamTrack);
@@ -135,6 +138,13 @@
     Platform::current()->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_service));
 
     m_service.set_connection_error_handler(createBaseCallback(bind(&ImageCapture::onServiceConnectionError, WeakPersistentThisPointer<ImageCapture>(this))));
+
+    m_service->GetCapabilities(m_streamTrack->component()->source()->id(), createBaseCallback(bind<mojom::blink::PhotoCapabilitiesPtr>(&ImageCapture::onCapabilities, this)));
+}
+
+void ImageCapture::onCapabilities(mojom::blink::PhotoCapabilitiesPtr capabilities)
+{
+    m_photoCapabilities->setZoom(MediaSettingsRange::create(capabilities->zoom->max, capabilities->zoom->min, capabilities->zoom->initial));
 }
 
 void ImageCapture::onTakePhoto(ScriptPromiseResolver* resolver, const String& mimeType, mojo::WTFArray<uint8_t> data)
@@ -161,6 +171,7 @@
 
 DEFINE_TRACE(ImageCapture)
 {
+    visitor->trace(m_photoCapabilities);
     visitor->trace(m_streamTrack);
     visitor->trace(m_serviceRequests);
     EventTargetWithInlineData::trace(visitor);
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
index a0e2fe7..6330ef6e 100644
--- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
+++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
@@ -18,6 +18,7 @@
 
 class ExceptionState;
 class MediaStreamTrack;
+class PhotoCapabilities;
 class WebImageCaptureFrameGrabber;
 
 // TODO(mcasas): Consideradding a LayoutTest checking that this class is not
@@ -42,6 +43,8 @@
     // ContextLifecycleObserver
     void contextDestroyed() override;
 
+    PhotoCapabilities* photoCapabilities() const { return m_photoCapabilities.get(); }
+
     MediaStreamTrack* videoStreamTrack() const { return m_streamTrack.get(); }
 
     ScriptPromise takePhoto(ScriptState*, ExceptionState&);
@@ -53,9 +56,12 @@
 private:
     ImageCapture(ExecutionContext*, MediaStreamTrack*);
 
+    void onCapabilities(mojom::blink::PhotoCapabilitiesPtr);
     void onTakePhoto(ScriptPromiseResolver*, const String& mimeType, mojo::WTFArray<uint8_t> data);
     void onServiceConnectionError();
 
+    Member<PhotoCapabilities> m_photoCapabilities;
+
     Member<MediaStreamTrack> m_streamTrack;
     OwnPtr<WebImageCaptureFrameGrabber> m_frameGrabber;
     mojom::blink::ImageCapturePtr m_service;
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.idl b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.idl
index c8c306e..12fa110 100644
--- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.idl
+++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.idl
@@ -11,6 +11,7 @@
     RaisesException=Constructor,
     RuntimeEnabled=ImageCapture,
 ] interface ImageCapture {
+    readonly attribute PhotoCapabilities photoCapabilities;
     readonly attribute MediaStreamTrack videoStreamTrack;
 
     [CallWith=ScriptState, RaisesException] Promise<Blob> takePhoto();
diff --git a/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.h b/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.h
new file mode 100644
index 0000000..0fcfc5a9
--- /dev/null
+++ b/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaSettingsRange_h
+#define MediaSettingsRange_h
+
+#include "bindings/core/v8/ScriptWrappable.h"
+
+namespace blink {
+
+class MediaSettingsRange final
+    : public GarbageCollected<MediaSettingsRange>
+    , public ScriptWrappable {
+    DEFINE_WRAPPERTYPEINFO();
+public:
+    static MediaSettingsRange* create(unsigned long max, unsigned long min, unsigned long initial)
+    {
+        return new MediaSettingsRange(max, min, initial);
+    }
+
+    unsigned long max() const { return m_max; }
+    unsigned long min() const { return m_min; }
+    unsigned long initial() const { return m_initial; }
+
+    DEFINE_INLINE_TRACE() {}
+
+private:
+    MediaSettingsRange(unsigned long max, unsigned long min, unsigned long initial)
+        : m_max(max)
+        , m_min(min)
+        , m_initial(initial) { }
+
+    unsigned long m_max;
+    unsigned long m_min;
+    unsigned long m_initial;
+};
+
+} // namespace blink
+
+#endif // MediaSettingsRange_h
diff --git a/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.idl b/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.idl
new file mode 100644
index 0000000..f5976c7
--- /dev/null
+++ b/third_party/WebKit/Source/modules/imagecapture/MediaSettingsRange.idl
@@ -0,0 +1,13 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://w3c.github.io/mediacapture-image/index.html#mediasettingsrange
+
+[
+    RuntimeEnabled=ImageCapture,
+] interface MediaSettingsRange {
+    readonly attribute unsigned long max;
+    readonly attribute unsigned long min;
+    readonly attribute unsigned long initial;
+};
diff --git a/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.h b/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.h
new file mode 100644
index 0000000..0d5afdc
--- /dev/null
+++ b/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PhotoCapabilities_h
+#define PhotoCapabilities_h
+
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "modules/imagecapture/MediaSettingsRange.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+class PhotoCapabilities final
+    : public GarbageCollectedFinalized<PhotoCapabilities>
+    , public ScriptWrappable {
+    DEFINE_WRAPPERTYPEINFO();
+public:
+    static PhotoCapabilities* create()
+    {
+        return new PhotoCapabilities();
+    }
+    virtual ~PhotoCapabilities() = default;
+
+    MediaSettingsRange* zoom() const { return m_zoom; }
+    void setZoom(MediaSettingsRange* value) { m_zoom = value; }
+
+    DEFINE_INLINE_TRACE()
+    {
+        visitor->trace(m_zoom);
+    }
+
+private:
+    PhotoCapabilities() = default;
+
+    Member<MediaSettingsRange> m_zoom;
+};
+
+} // namespace blink
+
+#endif // PhotoCapabilities_h
diff --git a/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.idl b/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.idl
new file mode 100644
index 0000000..f977f5b
--- /dev/null
+++ b/third_party/WebKit/Source/modules/imagecapture/PhotoCapabilities.idl
@@ -0,0 +1,12 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://w3c.github.io/mediacapture-image/index.html#idl-def-PhotoCapabilities
+[
+    RuntimeEnabled=ImageCapture,
+] interface PhotoCapabilities {
+    attribute MediaSettingsRange zoom;
+    // TODO(mcasas): Implement all other PhotoCapabilities fields
+    // https://crbug.com/518807
+};
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi
index 2aa27fd..33568743 100644
--- a/third_party/WebKit/Source/modules/modules.gypi
+++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -93,6 +93,8 @@
       'geolocation/PositionErrorCallback.idl',
       'imagebitmap/ImageBitmapRenderingContext.idl',
       'imagecapture/ImageCapture.idl',
+      'imagecapture/MediaSettingsRange.idl',
+      'imagecapture/PhotoCapabilities.idl',
       'indexeddb/IDBCursor.idl',
       'indexeddb/IDBCursorWithValue.idl',
       'indexeddb/IDBDatabase.idl',
@@ -1125,6 +1127,8 @@
       'imagebitmap/ImageBitmapRenderingContext.h',
       'imagecapture/ImageCapture.cpp',
       'imagecapture/ImageCapture.h',
+      'imagecapture/MediaSettingsRange.h',
+      'imagecapture/PhotoCapabilities.h',
       'indexeddb/GlobalIndexedDB.cpp',
       'indexeddb/GlobalIndexedDB.h',
       'indexeddb/IDBAny.cpp',
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.idl b/third_party/WebKit/Source/modules/quota/StorageManager.idl
index 7e8955b..0cb21440 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.idl
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.idl
@@ -6,10 +6,10 @@
 
 [
     Exposed=(Window,Worker),
-    RuntimeEnabled=DurableStorage,
+    OriginTrialEnabled=DurableStorage,
 ] interface StorageManager {
-    [CallWith=ScriptState] Promise<boolean> persisted();
-    [Exposed=Window, CallWith=ScriptState] Promise<boolean> persist();
+    [CallWith=ScriptState, MeasureAs=DurableStoragePersisted] Promise<boolean> persisted();
+    [Exposed=Window, CallWith=ScriptState, MeasureAs=DurableStoragePersist] Promise<boolean> persist();
 
-    [RuntimeEnabled=StorageEstimate, CallWith=ScriptState] Promise<StorageEstimate> estimate();
+    [RuntimeEnabled=StorageEstimate, CallWith=ScriptState, MeasureAs=DurableStorageEstimate] Promise<StorageEstimate> estimate();
 };
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp b/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp
index 7ffd475..fb96aef 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorAnimation.cpp
@@ -4,7 +4,6 @@
 
 #include "platform/animation/CompositorAnimation.h"
 
-#include "cc/animation/animation.h"
 #include "cc/animation/animation_curve.h"
 #include "cc/animation/animation_id_provider.h"
 #include "platform/animation/CompositorAnimationCurve.h"
@@ -117,37 +116,12 @@
 
 blink::CompositorAnimation::Direction CompositorAnimation::getDirection() const
 {
-    switch (m_animation->direction()) {
-    case cc::Animation::DIRECTION_NORMAL:
-        return DirectionNormal;
-    case cc::Animation::DIRECTION_REVERSE:
-        return DirectionReverse;
-    case cc::Animation::DIRECTION_ALTERNATE:
-        return DirectionAlternate;
-    case cc::Animation::DIRECTION_ALTERNATE_REVERSE:
-        return DirectionAlternateReverse;
-    default:
-        NOTREACHED();
-    }
-    return DirectionNormal;
+    return m_animation->direction();
 }
 
 void CompositorAnimation::setDirection(Direction direction)
 {
-    switch (direction) {
-    case DirectionNormal:
-        m_animation->set_direction(cc::Animation::DIRECTION_NORMAL);
-        break;
-    case DirectionReverse:
-        m_animation->set_direction(cc::Animation::DIRECTION_REVERSE);
-        break;
-    case DirectionAlternate:
-        m_animation->set_direction(cc::Animation::DIRECTION_ALTERNATE);
-        break;
-    case DirectionAlternateReverse:
-        m_animation->set_direction(cc::Animation::DIRECTION_ALTERNATE_REVERSE);
-        break;
-    }
+    m_animation->set_direction(direction);
 }
 
 double CompositorAnimation::playbackRate() const
@@ -162,37 +136,12 @@
 
 blink::CompositorAnimation::FillMode CompositorAnimation::getFillMode() const
 {
-    switch (m_animation->fill_mode()) {
-    case cc::Animation::FILL_MODE_NONE:
-        return FillModeNone;
-    case cc::Animation::FILL_MODE_FORWARDS:
-        return FillModeForwards;
-    case cc::Animation::FILL_MODE_BACKWARDS:
-        return FillModeBackwards;
-    case cc::Animation::FILL_MODE_BOTH:
-        return FillModeBoth;
-    default:
-        NOTREACHED();
-    }
-    return FillModeNone;
+    return m_animation->fill_mode();
 }
 
 void CompositorAnimation::setFillMode(FillMode fillMode)
 {
-    switch (fillMode) {
-    case FillModeNone:
-        m_animation->set_fill_mode(cc::Animation::FILL_MODE_NONE);
-        break;
-    case FillModeForwards:
-        m_animation->set_fill_mode(cc::Animation::FILL_MODE_FORWARDS);
-        break;
-    case FillModeBackwards:
-        m_animation->set_fill_mode(cc::Animation::FILL_MODE_BACKWARDS);
-        break;
-    case FillModeBoth:
-        m_animation->set_fill_mode(cc::Animation::FILL_MODE_BOTH);
-        break;
-    }
+    m_animation->set_fill_mode(fillMode);
 }
 
 std::unique_ptr<cc::Animation> CompositorAnimation::passAnimation()
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimation.h b/third_party/WebKit/Source/platform/animation/CompositorAnimation.h
index 644567e..3fbe7ca8 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimation.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorAnimation.h
@@ -5,6 +5,7 @@
 #ifndef CompositorAnimation_h
 #define CompositorAnimation_h
 
+#include "cc/animation/animation.h"
 #include "platform/PlatformExport.h"
 #include "platform/animation/CompositorTargetProperty.h"
 #include "wtf/Noncopyable.h"
@@ -23,19 +24,8 @@
 class PLATFORM_EXPORT CompositorAnimation {
     WTF_MAKE_NONCOPYABLE(CompositorAnimation);
 public:
-    enum Direction {
-        DirectionNormal,
-        DirectionReverse,
-        DirectionAlternate,
-        DirectionAlternateReverse
-    };
-
-    enum FillMode {
-        FillModeNone,
-        FillModeForwards,
-        FillModeBackwards,
-        FillModeBoth
-    };
+    using Direction = cc::Animation::Direction;
+    using FillMode = cc::Animation::FillMode;
 
     CompositorAnimation(const CompositorAnimationCurve&, CompositorTargetProperty::Type, int animationId, int groupId);
     virtual ~CompositorAnimation();
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimationTest.cpp b/third_party/WebKit/Source/platform/animation/CompositorAnimationTest.cpp
index 401f9ff..6b9015a 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimationTest.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorAnimationTest.cpp
@@ -19,7 +19,7 @@
     EXPECT_EQ(1, animation->iterations());
     EXPECT_EQ(0, animation->startTime());
     EXPECT_EQ(0, animation->timeOffset());
-    EXPECT_EQ(CompositorAnimation::DirectionNormal, animation->getDirection());
+    EXPECT_EQ(CompositorAnimation::Direction::NORMAL, animation->getDirection());
 }
 
 TEST(WebCompositorAnimationTest, ModifiedSettings)
@@ -30,12 +30,12 @@
     animation->setIterations(2);
     animation->setStartTime(2);
     animation->setTimeOffset(2);
-    animation->setDirection(CompositorAnimation::DirectionReverse);
+    animation->setDirection(CompositorAnimation::Direction::REVERSE);
 
     EXPECT_EQ(2, animation->iterations());
     EXPECT_EQ(2, animation->startTime());
     EXPECT_EQ(2, animation->timeOffset());
-    EXPECT_EQ(CompositorAnimation::DirectionReverse, animation->getDirection());
+    EXPECT_EQ(CompositorAnimation::Direction::REVERSE, animation->getDirection());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
index 9548e5b..0f86ff9 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.cpp
@@ -43,12 +43,12 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorFilterAnimationCurve::add(const CompositorFilterKeyframe& keyframe, int steps, float stepsStartOffset)
+void CompositorFilterAnimationCurve::add(const CompositorFilterKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     const cc::FilterOperations& filterOperations = keyframe.value().asFilterOperations();
     m_curve->AddKeyframe(cc::FilterKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time()), filterOperations,
-        cc::StepsTimingFunction::Create(steps, stepsStartOffset)));
+        cc::StepsTimingFunction::Create(steps, stepPosition)));
 }
 
 void CompositorFilterAnimationCurve::setLinearTimingFunction()
@@ -66,9 +66,9 @@
     m_curve->SetTimingFunction(cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2));
 }
 
-void CompositorFilterAnimationCurve::setStepsTimingFunction(int numberOfSteps, float stepsStartOffset)
+void CompositorFilterAnimationCurve::setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition stepPosition)
 {
-    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepsStartOffset));
+    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepPosition));
 }
 
 std::unique_ptr<cc::AnimationCurve> CompositorFilterAnimationCurve::cloneToAnimationCurve() const
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
index ef9ff92..7e8f0b5 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorFilterAnimationCurve.h
@@ -8,6 +8,7 @@
 #include "platform/PlatformExport.h"
 #include "platform/animation/CompositorAnimationCurve.h"
 #include "platform/animation/CompositorFilterKeyframe.h"
+#include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
 #include <memory>
@@ -35,12 +36,12 @@
     // assumed that x0 = y0, and x3 = y3 = 1.
     virtual void add(const CompositorFilterKeyframe&, double x1, double y1, double x2, double y2);
     // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorFilterKeyframe&, int steps, float stepsStartOffset);
+    virtual void add(const CompositorFilterKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
     virtual void setCubicBezierTimingFunction(TimingFunctionType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
-    virtual void setStepsTimingFunction(int numberOfSteps, float stepsStartOffset);
+    virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
     // blink::CompositorAnimationCurve implementation.
     AnimationCurveType type() const override;
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
index 10574ac..d294fb59 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.cpp
@@ -46,11 +46,11 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe, int steps, float stepsStartOffset)
+void CompositorFloatAnimationCurve::add(const CompositorFloatKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     m_curve->AddKeyframe(cc::FloatKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time), keyframe.value,
-        cc::StepsTimingFunction::Create(steps, stepsStartOffset)));
+        cc::StepsTimingFunction::Create(steps, stepPosition)));
 }
 
 void CompositorFloatAnimationCurve::setLinearTimingFunction()
@@ -68,9 +68,9 @@
     m_curve->SetTimingFunction(cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2));
 }
 
-void CompositorFloatAnimationCurve::setStepsTimingFunction(int numberOfSteps, float stepsStartOffset)
+void CompositorFloatAnimationCurve::setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition stepPosition)
 {
-    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepsStartOffset));
+    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepPosition));
 }
 
 float CompositorFloatAnimationCurve::getValue(double time) const
diff --git a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
index 0362bfe7..03c9e0d3 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorFloatAnimationCurve.h
@@ -8,6 +8,7 @@
 #include "platform/PlatformExport.h"
 #include "platform/animation/CompositorAnimationCurve.h"
 #include "platform/animation/CompositorFloatKeyframe.h"
+#include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
 #include <memory>
@@ -37,12 +38,12 @@
     // assumed that x0 = y0 , and x3 = y3 = 1.
     virtual void add(const CompositorFloatKeyframe&, double x1, double y1, double x2, double y2);
     // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorFloatKeyframe&, int steps, float stepsStartOffset);
+    virtual void add(const CompositorFloatKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
     virtual void setCubicBezierTimingFunction(TimingFunctionType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
-    virtual void setStepsTimingFunction(int numberOfSteps, float stepsStartOffset);
+    virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
     virtual float getValue(double time) const;
 
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
index 027f391..4a95aca 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.cpp
@@ -48,12 +48,12 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2)));
 }
 
-void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe, int steps, float stepsStartOffset)
+void CompositorTransformAnimationCurve::add(const CompositorTransformKeyframe& keyframe, int steps, StepsTimingFunction::StepPosition stepPosition)
 {
     const cc::TransformOperations& transformOperations = keyframe.value().asTransformOperations();
     m_curve->AddKeyframe(cc::TransformKeyframe::Create(
         base::TimeDelta::FromSecondsD(keyframe.time()), transformOperations,
-        cc::StepsTimingFunction::Create(steps, stepsStartOffset)));
+        cc::StepsTimingFunction::Create(steps, stepPosition)));
 }
 
 void CompositorTransformAnimationCurve::setLinearTimingFunction()
@@ -72,9 +72,9 @@
         cc::CubicBezierTimingFunction::Create(x1, y1, x2, y2));
 }
 
-void CompositorTransformAnimationCurve::setStepsTimingFunction(int numberOfSteps, float stepsStartOffset)
+void CompositorTransformAnimationCurve::setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition stepPosition)
 {
-    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepsStartOffset));
+    m_curve->SetTimingFunction(cc::StepsTimingFunction::Create(numberOfSteps, stepPosition));
 }
 
 std::unique_ptr<cc::AnimationCurve> CompositorTransformAnimationCurve::cloneToAnimationCurve() const
diff --git a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
index 8b701725..942dba00 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
+++ b/third_party/WebKit/Source/platform/animation/CompositorTransformAnimationCurve.h
@@ -8,6 +8,7 @@
 #include "platform/PlatformExport.h"
 #include "platform/animation/CompositorAnimationCurve.h"
 #include "platform/animation/CompositorTransformKeyframe.h"
+#include "platform/animation/TimingFunction.h"
 #include "wtf/Noncopyable.h"
 
 #include <memory>
@@ -37,12 +38,12 @@
     // assumed that x0 = y0, and x3 = y3 = 1.
     virtual void add(const CompositorTransformKeyframe&, double x1, double y1, double x2, double y2);
     // Adds the keyframe with a steps timing function.
-    virtual void add(const CompositorTransformKeyframe&, int steps, float stepsStartOffset);
+    virtual void add(const CompositorTransformKeyframe&, int steps, StepsTimingFunction::StepPosition);
 
     virtual void setLinearTimingFunction();
     virtual void setCubicBezierTimingFunction(TimingFunctionType);
     virtual void setCubicBezierTimingFunction(double x1, double y1, double x2, double y2);
-    virtual void setStepsTimingFunction(int numberOfSteps, float stepsStartOffset);
+    virtual void setStepsTimingFunction(int numberOfSteps, StepsTimingFunction::StepPosition);
 
     // CompositorAnimationCurve implementation.
     AnimationCurveType type() const override;
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
index 3d2eb8d2..905fbf04 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
+++ b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
@@ -46,9 +46,7 @@
 
 double CubicBezierTimingFunction::evaluate(double fraction, double accuracy) const
 {
-    if (!m_bezier)
-        m_bezier = adoptPtr(new UnitBezier(m_x1, m_y1, m_x2, m_y2));
-    return m_bezier->solveWithEpsilon(fraction, accuracy);
+    return m_bezier.SolveWithEpsilon(fraction, accuracy);
 }
 
 // This works by taking taking the derivative of the cubic bezier, on the y
@@ -89,22 +87,20 @@
 
     // If the solution is in the range [0,1] then we include it, otherwise we
     // ignore it.
-    if (!m_bezier)
-        m_bezier = adoptPtr(new UnitBezier(m_x1, m_y1, m_x2, m_y2));
 
     // An interesting fact about these beziers is that they are only
     // actually evaluated in [0,1]. After that we take the tangent at that point
     // and linearly project it out.
     if (0 < t1 && t1 < 1)
-        solution1 = m_bezier->sampleCurveY(t1);
+        solution1 = m_bezier.SampleCurveY(t1);
 
     if (0 < t2 && t2 < 1)
-        solution2 = m_bezier->sampleCurveY(t2);
+        solution2 = m_bezier.SampleCurveY(t2);
 
     // Since our input values can be out of the range 0->1 so we must also
     // consider the minimum and maximum points.
-    double solutionMin = m_bezier->solveWithEpsilon(*minValue, std::numeric_limits<double>::epsilon());
-    double solutionMax = m_bezier->solveWithEpsilon(*maxValue, std::numeric_limits<double>::epsilon());
+    double solutionMin = m_bezier.SolveWithEpsilon(*minValue, std::numeric_limits<double>::epsilon());
+    double solutionMax = m_bezier.SolveWithEpsilon(*maxValue, std::numeric_limits<double>::epsilon());
     *minValue = std::min(std::min(solutionMin, solutionMax), 0.0);
     *maxValue = std::max(std::max(solutionMin, solutionMax), 1.0);
     *minValue = std::min(std::min(*minValue, solution1), solution2);
@@ -114,14 +110,14 @@
 String StepsTimingFunction::toString() const
 {
     const char* positionString = nullptr;
-    switch (getStepAtPosition()) {
-    case Start:
+    switch (getStepPosition()) {
+    case StepPosition::START:
         positionString = "start";
         break;
-    case Middle:
+    case StepPosition::MIDDLE:
         positionString = "middle";
         break;
-    case End:
+    case StepPosition::END:
         positionString = "end";
         break;
     }
@@ -147,19 +143,16 @@
 double StepsTimingFunction::evaluate(double fraction, double) const
 {
     double startOffset = 0;
-    switch (m_stepAtPosition) {
-    case Start:
+    switch (m_stepPosition) {
+    case StepPosition::START:
         startOffset = 1;
         break;
-    case Middle:
+    case StepPosition::MIDDLE:
         startOffset = 0.5;
         break;
-    case End:
+    case StepPosition::END:
         startOffset = 0;
         break;
-    default:
-        ASSERT_NOT_REACHED();
-        break;
     }
     return clampTo(floor((m_steps * fraction) + startOffset) / m_steps, 0.0, 1.0);
 }
@@ -188,7 +181,7 @@
         return false;
 
     const StepsTimingFunction& stf = toStepsTimingFunction(rhs);
-    return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.getStepAtPosition() == stf.getStepAtPosition());
+    return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.getStepPosition() == stf.getStepPosition());
 }
 
 // The generic operator== *must* come after the
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.h b/third_party/WebKit/Source/platform/animation/TimingFunction.h
index 3c303e1..325e67d 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunction.h
+++ b/third_party/WebKit/Source/platform/animation/TimingFunction.h
@@ -25,10 +25,11 @@
 #ifndef TimingFunction_h
 #define TimingFunction_h
 
+#include "cc/animation/timing_function.h"
 #include "platform/animation/AnimationUtilities.h" // For blend()
-#include "platform/animation/UnitBezier.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/Heap.h"
+#include "ui/gfx/geometry/cubic_bezier.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
@@ -152,6 +153,7 @@
 private:
     explicit CubicBezierTimingFunction(FunctionSubType subType, double x1, double y1, double x2, double y2)
         : TimingFunction(kCubicBezierFunction)
+        , m_bezier(x1, y1, x2, y2)
         , m_x1(x1)
         , m_y1(y1)
         , m_x2(x2)
@@ -165,46 +167,41 @@
     // number of solutions found.
     size_t findIntersections(double intersectionY, double& solution1, double& solution2, double& solution3) const;
 
-    double m_x1;
-    double m_y1;
-    double m_x2;
-    double m_y2;
+    gfx::CubicBezier m_bezier;
+    const double m_x1;
+    const double m_y1;
+    const double m_x2;
+    const double m_y2;
     FunctionSubType m_subType;
-    mutable OwnPtr<UnitBezier> m_bezier;
 };
 
 class PLATFORM_EXPORT StepsTimingFunction final : public TimingFunction {
 public:
-    enum StepAtPosition {
-        Start,
-        Middle,
-        End
-    };
+    using StepPosition = cc::StepsTimingFunction::StepPosition;
 
-    static PassRefPtr<StepsTimingFunction> create(int steps, StepAtPosition stepAtPosition)
+    static PassRefPtr<StepsTimingFunction> create(int steps, StepPosition stepPosition)
     {
-        return adoptRef(new StepsTimingFunction(steps, stepAtPosition));
+        return adoptRef(new StepsTimingFunction(steps, stepPosition));
     }
 
-    static StepsTimingFunction* preset(StepAtPosition position)
+    static StepsTimingFunction* preset(StepPosition position)
     {
-        DEFINE_STATIC_REF(StepsTimingFunction, start, create(1, Start));
-        DEFINE_STATIC_REF(StepsTimingFunction, middle, create(1, Middle));
-        DEFINE_STATIC_REF(StepsTimingFunction, end, create(1, End));
+        DEFINE_STATIC_REF(StepsTimingFunction, start, create(1, StepPosition::START));
+        DEFINE_STATIC_REF(StepsTimingFunction, middle, create(1, StepPosition::MIDDLE));
+        DEFINE_STATIC_REF(StepsTimingFunction, end, create(1, StepPosition::END));
         switch (position) {
-        case Start:
+        case StepPosition::START:
             return start;
-        case Middle:
+        case StepPosition::MIDDLE:
             return middle;
-        case End:
+        case StepPosition::END:
             return end;
         default:
-            ASSERT_NOT_REACHED();
+            NOTREACHED();
             return end;
         }
     }
 
-
     ~StepsTimingFunction() override { }
 
     String toString() const override;
@@ -213,18 +210,18 @@
     void range(double* minValue, double* maxValue) const override;
 
     int numberOfSteps() const { return m_steps; }
-    StepAtPosition getStepAtPosition() const { return m_stepAtPosition; }
+    StepPosition getStepPosition() const { return m_stepPosition; }
 
 private:
-    StepsTimingFunction(int steps, StepAtPosition stepAtPosition)
+    StepsTimingFunction(int steps, StepPosition stepPosition)
         : TimingFunction(kStepsFunction)
         , m_steps(steps)
-        , m_stepAtPosition(stepAtPosition)
+        , m_stepPosition(stepPosition)
     {
     }
 
     int m_steps;
-    StepAtPosition m_stepAtPosition;
+    StepPosition m_stepPosition;
 };
 
 PLATFORM_EXPORT bool operator==(const LinearTimingFunction&, const TimingFunction&);
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp b/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
index 71d414c..67b0a39 100644
--- a/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
+++ b/third_party/WebKit/Source/platform/animation/TimingFunctionTest.cpp
@@ -88,22 +88,22 @@
 
 TEST_F(TimingFunctionTest, StepToString)
 {
-    RefPtr<TimingFunction> stepTimingStart = StepsTimingFunction::preset(StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepTimingStart = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
     EXPECT_EQ("step-start", stepTimingStart->toString());
 
-    RefPtr<TimingFunction> stepTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::Middle);
+    RefPtr<TimingFunction> stepTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::MIDDLE);
     EXPECT_EQ("step-middle", stepTimingMiddle->toString());
 
-    RefPtr<TimingFunction> stepTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
     EXPECT_EQ("step-end", stepTimingEnd->toString());
 
-    RefPtr<TimingFunction> stepTimingCustomStart = StepsTimingFunction::create(3, StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepTimingCustomStart = StepsTimingFunction::create(3, StepsTimingFunction::StepPosition::START);
     EXPECT_EQ("steps(3, start)", stepTimingCustomStart->toString());
 
-    RefPtr<TimingFunction> stepTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::Middle);
+    RefPtr<TimingFunction> stepTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::MIDDLE);
     EXPECT_EQ("steps(4, middle)", stepTimingCustomMiddle->toString());
 
-    RefPtr<TimingFunction> stepTimingCustomEnd = StepsTimingFunction::create(5, StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepTimingCustomEnd = StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::END);
     EXPECT_EQ("steps(5, end)", stepTimingCustomEnd->toString());
 }
 
@@ -112,8 +112,8 @@
     RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
     RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
     RefPtr<TimingFunction> cubicTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
-    RefPtr<TimingFunction> stepsTiming1 = StepsTimingFunction::preset(StepsTimingFunction::End);
-    RefPtr<TimingFunction> stepsTiming2 = StepsTimingFunction::create(5, StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepsTiming1 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
+    RefPtr<TimingFunction> stepsTiming2 = StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::START);
 
     Vector<std::pair<std::string, RefPtr<TimingFunction>>> v;
     v.append(std::make_pair("linearTiming", linearTiming));
@@ -172,25 +172,25 @@
 
 TEST_F(TimingFunctionTest, StepsOperatorEq)
 {
-    RefPtr<TimingFunction> stepsTimingStart1 = StepsTimingFunction::preset(StepsTimingFunction::Start);
-    RefPtr<TimingFunction> stepsTimingStart2 = StepsTimingFunction::preset(StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepsTimingStart1 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
+    RefPtr<TimingFunction> stepsTimingStart2 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
     EXPECT_EQ(*stepsTimingStart1, *stepsTimingStart1);
     EXPECT_EQ(*stepsTimingStart1, *stepsTimingStart2);
 
-    RefPtr<TimingFunction> stepsTimingEnd1 = StepsTimingFunction::preset(StepsTimingFunction::End);
-    RefPtr<TimingFunction> stepsTimingEnd2 = StepsTimingFunction::preset(StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepsTimingEnd1 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
+    RefPtr<TimingFunction> stepsTimingEnd2 = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
     EXPECT_EQ(*stepsTimingEnd1, *stepsTimingEnd1);
     EXPECT_EQ(*stepsTimingEnd1, *stepsTimingEnd2);
 
-    RefPtr<TimingFunction> stepsTimingCustom1 = StepsTimingFunction::create(5, StepsTimingFunction::Start);
-    RefPtr<TimingFunction> stepsTimingCustom2 = StepsTimingFunction::create(5, StepsTimingFunction::End);
-    RefPtr<TimingFunction> stepsTimingCustom3 = StepsTimingFunction::create(7, StepsTimingFunction::Start);
-    RefPtr<TimingFunction> stepsTimingCustom4 = StepsTimingFunction::create(7, StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepsTimingCustom1 = StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::START);
+    RefPtr<TimingFunction> stepsTimingCustom2 = StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::END);
+    RefPtr<TimingFunction> stepsTimingCustom3 = StepsTimingFunction::create(7, StepsTimingFunction::StepPosition::START);
+    RefPtr<TimingFunction> stepsTimingCustom4 = StepsTimingFunction::create(7, StepsTimingFunction::StepPosition::END);
 
-    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::Start), *stepsTimingCustom1);
-    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::End), *stepsTimingCustom2);
-    EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::Start), *stepsTimingCustom3);
-    EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::End), *stepsTimingCustom4);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::START), *stepsTimingCustom1);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepPosition::END), *stepsTimingCustom2);
+    EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::StepPosition::START), *stepsTimingCustom3);
+    EXPECT_EQ(*StepsTimingFunction::create(7, StepsTimingFunction::StepPosition::END), *stepsTimingCustom4);
 
     Vector<std::pair<std::string, RefPtr<TimingFunction>>> v;
     v.append(std::make_pair("stepsTimingStart1", stepsTimingStart1));
@@ -204,8 +204,8 @@
 
 TEST_F(TimingFunctionTest, StepsOperatorEqPreset)
 {
-    RefPtr<TimingFunction> stepsA = StepsTimingFunction::preset(StepsTimingFunction::Start);
-    RefPtr<TimingFunction> stepsB = StepsTimingFunction::create(1, StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepsA = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
+    RefPtr<TimingFunction> stepsB = StepsTimingFunction::create(1, StepsTimingFunction::StepPosition::START);
     EXPECT_EQ(*stepsA, *stepsB);
     EXPECT_EQ(*stepsB, *stepsA);
 }
@@ -238,7 +238,7 @@
 {
     double start = 0;
     double end = 1;
-    RefPtr<TimingFunction> steps = StepsTimingFunction::preset(StepsTimingFunction::Start);
+    RefPtr<TimingFunction> steps = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
     steps->range(&start, &end);
     EXPECT_NEAR(0, start, 0.01);
     EXPECT_NEAR(1, end, 0.01);
@@ -348,7 +348,7 @@
 
 TEST_F(TimingFunctionTest, StepsEvaluate)
 {
-    RefPtr<TimingFunction> stepsTimingStart = StepsTimingFunction::preset(StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepsTimingStart = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::START);
     EXPECT_EQ(0.00, stepsTimingStart->evaluate(-1.10, 0));
     EXPECT_EQ(0.00, stepsTimingStart->evaluate(-0.10, 0));
     EXPECT_EQ(1.00, stepsTimingStart->evaluate(0.00, 0));
@@ -357,7 +357,7 @@
     EXPECT_EQ(1.00, stepsTimingStart->evaluate(1.00, 0));
     EXPECT_EQ(1.00, stepsTimingStart->evaluate(2.00, 0));
 
-    RefPtr<TimingFunction> stepsTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::Middle);
+    RefPtr<TimingFunction> stepsTimingMiddle = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::MIDDLE);
     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(-2.50, 0));
     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(0.00, 0));
     EXPECT_EQ(0.00, stepsTimingMiddle->evaluate(0.49, 0));
@@ -365,7 +365,7 @@
     EXPECT_EQ(1.00, stepsTimingMiddle->evaluate(1.00, 0));
     EXPECT_EQ(1.00, stepsTimingMiddle->evaluate(2.50, 0));
 
-    RefPtr<TimingFunction> stepsTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepsTimingEnd = StepsTimingFunction::preset(StepsTimingFunction::StepPosition::END);
     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(-2.00, 0));
     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(0.00, 0));
     EXPECT_EQ(0.00, stepsTimingEnd->evaluate(0.20, 0));
@@ -373,7 +373,7 @@
     EXPECT_EQ(1.00, stepsTimingEnd->evaluate(1.00, 0));
     EXPECT_EQ(1.00, stepsTimingEnd->evaluate(2.00, 0));
 
-    RefPtr<TimingFunction> stepsTimingCustomStart = StepsTimingFunction::create(4, StepsTimingFunction::Start);
+    RefPtr<TimingFunction> stepsTimingCustomStart = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::START);
     EXPECT_EQ(0.00, stepsTimingCustomStart->evaluate(-0.50, 0));
     EXPECT_EQ(0.25, stepsTimingCustomStart->evaluate(0.00, 0));
     EXPECT_EQ(0.25, stepsTimingCustomStart->evaluate(0.24, 0));
@@ -385,7 +385,7 @@
     EXPECT_EQ(1.00, stepsTimingCustomStart->evaluate(1.00, 0));
     EXPECT_EQ(1.00, stepsTimingCustomStart->evaluate(1.50, 0));
 
-    RefPtr<TimingFunction> stepsTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::Middle);
+    RefPtr<TimingFunction> stepsTimingCustomMiddle = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::MIDDLE);
     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(-2.00, 0));
     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(0.00, 0));
     EXPECT_EQ(0.00, stepsTimingCustomMiddle->evaluate(0.12, 0));
@@ -399,7 +399,7 @@
     EXPECT_EQ(1.00, stepsTimingCustomMiddle->evaluate(1.00, 0));
     EXPECT_EQ(1.00, stepsTimingCustomMiddle->evaluate(3.00, 0));
 
-    RefPtr<TimingFunction> stepsTimingCustomEnd = StepsTimingFunction::create(4, StepsTimingFunction::End);
+    RefPtr<TimingFunction> stepsTimingCustomEnd = StepsTimingFunction::create(4, StepsTimingFunction::StepPosition::END);
     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(-2.00, 0));
     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(0.00, 0));
     EXPECT_EQ(0.00, stepsTimingCustomEnd->evaluate(0.24, 0));
diff --git a/third_party/WebKit/Source/platform/animation/UnitBezier.h b/third_party/WebKit/Source/platform/animation/UnitBezier.h
deleted file mode 100644
index bd4c6480..0000000
--- a/third_party/WebKit/Source/platform/animation/UnitBezier.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UnitBezier_h
-#define UnitBezier_h
-
-#include "ui/gfx/geometry/cubic_bezier.h"
-#include "wtf/Allocator.h"
-
-namespace blink {
-
-// TODO(loyso): Erase blink::UnitBezier and use gfx::CubicBezier directly.
-struct UnitBezier {
-    USING_FAST_MALLOC(UnitBezier);
-public:
-    UnitBezier(double p1x, double p1y, double p2x, double p2y)
-        : m_cubicBezier(p1x, p1y, p2x, p2y)
-    {
-    }
-
-    double sampleCurveX(double t) const
-    {
-        return m_cubicBezier.SampleCurveX(t);
-    }
-
-    double sampleCurveY(double t) const
-    {
-        return m_cubicBezier.SampleCurveY(t);
-    }
-
-    // Evaluates y at the given x.
-    double solve(double x) const
-    {
-        return m_cubicBezier.Solve(x);
-    }
-
-    // Evaluates y at the given x. The epsilon parameter provides a hint as to the required
-    // accuracy and is not guaranteed.
-    double solveWithEpsilon(double x, double epsilon) const
-    {
-        return m_cubicBezier.SolveWithEpsilon(x, epsilon);
-    }
-
-private:
-    gfx::CubicBezier m_cubicBezier;
-};
-
-} // namespace blink
-
-#endif // UnitBezier_h
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index 29486e5..625cdcc 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -172,7 +172,6 @@
       'animation/CubicBezierControlPoints.h',
       'animation/TimingFunction.cpp',
       'animation/TimingFunction.h',
-      'animation/UnitBezier.h',
       'audio/AudioArray.h',
       'audio/AudioBus.cpp',
       'audio/AudioBus.h',
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
index 42bf7adb..9367176 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -241,19 +241,19 @@
                     offset = spacing.letterSpacing();
                     glyphData.offset.expand(offsetX, offsetY);
                 }
-                continue;
+            } else {
+                offsetX = offsetY = 0;
+                float space = spacing.computeSpacing(textRun,
+                    run->m_startIndex + glyphData.characterIndex, offset);
+                glyphData.advance += space;
+                totalSpaceForRun += space;
+                if (textRun.rtl()) {
+                    // In RTL, spacing should be added to left side of glyphs.
+                    offset += space;
+                }
+                glyphData.offset.expand(offsetX, offsetY);
             }
-
-            offsetX = offsetY = 0;
-            float space = spacing.computeSpacing(textRun,
-                run->m_startIndex + glyphData.characterIndex, offset);
-            glyphData.advance += space;
-            totalSpaceForRun += space;
-            if (textRun.rtl()) {
-                // In RTL, spacing should be added to left side of glyphs.
-                offset += space;
-            }
-            glyphData.offset.expand(offsetX, offsetY);
+            m_hasVerticalOffsets |= (glyphData.offset.height() != 0);
         }
         run->m_width += totalSpaceForRun;
         totalSpace += totalSpaceForRun;
diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h
index 5c3a6a0..9f0b0ab 100644
--- a/third_party/WebKit/Source/platform/heap/Handle.h
+++ b/third_party/WebKit/Source/platform/heap/Handle.h
@@ -40,7 +40,6 @@
 #include "platform/heap/Visitor.h"
 #include "wtf/Allocator.h"
 #include "wtf/Atomics.h"
-#include "wtf/Functional.h"
 #include "wtf/HashFunctions.h"
 #include "wtf/TypeTraits.h"
 
@@ -1160,16 +1159,6 @@
     static const bool value = true;
 };
 
-template<typename T> inline T* getPtr(const blink::Member<T>& p)
-{
-    return p.get();
-}
-
-template<typename T> inline T* getPtr(const blink::Persistent<T>& p)
-{
-    return p.get();
-}
-
 // For wtf/Functional.h
 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits;
 
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Array.h b/third_party/WebKit/Source/platform/inspector_protocol/Array.h
index e740988..015d07b 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Array.h
+++ b/third_party/WebKit/Source/platform/inspector_protocol/Array.h
@@ -40,7 +40,7 @@
         errors->pop();
         if (errors->hasErrors())
             return nullptr;
-        return result.release();
+        return result;
     }
 
     void addItem(const T& value)
@@ -63,7 +63,7 @@
         OwnPtr<protocol::ListValue> result = ListValue::create();
         for (auto& item : m_vector)
             result->pushValue(toValue(item));
-        return result.release();
+        return result;
     }
 
 private:
@@ -96,12 +96,12 @@
         for (size_t i = 0; i < array->size(); ++i) {
             errors->setName(String16::number(i));
             OwnPtr<T> item = FromValue<T>::parse(array->at(i), errors);
-            result->m_vector.append(item.release());
+            result->m_vector.append(std::move(item));
         }
         errors->pop();
         if (errors->hasErrors())
             return nullptr;
-        return result.release();
+        return result;
     }
 
     void addItem(PassOwnPtr<T> value)
@@ -124,7 +124,7 @@
         OwnPtr<protocol::ListValue> result = ListValue::create();
         for (auto& item : m_vector)
             result->pushValue(toValue(item.get()));
-        return result.release();
+        return result;
     }
 
 private:
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py b/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py
index fc4abe5..3f82c1f 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py
+++ b/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py
@@ -110,7 +110,7 @@
         "return_type": "PassOwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
         "pass_type": "PassOwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
         "to_raw_type": "%s.get()",
-        "to_pass_type": "%s.release()",
+        "to_pass_type": "std::move(%s)",
         "to_rvalue": "std::move(%s)",
         "type": "OwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
         "raw_type": "protocol::%s::%s" % (domain_name, type["id"]),
@@ -124,7 +124,7 @@
         "return_type": "PassOwnPtr<protocol::DictionaryValue>",
         "pass_type": "PassOwnPtr<protocol::DictionaryValue>",
         "to_raw_type": "%s.get()",
-        "to_pass_type": "%s.release()",
+        "to_pass_type": "std::move(%s)",
         "to_rvalue": "std::move(%s)",
         "type": "OwnPtr<protocol::DictionaryValue>",
         "raw_type": "protocol::DictionaryValue",
@@ -138,7 +138,7 @@
         "return_type": "PassOwnPtr<protocol::Value>",
         "pass_type": "PassOwnPtr<protocol::Value>",
         "to_raw_type": "%s.get()",
-        "to_pass_type": "%s.release()",
+        "to_pass_type": "std::move(%s)",
         "to_rvalue": "std::move(%s)",
         "type": "OwnPtr<protocol::Value>",
         "raw_type": "protocol::Value",
@@ -208,7 +208,7 @@
         "return_type": "PassOwnPtr<protocol::Array<%s>>" % type["raw_type"],
         "pass_type": "PassOwnPtr<protocol::Array<%s>>" % type["raw_type"],
         "to_raw_type": "%s.get()",
-        "to_pass_type": "%s.release()",
+        "to_pass_type": "std::move(%s)",
         "to_rvalue": "std::move(%s)",
         "type": "OwnPtr<protocol::Array<%s>>" % type["raw_type"],
         "raw_type": "protocol::Array<%s>" % type["raw_type"],
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Dispatcher_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/Dispatcher_cpp.template
index e05a207c..fdc83d38 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Dispatcher_cpp.template
+++ b/third_party/WebKit/Source/platform/inspector_protocol/Dispatcher_cpp.template
@@ -67,7 +67,7 @@
     {
         OwnPtr<DispatcherImplWeakPtr> weak = adoptPtr(new DispatcherImplWeakPtr(this));
         m_weakPtrs.add(weak.get());
-        return weak.release();
+        return weak;
     }
 
     virtual void dispatch(int sessionId, const String16& message);
@@ -178,7 +178,7 @@
         resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}}));
             {% endif %}
           {% endfor %}
-        sendIfActive(resultObject.release(), ErrorString());
+        sendIfActive(std::move(resultObject), ErrorString());
     }
 
     void sendFailure(const ErrorString& error) override
@@ -248,7 +248,7 @@
         {%- endif -%}
       {%- endfor %}
       {%- if "async" in command -%}
-        , callback.release()
+        , std::move(callback)
       {%- elif "returns" in command %}
         {%- for property in command.returns -%}
           , &out_{{property.name}}
@@ -266,7 +266,7 @@
       {% endfor %}
     }
     if (weak->get())
-        weak->get()->sendResponse(sessionId, callId, error, result.release());
+        weak->get()->sendResponse(sessionId, callId, error, std::move(result));
     {% elif not("async" in command) %}
     if (weak->get())
         weak->get()->sendResponse(sessionId, callId, error);
@@ -285,7 +285,7 @@
     int callId = 0;
     OwnPtr<protocol::Value> parsedMessage = parseJSON(message);
     ASSERT(parsedMessage);
-    OwnPtr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(parsedMessage.release());
+    OwnPtr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
     ASSERT(messageObject);
 
     protocol::Value* callIdValue = messageObject->get("id");
@@ -304,7 +304,7 @@
     }
 
     protocol::ErrorSupport errors;
-    ((*this).*(*it->second))(sessionId, callId, messageObject.release(), &errors);
+    ((*this).*(*it->second))(sessionId, callId, std::move(messageObject), &errors);
 }
 
 void DispatcherImpl::sendResponse(int sessionId, int callId, const ErrorString& invocationError, ErrorSupport* errors, PassOwnPtr<protocol::DictionaryValue> result)
@@ -318,7 +318,7 @@
     responseMessage->setNumber("id", callId);
     responseMessage->setObject("result", std::move(result));
     if (m_frontendChannel)
-        m_frontendChannel->sendProtocolResponse(sessionId, callId, responseMessage.release());
+        m_frontendChannel->sendProtocolResponse(sessionId, callId, std::move(responseMessage));
 }
 
 void Dispatcher::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String16& errorMessage) const
@@ -339,10 +339,10 @@
     if (errors && errors->hasErrors())
         error->setString("data", errors->errors());
     OwnPtr<protocol::DictionaryValue> message = DictionaryValue::create();
-    message->setObject("error", error.release());
+    message->setObject("error", std::move(error));
     message->setNumber("id", callId);
     if (m_frontendChannel)
-        m_frontendChannel->sendProtocolResponse(sessionId, callId, message.release());
+        m_frontendChannel->sendProtocolResponse(sessionId, callId, std::move(message));
 }
 
 bool Dispatcher::getCommandName(const String16& message, String16* result)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Frontend_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/Frontend_cpp.template
index 476152c..58c7691d 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Frontend_cpp.template
+++ b/third_party/WebKit/Source/platform/inspector_protocol/Frontend_cpp.template
@@ -42,9 +42,9 @@
     paramsObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}}));
       {% endif %}
     {% endfor %}
-    jsonMessage->setObject("params", paramsObject.release());
+    jsonMessage->setObject("params", std::move(paramsObject));
     if (m_frontendChannel)
-        m_frontendChannel->sendProtocolNotification(jsonMessage.release());
+        m_frontendChannel->sendProtocolNotification(std::move(jsonMessage));
 }
   {% endfor %}
 {% endfor %}
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp b/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp
index 6e79ed2b..c39dd1db 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp
+++ b/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp
@@ -401,7 +401,7 @@
             OwnPtr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
             if (!arrayNode)
                 return nullptr;
-            array->pushValue(arrayNode.release());
+            array->pushValue(std::move(arrayNode));
 
             // After a list value, we expect a comma or the end of the list.
             start = tokenEnd;
@@ -418,7 +418,7 @@
         }
         if (token != ArrayEnd)
             return nullptr;
-        result = array.release();
+        result = std::move(array);
         break;
     }
     case ObjectBegin: {
@@ -441,7 +441,7 @@
             OwnPtr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
             if (!value)
                 return nullptr;
-            object->setValue(key, value.release());
+            object->setValue(key, std::move(value));
             start = tokenEnd;
 
             // After a key/value pair, we expect a comma or the end of the
@@ -459,7 +459,7 @@
         }
         if (token != ObjectEnd)
             return nullptr;
-        result = object.release();
+        result = std::move(object);
         break;
     }
 
@@ -469,7 +469,7 @@
     }
 
     skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
-    return result.release();
+    return result;
 }
 
 PassOwnPtr<Value> parseJSONInternal(const UChar* start, unsigned length)
@@ -479,7 +479,7 @@
     OwnPtr<Value> value = buildValue(start, end, &tokenEnd, 0);
     if (!value || tokenEnd != end)
         return nullptr;
-    return value.release();
+    return value;
 }
 
 } // anonymous namespace
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template
index 229a0cb..e0a79972 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template
+++ b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template
@@ -80,7 +80,7 @@
     errors->pop();
     if (errors->hasErrors())
         return nullptr;
-    return result.release();
+    return result;
 }
 
 PassOwnPtr<protocol::DictionaryValue> {{type.id}}::serialize() const
@@ -94,7 +94,7 @@
     result->setValue("{{property.name}}", toValue({{resolve_type(property).to_raw_type % ("m_" + property.name)}}));
       {% endif %}
     {% endfor %}
-    return result.release();
+    return result;
 }
 
 PassOwnPtr<{{type.id}}> {{type.id}}::clone() const
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template
index 6f00bc0b..eec0efe 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template
+++ b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template
@@ -166,7 +166,7 @@
         PassOwnPtr<{{type.id}}> build()
         {
             static_assert(STATE == AllFieldsSet, "state should be AllFieldsSet");
-            return m_result.release();
+            return std::move(m_result);
         }
 
     private:
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp b/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp
index 8c0bac1..0471d90 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp
+++ b/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp
@@ -301,7 +301,7 @@
         ASSERT(value);
         result->setValue(key, value->clone());
     }
-    return result.release();
+    return std::move(result);
 }
 
 DictionaryValue::DictionaryValue()
@@ -329,7 +329,7 @@
     OwnPtr<ListValue> result = ListValue::create();
     for (Vector<OwnPtr<protocol::Value>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it)
         result->pushValue((*it)->clone());
-    return result.release();
+    return std::move(result);
 }
 
 ListValue::ListValue()
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
index 3d9ee343..8be31265 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
@@ -98,7 +98,7 @@
         return nullptr;
     if (!injectedScriptValue->IsObject())
         return nullptr;
-    return adoptPtr(new InjectedScript(inspectedContext, injectedScriptValue.As<v8::Object>(), injectedScriptNative.release()));
+    return adoptPtr(new InjectedScript(inspectedContext, injectedScriptValue.As<v8::Object>(), std::move(injectedScriptNative)));
 }
 
 InjectedScript::InjectedScript(InspectedContext* context, v8::Local<v8::Object> object, PassOwnPtr<InjectedScriptNative> injectedScriptNative)
@@ -137,7 +137,7 @@
     protocol::ErrorSupport errors(errorString);
     OwnPtr<Array<PropertyDescriptor>> result = Array<PropertyDescriptor>::parse(protocolValue.get(), &errors);
     if (!hasInternalError(errorString, errors.hasErrors()))
-        *properties = result.release();
+        *properties = std::move(result);
 }
 
 void InjectedScript::releaseObject(const String16& objectId)
@@ -164,7 +164,7 @@
     OwnPtr<protocol::Runtime::RemoteObject> remoteObject = protocol::Runtime::RemoteObject::parse(toProtocolValue(m_context->context(), wrappedObject).get(), &errors);
     if (!remoteObject)
         *errorString = "Object has too long reference chain";
-    return remoteObject.release();
+    return remoteObject;
 }
 
 bool InjectedScript::wrapObjectProperty(ErrorString* errorString, v8::Local<v8::Object> object, v8::Local<v8::Value> key, const String16& groupName, bool forceValueType, bool generatePreview) const
@@ -336,7 +336,7 @@
     v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace();
     if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0)
         exceptionDetailsObject->setStack(m_context->debugger()->createStackTrace(stackTrace, stackTrace->GetFrameCount())->buildInspectorObject());
-    return exceptionDetailsObject.release();
+    return exceptionDetailsObject;
 }
 
 void InjectedScript::wrapEvaluateResult(ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGroup, bool returnByValue, bool generatePreview, OwnPtr<protocol::Runtime::RemoteObject>* result, Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails)
@@ -350,7 +350,7 @@
             return;
         if (objectGroup == "console")
             m_lastEvaluationResult.Reset(m_context->isolate(), resultValue);
-        *result = remoteObject.release();
+        *result = std::move(remoteObject);
         if (wasThrown)
             *wasThrown = false;
     } else {
@@ -358,7 +358,7 @@
         OwnPtr<RemoteObject> remoteObject = wrapObject(errorString, exception, objectGroup, false, generatePreview && !exception->IsNativeError());
         if (!remoteObject)
             return;
-        *result = remoteObject.release();
+        *result = std::move(remoteObject);
         if (exceptionDetails)
             *exceptionDetails = createExceptionDetails(tryCatch.Message());
         if (wasThrown)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp
index 380dd6cd..50f430f 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp
@@ -21,7 +21,7 @@
     OwnPtr<protocol::DictionaryValue> parsedObjectId = adoptPtr(protocol::DictionaryValue::cast(parsedValue.leakPtr()));
     bool success = parsedObjectId->getNumber("injectedScriptId", &m_injectedScriptId);
     if (success)
-        return parsedObjectId.release();
+        return parsedObjectId;
     return nullptr;
 }
 
@@ -41,7 +41,7 @@
         *errorString = "Invalid remote object id";
         return nullptr;
     }
-    return result.release();
+    return result;
 }
 
 RemoteCallFrameId::RemoteCallFrameId() : RemoteObjectIdBase(), m_frameOrdinal(0) { }
@@ -61,7 +61,7 @@
         return nullptr;
     }
 
-    return result.release();
+    return result;
 }
 
 String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
index 0eccb82..8e47b27 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
@@ -585,7 +585,7 @@
     if (copyToClipboard)
         hints->setBoolean("copyToClipboard", true);
     if (V8InspectorSessionImpl* session = helper.currentSession())
-        session->runtimeAgentImpl()->inspect(wrappedObject.release(), hints.release());
+        session->runtimeAgentImpl()->inspect(std::move(wrappedObject), std::move(hints));
 }
 
 void V8Console::inspectCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index 5099b24..bd703af 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -335,7 +335,7 @@
     breakpointObject->setNumber(DebuggerAgentState::columnNumber, columnNumber);
     breakpointObject->setString(DebuggerAgentState::condition, condition);
     breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex);
-    return breakpointObject.release();
+    return breakpointObject;
 }
 
 static bool matches(V8DebuggerImpl* debugger, const String16& url, const String16& pattern, bool isRegex)
@@ -379,7 +379,7 @@
     if (!breakpointsCookie) {
         OwnPtr<protocol::DictionaryValue> newValue = protocol::DictionaryValue::create();
         breakpointsCookie = newValue.get();
-        m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, newValue.release());
+        m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, std::move(newValue));
     }
     if (breakpointsCookie->get(breakpointId)) {
         *errorString = "Breakpoint at specified location already exists.";
@@ -394,7 +394,7 @@
             continue;
         OwnPtr<protocol::Debugger::Location> location = resolveBreakpoint(breakpointId, script.first, breakpoint, UserBreakpointSource);
         if (location)
-            (*locations)->addItem(location.release());
+            (*locations)->addItem(std::move(location));
     }
 
     *outBreakpointId = breakpointId;
@@ -630,7 +630,7 @@
     OwnPtr<Array<CallFrame>> callFrames = currentCallFrames(errorString);
     if (!callFrames)
         return;
-    *newCallFrames = callFrames.release();
+    *newCallFrames = std::move(callFrames);
     *asyncStackTrace = currentAsyncStackTrace();
 
     ScriptsMap::iterator it = m_scripts.find(scriptId);
@@ -711,10 +711,10 @@
         OwnPtr<protocol::Array<protocol::Debugger::Scope>> scopeChain = protocol::Array<protocol::Debugger::Scope>::parse(toProtocolValue(scope.context(), scopes).get(), &errorSupport);
         if (hasInternalError(errorString, errorSupport.hasErrors()))
             return;
-        functionDetails->setScopeChain(scopeChain.release());
+        functionDetails->setScopeChain(std::move(scopeChain));
     }
 
-    *details = functionDetails.release();
+    *details = std::move(functionDetails);
 }
 
 void V8DebuggerAgentImpl::getGeneratorObjectDetails(ErrorString* errorString, const String16& objectId, OwnPtr<GeneratorObjectDetails>* outDetails)
@@ -742,7 +742,7 @@
     OwnPtr<GeneratorObjectDetails> protocolDetails = GeneratorObjectDetails::parse(toProtocolValue(scope.context(), detailsObject).get(), &errors);
     if (hasInternalError(errorString, !protocolDetails))
         return;
-    *outDetails = protocolDetails.release();
+    *outDetails = std::move(protocolDetails);
 }
 
 void V8DebuggerAgentImpl::getCollectionEntries(ErrorString* errorString, const String16& objectId, OwnPtr<protocol::Array<CollectionEntry>>* outEntries)
@@ -776,7 +776,7 @@
     OwnPtr<protocol::Array<CollectionEntry>> entries = protocol::Array<CollectionEntry>::parse(toProtocolValue(scope.context(), entriesArray).get(), &errors);
     if (hasInternalError(errorString, !entries))
         return;
-    *outEntries = entries.release();
+    *outEntries = std::move(entries);
 }
 
 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(const String16& breakReason, PassOwnPtr<protocol::DictionaryValue> data)
@@ -1007,7 +1007,7 @@
     v8::HandleScope scope(m_isolate);
     OwnPtr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(this, V8StackTrace::maxCallStackSizeToCapture, taskName);
     if (chain) {
-        m_asyncTaskStacks.set(task, chain.release());
+        m_asyncTaskStacks.set(task, std::move(chain));
         if (recurring)
             m_recurringTasks.add(task);
     }
@@ -1097,7 +1097,7 @@
         *errorString = "Pattern parser error: " + regex->errorMessage();
         return false;
     }
-    m_blackboxPattern = regex.release();
+    m_blackboxPattern = std::move(regex);
     return true;
 }
 
@@ -1244,7 +1244,7 @@
     OwnPtr<Array<CallFrame>> callFrames = Array<CallFrame>::parse(toProtocolValue(context, objects).get(), &errorSupport);
     if (hasInternalError(errorString, !callFrames))
         return Array<CallFrame>::create();
-    return callFrames.release();
+    return callFrames;
 }
 
 PassOwnPtr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace()
@@ -1324,7 +1324,7 @@
         breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.condition);
         OwnPtr<protocol::Debugger::Location> location = resolveBreakpoint(cookie.first, parsedScript.scriptId, breakpoint, UserBreakpointSource);
         if (location)
-            m_frontend->breakpointResolved(cookie.first, location.release());
+            m_frontend->breakpointResolved(cookie.first, std::move(location));
     }
 }
 
@@ -1384,7 +1384,7 @@
     }
 
     ErrorString errorString;
-    m_frontend->paused(currentCallFrames(&errorString), m_breakReason, m_breakAuxData.release(), hitBreakpointIds.release(), currentAsyncStackTrace());
+    m_frontend->paused(currentCallFrames(&errorString), m_breakReason, std::move(m_breakAuxData), std::move(hitBreakpointIds), currentAsyncStackTrace());
     m_scheduledDebuggerStep = NoStep;
     m_javaScriptPauseScheduled = false;
     m_steppingFromFramework = false;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
index 40898de..1899361 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerImpl.cpp
@@ -741,7 +741,7 @@
     ASSERT(!m_sessions.contains(contextGroupId));
     OwnPtr<V8InspectorSessionImpl> session = V8InspectorSessionImpl::create(this, contextGroupId);
     m_sessions.set(contextGroupId, session.get());
-    return session.release();
+    return std::move(session);
 }
 
 void V8DebuggerImpl::disconnect(V8InspectorSessionImpl* session)
@@ -766,7 +766,7 @@
 
     OwnPtr<InspectedContext> contextOwner = adoptPtr(new InspectedContext(this, info, contextId));
     InspectedContext* inspectedContext = contextOwner.get();
-    m_contexts.get(info.contextGroupId)->set(contextId, contextOwner.release());
+    m_contexts.get(info.contextGroupId)->set(contextId, std::move(contextOwner));
 
     if (V8InspectorSessionImpl* session = m_sessions.get(info.contextGroupId))
         session->runtimeAgentImpl()->reportExecutionContextCreated(inspectedContext);
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
index f5bc036b..4323af3 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
@@ -139,7 +139,7 @@
             statsDiff->addItem(updateData[i].count);
             statsDiff->addItem(updateData[i].size);
         }
-        m_frontend->heapStatsUpdate(statsDiff.release());
+        m_frontend->heapStatsUpdate(std::move(statsDiff));
         return kContinue;
     }
 
@@ -379,7 +379,7 @@
         .setColumnNumber(node->column_number)
         .setSelfSize(selfSize)
         .setChildren(std::move(children)).build();
-    return result.release();
+    return result;
 }
 } // namespace
 #endif
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.cpp
index 0e2a7630..98dedee 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.cpp
@@ -26,7 +26,7 @@
     OwnPtr<protocol::Array<protocol::Profiler::PositionTickInfo>> array = protocol::Array<protocol::Profiler::PositionTickInfo>::create();
     unsigned lineCount = node->GetHitLineCount();
     if (!lineCount)
-        return array.release();
+        return array;
 
     protocol::Vector<v8::CpuProfileNode::LineTick> entries(lineCount);
     if (node->GetLineTicks(&entries[0], lineCount)) {
@@ -34,11 +34,11 @@
             OwnPtr<protocol::Profiler::PositionTickInfo> line = protocol::Profiler::PositionTickInfo::create()
                 .setLine(entries[i].line)
                 .setTicks(entries[i].hit_count).build();
-            array->addItem(line.release());
+            array->addItem(std::move(line));
         }
     }
 
-    return array.release();
+    return array;
 }
 
 PassOwnPtr<protocol::Profiler::CPUProfileNode> buildInspectorObjectFor(v8::Isolate* isolate, const v8::CpuProfileNode* node)
@@ -62,11 +62,11 @@
         .setColumnNumber(node->GetColumnNumber())
         .setHitCount(node->GetHitCount())
         .setCallUID(node->GetCallUid())
-        .setChildren(children.release())
-        .setPositionTicks(positionTicks.release())
+        .setChildren(std::move(children))
+        .setPositionTicks(std::move(positionTicks))
         .setDeoptReason(node->GetBailoutReason())
         .setId(node->GetNodeId()).build();
-    return result.release();
+    return result;
 }
 
 PassOwnPtr<protocol::Array<int>> buildInspectorObjectForSamples(v8::CpuProfile* v8profile)
@@ -75,7 +75,7 @@
     int count = v8profile->GetSamplesCount();
     for (int i = 0; i < count; i++)
         array->addItem(v8profile->GetSample(i)->GetNodeId());
-    return array.release();
+    return array;
 }
 
 PassOwnPtr<protocol::Array<double>> buildInspectorObjectForTimestamps(v8::CpuProfile* v8profile)
@@ -84,7 +84,7 @@
     int count = v8profile->GetSamplesCount();
     for (int i = 0; i < count; i++)
         array->addItem(v8profile->GetSampleTimestamp(i));
-    return array.release();
+    return array;
 }
 
 PassOwnPtr<protocol::Profiler::CPUProfile> createCPUProfile(v8::Isolate* isolate, v8::CpuProfile* v8profile)
@@ -95,7 +95,7 @@
         .setEndTime(static_cast<double>(v8profile->GetEndTime()) / 1000000).build();
     profile->setSamples(buildInspectorObjectForSamples(v8profile));
     profile->setTimestamps(buildInspectorObjectForTimestamps(v8profile));
-    return profile.release();
+    return profile;
 }
 
 PassOwnPtr<protocol::Debugger::Location> currentDebugLocation(V8DebuggerImpl* debugger)
@@ -105,7 +105,7 @@
         .setScriptId(callStack->topScriptId())
         .setLineNumber(callStack->topLineNumber()).build();
     location->setColumnNumber(callStack->topColumnNumber());
-    return location.release();
+    return location;
 }
 
 volatile int s_lastProfileId = 0;
@@ -176,7 +176,7 @@
     if (!profile)
         return;
     OwnPtr<protocol::Debugger::Location> location = currentDebugLocation(m_session->debugger());
-    m_frontend->consoleProfileFinished(id, location.release(), profile.release(), resolvedTitle);
+    m_frontend->consoleProfileFinished(id, std::move(location), std::move(profile), resolvedTitle);
 }
 
 void V8ProfilerAgentImpl::enable(ErrorString*)
@@ -261,7 +261,7 @@
     m_recordingCPUProfile = false;
     OwnPtr<protocol::Profiler::CPUProfile> cpuProfile = stopProfiling(m_frontendInitiatedProfileId, !!profile);
     if (profile) {
-        *profile = cpuProfile.release();
+        *profile = std::move(cpuProfile);
         if (!profile->get() && errorString)
             *errorString = "Profile is not found";
     }
@@ -291,7 +291,7 @@
     if (serialize)
         result = createCPUProfile(m_isolate, profile);
     profile->Delete();
-    return result.release();
+    return result;
 }
 
 bool V8ProfilerAgentImpl::isRecording() const
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
index 84338fe..56cbcf0 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
@@ -236,11 +236,11 @@
             return;
         propertiesProtocolArray->addItem(InternalPropertyDescriptor::create()
             .setName(toProtocolString(name.As<v8::String>()))
-            .setValue(wrappedValue.release()).build());
+            .setValue(std::move(wrappedValue)).build());
     }
     if (!propertiesProtocolArray->length())
         return;
-    *internalProperties = propertiesProtocolArray.release();
+    *internalProperties = std::move(propertiesProtocolArray);
 }
 
 void V8RuntimeAgentImpl::releaseObject(ErrorString* errorString, const String16& objectId)
@@ -298,7 +298,7 @@
 
     String16 scriptValueId = String16::number(script->GetUnboundScript()->GetId());
     OwnPtr<v8::Global<v8::Script>> global = adoptPtr(new v8::Global<v8::Script>(m_debugger->isolate(), script));
-    m_compiledScripts.set(scriptValueId, global.release());
+    m_compiledScripts.set(scriptValueId, std::move(global));
     *scriptId = scriptValueId;
 }
 
@@ -420,7 +420,7 @@
         .setName(context->humanReadableName())
         .setOrigin(context->origin())
         .setFrameId(context->frameId()).build();
-    m_frontend->executionContextCreated(description.release());
+    m_frontend->executionContextCreated(std::move(description));
 }
 
 void V8RuntimeAgentImpl::reportExecutionContextDestroyed(InspectedContext* context)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
index 02b9176..285bac4d 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
@@ -118,7 +118,7 @@
     if (deepest)
         deepest->m_parent.clear();
 
-    return result.release();
+    return result;
 }
 
 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::capture(V8DebuggerAgentImpl* agent, size_t maxStackSize, const String16& description)
@@ -189,12 +189,12 @@
         frames->addItem(m_frames.at(i).buildInspectorObject());
 
     OwnPtr<protocol::Runtime::StackTrace> stackTrace = protocol::Runtime::StackTrace::create()
-        .setCallFrames(frames.release()).build();
+        .setCallFrames(std::move(frames)).build();
     if (!m_description.isEmpty())
         stackTrace->setDescription(m_description);
     if (m_parent)
         stackTrace->setParent(m_parent->buildInspectorObject());
-    return stackTrace.release();
+    return stackTrace;
 }
 
 PassOwnPtr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorObjectForTail(V8DebuggerAgentImpl* agent) const
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp
index e850dd5..50ab02a 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp
@@ -110,7 +110,7 @@
     }
     result->append(text.length());
 
-    return result.release();
+    return result;
 }
 
 protocol::Vector<std::pair<int, String16>> scriptRegexpMatchesByLines(const V8Regex& regex, const String16& text)
@@ -204,7 +204,7 @@
     for (const auto& match : matches)
         result->addItem(buildObjectForSearchMatch(match.first, match.second));
 
-    return result.release();
+    return result;
 }
 
 } // namespace V8ContentSearchUtil
@@ -239,9 +239,9 @@
             OwnPtr<protocol::Value> element = toProtocolValue(context, value, maxDepth);
             if (!element)
                 return nullptr;
-            inspectorArray->pushValue(element.release());
+            inspectorArray->pushValue(std::move(element));
         }
-        return inspectorArray.release();
+        return std::move(inspectorArray);
     }
     if (value->IsObject()) {
         OwnPtr<protocol::DictionaryValue> jsonObject = protocol::DictionaryValue::create();
@@ -269,9 +269,9 @@
             OwnPtr<protocol::Value> propertyValue = toProtocolValue(context, property, maxDepth);
             if (!propertyValue)
                 return nullptr;
-            jsonObject->setValue(toProtocolString(propertyName), propertyValue.release());
+            jsonObject->setValue(toProtocolString(propertyName), std::move(propertyValue));
         }
-        return jsonObject.release();
+        return std::move(jsonObject);
     }
     ASSERT_NOT_REACHED();
     return nullptr;
diff --git a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
index eb39176..4923081 100644
--- a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
+++ b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
@@ -739,7 +739,7 @@
 STATIC_ASSERT_ENUM(WebFrameLoadType::Standard, FrameLoadTypeStandard);
 STATIC_ASSERT_ENUM(WebFrameLoadType::BackForward, FrameLoadTypeBackForward);
 STATIC_ASSERT_ENUM(WebFrameLoadType::Reload, FrameLoadTypeReload);
-STATIC_ASSERT_ENUM(WebFrameLoadType::Same, FrameLoadTypeSame);
+STATIC_ASSERT_ENUM(WebFrameLoadType::ReloadMainResource, FrameLoadTypeReloadMainResource);
 STATIC_ASSERT_ENUM(WebFrameLoadType::ReplaceCurrentItem, FrameLoadTypeReplaceCurrentItem);
 STATIC_ASSERT_ENUM(WebFrameLoadType::InitialInChildFrame, FrameLoadTypeInitialInChildFrame);
 STATIC_ASSERT_ENUM(WebFrameLoadType::InitialHistoryLoad, FrameLoadTypeInitialHistoryLoad);
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index ed3ada6..3d9efdd 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -6064,20 +6064,20 @@
 class TestSameDocumentWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
     TestSameDocumentWebFrameClient()
-        : m_frameLoadTypeSameSeen(false)
+        : m_frameLoadTypeReloadMainResourceSeen(false)
     {
     }
 
     virtual void willSendRequest(WebLocalFrame* frame, unsigned, WebURLRequest&, const WebURLResponse&)
     {
-        if (toWebLocalFrameImpl(frame)->frame()->loader().loadType() == FrameLoadTypeSame)
-            m_frameLoadTypeSameSeen = true;
+        if (toWebLocalFrameImpl(frame)->frame()->loader().loadType() == FrameLoadTypeReloadMainResource)
+            m_frameLoadTypeReloadMainResourceSeen = true;
     }
 
-    bool frameLoadTypeSameSeen() const { return m_frameLoadTypeSameSeen; }
+    bool frameLoadTypeReloadMainResourceSeen() const { return m_frameLoadTypeReloadMainResourceSeen; }
 
 private:
-    bool m_frameLoadTypeSameSeen;
+    bool m_frameLoadTypeReloadMainResourceSeen;
 };
 
 TEST_P(ParameterizedWebFrameTest, NavigateToSame)
@@ -6086,13 +6086,13 @@
     TestSameDocumentWebFrameClient client;
     FrameTestHelpers::WebViewHelper webViewHelper(this);
     webViewHelper.initializeAndLoad(m_baseURL + "navigate_to_same.html", true, &client);
-    EXPECT_FALSE(client.frameLoadTypeSameSeen());
+    EXPECT_FALSE(client.frameLoadTypeReloadMainResourceSeen());
 
     FrameLoadRequest frameRequest(0, ResourceRequest(toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document()->url()));
     toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->loader().load(frameRequest);
     FrameTestHelpers::pumpPendingRequestsForFrameToLoad(webViewHelper.webView()->mainFrame());
 
-    EXPECT_TRUE(client.frameLoadTypeSameSeen());
+    EXPECT_TRUE(client.frameLoadTypeReloadMainResourceSeen());
 }
 
 class TestSameDocumentWithImageWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
diff --git a/third_party/WebKit/Source/wtf/Vector.h b/third_party/WebKit/Source/wtf/Vector.h
index 0d55085..0dfcdab7 100644
--- a/third_party/WebKit/Source/wtf/Vector.h
+++ b/third_party/WebKit/Source/wtf/Vector.h
@@ -30,6 +30,7 @@
 #include "wtf/VectorTraits.h"
 #include "wtf/allocator/PartitionAllocator.h"
 #include <algorithm>
+#include <initializer_list>
 #include <iterator>
 #include <string.h>
 #include <utility>
@@ -406,7 +407,7 @@
     {
     }
 
-    VectorBuffer(size_t capacity)
+    explicit VectorBuffer(size_t capacity)
     {
         // Calling malloc(0) might take a lock and may actually do an allocation
         // on some systems.
@@ -831,6 +832,9 @@
     Vector(Vector&&);
     Vector& operator=(Vector&&);
 
+    Vector(std::initializer_list<T> elements);
+    Vector& operator=(std::initializer_list<T> elements);
+
     size_t size() const { return m_size; }
     size_t capacity() const { return Base::capacity(); }
     bool isEmpty() const { return !size(); }
@@ -1050,6 +1054,34 @@
 }
 
 template <typename T, size_t inlineCapacity, typename Allocator>
+Vector<T, inlineCapacity, Allocator>::Vector(std::initializer_list<T> elements)
+    : Base(elements.size())
+{
+    ANNOTATE_NEW_BUFFER(begin(), capacity(), elements.size());
+    m_size = elements.size();
+    TypeOperations::uninitializedCopy(elements.begin(), elements.end(), begin());
+}
+
+template <typename T, size_t inlineCapacity, typename Allocator>
+Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::operator=(std::initializer_list<T> elements)
+{
+    if (size() > elements.size()) {
+        shrink(elements.size());
+    } else if (elements.size() > capacity()) {
+        clear();
+        reserveCapacity(elements.size());
+        DCHECK(begin());
+    }
+
+    ANNOTATE_CHANGE_SIZE(begin(), capacity(), m_size, elements.size());
+    std::copy(elements.begin(), elements.begin() + m_size, begin());
+    TypeOperations::uninitializedCopy(elements.begin() + m_size, elements.end(), end());
+    m_size = elements.size();
+
+    return *this;
+}
+
+template <typename T, size_t inlineCapacity, typename Allocator>
 template <typename U>
 bool Vector<T, inlineCapacity, Allocator>::contains(const U& value) const
 {
diff --git a/third_party/WebKit/Source/wtf/VectorTest.cpp b/third_party/WebKit/Source/wtf/VectorTest.cpp
index 7203ea4..74c6fe9 100644
--- a/third_party/WebKit/Source/wtf/VectorTest.cpp
+++ b/third_party/WebKit/Source/wtf/VectorTest.cpp
@@ -615,6 +615,80 @@
     EXPECT_EQ(-1, *vector[0]);
 }
 
+bool isOneTwoThree(const Vector<int>& vector)
+{
+    return vector.size() == 3 && vector[0] == 1 && vector[1] == 2 && vector[2] == 3;
+}
+
+Vector<int> returnOneTwoThree()
+{
+    return {1, 2, 3};
+}
+
+TEST(VectorTest, InitializerList)
+{
+    Vector<int> empty({});
+    EXPECT_TRUE(empty.isEmpty());
+
+    Vector<int> one({1});
+    ASSERT_EQ(1u, one.size());
+    EXPECT_EQ(1, one[0]);
+
+    Vector<int> oneTwoThree({1, 2, 3});
+    ASSERT_EQ(3u, oneTwoThree.size());
+    EXPECT_EQ(1, oneTwoThree[0]);
+    EXPECT_EQ(2, oneTwoThree[1]);
+    EXPECT_EQ(3, oneTwoThree[2]);
+
+    // Put some jank so we can check if the assignments later can clear them.
+    empty.append(9999);
+    one.append(9999);
+    oneTwoThree.append(9999);
+
+    empty = {};
+    EXPECT_TRUE(empty.isEmpty());
+
+    one = {1};
+    ASSERT_EQ(1u, one.size());
+    EXPECT_EQ(1, one[0]);
+
+    oneTwoThree = {1, 2, 3};
+    ASSERT_EQ(3u, oneTwoThree.size());
+    EXPECT_EQ(1, oneTwoThree[0]);
+    EXPECT_EQ(2, oneTwoThree[1]);
+    EXPECT_EQ(3, oneTwoThree[2]);
+
+    // Other ways of construction: as a function parameter and in a return statement.
+    EXPECT_TRUE(isOneTwoThree({1, 2, 3}));
+    EXPECT_TRUE(isOneTwoThree(returnOneTwoThree()));
+
+    // The tests below correspond to the cases in the "if" branch in operator=(std::initializer_list<T>).
+
+    // Shrinking.
+    Vector<int, 1> vector1(3); // capacity = 3.
+    vector1 = {1, 2};
+    ASSERT_EQ(2u, vector1.size());
+    EXPECT_EQ(1, vector1[0]);
+    EXPECT_EQ(2, vector1[1]);
+
+    // Expanding.
+    Vector<int, 1> vector2(3);
+    vector2 = {1, 2, 3, 4};
+    ASSERT_EQ(4u, vector2.size());
+    EXPECT_EQ(1, vector2[0]);
+    EXPECT_EQ(2, vector2[1]);
+    EXPECT_EQ(3, vector2[2]);
+    EXPECT_EQ(4, vector2[3]);
+
+    // Exact match.
+    Vector<int, 1> vector3(3);
+    vector3 = {1, 2, 3};
+    ASSERT_EQ(3u, vector3.size());
+    EXPECT_EQ(1, vector3[0]);
+    EXPECT_EQ(2, vector3[1]);
+    EXPECT_EQ(3, vector3[2]);
+}
+
 } // anonymous namespace
 
 } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp b/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
index 466d5ed1..722a5ec 100644
--- a/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
+++ b/third_party/WebKit/Source/wtf/typed_arrays/ArrayBufferContents.cpp
@@ -139,11 +139,11 @@
 {
     ASSERT(!m_data);
     void* data = nullptr;
-    if (s_adjustAmountOfExternalAllocatedMemoryFunction)
-        s_adjustAmountOfExternalAllocatedMemoryFunction(static_cast<int>(sizeInBytes));
     allocateMemory(sizeInBytes, policy, data);
     m_data = data;
     m_sizeInBytes = data ? sizeInBytes : 0;
+    if (s_adjustAmountOfExternalAllocatedMemoryFunction)
+        s_adjustAmountOfExternalAllocatedMemoryFunction(static_cast<int>(m_sizeInBytes));
     m_isShared = isShared;
 }
 
diff --git a/third_party/WebKit/public/platform/modules/imagecapture/image_capture.mojom b/third_party/WebKit/public/platform/modules/imagecapture/image_capture.mojom
index 11c909f..461d7f1 100644
--- a/third_party/WebKit/public/platform/modules/imagecapture/image_capture.mojom
+++ b/third_party/WebKit/public/platform/modules/imagecapture/image_capture.mojom
@@ -4,8 +4,24 @@
 
 module blink.mojom;
 
+// Equivalent to idl MediaSettingsRange, arbitrary range representing the
+// allowed variations of a Capability or an Option.
+// http://w3c.github.io/mediacapture-image/#mediasettingsrange
+struct Range {
+  uint32 max;
+  uint32 min;
+  uint32 initial;
+};
+
+struct PhotoCapabilities {
+  Range zoom;
+};
+
 interface ImageCapture
 {
-    TakePhoto(string sourceid)
+    GetCapabilities(string source_id)
+        => (PhotoCapabilities capabilities);
+
+    TakePhoto(string source_id)
         => (string mime_type, array<uint8> data);
 };
diff --git a/third_party/WebKit/public/web/WebFrameLoadType.h b/third_party/WebKit/public/web/WebFrameLoadType.h
index 0d237f5..df55aa61 100644
--- a/third_party/WebKit/public/web/WebFrameLoadType.h
+++ b/third_party/WebKit/public/web/WebFrameLoadType.h
@@ -11,15 +11,40 @@
 // The type of load for a navigation.
 // TODO(clamy): Return a WebFrameLoadType instead of a WebHistoryCommitType
 // in DidCommitProvisionalLoad.
+//
+// Standard:
+//   Follows network and cache protocols, e.g. using cached entries unless
+//   they are expired. Used in usual navigations.
+// BackForward:
+//   Uses cached entries even if the entries are stale. Used in history back and
+//   forward navigations.
+// Reload:
+//   Revalidates cached entries even if the entries are fresh. Used in usual
+//   reload.
+// ReloadMainResource:
+//   Revalidates a cached entry for the main resource if one exists, but follows
+//   protocols for other subresources. Blink internally uses this for the same
+//   page navigation. Also used in optimized reload for mobiles in a field
+//   trial.
+// ReplaceCurrentItem:
+//   Same as Standard, but replaces current navigation entry in the history.
+// InitialInChildFrame:
+//   Used in the first load for a subframe.
+// InitialHistoryLoad:
+//   Used in history navigation in a newly created frame.
+// ReloadBypassingCache:
+//   Bypasses any caches, memory and disk cache in the browser, and caches in
+//   proxy servers, to fetch fresh contents directly from the end server.
+//   Used in Shift-Reload.
 enum class WebFrameLoadType {
     Standard,
     BackForward,
     Reload,
-    Same, // user loads same URL again (but not reload button)
+    ReloadMainResource,
     ReplaceCurrentItem,
     InitialInChildFrame,
-    InitialHistoryLoad, // history navigation in a newly created frame
-    ReloadBypassingCache, // super reload
+    InitialHistoryLoad,
+    ReloadBypassingCache,
 };
 
 } // namespace blink
diff --git a/third_party/brotli/README.chromium b/third_party/brotli/README.chromium
index 52115cd..15cb9eb 100644
--- a/third_party/brotli/README.chromium
+++ b/third_party/brotli/README.chromium
@@ -1,6 +1,6 @@
 Name: Brotli
 URL: https://github.com/google/brotli
-Version: 45f130ac4c5d2abf13e0ed1e9a3e08369c6b9c34
+Version: 4cc756ec0a986db7df0a686f4f3f2a6dddb1af96
 License: MIT
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/brotli/dec/decode.c b/third_party/brotli/dec/decode.c
index d5abd6ed..acf0385 100644
--- a/third_party/brotli/dec/decode.c
+++ b/third_party/brotli/dec/decode.c
@@ -26,7 +26,7 @@
 extern "C" {
 #endif
 
-#define BROTLI_FAILURE() (BROTLI_DUMP(), BROTLI_RESULT_ERROR)
+#define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE)
 
 #define BROTLI_LOG_UINT(name)                                       \
   BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)))
@@ -74,6 +74,7 @@
     return 0;
   }
   BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque);
+  state->error_code = BROTLI_NO_ERROR;
   return state;
 }
 
@@ -89,6 +90,18 @@
   }
 }
 
+/* Saves error code and converts it to BrotliResult */
+static BROTLI_NOINLINE BrotliResult SaveErrorCode(
+    BrotliState* s, BrotliErrorCode e) {
+  s->error_code = (int)e;
+  switch (e) {
+    case BROTLI_SUCCESS: return BROTLI_RESULT_SUCCESS;
+    case BROTLI_NEEDS_MORE_INPUT: return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    case BROTLI_NEEDS_MORE_OUTPUT: return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    default: return BROTLI_RESULT_ERROR;
+  }
+}
+
 /* Decodes a number in the range [9..24], by reading 1 - 7 bits.
    Precondition: bit-reader accumulator has at least 7 bits. */
 static uint32_t DecodeWindowBits(BrotliBitReader* br) {
@@ -119,29 +132,29 @@
 }
 
 /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
-static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s,
+static BROTLI_NOINLINE BrotliErrorCode DecodeVarLenUint8(BrotliState* s,
     BrotliBitReader* br, uint32_t* value) {
   uint32_t bits;
   switch (s->substate_decode_uint8) {
     case BROTLI_STATE_DECODE_UINT8_NONE:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits == 0) {
         *value = 0;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       /* No break, transit to the next state. */
 
     case BROTLI_STATE_DECODE_UINT8_SHORT:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits == 0) {
         *value = 1;
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       /* Use output value as a temporary storage. It MUST be persisted. */
       *value = bits;
@@ -150,27 +163,27 @@
     case BROTLI_STATE_DECODE_UINT8_LONG:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       *value = (1U << *value) + bits;
       s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
 
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_1);
   }
 }
 
 /* Decodes a metablock length and flags by reading 2 - 31 bits. */
-static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
-                                                          BrotliBitReader* br) {
+static BrotliErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
+    BrotliState* s, BrotliBitReader* br) {
   uint32_t bits;
   int i;
   for (;;) {
     switch (s->substate_metablock_header) {
       case BROTLI_STATE_METABLOCK_HEADER_NONE:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->is_last_metablock = (uint8_t)bits;
         s->meta_block_remaining_len = 0;
@@ -185,18 +198,18 @@
 
       case BROTLI_STATE_METABLOCK_HEADER_EMPTY:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits) {
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-          return BROTLI_RESULT_SUCCESS;
+          return BROTLI_SUCCESS;
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_NIBBLES:
         if (!BrotliSafeReadBits(br, 2, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->size_nibbles = (uint8_t)(bits + 4);
         s->loop_counter = 0;
@@ -213,10 +226,10 @@
         for (; i < s->size_nibbles; ++i) {
           if (!BrotliSafeReadBits(br, 4, &bits)) {
             s->loop_counter = i;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           if (i + 1 == s->size_nibbles && s->size_nibbles > 4 && bits == 0) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_NIBBLE);
           }
           s->meta_block_remaining_len |= (int)(bits << (i * 4));
         }
@@ -227,31 +240,31 @@
       case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED:
         if (!s->is_last_metablock) {
           if (!BrotliSafeReadBits(br, 1, &bits)) {
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           s->is_uncompressed = (uint8_t)bits;
         }
         ++s->meta_block_remaining_len;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
 
       case BROTLI_STATE_METABLOCK_HEADER_RESERVED:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits != 0) {
-          return BROTLI_FAILURE();
+          return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_RESERVED);
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_BYTES:
         if (!BrotliSafeReadBits(br, 2, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits == 0) {
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-          return BROTLI_RESULT_SUCCESS;
+          return BROTLI_SUCCESS;
         }
         s->size_nibbles = (uint8_t)bits;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA;
@@ -262,19 +275,19 @@
         for (; i < s->size_nibbles; ++i) {
           if (!BrotliSafeReadBits(br, 8, &bits)) {
             s->loop_counter = i;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           if (i + 1 == s->size_nibbles && s->size_nibbles > 1 && bits == 0) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
           }
           s->meta_block_remaining_len |= (int)(bits << (i * 8));
         }
         ++s->meta_block_remaining_len;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
 
       default:
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_2);
     }
   }
 }
@@ -406,8 +419,8 @@
    Totally 1..4 symbols are read, 1..10 bits each.
    The list of symbols MUST NOT contain duplicates.
  */
-static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
-                                             BrotliState* s) {
+static BrotliErrorCode ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
+                                                BrotliState* s) {
   /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */
   BrotliBitReader* br = &s->br;
   uint32_t max_bits = Log2Floor(alphabet_size - 1);
@@ -418,10 +431,10 @@
     if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
       s->sub_loop_counter = i;
       s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     if (v >= alphabet_size) {
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
     }
     s->symbols_lists_array[i] = (uint16_t)v;
     BROTLI_LOG_UINT(s->symbols_lists_array[i]);
@@ -432,12 +445,12 @@
     uint32_t k = i + 1;
     for (; k <= num_symbols; ++k) {
       if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
       }
     }
   }
 
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Process single decoded symbol code length:
@@ -518,7 +531,7 @@
 }
 
 /* Reads and decodes symbol codelengths. */
-static BrotliResult ReadSymbolCodeLengths(
+static BrotliErrorCode ReadSymbolCodeLengths(
     uint32_t alphabet_size, BrotliState* s) {
   BrotliBitReader* br = &s->br;
   uint32_t symbol = s->symbol;
@@ -530,7 +543,7 @@
   uint16_t* code_length_histo = s->code_length_histo;
   int* next_symbol = s->next_symbol;
   if (!BrotliWarmupBitReader(br)) {
-    return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    return BROTLI_NEEDS_MORE_INPUT;
   }
   while (symbol < alphabet_size && space > 0) {
     const HuffmanCode* p = s->table;
@@ -541,7 +554,7 @@
       s->prev_code_len = prev_code_len;
       s->repeat_code_len = repeat_code_len;
       s->space = space;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     BrotliFillBitWindow16(br);
     p += BrotliGetBitsUnmasked(br) &
@@ -561,10 +574,10 @@
     }
   }
   s->space = space;
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
-static BrotliResult SafeReadSymbolCodeLengths(
+static BrotliErrorCode SafeReadSymbolCodeLengths(
     uint32_t alphabet_size, BrotliState* s) {
   BrotliBitReader* br = &s->br;
   while (s->symbol < alphabet_size && s->space > 0) {
@@ -597,15 +610,15 @@
 
 pullMoreInput:
     if (!BrotliPullByte(br)) {
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Reads and decodes 15..18 codes using static prefix code.
    Each code is 2..4 bits long. In total 30..72 bits are used. */
-static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
+static BrotliErrorCode ReadCodeLengthCodeLengths(BrotliState* s) {
   BrotliBitReader* br = &s->br;
   uint32_t num_codes = s->repeat;
   unsigned space = s->space;
@@ -626,7 +639,7 @@
         s->repeat = num_codes;
         s->space = space;
         s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
     }
     v = kCodeLengthPrefixValue[ix];
@@ -644,9 +657,9 @@
     }
   }
   if (!(num_codes == 1 || space == 0)) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CL_SPACE);
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Decodes the Huffman tables.
@@ -661,10 +674,10 @@
     B.2) Decoded table is used to decode code lengths of symbols in resulting
          Huffman table. In worst case 3520 bits are read.
 */
-static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
-                                    HuffmanCode* table,
-                                    uint32_t* opt_table_size,
-                                    BrotliState* s) {
+static BrotliErrorCode ReadHuffmanCode(uint32_t alphabet_size,
+                                       HuffmanCode* table,
+                                       uint32_t* opt_table_size,
+                                       BrotliState* s) {
   BrotliBitReader* br = &s->br;
   /* Unnecessary masking, but might be good for safety. */
   alphabet_size &= 0x3ff;
@@ -672,7 +685,7 @@
   switch (s->substate_huffman) {
     case BROTLI_STATE_HUFFMAN_NONE:
       if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       BROTLI_LOG_UINT(s->sub_loop_counter);
       /* The value is used as follows:
@@ -694,13 +707,13 @@
       /* Read symbols, codes & code lengths directly. */
       if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
         s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       s->sub_loop_counter = 0;
       /* No break, transit to the next state. */
     case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
-      BrotliResult result = ReadSimpleHuffmanSymbols(alphabet_size, s);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      BrotliErrorCode result = ReadSimpleHuffmanSymbols(alphabet_size, s);
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       /* No break, transit to the next state. */
@@ -711,7 +724,7 @@
         uint32_t bits;
         if (!BrotliSafeReadBits(br, 1, &bits)) {
           s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->symbol += bits;
       }
@@ -722,14 +735,14 @@
         *opt_table_size = table_size;
       }
       s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
 
 Complex: /* Decode Huffman-coded code lengths. */
     case BROTLI_STATE_HUFFMAN_COMPLEX: {
       uint32_t i;
-      BrotliResult result = ReadCodeLengthCodeLengths(s);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      BrotliErrorCode result = ReadCodeLengthCodeLengths(s);
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       BrotliBuildCodeLengthsHuffmanTable(s->table,
@@ -751,17 +764,17 @@
     }
     case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
       uint32_t table_size;
-      BrotliResult result = ReadSymbolCodeLengths(alphabet_size, s);
-      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+      BrotliErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);
+      if (result == BROTLI_NEEDS_MORE_INPUT) {
         result = SafeReadSymbolCodeLengths(alphabet_size, s);
       }
-      if (result != BROTLI_RESULT_SUCCESS) {
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
 
       if (s->space != 0) {
         BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_HUFFMAN_SPACE);
       }
       table_size = BrotliBuildHuffmanTable(
           table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
@@ -769,11 +782,11 @@
         *opt_table_size = table_size;
       }
       s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
 
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_3);
   }
 }
 
@@ -867,8 +880,8 @@
 }
 
 /* Decodes a series of Huffman table using ReadHuffmanCode function. */
-static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
-                                           BrotliState* s) {
+static BrotliErrorCode HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
+                                              BrotliState* s) {
   if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
     s->next = group->codes;
     s->htree_index = 0;
@@ -876,15 +889,15 @@
   }
   while (s->htree_index < group->num_htrees) {
     uint32_t table_size;
-    BrotliResult result =
+    BrotliErrorCode result =
         ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
-    if (result != BROTLI_RESULT_SUCCESS) return result;
+    if (result != BROTLI_SUCCESS) return result;
     group->htrees[s->htree_index] = s->next;
     s->next += table_size;
     ++s->htree_index;
   }
   s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Decodes a context map.
@@ -896,17 +909,17 @@
     3) Read context map items; "0" values could be run-length encoded.
     4) Optionally, apply InverseMoveToFront transform to the resulting map.
  */
-static BrotliResult DecodeContextMap(uint32_t context_map_size,
-                                     uint32_t* num_htrees,
-                                     uint8_t** context_map_arg,
-                                     BrotliState* s) {
+static BrotliErrorCode DecodeContextMap(uint32_t context_map_size,
+                                        uint32_t* num_htrees,
+                                        uint8_t** context_map_arg,
+                                        BrotliState* s) {
   BrotliBitReader* br = &s->br;
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
 
   switch ((int)s->substate_context_map) {
     case BROTLI_STATE_CONTEXT_MAP_NONE:
       result = DecodeVarLenUint8(s, br, num_htrees);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       (*num_htrees)++;
@@ -915,11 +928,11 @@
       BROTLI_LOG_UINT(*num_htrees);
       *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size);
       if (*context_map_arg == 0) {
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MAP);
       }
       if (*num_htrees <= 1) {
         memset(*context_map_arg, 0, (size_t)context_map_size);
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
       /* No break, continue to next state. */
@@ -928,7 +941,7 @@
       /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
          to peek 4 bits ahead. */
       if (!BrotliSafeGetBits(br, 5, &bits)) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if ((bits & 1) != 0) { /* Use RLE for zeroes. */
         s->max_run_length_prefix = (bits >> 1) + 1;
@@ -944,7 +957,7 @@
     case BROTLI_STATE_CONTEXT_MAP_HUFFMAN:
       result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,
                                s->context_map_table, NULL, s);
-      if (result != BROTLI_RESULT_SUCCESS) return result;
+      if (result != BROTLI_SUCCESS) return result;
       s->code = 0xFFFF;
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
       /* No break, continue to next state. */
@@ -960,7 +973,7 @@
         if (!SafeReadSymbol(s->context_map_table, br, &code)) {
           s->code = 0xFFFF;
           s->context_index = context_index;
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         BROTLI_LOG_UINT(code);
 
@@ -979,12 +992,12 @@
           if (!BrotliSafeReadBits(br, code, &reps)) {
             s->code = code;
             s->context_index = context_index;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           reps += 1U << code;
           BROTLI_LOG_UINT(reps);
           if (context_index + reps > context_map_size) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CONTEXT_MAP_REPEAT);
           }
           do {
             context_map[context_index++] = 0;
@@ -997,16 +1010,16 @@
       uint32_t bits;
       if (!BrotliSafeReadBits(br, 1, &bits)) {
         s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits != 0) {
         InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_4);
   }
 }
 
@@ -1119,8 +1132,8 @@
   return DecodeDistanceBlockSwitchInternal(1, s);
 }
 
-static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
-    size_t* total_out, BrotliState* s) {
+static BrotliErrorCode BROTLI_NOINLINE WriteRingBuffer(size_t* available_out,
+    uint8_t** next_out, size_t* total_out, BrotliState* s) {
   size_t pos = (s->pos > s->ringbuffer_size) ? (size_t)s->ringbuffer_size
                                              : (size_t)(s->pos);
   uint8_t* start =
@@ -1132,7 +1145,7 @@
     num_written = to_write;
   }
   if (s->meta_block_remaining_len < 0) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_1);
   }
   memcpy(*next_out, start, num_written);
   *next_out += num_written;
@@ -1142,9 +1155,14 @@
   s->partial_pos_out += num_written;
   *total_out = s->partial_pos_out;
   if (num_written < to_write) {
-    return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    return BROTLI_NEEDS_MORE_OUTPUT;
   }
-  return BROTLI_RESULT_SUCCESS;
+
+  if (s->pos >= s->ringbuffer_size) {
+    s->pos -= s->ringbuffer_size;
+    s->rb_roundtrips++;
+  }
+  return BROTLI_SUCCESS;
 }
 
 /* Allocates ringbuffer.
@@ -1181,12 +1199,12 @@
   return 1;
 }
 
-static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
+static BrotliErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
     size_t* available_out, uint8_t** next_out, size_t* total_out,
     BrotliState* s) {
   /* TODO: avoid allocation for single uncompressed block. */
   if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_1);
   }
 
   /* State machine */
@@ -1206,21 +1224,19 @@
         s->meta_block_remaining_len -= nbytes;
         if (s->pos < s->ringbuffer_size) {
           if (s->meta_block_remaining_len == 0) {
-            return BROTLI_RESULT_SUCCESS;
+            return BROTLI_SUCCESS;
           }
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
         /* No break, continue to next state */
       }
       case BROTLI_STATE_UNCOMPRESSED_WRITE: {
-        BrotliResult result =
+        BrotliErrorCode result =
             WriteRingBuffer(available_out, next_out, total_out, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           return result;
         }
-        s->pos = 0;
-        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
         break;
@@ -1242,7 +1258,7 @@
     return 0;
   }
   DecodeWindowBits(&s.br);
-  if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_RESULT_SUCCESS) {
+  if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_SUCCESS) {
     return 0;
   }
   *decoded_size = (size_t)s.meta_block_remaining_len;
@@ -1292,7 +1308,7 @@
 }
 
 /* Reads 1..256 2-bit context modes. */
-static BrotliResult ReadContextModes(BrotliState* s) {
+static BrotliErrorCode ReadContextModes(BrotliState* s) {
   BrotliBitReader* br = &s->br;
   int i = s->loop_counter;
 
@@ -1300,13 +1316,13 @@
     uint32_t bits;
     if (!BrotliSafeReadBits(br, 2, &bits)) {
       s->loop_counter = i;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     s->context_modes[i] = (uint8_t)(bits << 1);
     BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
     i++;
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliState* s) {
@@ -1470,27 +1486,27 @@
   return BrotliCheckInputAmount(br, num);
 }
 
-#define BROTLI_SAFE(METHOD)                      \
-  {                                              \
-    if (safe) {                                  \
-      if (!Safe##METHOD) {                       \
-        result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
-        goto saveStateAndReturn;                 \
-      }                                          \
-    } else {                                     \
-      METHOD;                                    \
-    }                                            \
+#define BROTLI_SAFE(METHOD)               \
+  {                                       \
+    if (safe) {                           \
+      if (!Safe##METHOD) {                \
+        result = BROTLI_NEEDS_MORE_INPUT; \
+        goto saveStateAndReturn;          \
+      }                                   \
+    } else {                              \
+      METHOD;                             \
+    }                                     \
   }
 
-static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
+static BROTLI_INLINE BrotliErrorCode ProcessCommandsInternal(int safe,
     BrotliState* s) {
   int pos = s->pos;
   int i = s->loop_counter;
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
   BrotliBitReader* br = &s->br;
 
   if (!CheckInputAmount(safe, br, 28)) {
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     goto saveStateAndReturn;
   }
   if (!safe) {
@@ -1507,7 +1523,7 @@
   } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
     goto CommandPostWrapCopy;
   } else {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_5);
   }
 
 CommandBegin:
@@ -1516,7 +1532,7 @@
   }
   if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */
     s->state = BROTLI_STATE_COMMAND_BEGIN;
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     goto saveStateAndReturn;
   }
   if (PREDICT_FALSE(s->block_length[1] == 0)) {
@@ -1544,7 +1560,7 @@
     do {
       if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
         s->state = BROTLI_STATE_COMMAND_INNER;
-        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        result = BROTLI_NEEDS_MORE_INPUT;
         goto saveStateAndReturn;
       }
       if (PREDICT_FALSE(s->block_length[0] == 0)) {
@@ -1557,7 +1573,7 @@
       } else {
         uint32_t literal;
         if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           goto saveStateAndReturn;
         }
         s->ringbuffer[pos] = (uint8_t)literal;
@@ -1580,7 +1596,7 @@
       uint8_t context;
       if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
         s->state = BROTLI_STATE_COMMAND_INNER;
-        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        result = BROTLI_NEEDS_MORE_INPUT;
         goto saveStateAndReturn;
       }
       if (PREDICT_FALSE(s->block_length[0] == 0)) {
@@ -1595,7 +1611,7 @@
       } else {
         uint32_t literal;
         if (!SafeReadSymbol(hc, br, &literal)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           goto saveStateAndReturn;
         }
         p1 = (uint8_t)literal;
@@ -1675,13 +1691,13 @@
         BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
             "len: %d bytes left: %d\n",
             pos, s->distance_code, i, s->meta_block_remaining_len));
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_TRANSFORM);
       }
     } else {
       BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
           "len: %d bytes left: %d\n",
           pos, s->distance_code, i, s->meta_block_remaining_len));
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_DICTIONARY);
     }
   } else {
     int src_start = (pos - s->distance_code) & s->ringbuffer_mask;
@@ -1697,7 +1713,7 @@
       BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
           "len: %d bytes left: %d\n",
           pos, s->distance_code, i, s->meta_block_remaining_len));
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_2);
     }
     /* There are 32+ bytes of slack in the ringbuffer allocation.
        Also, we have 16 short codes, that make these 16 bytes irrelevant
@@ -1760,11 +1776,11 @@
 
 #undef BROTLI_SAFE
 
-static BROTLI_NOINLINE BrotliResult ProcessCommands(BrotliState* s) {
+static BROTLI_NOINLINE BrotliErrorCode ProcessCommands(BrotliState* s) {
   return ProcessCommandsInternal(0, s);
 }
 
-static BROTLI_NOINLINE BrotliResult SafeProcessCommands(BrotliState* s) {
+static BROTLI_NOINLINE BrotliErrorCode SafeProcessCommands(BrotliState* s) {
   return ProcessCommandsInternal(1, s);
 }
 
@@ -1805,7 +1821,7 @@
 BrotliResult BrotliDecompressStream(size_t* available_in,
     const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
     size_t* total_out, BrotliState* s) {
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
   BrotliBitReader* br = &s->br;
   if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
     br->avail_in = *available_in;
@@ -1814,13 +1830,13 @@
     /* At least one byte of input is required. More than one byte of input may
        be required to complete the transaction -> reading more data must be
        done in a loop -> do it in a main loop. */
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     br->next_in = &s->buffer.u8[0];
   }
   /* State machine */
   for (;;) {
-    if (result != BROTLI_RESULT_SUCCESS) { /* Error | needs more input/output */
-      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+    if (result != BROTLI_SUCCESS) { /* Error | needs more input/output */
+      if (result == BROTLI_NEEDS_MORE_INPUT) {
         if (s->ringbuffer != 0) { /* Proactively push output. */
           WriteRingBuffer(available_out, next_out, total_out, s);
         }
@@ -1830,14 +1846,14 @@
                is expanded byte-by-byte until it is enough to complete read. */
             s->buffer_length = 0;
             /* Switch to input stream and restart. */
-            result = BROTLI_RESULT_SUCCESS;
+            result = BROTLI_SUCCESS;
             br->avail_in = *available_in;
             br->next_in = *next_in;
             continue;
           } else if (*available_in != 0) {
             /* Not enough data in buffer, but can take one more byte from
                input stream. */
-            result = BROTLI_RESULT_SUCCESS;
+            result = BROTLI_SUCCESS;
             s->buffer.u8[s->buffer_length] = **next_in;
             s->buffer_length++;
             br->avail_in = s->buffer_length;
@@ -1883,7 +1899,7 @@
       case BROTLI_STATE_UNINITED:
         /* Prepare to the first read. */
         if (!BrotliWarmupBitReader(br)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         /* Decode window size. */
@@ -1891,7 +1907,7 @@
         BROTLI_LOG_UINT(s->window_bits);
         if (s->window_bits == 9) {
           /* Value 9 is reserved for future use. */
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_WINDOW_BITS);
           break;
         }
         /* Maximum distance, see section 9.1. of the spec. */
@@ -1909,7 +1925,7 @@
             sizeof(HuffmanCode) * 3 *
                 (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26));
         if (s->block_type_trees == 0) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_BLOCK_TYPE_TREES);
           break;
         }
         s->block_len_trees =
@@ -1924,7 +1940,7 @@
         /* No break, continue to next state */
       case BROTLI_STATE_METABLOCK_HEADER:
         result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         BROTLI_LOG_UINT(s->is_last_metablock);
@@ -1933,7 +1949,7 @@
         BROTLI_LOG_UINT(s->is_uncompressed);
         if (s->is_metadata || s->is_uncompressed) {
           if (!BrotliJumpToByteBoundary(br)) {
-            result = BROTLI_FAILURE();
+            result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_1);
             break;
           }
         }
@@ -1960,7 +1976,7 @@
         result = CopyUncompressedBlockToOutput(
             available_out, next_out, total_out, s);
         bytes_copied -= s->meta_block_remaining_len;
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->state = BROTLI_STATE_METABLOCK_DONE;
@@ -1971,11 +1987,11 @@
           uint32_t bits;
           /* Read one byte and ignore it. */
           if (!BrotliSafeReadBits(br, 8, &bits)) {
-            result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+            result = BROTLI_NEEDS_MORE_INPUT;
             break;
           }
         }
-        if (result == BROTLI_RESULT_SUCCESS) {
+        if (result == BROTLI_SUCCESS) {
           s->state = BROTLI_STATE_METABLOCK_DONE;
         }
         break;
@@ -1986,7 +2002,7 @@
         }
         /* Reads 1..11 bits. */
         result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->num_block_types[s->loop_counter]++;
@@ -2001,7 +2017,7 @@
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
         result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2,
             &s->block_type_trees[tree_offset], NULL, s);
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->state = BROTLI_STATE_HUFFMAN_CODE_2;
         /* No break, continue to next state */
       }
@@ -2009,7 +2025,7 @@
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
         result = ReadHuffmanCode(kNumBlockLengthCodes,
             &s->block_len_trees[tree_offset], NULL, s);
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->state = BROTLI_STATE_HUFFMAN_CODE_3;
         /* No break, continue to next state */
       }
@@ -2017,7 +2033,7 @@
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
         if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter],
             &s->block_len_trees[tree_offset], br)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         BROTLI_LOG_UINT(s->block_length[s->loop_counter]);
@@ -2028,7 +2044,7 @@
       case BROTLI_STATE_METABLOCK_HEADER_2: {
         uint32_t bits;
         if (!BrotliSafeReadBits(br, 6, &bits)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         s->distance_postfix_bits = bits & BitMask(2);
@@ -2041,7 +2057,7 @@
         s->context_modes =
             (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]);
         if (s->context_modes == 0) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MODES);
           break;
         }
         s->loop_counter = 0;
@@ -2050,7 +2066,7 @@
       }
       case BROTLI_STATE_CONTEXT_MODES:
         result = ReadContextModes(s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->state = BROTLI_STATE_CONTEXT_MAP_1;
@@ -2059,7 +2075,7 @@
         uint32_t j;
         result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits,
                                   &s->num_literal_htrees, &s->context_map, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->trivial_literal_context = 1;
@@ -2079,7 +2095,7 @@
           result = DecodeContextMap(
               s->num_block_types[2] << kDistanceContextBits,
               &s->num_dist_htrees, &s->dist_context_map, s);
-          if (result != BROTLI_RESULT_SUCCESS) {
+          if (result != BROTLI_SUCCESS) {
             break;
           }
           BrotliHuffmanTreeGroupInit(s, &s->literal_hgroup, kNumLiteralCodes,
@@ -2092,7 +2108,8 @@
           if (s->literal_hgroup.codes == 0 ||
               s->insert_copy_hgroup.codes == 0 ||
               s->distance_hgroup.codes == 0) {
-            return BROTLI_FAILURE();
+            return SaveErrorCode(s,
+                BROTLI_FAILURE(BROTLI_ERROR_ALLOC_TREE_GROUPS));
           }
         }
         s->loop_counter = 0;
@@ -2112,11 +2129,12 @@
               hgroup = &s->distance_hgroup;
               break;
             default:
-              return BROTLI_FAILURE();
+              return SaveErrorCode(s,
+                  BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE_6));
           }
           result = HuffmanTreeGroupDecode(hgroup, s);
         }
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->loop_counter++;
         if (s->loop_counter >= 3) {
           uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
@@ -2129,7 +2147,7 @@
           s->htree_command = s->insert_copy_hgroup.htrees[0];
           s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
           if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
-            result = BROTLI_FAILURE();
+            result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_2);
             break;
           }
           s->state = BROTLI_STATE_COMMAND_BEGIN;
@@ -2140,7 +2158,7 @@
       case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS:
       case BROTLI_STATE_COMMAND_POST_WRAP_COPY:
         result = ProcessCommands(s);
-        if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+        if (result == BROTLI_NEEDS_MORE_INPUT) {
           result = SafeProcessCommands(s);
         }
         break;
@@ -2148,11 +2166,9 @@
       case BROTLI_STATE_COMMAND_POST_WRITE_1:
       case BROTLI_STATE_COMMAND_POST_WRITE_2:
         result = WriteRingBuffer(available_out, next_out, total_out, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
-        s->pos -= s->ringbuffer_size;
-        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
         if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
           memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
@@ -2184,7 +2200,8 @@
           break;
         }
         if (!BrotliJumpToByteBoundary(br)) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_2);
+          break;
         }
         if (s->buffer_length == 0) {
           BrotliBitReaderUnload(br);
@@ -2196,14 +2213,14 @@
       case BROTLI_STATE_DONE:
         if (s->ringbuffer != 0) {
           result = WriteRingBuffer(available_out, next_out, total_out, s);
-          if (result != BROTLI_RESULT_SUCCESS) {
+          if (result != BROTLI_SUCCESS) {
             break;
           }
         }
-        return result;
+        return SaveErrorCode(s, result);
     }
   }
-  return result;
+  return SaveErrorCode(s, result);
 }
 
 void BrotliSetCustomDictionary(
@@ -2215,6 +2232,9 @@
   s->custom_dict_size = (int)size;
 }
 
+BrotliErrorCode BrotliGetErrorCode(const BrotliState* s) {
+  return (BrotliErrorCode)s->error_code;
+}
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }  /* extern "C" */
diff --git a/third_party/brotli/dec/decode.h b/third_party/brotli/dec/decode.h
index 4a7bcd1..51a49784 100644
--- a/third_party/brotli/dec/decode.h
+++ b/third_party/brotli/dec/decode.h
@@ -28,6 +28,51 @@
   BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
 } BrotliResult;
 
+typedef enum {
+  BROTLI_NO_ERROR = 0,
+  /* Same as BrotliResult values */
+  BROTLI_SUCCESS = 1,
+  BROTLI_NEEDS_MORE_INPUT = 2,
+  BROTLI_NEEDS_MORE_OUTPUT = 3,
+
+  /* Errors caused by invalid input */
+  BROTLI_ERROR_FORMAT_EXUBERANT_NIBBLE = -1,
+  BROTLI_ERROR_FORMAT_RESERVED = -2,
+  BROTLI_ERROR_FORMAT_EXUBERANT_META_NIBBLE = -3,
+  BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET = -4,
+  BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME = -5,
+  BROTLI_ERROR_FORMAT_CL_SPACE = -6,
+  BROTLI_ERROR_FORMAT_HUFFMAN_SPACE = -7,
+  BROTLI_ERROR_FORMAT_CONTEXT_MAP_REPEAT = -8,
+  BROTLI_ERROR_FORMAT_BLOCK_LENGTH_1 = -9,
+  BROTLI_ERROR_FORMAT_BLOCK_LENGTH_2 = -10,
+  BROTLI_ERROR_FORMAT_TRANSFORM = -11,
+  BROTLI_ERROR_FORMAT_DICTIONARY = -12,
+  BROTLI_ERROR_FORMAT_WINDOW_BITS = -13,
+  BROTLI_ERROR_FORMAT_PADDING_1 = -14,
+  BROTLI_ERROR_FORMAT_PADDING_2 = -15,
+
+  /* -16..-20 codes are reserved */
+
+  /* Memory allocation problems */
+  BROTLI_ERROR_ALLOC_CONTEXT_MODES = -21,
+  BROTLI_ERROR_ALLOC_TREE_GROUPS = -22,  /* Literal, insert, distance */
+  /* -23..-24 codes are reserved for distinct tree groups */
+  BROTLI_ERROR_ALLOC_CONTEXT_MAP = -25,
+  BROTLI_ERROR_ALLOC_RING_BUFFER_1 = -26,
+  BROTLI_ERROR_ALLOC_RING_BUFFER_2 = -27,
+  /* -28..-29 codes are reserved for dynamic ringbuffer allocation */
+  BROTLI_ERROR_ALLOC_BLOCK_TYPE_TREES = -30,
+
+  /* "Impossible" states */
+  BROTLI_ERROR_UNREACHABLE_1 = -31,
+  BROTLI_ERROR_UNREACHABLE_2 = -32,
+  BROTLI_ERROR_UNREACHABLE_3 = -33,
+  BROTLI_ERROR_UNREACHABLE_4 = -34,
+  BROTLI_ERROR_UNREACHABLE_5 = -35,
+  BROTLI_ERROR_UNREACHABLE_6 = -36
+} BrotliErrorCode;
+
 /* Creates the instance of BrotliState and initializes it. |alloc_func| and
    |free_func| MUST be both zero or both non-zero. In the case they are both
    zero, default memory allocators are used. |opaque| is passed to |alloc_func|
@@ -98,6 +143,10 @@
    produced all of the output, and 0 otherwise. */
 int BrotliStateIsStreamEnd(const BrotliState* s);
 
+/* Returns detailed error code after BrotliDecompressStream returns
+   BROTLI_RESULT_ERROR. */
+BrotliErrorCode BrotliGetErrorCode(const BrotliState* s);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 } /* extern "C" */
 #endif
diff --git a/third_party/brotli/dec/state.h b/third_party/brotli/dec/state.h
index d85239e..f8e1259 100644
--- a/third_party/brotli/dec/state.h
+++ b/third_party/brotli/dec/state.h
@@ -120,6 +120,8 @@
   int ringbuffer_mask;
   int dist_rb_idx;
   int dist_rb[4];
+  int error_code;
+  uint32_t sub_loop_counter;
   uint8_t* ringbuffer;
   uint8_t* ringbuffer_end;
   HuffmanCode* htree_command;
@@ -128,8 +130,6 @@
   uint8_t* context_map_slice;
   uint8_t* dist_context_map_slice;
 
-  uint32_t sub_loop_counter;
-
   /* This ring buffer holds a few past copy distances that will be used by */
   /* some special distance codes. */
   HuffmanTreeGroup literal_hgroup;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 36178b0c..1d29873 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -34459,6 +34459,9 @@
 
 <histogram name="OfflinePages.Edit.BookmarkUrlChangedForOfflinePage"
     enum="BooleanMatched">
+  <obsolete>
+    Deprecated 5/2016. Offline pages no longer depend on bookmarks UI.
+  </obsolete>
   <owner>dougarnett@chromium.org</owner>
   <summary>
     Whether a user-edited bookmark URL had a saved offline page.
@@ -34466,6 +34469,9 @@
 </histogram>
 
 <histogram name="OfflinePages.Filter.OnlineWhenEntering" enum="Boolean">
+  <obsolete>
+    Deprecated 5/2016. Offline pages no longer depend on bookmarks UI.
+  </obsolete>
   <owner>fgorski@chromium.org</owner>
   <owner>jianli@chromium.org</owner>
   <summary>
@@ -34475,6 +34481,9 @@
 </histogram>
 
 <histogram name="OfflinePages.Filter.OnlineWhenLeaving" enum="Boolean">
+  <obsolete>
+    Deprecated 5/2016. Offline pages no longer depend on bookmarks UI.
+  </obsolete>
   <owner>fgorski@chromium.org</owner>
   <owner>jianli@chromium.org</owner>
   <summary>
@@ -34491,6 +34500,9 @@
 </histogram>
 
 <histogram name="OfflinePages.IncognitoSave" enum="Boolean">
+  <obsolete>
+    Deprecated 5/2016. Not longer needed.
+  </obsolete>
   <owner>jianli@chromium.org</owner>
   <summary>
     Whether the page that was being saved offline was in incognito mode.
@@ -34498,6 +34510,9 @@
 </histogram>
 
 <histogram name="OfflinePages.LaunchLocation" enum="StarsLaunchLocation">
+  <obsolete>
+    Deprecated 5/2016. Offline pages no longer depend on bookmarks UI.
+  </obsolete>
   <owner>fgorski@chromium.org</owner>
   <owner>jianli@chromium.org</owner>
   <summary>Logs a UI location from which an offline page is launched.</summary>
@@ -34538,12 +34553,18 @@
 </histogram>
 
 <histogram name="OfflinePages.OfflinePageCount">
+  <obsolete>
+    Deprecated 5/2016. This was the dup of OfflinePages.SavedPageCount.
+  </obsolete>
   <owner>fgorski@chromium.org</owner>
   <owner>jianli@chromium.org</owner>
   <summary>Number of offline pages the user has. Android only.</summary>
 </histogram>
 
 <histogram name="OfflinePages.OnlineOnOpen" enum="Boolean">
+  <obsolete>
+    Deprecated 5/2016. Offline pages no longer depend on bookmarks UI.
+  </obsolete>
   <owner>jianli@chromium.org</owner>
   <summary>
     Whether the user was online when a saved page with offline copy was opened.
@@ -34627,6 +34648,14 @@
   <summary>Whether a shared page was an offline page or not.</summary>
 </histogram>
 
+<histogram name="OfflinePages.ShowOfflinePageOnBadNetwork" enum="Boolean">
+  <owner>jianli@chromium.org</owner>
+  <summary>
+    Whether an offline page is shown, instead of error page, when the network is
+    disconnected or poor condition.
+  </summary>
+</histogram>
+
 <histogram name="OfflinePages.TotalPageSize" units="MB">
   <owner>fgorski@chromium.org</owner>
   <owner>jianli@chromium.org</owner>
@@ -59833,10 +59862,7 @@
 </histogram>
 
 <histogram name="WebCore.PreloadDelayMs" units="ms">
-  <obsolete>
-    Removed in April 2016, due to lack of use.
-  </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>csharrison@chromium.org</owner>
   <summary>
     The delay between when the preload scanner discovers a resource on the
     parser thread and when the preload request is issued on the main thread.
@@ -73014,6 +73040,9 @@
   <int value="1366" label="AudioListenerSetPosition"/>
   <int value="1367" label="AudioListenerSetOrientation"/>
   <int value="1368" label="IntersectionObserver_Constructor"/>
+  <int value="1369" label="DurableStoragePersist"/>
+  <int value="1370" label="DurableStoragePersisted"/>
+  <int value="1371" label="DurableStorageEstimate"/>
 </enum>
 
 <enum name="FetchRequestMode" type="int">
@@ -93797,6 +93826,21 @@
   <affected-histogram name="SBOffDomainInclusion2.Abort"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="OfflinePagesNamespace" separator=".">
+  <suffix name="bookmark" label="Offline bookmark cache"/>
+  <suffix name="last-n" label="Offline recent pages"/>
+  <affected-histogram name="OfflinePages.DeletePage.AccessCount"/>
+  <affected-histogram name="OfflinePages.DeletePage.LastOpenToCreated"/>
+  <affected-histogram name="OfflinePages.DeletePage.PageSize"/>
+  <affected-histogram name="OfflinePages.DeletePage.TimeSinceLastOpen"/>
+  <affected-histogram name="OfflinePages.FirstOpenSinceCreated"/>
+  <affected-histogram name="OfflinePages.OpenSinceLastOpen"/>
+  <affected-histogram name="OfflinePages.PageLifetime"/>
+  <affected-histogram name="OfflinePages.PageSize"/>
+  <affected-histogram name="OfflinePages.SavePageResult"/>
+  <affected-histogram name="OfflinePages.SavePageTime"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="OmniboxProviderTime" separator=".">
   <suffix name="Bookmark"/>
   <suffix name="Builtin"/>
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py
index 8a76a6f..ce7cf1e 100644
--- a/tools/perf/benchmarks/system_health.py
+++ b/tools/perf/benchmarks/system_health.py
@@ -72,7 +72,8 @@
   def Name(cls):
     return 'system_health.memory_%s' % cls.page_set.PLATFORM
 
-
+# https://github.com/catapult-project/catapult/issues/2340
+@benchmark.Disabled('all')
 class DesktopMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Desktop Chrome Memory System Health Benchmark."""
   page_set = page_sets.DesktopMemorySystemHealthStorySet
@@ -81,7 +82,8 @@
   def ShouldDisable(cls, possible_browser):
     return possible_browser.platform.GetDeviceTypeName() != 'Desktop'
 
-
+# https://github.com/catapult-project/catapult/issues/2340
+@benchmark.Disabled('all')
 class MobileMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Mobile Chrome Memory System Health Benchmark."""
   page_set = page_sets.MobileMemorySystemHealthStorySet
diff --git a/ui/accessibility/platform/atk_util_auralinux.cc b/ui/accessibility/platform/atk_util_auralinux.cc
index 46ad3be..98e98dff 100644
--- a/ui/accessibility/platform/atk_util_auralinux.cc
+++ b/ui/accessibility/platform/atk_util_auralinux.cc
@@ -53,7 +53,45 @@
 const char kGnomeAccessibilityEnabledKey[] =
     "/desktop/gnome/interface/accessibility";
 
-#endif
+bool PlatformShouldEnableAccessibility() {
+  GConfClient* client = gconf_client_get_default();
+  if (!client) {
+    LOG(ERROR) << "gconf_client_get_default failed";
+    return false;
+  }
+
+  GError* error = nullptr;
+  gboolean value = gconf_client_get_bool(client,
+                                         kGnomeAccessibilityEnabledKey,
+                                         &error);
+  g_object_unref(client);
+
+  if (error) {
+    VLOG(1) << "gconf_client_get_bool failed";
+    g_error_free(error);
+    return false;
+  }
+
+  return value;
+}
+
+#else  // !defined(USE_GCONF)
+
+bool PlatformShouldEnableAccessibility() {
+  // TODO(iceman): implement this for non-GNOME desktops.
+  return false;
+}
+
+#endif  // defined(USE_GCONF)
+
+bool ShouldEnableAccessibility() {
+  char* enable_accessibility = getenv(kAccessibilityEnabled);
+  if ((enable_accessibility && atoi(enable_accessibility) == 1) ||
+      PlatformShouldEnableAccessibility())
+    return true;
+
+  return false;
+}
 
 }  // namespace
 
@@ -161,6 +199,9 @@
   // Register our util class.
   g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE));
 
+  if (!ShouldEnableAccessibility())
+    return;
+
   init_task_runner->PostTaskAndReply(
       FROM_HERE,
       base::Bind(
@@ -177,33 +218,7 @@
 #if defined(USE_GCONF)
 
 void AtkUtilAuraLinux::CheckIfAccessibilityIsEnabledOnFileThread() {
-  char* enable_accessibility = getenv(kAccessibilityEnabled);
-  if ((enable_accessibility && atoi(enable_accessibility) == 1) ||
-      CheckPlatformAccessibilitySupportOnFileThread())
-    is_enabled_ = AccessibilityModuleInitOnFileThread();
-}
-
-bool AtkUtilAuraLinux::CheckPlatformAccessibilitySupportOnFileThread() {
-  GConfClient* client = gconf_client_get_default();
-  if (!client) {
-    LOG(ERROR) << "gconf_client_get_default failed";
-    return false;
-  }
-
-  GError* error = nullptr;
-  bool is_enabled = gconf_client_get_bool(client,
-                                    kGnomeAccessibilityEnabledKey,
-                                    &error);
-
-  g_object_unref(client);
-
-  if (error) {
-    VLOG(1) << "gconf_client_get_bool failed";
-    g_error_free(error);
-    return false;
-  }
-
-  return is_enabled;
+  is_enabled_ = AccessibilityModuleInitOnFileThread();
 }
 
 void AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread() {
diff --git a/ui/accessibility/platform/atk_util_auralinux.h b/ui/accessibility/platform/atk_util_auralinux.h
index 8342a129..f609109e 100644
--- a/ui/accessibility/platform/atk_util_auralinux.h
+++ b/ui/accessibility/platform/atk_util_auralinux.h
@@ -31,7 +31,6 @@
   friend struct base::DefaultSingletonTraits<AtkUtilAuraLinux>;
 
   void CheckIfAccessibilityIsEnabledOnFileThread();
-  bool CheckPlatformAccessibilitySupportOnFileThread();
   void FinishAccessibilityInitOnUIThread();
 
 #if defined(USE_GCONF)
diff --git a/ui/file_manager/file_manager/foreground/elements/elements_bundle.html b/ui/file_manager/file_manager/foreground/elements/elements_bundle.html
index 2159874..104b9c0 100644
--- a/ui/file_manager/file_manager/foreground/elements/elements_bundle.html
+++ b/ui/file_manager/file_manager/foreground/elements/elements_bundle.html
@@ -4,8 +4,6 @@
   -->
 
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/image-icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-input/iron-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-container.html">
@@ -14,3 +12,4 @@
 <link rel="import" href="files_ripple.html">
 <link rel="import" href="files_toggle_ripple.html">
 <link rel="import" href="files_tooltip.html">
+<link rel="import" href="icons.html">
diff --git a/ui/file_manager/file_manager/foreground/elements/icons.html b/ui/file_manager/file_manager/foreground/elements/icons.html
new file mode 100644
index 0000000..325c2d05
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/elements/icons.html
@@ -0,0 +1,25 @@
+<!-- Copyright 2016 The Chromium Authors. All rights reserved.
+  -- Use of this source code is governed by a BSD-style license that can be
+  -- found in the LICENSE file.
+  -->
+
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="files" size="24">
+  <svg>
+    <defs>
+      <!--
+      These icons are copied from Polymer's iron-icons and kept in sorted order.
+      See http://goo.gl/Y1OdAq for instructions on adding additional icons.
+      -->
+      <g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"/></g>
+      <g id="autorenew"><path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"/></g>
+      <g id="cloud-done"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z"/></g>
+      <g id="cloud-off"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z"/></g>
+      <g id="cloud-queue"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z"/></g>
+      <g id="cloud-upload"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"/></g>
+      <g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></g>
+    </defs>
+  </svg>
+</iron-iconset-svg>
diff --git a/ui/file_manager/file_manager/foreground/js/import_controller.js b/ui/file_manager/file_manager/foreground/js/import_controller.js
index 73b7f7c..7b5bc99 100644
--- a/ui/file_manager/file_manager/foreground/js/import_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/import_controller.js
@@ -755,8 +755,8 @@
 
       this.comboButton_.hidden = true;
 
-      this.toolbarIcon_.setAttribute('icon', 'cloud-off');
-      this.statusIcon_.setAttribute('icon', 'cloud-off');
+      this.toolbarIcon_.setAttribute('icon', 'files:cloud-off');
+      this.statusIcon_.setAttribute('icon', 'files:cloud-off');
 
       break;
 
@@ -776,8 +776,8 @@
       this.cancelButton_.hidden = false;
       this.progressContainer_.hidden = true;
 
-      this.toolbarIcon_.setAttribute('icon', 'autorenew');
-      this.statusIcon_.setAttribute('icon', 'autorenew');
+      this.toolbarIcon_.setAttribute('icon', 'files:autorenew');
+      this.statusIcon_.setAttribute('icon', 'files:autorenew');
 
       break;
 
@@ -795,8 +795,8 @@
       this.cancelButton_.hidden = true;
       this.progressContainer_.hidden = true;
 
-      this.toolbarIcon_.setAttribute('icon', 'cloud-off');
-      this.statusIcon_.setAttribute('icon', 'image:photo');
+      this.toolbarIcon_.setAttribute('icon', 'files:cloud-off');
+      this.statusIcon_.setAttribute('icon', 'files:photo');
       break;
 
     case importer.ActivityState.NO_MEDIA:
@@ -810,8 +810,8 @@
       this.cancelButton_.hidden = true;
       this.progressContainer_.hidden = true;
 
-      this.toolbarIcon_.setAttribute('icon', 'cloud-done');
-      this.statusIcon_.setAttribute('icon', 'cloud-done');
+      this.toolbarIcon_.setAttribute('icon', 'files:cloud-done');
+      this.statusIcon_.setAttribute('icon', 'files:cloud-done');
       break;
 
     case importer.ActivityState.READY:
@@ -829,8 +829,8 @@
       this.cancelButton_.hidden = true;
       this.progressContainer_.hidden = true;
 
-      this.toolbarIcon_.setAttribute('icon', 'cloud-upload');
-      this.statusIcon_.setAttribute('icon', 'image:photo');
+      this.toolbarIcon_.setAttribute('icon', 'files:cloud-upload');
+      this.statusIcon_.setAttribute('icon', 'files:photo');
       break;
 
     case importer.ActivityState.SCANNING:
@@ -851,8 +851,8 @@
       var stats = opt_scan.getStatistics();
       this.progressBar_.style.width = stats.progress + '%';
 
-      this.toolbarIcon_.setAttribute('icon', 'autorenew');
-      this.statusIcon_.setAttribute('icon', 'autorenew');
+      this.toolbarIcon_.setAttribute('icon', 'files:autorenew');
+      this.statusIcon_.setAttribute('icon', 'files:autorenew');
       break;
 
     default:
diff --git a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
index c2d639e..4e66457 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
@@ -82,7 +82,7 @@
       buttonLayer.appendChild(this.actionNode_);
 
       var triggerIcon = this.ownerDocument.createElement('iron-icon');
-      triggerIcon.setAttribute('icon', 'arrow-drop-down');
+      triggerIcon.setAttribute('icon', 'files:arrow-drop-down');
       this.trigger_ = this.ownerDocument.createElement('div');
       this.trigger_.classList.add('trigger');
       this.trigger_.appendChild(triggerIcon);
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index f02982148..fdc366dc 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -280,14 +280,14 @@
                   tabindex="15"
                   i18n-values="aria-label:CLOUD_IMPORT_COMMAND"
                   has-tooltip>
-            <iron-icon icon="cloud-queue"></iron-icon>
+            <iron-icon icon="files:cloud-queue"></iron-icon>
           </button>
           <button id="cloud-import-details-button"
                   class="icon-button"
                   tabindex="-1"
                   i18n-values="aria-label:CLOUD_IMPORT_SHOW_DETAILS"
                   has-tooltip>
-            <iron-icon icon="arrow-drop-down"></iron-icon>
+            <iron-icon icon="files:arrow-drop-down"></iron-icon>
           </button>
         </div>
         <div class="ripples">
@@ -332,7 +332,7 @@
       </div>
       <div class="main">
         <div class="status">
-          <iron-icon icon="cloud-queue"></iron-icon>
+          <iron-icon icon="files:cloud-queue"></iron-icon>
           <div class="content"></div>
         </div>
         <div class="progress"><div class="value"></div></div>
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd
index c03e381..0aa5f3e8 100644
--- a/ui/file_manager/file_manager_resources.grd
+++ b/ui/file_manager/file_manager_resources.grd
@@ -62,6 +62,7 @@
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_TOGGLE_RIPPLE_JS" file="file_manager/foreground/elements/files_toggle_ripple.js" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_TOOLTIP_HTML" file="file_manager/foreground/elements/files_tooltip.html" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_TOOLTIP_JS" file="file_manager/foreground/elements/files_tooltip.js" type="BINDATA" />
+      <include name="IDR_FILE_MANAGER_ELEMENTS_ICONS_HTML" file="file_manager/foreground/elements/icons.html" type="BINDATA" />
 
       <!-- Scripts referred by the gallery app. -->
       <include name="IDR_FILE_MANAGER_FILE_TYPE_JS" file="file_manager/common/js/file_type.js" flattenhtml="false" type="BINDATA" />
diff --git a/ui/wm/core/visibility_controller_unittest.cc b/ui/wm/core/visibility_controller_unittest.cc
index 36f1bb6..4e6aa8c 100644
--- a/ui/wm/core/visibility_controller_unittest.cc
+++ b/ui/wm/core/visibility_controller_unittest.cc
@@ -54,6 +54,32 @@
   EXPECT_FALSE(window->IsVisible());
 }
 
+// Check that a hiding animation would not change a window's bounds in screen.
+TEST_F(VisibilityControllerTest, HideAnimationWindowBoundsTest) {
+  // We cannot disable animations for this test.
+  ui::ScopedAnimationDurationScaleMode test_duration_mode(
+      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
+
+  VisibilityController controller;
+  aura::client::SetVisibilityClient(root_window(), &controller);
+
+  // Set bound expectation.
+  gfx::Rect expected_bounds(4, 5, 123, 245);
+  aura::test::TestWindowDelegate d;
+  std::unique_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
+      &d, -2, expected_bounds, root_window()));
+  window->Show();
+  SetWindowVisibilityChangesAnimated(window.get());
+  SetWindowVisibilityAnimationDuration(window.get(),
+                                       base::TimeDelta::FromMilliseconds(5));
+  SetWindowVisibilityAnimationType(window.get(),
+                                   WINDOW_VISIBILITY_ANIMATION_TYPE_DROP);
+  // Check that the bound is correct after the hide animation has finished.
+  window->Hide();
+  window->layer()->GetAnimator()->StopAnimating();
+  EXPECT_EQ(expected_bounds, window->GetBoundsInScreen());
+}
+
 // Test if SetWindowVisibilityChagngesAnimated will animate the specified
 // window.
 TEST_F(VisibilityControllerTest, SetWindowVisibilityChagnesAnimated) {
diff --git a/ui/wm/core/window_animations.cc b/ui/wm/core/window_animations.cc
index 07476c3..2d0ecea 100644
--- a/ui/wm/core/window_animations.cc
+++ b/ui/wm/core/window_animations.cc
@@ -103,6 +103,11 @@
             layer_owner_->root(), topmost_transient_child->layer());
       }
     }
+    // Reset the transform for the |window_|. Because the animation may have
+    // changed the transform, when recreating the layers we need to reset the
+    // transform otherwise the recreated layer has the transform installed
+    // for the animation.
+    window_->layer()->SetTransform(gfx::Transform());
   }
 
  protected: