diff --git a/DEPS b/DEPS
index f13a8c6..39994fb 100644
--- a/DEPS
+++ b/DEPS
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'b8a441daccc8d76c07e9a9374220695f2aba24bc',
+  'catapult_revision': '0e86ab1c3ba9f4496ec9035e245817dc72649a76',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 9c5ae1b..1399bb9 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -873,13 +873,8 @@
 gfx::Transform LayerImpl::DrawTransform() const {
   // Only drawn layers have up-to-date draw properties.
   if (!contributes_to_drawn_render_surface()) {
-    if (GetPropertyTrees()->non_root_surfaces_enabled) {
       return draw_property_utils::DrawTransform(this, GetTransformTree(),
                                                 GetEffectTree());
-    } else {
-      return draw_property_utils::ScreenSpaceTransform(this,
-                                                       GetTransformTree());
-    }
   }
 
   return draw_properties().target_space_transform;
diff --git a/cc/output/bsp_tree_perftest.cc b/cc/output/bsp_tree_perftest.cc
index aaf85655..f8f16d0 100644
--- a/cc/output/bsp_tree_perftest.cc
+++ b/cc/output/bsp_tree_perftest.cc
@@ -71,10 +71,8 @@
     LayerTreeImpl* active_tree = host_impl->active_tree();
     // First build the tree and then we'll start running tests on layersorter
     // itself
-    bool can_render_to_separate_surface = true;
     int max_texture_size = 8096;
-    DoCalcDrawPropertiesImpl(can_render_to_separate_surface, max_texture_size,
-                             active_tree, host_impl);
+    DoCalcDrawPropertiesImpl(max_texture_size, active_tree, host_impl);
 
     LayerImplList base_list;
     BuildLayerImplList(active_tree->root_layer_for_testing(), &base_list);
@@ -104,8 +102,7 @@
     EndTest();
   }
 
-  void DoCalcDrawPropertiesImpl(bool can_render_to_separate_surface,
-                                int max_texture_size,
+  void DoCalcDrawPropertiesImpl(int max_texture_size,
                                 LayerTreeImpl* active_tree,
                                 LayerTreeHostImpl* host_impl) {
     RenderSurfaceList update_list;
@@ -119,7 +116,6 @@
         active_tree->OuterViewportScrollLayer(),
         active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()),
         active_tree->OverscrollElasticityLayer(), max_texture_size,
-        can_render_to_separate_surface,
         host_impl->settings().layer_transforms_should_scale_layer_contents,
         &update_list, active_tree->property_trees());
     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 893f6ba..15535c5 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -713,27 +713,18 @@
       effect_node->has_render_surface
           ? effect_node
           : effect_tree->Node(effect_node->target_id);
-  // TODO(weiliangc): When effect node has up to date render surface info on
-  // compositor thread, no need to check for resourceless draw mode
-  if (!property_trees->non_root_surfaces_enabled) {
-    target_node = effect_tree->Node(1);
-  }
-
   bool include_expanding_clips = false;
   return ComputeAccumulatedClip(property_trees, include_expanding_clips,
                                 layer->clip_tree_index(), target_node->id);
 }
 
-static void UpdateRenderTarget(EffectTree* effect_tree,
-                               bool can_render_to_separate_surface) {
+static void UpdateRenderTarget(EffectTree* effect_tree) {
   for (int i = EffectTree::kContentsRootNodeId;
        i < static_cast<int>(effect_tree->size()); ++i) {
     EffectNode* node = effect_tree->Node(i);
     if (i == EffectTree::kContentsRootNodeId) {
       // Render target of the node corresponding to root is itself.
       node->target_id = EffectTree::kContentsRootNodeId;
-    } else if (!can_render_to_separate_surface) {
-      node->target_id = EffectTree::kContentsRootNodeId;
     } else if (effect_tree->parent(node)->has_render_surface) {
       node->target_id = node->parent_id;
     } else {
@@ -877,16 +868,10 @@
 }
 
 void UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
-                         PropertyTrees* property_trees,
-                         bool can_render_to_separate_surface) {
+                         PropertyTrees* property_trees) {
   DCHECK(layer_tree_host);
   DCHECK(property_trees);
   DCHECK_EQ(layer_tree_host->property_trees(), property_trees);
-  if (property_trees->non_root_surfaces_enabled !=
-      can_render_to_separate_surface) {
-    property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
-    property_trees->transform_tree.set_needs_update(true);
-  }
   if (property_trees->transform_tree.needs_update()) {
     property_trees->clip_tree.set_needs_update(true);
     property_trees->effect_tree.set_needs_update(true);
@@ -901,15 +886,8 @@
 
 void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
                                           PropertyTrees* property_trees,
-                                          bool can_render_to_separate_surface,
                                           bool can_adjust_raster_scales) {
   bool render_surfaces_need_update = false;
-  if (property_trees->non_root_surfaces_enabled !=
-      can_render_to_separate_surface) {
-    property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
-    property_trees->transform_tree.set_needs_update(true);
-    render_surfaces_need_update = true;
-  }
   if (property_trees->can_adjust_raster_scales != can_adjust_raster_scales) {
     property_trees->can_adjust_raster_scales = can_adjust_raster_scales;
     property_trees->transform_tree.set_needs_update(true);
@@ -921,11 +899,9 @@
   }
   if (render_surfaces_need_update) {
     property_trees->effect_tree.UpdateRenderSurfaces(
-        root_layer->layer_tree_impl(),
-        property_trees->non_root_surfaces_enabled);
+        root_layer->layer_tree_impl());
   }
-  UpdateRenderTarget(&property_trees->effect_tree,
-                     property_trees->non_root_surfaces_enabled);
+  UpdateRenderTarget(&property_trees->effect_tree);
 
   ComputeTransforms(&property_trees->transform_tree);
   ComputeEffects(&property_trees->effect_tree);
@@ -953,12 +929,9 @@
   // node and surface's transform node and scales it by the surface's content
   // scale.
   gfx::Transform xform;
-  if (transform_tree.property_trees()->non_root_surfaces_enabled)
-    transform_tree.property_trees()->GetToTarget(
-        layer->transform_tree_index(), layer->render_target_effect_tree_index(),
-        &xform);
-  else
-    xform = transform_tree.ToScreen(layer->transform_tree_index());
+  transform_tree.property_trees()->GetToTarget(
+      layer->transform_tree_index(), layer->render_target_effect_tree_index(),
+      &xform);
   if (layer->should_flatten_transform_from_property_tree())
     xform.FlattenTo2d();
   xform.Translate(layer->offset_to_transform_parent().x(),
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h
index c8ae09c7..45ed01f 100644
--- a/cc/trees/draw_property_utils.h
+++ b/cc/trees/draw_property_utils.h
@@ -37,15 +37,12 @@
 // Computes screen space opacity for every node in the opacity tree.
 void CC_EXPORT ComputeEffects(EffectTree* effect_tree);
 
-
 void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
-                                   PropertyTrees* property_trees,
-                                   bool can_render_to_separate_surface);
+                                   PropertyTrees* property_trees);
 
 void CC_EXPORT
 UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
                                      PropertyTrees* property_trees,
-                                     bool can_render_to_separate_surface,
                                      bool can_adjust_raster_scales);
 
 void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 7abf735a..b59572d 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -686,7 +686,6 @@
     TRACE_EVENT0(
         TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
         "LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees");
-    bool can_render_to_separate_surface = true;
     PropertyTrees* property_trees = &property_trees_;
     if (!settings_.use_layer_lists) {
       // If use_layer_lists is set, then the property trees should have been
@@ -706,8 +705,7 @@
           TRACE_EVENT_SCOPE_THREAD, "property_trees",
           property_trees->AsTracedValue());
     }
-    draw_property_utils::UpdatePropertyTrees(this, property_trees,
-                                             can_render_to_separate_surface);
+    draw_property_utils::UpdatePropertyTrees(this, property_trees);
     draw_property_utils::FindLayersThatNeedUpdates(this, property_trees,
                                                    &update_layer_list);
   }
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index ca04844..47f3fc2 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -78,7 +78,6 @@
     const gfx::Vector2dF& elastic_overscroll,
     const LayerImpl* elastic_overscroll_application_layer,
     int max_texture_size,
-    bool can_render_to_separate_surface,
     bool can_adjust_raster_scales,
     RenderSurfaceList* render_surface_list,
     PropertyTrees* property_trees)
@@ -94,7 +93,6 @@
       elastic_overscroll_application_layer(
           elastic_overscroll_application_layer),
       max_texture_size(max_texture_size),
-      can_render_to_separate_surface(can_render_to_separate_surface),
       can_adjust_raster_scales(can_adjust_raster_scales),
       render_surface_list(render_surface_list),
       property_trees(property_trees) {}
@@ -116,7 +114,6 @@
                               gfx::Vector2dF(),
                               NULL,
                               std::numeric_limits<int>::max() / 2,
-                              true,
                               false,
                               render_surface_list,
                               GetPropertyTrees(root_layer)) {
@@ -347,8 +344,7 @@
 static void ComputeInitialRenderSurfaceList(
     LayerTreeImpl* layer_tree_impl,
     PropertyTrees* property_trees,
-    RenderSurfaceList* render_surface_list,
-    bool can_render_to_separate_surface) {
+    RenderSurfaceList* render_surface_list) {
   EffectTree& effect_tree = property_trees->effect_tree;
   for (int i = EffectTree::kContentsRootNodeId;
        i < static_cast<int>(effect_tree.size()); ++i) {
@@ -488,7 +484,6 @@
     LayerTreeImpl* layer_tree_impl,
     PropertyTrees* property_trees,
     RenderSurfaceList* render_surface_list,
-    const bool can_render_to_separate_surface,
     const int max_texture_size) {
   RenderSurfaceList initial_render_surface_list;
 
@@ -496,8 +491,7 @@
   // have an empty content rect. After surface content rects are computed,
   // produce a final list that omits empty surfaces.
   ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees,
-                                  &initial_render_surface_list,
-                                  can_render_to_separate_surface);
+                                  &initial_render_surface_list);
   ComputeSurfaceContentRects(layer_tree_impl, property_trees,
                              &initial_render_surface_list, max_texture_size);
   ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees,
@@ -535,7 +529,6 @@
           inputs->device_transform, inputs->property_trees);
       draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
           inputs->root_layer, inputs->property_trees,
-          inputs->can_render_to_separate_surface,
           inputs->can_adjust_raster_scales);
 
       // Property trees are normally constructed on the main thread and
@@ -582,7 +575,6 @@
           inputs->device_transform, inputs->root_layer->position());
       draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
           inputs->root_layer, inputs->property_trees,
-          inputs->can_render_to_separate_surface,
           inputs->can_adjust_raster_scales);
       break;
     }
@@ -596,15 +588,12 @@
   draw_property_utils::FindLayersThatNeedUpdates(
       inputs->root_layer->layer_tree_impl(), inputs->property_trees,
       &visible_layer_list);
-  DCHECK(inputs->can_render_to_separate_surface ==
-         inputs->property_trees->non_root_surfaces_enabled);
   draw_property_utils::ComputeDrawPropertiesOfVisibleLayers(
       &visible_layer_list, inputs->property_trees);
 
   CalculateRenderSurfaceLayerList(
       inputs->root_layer->layer_tree_impl(), inputs->property_trees,
-      inputs->render_surface_list, inputs->can_render_to_separate_surface,
-      inputs->max_texture_size);
+      inputs->render_surface_list, inputs->max_texture_size);
 
   if (should_measure_property_tree_performance) {
     TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
@@ -620,7 +609,6 @@
 void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
     CalcDrawPropsMainInputsForTesting* inputs) {
   LayerList update_layer_list;
-  bool can_render_to_separate_surface = true;
   PropertyTrees* property_trees =
       inputs->root_layer->layer_tree_host()->property_trees();
   Layer* overscroll_elasticity_layer = nullptr;
@@ -633,8 +621,7 @@
       gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
       property_trees);
   draw_property_utils::UpdatePropertyTrees(
-      inputs->root_layer->layer_tree_host(), property_trees,
-      can_render_to_separate_surface);
+      inputs->root_layer->layer_tree_host(), property_trees);
   draw_property_utils::FindLayersThatNeedUpdates(
       inputs->root_layer->layer_tree_host(), property_trees,
       &update_layer_list);
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index d05bf59b..522ef93c 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -72,7 +72,6 @@
         const gfx::Vector2dF& elastic_overscroll,
         const LayerImpl* elastic_overscroll_application_layer,
         int max_texture_size,
-        bool can_render_to_separate_surface,
         bool can_adjust_raster_scales,
         RenderSurfaceList* render_surface_list,
         PropertyTrees* property_trees);
@@ -88,7 +87,6 @@
     gfx::Vector2dF elastic_overscroll;
     const LayerImpl* elastic_overscroll_application_layer;
     int max_texture_size;
-    bool can_render_to_separate_surface;
     bool can_adjust_raster_scales;
     RenderSurfaceList* render_surface_list;
     PropertyTrees* property_trees;
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index 30e43e4..c0b1e32 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -86,12 +86,8 @@
     LayerTreeImpl* active_tree = host_impl->active_tree();
 
     do {
-      bool can_render_to_separate_surface = true;
       int max_texture_size = 8096;
-      DoCalcDrawPropertiesImpl(can_render_to_separate_surface,
-                               max_texture_size,
-                               active_tree,
-                               host_impl);
+      DoCalcDrawPropertiesImpl(max_texture_size, active_tree, host_impl);
 
       timer_.NextLap();
     } while (!timer_.HasTimeLimitExpired());
@@ -99,8 +95,7 @@
     EndTest();
   }
 
-  void DoCalcDrawPropertiesImpl(bool can_render_to_separate_surface,
-                                int max_texture_size,
+  void DoCalcDrawPropertiesImpl(int max_texture_size,
                                 LayerTreeImpl* active_tree,
                                 LayerTreeHostImpl* host_impl) {
     RenderSurfaceList update_list;
@@ -114,7 +109,6 @@
         active_tree->OuterViewportScrollLayer(),
         active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()),
         active_tree->OverscrollElasticityLayer(), max_texture_size,
-        can_render_to_separate_surface,
         host_impl->settings().layer_transforms_should_scale_layer_contents,
         &update_list, active_tree->property_trees());
     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 873c926..6817657 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -181,8 +181,6 @@
 
   void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(Layer* root_layer) {
     DCHECK(root_layer->layer_tree_host());
-    bool can_render_to_separate_surface = true;
-
     const Layer* page_scale_layer =
         root_layer->layer_tree_host()->page_scale_layer();
     Layer* inner_viewport_scroll_layer =
@@ -207,8 +205,7 @@
         elastic_overscroll, page_scale_factor, device_scale_factor,
         gfx::Rect(device_viewport_size), gfx::Transform(), property_trees);
     draw_property_utils::UpdatePropertyTrees(root_layer->layer_tree_host(),
-                                             property_trees,
-                                             can_render_to_separate_surface);
+                                             property_trees);
     draw_property_utils::FindLayersThatNeedUpdates(
         root_layer->layer_tree_host(), property_trees, &update_layer_list_);
   }
@@ -216,7 +213,6 @@
   void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(
       LayerImpl* root_layer) {
     DCHECK(root_layer->layer_tree_impl());
-    bool can_render_to_separate_surface = true;
     bool can_adjust_raster_scales = true;
 
     const LayerImpl* page_scale_layer = nullptr;
@@ -244,8 +240,7 @@
         elastic_overscroll, page_scale_factor, device_scale_factor,
         gfx::Rect(device_viewport_size), gfx::Transform(), property_trees);
     draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
-        root_layer, property_trees, can_render_to_separate_surface,
-        can_adjust_raster_scales);
+        root_layer, property_trees, can_adjust_raster_scales);
     draw_property_utils::FindLayersThatNeedUpdates(
         root_layer->layer_tree_impl(), property_trees,
         update_layer_list_impl_.get());
@@ -263,7 +258,6 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root_layer, device_viewport_size, render_surface_list_impl_.get());
     inputs.can_adjust_raster_scales = true;
-    inputs.can_render_to_separate_surface = false;
 
     LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
   }
@@ -277,7 +271,6 @@
     DCHECK(!root_layer->bounds().IsEmpty());
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root_layer, device_viewport_size, render_surface_list_impl_.get());
-    inputs.can_render_to_separate_surface = true;
     inputs.can_adjust_raster_scales = false;
 
     LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
@@ -770,54 +763,6 @@
       child->render_target()->screen_space_transform());
 }
 
-TEST_F(LayerTreeHostCommonTest, TransformsWhenCannotRenderToSeparateSurface) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChildToRoot<LayerImpl>();
-  LayerImpl* child = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child);
-
-  gfx::Transform parent_transform;
-  parent_transform.Translate(10.0, 10.0);
-
-  gfx::Transform child_transform;
-  child_transform.Rotate(45.0);
-
-  root->SetBounds(gfx::Size(100, 100));
-  parent->test_properties()->transform = parent_transform;
-  parent->SetBounds(gfx::Size(10, 10));
-  child->test_properties()->transform = child_transform;
-  child->SetBounds(gfx::Size(10, 10));
-  child->test_properties()->force_render_surface = true;
-  grand_child->SetPosition(gfx::PointF(2.f, 2.f));
-  grand_child->SetBounds(gfx::Size(20, 20));
-  grand_child->SetDrawsContent(true);
-
-  gfx::Transform expected_grand_child_screen_space_transform;
-  expected_grand_child_screen_space_transform.Translate(10.0, 10.0);
-  expected_grand_child_screen_space_transform.Rotate(45.0);
-  expected_grand_child_screen_space_transform.Translate(2.0, 2.0);
-
-  // First compute draw properties with separate surfaces enabled.
-  ExecuteCalculateDrawProperties(root);
-
-  // The grand child's draw transform should be its offset wrt the child.
-  gfx::Transform expected_grand_child_draw_transform;
-  expected_grand_child_draw_transform.Translate(2.0, 2.0);
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform,
-                                  grand_child->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
-                                  grand_child->ScreenSpaceTransform());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-
-  // With separate surfaces disabled, the grand child's draw transform should be
-  // the same as its screen space transform.
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
-                                  grand_child->DrawTransform());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
-                                  grand_child->ScreenSpaceTransform());
-}
-
 TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) {
   // This test creates a more complex tree and verifies it all at once. This
   // covers the following cases:
@@ -1611,66 +1556,6 @@
   EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity());
 }
 
-TEST_F(LayerTreeHostCommonTest, DrawOpacityWhenCannotRenderToSeparateSurface) {
-  // Tests that when separate surfaces are disabled, a layer's draw opacity is
-  // the product of all ancestor layer opacties and the layer's own opacity.
-  // (Rendering will still be incorrect in situations where we really do need
-  // surfaces to apply opacity, such as when we have overlapping layers with an
-  // ancestor whose opacity is <1.)
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child1 = AddChild<LayerImpl>(parent);
-  LayerImpl* child2 = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child1);
-  LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
-  LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
-
-  root->SetBounds(gfx::Size(100, 100));
-  root->SetDrawsContent(true);
-  parent->SetBounds(gfx::Size(100, 100));
-  parent->SetDrawsContent(true);
-  child1->SetBounds(gfx::Size(100, 100));
-  child1->SetDrawsContent(true);
-  child1->test_properties()->opacity = 0.5f;
-  child1->test_properties()->force_render_surface = true;
-  child2->SetBounds(gfx::Size(100, 100));
-  child2->SetDrawsContent(true);
-  grand_child->SetBounds(gfx::Size(100, 100));
-  grand_child->SetDrawsContent(true);
-  grand_child->test_properties()->opacity = 0.5f;
-  grand_child->test_properties()->force_render_surface = true;
-  leaf_node1->SetBounds(gfx::Size(100, 100));
-  leaf_node1->SetDrawsContent(true);
-  leaf_node1->test_properties()->opacity = 0.5f;
-  leaf_node2->SetBounds(gfx::Size(100, 100));
-  leaf_node2->SetDrawsContent(true);
-  leaf_node2->test_properties()->opacity = 0.5f;
-
-  // With surfaces enabled, each layer's draw opacity is the product of layer
-  // opacities on the path from the layer to its render target, not including
-  // the opacity of the layer that owns the target surface (since that opacity
-  // is applied by the surface).
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_EQ(1.f, root->draw_opacity());
-  EXPECT_EQ(1.f, parent->draw_opacity());
-  EXPECT_EQ(1.f, child1->draw_opacity());
-  EXPECT_EQ(1.f, child2->draw_opacity());
-  EXPECT_EQ(1.f, grand_child->draw_opacity());
-  EXPECT_EQ(0.5f, leaf_node1->draw_opacity());
-  EXPECT_EQ(0.5f, leaf_node2->draw_opacity());
-
-  // With surfaces disabled, each layer's draw opacity is the product of layer
-  // opacities on the path from the layer to the root.
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_EQ(1.f, root->draw_opacity());
-  EXPECT_EQ(1.f, parent->draw_opacity());
-  EXPECT_EQ(0.5f, child1->draw_opacity());
-  EXPECT_EQ(1.f, child2->draw_opacity());
-  EXPECT_EQ(0.25f, grand_child->draw_opacity());
-  EXPECT_EQ(0.125f, leaf_node1->draw_opacity());
-  EXPECT_EQ(0.5f, leaf_node2->draw_opacity());
-}
-
 TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) {
   LayerImpl* root = root_layer_for_testing();
   LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>();
@@ -1953,154 +1838,6 @@
   EXPECT_EQ(gfx::Rect(), child->clip_rect());
 }
 
-TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) {
-  // Tests that when separate surfaces are disabled, is_clipped is true exactly
-  // when a layer or its ancestor has a clip; in particular, if a layer
-  // is_clipped, so is its entire subtree (since there are no render surfaces
-  // that can reset is_clipped).
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child1 = AddChild<LayerImpl>(parent);
-  LayerImpl* child2 = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child1);
-  LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
-  LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
-
-  root->SetBounds(gfx::Size(100, 100));
-  root->SetDrawsContent(true);
-  parent->SetBounds(gfx::Size(100, 100));
-  parent->SetDrawsContent(true);
-  child1->SetBounds(gfx::Size(100, 100));
-  child1->SetDrawsContent(true);
-  child1->test_properties()->force_render_surface = true;
-  child2->SetBounds(gfx::Size(100, 100));
-  child2->SetDrawsContent(true);
-  grand_child->SetBounds(gfx::Size(100, 100));
-  grand_child->SetDrawsContent(true);
-  grand_child->test_properties()->force_render_surface = true;
-  leaf_node1->SetBounds(gfx::Size(100, 100));
-  leaf_node1->SetDrawsContent(true);
-  leaf_node2->SetBounds(gfx::Size(100, 100));
-  leaf_node2->SetDrawsContent(true);
-
-  // Case 1: Nothing is clipped. In this case, is_clipped is always false, with
-  // or without surfaces.
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-
-  // Case 2: The root is clipped. With surfaces, this only persists until the
-  // next render surface. Without surfaces, the entire tree is clipped.
-  root->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_TRUE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_TRUE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_TRUE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-
-  root->SetMasksToBounds(false);
-
-  // Case 3: The parent is clipped. Again, with surfaces, this only persists
-  // until the next render surface. Without surfaces, parent's entire subtree is
-  // clipped.
-  parent->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_TRUE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-
-  parent->SetMasksToBounds(false);
-
-  // Case 4: child1 is clipped. With surfaces, only child1 is_clipped, since it
-  // has no non-surface children. Without surfaces, child1's entire subtree is
-  // clipped.
-  child1->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_TRUE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-
-  child1->SetMasksToBounds(false);
-
-  // Case 5: Only the leaf nodes are clipped. The behavior with and without
-  // surfaces is the same.
-  leaf_node1->SetMasksToBounds(true);
-  leaf_node2->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-}
-
 TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
   // Verify that layers get the appropriate DrawableContentRect when their
   // parent MasksToBounds is true.
@@ -2210,274 +1947,6 @@
             GetRenderSurface(grand_child3)->clip_rect());
 }
 
-TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) {
-  // Tests that when separate surfaces are disabled, a layer's clip_rect is the
-  // intersection of all ancestor clips in screen space; in particular, if a
-  // layer masks to bounds, it contributes to the clip_rect of all layers in its
-  // subtree (since there are no render surfaces that can reset the clip_rect).
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child1 = AddChild<LayerImpl>(parent);
-  LayerImpl* child2 = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child1);
-  LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
-  LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
-
-  root->SetBounds(gfx::Size(100, 100));
-  parent->SetPosition(gfx::PointF(2.f, 2.f));
-  parent->SetBounds(gfx::Size(400, 400));
-  child1->SetPosition(gfx::PointF(4.f, 4.f));
-  child1->SetBounds(gfx::Size(800, 800));
-  child2->SetPosition(gfx::PointF(3.f, 3.f));
-  child2->SetBounds(gfx::Size(800, 800));
-  grand_child->SetPosition(gfx::PointF(8.f, 8.f));
-  grand_child->SetBounds(gfx::Size(1500, 1500));
-  leaf_node1->SetPosition(gfx::PointF(16.f, 16.f));
-  leaf_node1->SetBounds(gfx::Size(2000, 2000));
-  leaf_node2->SetPosition(gfx::PointF(9.f, 9.f));
-  leaf_node2->SetBounds(gfx::Size(2000, 2000));
-
-  root->SetDrawsContent(true);
-  parent->SetDrawsContent(true);
-  child1->SetDrawsContent(true);
-  child2->SetDrawsContent(true);
-  grand_child->SetDrawsContent(true);
-  leaf_node1->SetDrawsContent(true);
-  leaf_node2->SetDrawsContent(true);
-
-  root->test_properties()->force_render_surface = true;
-  child1->test_properties()->force_render_surface = true;
-  grand_child->test_properties()->force_render_surface = true;
-
-  // Case 1: Nothing is clipped. In this case, each layer's clip rect is its
-  // bounds in target space. The only thing that changes when surfaces are
-  // disabled is that target space is always screen space.
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_TRUE(GetRenderSurface(root));
-  EXPECT_FALSE(GetRenderSurface(parent));
-  EXPECT_TRUE(GetRenderSurface(child1));
-  EXPECT_FALSE(GetRenderSurface(child2));
-  EXPECT_TRUE(GetRenderSurface(grand_child));
-  EXPECT_FALSE(GetRenderSurface(leaf_node1));
-  EXPECT_FALSE(GetRenderSurface(leaf_node2));
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
-  EXPECT_FALSE(GetRenderSurface(child1)->is_clipped());
-  EXPECT_FALSE(GetRenderSurface(grand_child)->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(root)->clip_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_FALSE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_FALSE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_FALSE(leaf_node2->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(root)->clip_rect());
-
-  // Case 2: The root is clipped. In this case, layers that draw into the root
-  // render surface are clipped by the root's bounds.
-  root->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  root->test_properties()->force_render_surface = true;
-  child1->test_properties()->force_render_surface = true;
-  grand_child->test_properties()->force_render_surface = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_TRUE(GetRenderSurface(root));
-  EXPECT_FALSE(GetRenderSurface(parent));
-  EXPECT_TRUE(GetRenderSurface(child1));
-  EXPECT_FALSE(GetRenderSurface(child2));
-  EXPECT_TRUE(GetRenderSurface(grand_child));
-  EXPECT_FALSE(GetRenderSurface(leaf_node1));
-  EXPECT_FALSE(GetRenderSurface(leaf_node2));
-  EXPECT_TRUE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_FALSE(child1->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(child1)->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_FALSE(GetRenderSurface(grand_child)->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(child1)->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_TRUE(root->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_TRUE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), grand_child->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), leaf_node1->clip_rect());
-  EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect());
-
-  root->SetMasksToBounds(false);
-
-  // Case 3: The parent and child1 are clipped. When surfaces are enabled, the
-  // parent clip rect only contributes to the subtree rooted at child2, since
-  // the subtree rooted at child1 renders into a separate surface. Similarly,
-  // child1's clip rect doesn't contribute to its descendants, since its only
-  // child is a render surface. However, without surfaces, these clip rects
-  // contribute to all descendants.
-  parent->SetMasksToBounds(true);
-  child1->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  root->test_properties()->force_render_surface = true;
-  child1->test_properties()->force_render_surface = true;
-  grand_child->test_properties()->force_render_surface = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_TRUE(GetRenderSurface(root));
-  EXPECT_FALSE(GetRenderSurface(parent));
-  EXPECT_TRUE(GetRenderSurface(child1));
-  EXPECT_FALSE(GetRenderSurface(child2));
-  EXPECT_TRUE(GetRenderSurface(grand_child));
-  EXPECT_FALSE(GetRenderSurface(leaf_node1));
-  EXPECT_FALSE(GetRenderSurface(leaf_node2));
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_FALSE(grand_child->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(grand_child)->is_clipped());
-  EXPECT_FALSE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(root)->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), GetRenderSurface(grand_child)->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_FALSE(root->is_clipped());
-  EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
-  EXPECT_TRUE(parent->is_clipped());
-  EXPECT_TRUE(child1->is_clipped());
-  EXPECT_TRUE(child2->is_clipped());
-  EXPECT_TRUE(grand_child->is_clipped());
-  EXPECT_TRUE(leaf_node1->is_clipped());
-  EXPECT_TRUE(leaf_node2->is_clipped());
-  EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(root)->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 396, 396), grand_child->clip_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node1->clip_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect());
-}
-
-TEST_F(LayerTreeHostCommonTest, HitTestingWhenSurfacesDisabled) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child);
-  LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child);
-
-  root->SetBounds(gfx::Size(100, 100));
-  parent->SetPosition(gfx::PointF(2.f, 2.f));
-  parent->SetBounds(gfx::Size(400, 400));
-  parent->SetMasksToBounds(true);
-  child->SetPosition(gfx::PointF(4.f, 4.f));
-  child->SetBounds(gfx::Size(800, 800));
-  child->SetMasksToBounds(true);
-  child->test_properties()->force_render_surface = true;
-  grand_child->SetPosition(gfx::PointF(8.f, 8.f));
-  grand_child->SetBounds(gfx::Size(1500, 1500));
-  grand_child->test_properties()->force_render_surface = true;
-  leaf_node->SetPosition(gfx::PointF(16.f, 16.f));
-  leaf_node->SetBounds(gfx::Size(2000, 2000));
-
-  root->SetDrawsContent(true);
-  parent->SetDrawsContent(true);
-  child->SetDrawsContent(true);
-  grand_child->SetDrawsContent(true);
-  leaf_node->SetDrawsContent(true);
-
-  host_impl()->set_resourceless_software_draw_for_testing();
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  gfx::PointF test_point(90.f, 90.f);
-  LayerImpl* result_layer =
-      root->layer_tree_impl()->FindLayerThatIsHitByPoint(test_point);
-  ASSERT_TRUE(result_layer);
-  EXPECT_EQ(leaf_node, result_layer);
-}
-
-TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) {
-  // Tests that draw properties are computed correctly when we disable and then
-  // re-enable separate surfaces.
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child = AddChild<LayerImpl>(child);
-  LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child);
-
-  root->SetBounds(gfx::Size(100, 100));
-  parent->SetPosition(gfx::PointF(2.f, 2.f));
-  parent->SetBounds(gfx::Size(400, 400));
-  parent->SetMasksToBounds(true);
-  child->SetPosition(gfx::PointF(4.f, 4.f));
-  child->SetBounds(gfx::Size(800, 800));
-  child->SetMasksToBounds(true);
-  child->test_properties()->force_render_surface = true;
-  grand_child->SetPosition(gfx::PointF(8.f, 8.f));
-  grand_child->SetBounds(gfx::Size(1500, 1500));
-  grand_child->test_properties()->force_render_surface = true;
-  leaf_node->SetPosition(gfx::PointF(16.f, 16.f));
-  leaf_node->SetBounds(gfx::Size(2000, 2000));
-
-  root->SetDrawsContent(true);
-  parent->SetDrawsContent(true);
-  child->SetDrawsContent(true);
-  grand_child->SetDrawsContent(true);
-  leaf_node->SetDrawsContent(true);
-
-  gfx::Transform expected_leaf_draw_transform_with_surfaces;
-  expected_leaf_draw_transform_with_surfaces.Translate(16.0, 16.0);
-
-  gfx::Transform expected_leaf_draw_transform_without_surfaces;
-  expected_leaf_draw_transform_without_surfaces.Translate(30.0, 30.0);
-
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(leaf_node->is_clipped());
-  EXPECT_TRUE(leaf_node->render_target()->is_clipped());
-  EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_with_surfaces,
-                                  leaf_node->DrawTransform());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_TRUE(leaf_node->is_clipped());
-  EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node->clip_rect());
-  EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node->drawable_content_rect());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_without_surfaces,
-                                  leaf_node->DrawTransform());
-
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(leaf_node->is_clipped());
-  EXPECT_TRUE(leaf_node->render_target()->is_clipped());
-  EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_with_surfaces,
-                                  leaf_node->DrawTransform());
-}
-
 TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
   LayerImpl* root = root_layer_for_testing();
   LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>();
@@ -3352,184 +2821,6 @@
 }
 
 TEST_F(LayerTreeHostCommonTest,
-       DrawableAndVisibleRectsWhenCannotRenderToSeparateSurface) {
-  LayerImpl* root = root_layer_for_testing();
-  LayerImpl* parent = AddChild<LayerImpl>(root);
-  LayerImpl* child1 = AddChild<LayerImpl>(parent);
-  LayerImpl* child2 = AddChild<LayerImpl>(parent);
-  LayerImpl* grand_child1 = AddChild<LayerImpl>(child1);
-  LayerImpl* grand_child2 = AddChild<LayerImpl>(child2);
-  LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child1);
-  LayerImpl* leaf_node2 = AddChild<LayerImpl>(grand_child2);
-
-  root->SetBounds(gfx::Size(100, 100));
-  parent->SetPosition(gfx::PointF(2.f, 2.f));
-  parent->SetBounds(gfx::Size(400, 400));
-  child1->SetPosition(gfx::PointF(4.f, 4.f));
-  child1->SetBounds(gfx::Size(800, 800));
-  child1->test_properties()->force_render_surface = true;
-  child2->SetPosition(gfx::PointF(3.f, 3.f));
-  child2->SetBounds(gfx::Size(800, 800));
-  child2->test_properties()->force_render_surface = true;
-  grand_child1->SetPosition(gfx::PointF(8.f, 8.f));
-  grand_child1->SetBounds(gfx::Size(1500, 1500));
-  grand_child2->SetPosition(gfx::PointF(7.f, 7.f));
-  grand_child2->SetBounds(gfx::Size(1500, 1500));
-  leaf_node1->SetPosition(gfx::PointF(16.f, 16.f));
-  leaf_node1->SetBounds(gfx::Size(2000, 2000));
-  leaf_node2->SetPosition(gfx::PointF(9.f, 9.f));
-  leaf_node2->SetBounds(gfx::Size(2000, 2000));
-
-  root->SetDrawsContent(true);
-  parent->SetDrawsContent(true);
-  child1->SetDrawsContent(true);
-  child2->SetDrawsContent(true);
-  grand_child1->SetDrawsContent(true);
-  grand_child2->SetDrawsContent(true);
-  leaf_node1->SetDrawsContent(true);
-  leaf_node2->SetDrawsContent(true);
-
-  // Case 1: No layers clip. Visible rects are clipped by the viewport.
-  // Each layer's drawable content rect is its bounds in target space; the only
-  // thing that changes with surfaces disabled is that target space is always
-  // screen space.
-  child1->test_properties()->force_render_surface = true;
-  child2->test_properties()->force_render_surface = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(0, 0, 98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(14, 14, 1500, 1500),
-            grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500),
-            grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(30, 30, 2000, 2000), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(21, 21, 2000, 2000), leaf_node2->drawable_content_rect());
-
-  // Case 2: The parent clips. In this case, neither surface is unclipped, so
-  // all visible layer rects are clipped by the intersection of all ancestor
-  // clips, whether or not surfaces are disabled. However, drawable content
-  // rects are clipped only until the next render surface is reached, so
-  // descendants of parent have their drawable content rects clipped only when
-  // surfaces are disabled.
-  parent->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(5, 5, 397, 397), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(14, 14, 388, 388), grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(12, 12, 390, 390), grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(21, 21, 381, 381), leaf_node2->drawable_content_rect());
-
-  parent->SetMasksToBounds(false);
-
-  // Case 3: child1 and grand_child2 clip. In this case, descendants of these
-  // layers have their visible rects clipped by them; Similarly, descendants of
-  // these layers have their drawable content rects clipped by them.
-  child1->SetMasksToBounds(true);
-  grand_child2->SetMasksToBounds(true);
-  host_impl()->active_tree()->property_trees()->needs_rebuild = true;
-  ExecuteCalculateDrawProperties(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(8, 8, 792, 792), grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(24, 24, 776, 776), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(16, 16, 1491, 1491), leaf_node2->drawable_content_rect());
-
-  ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
-  EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
-  EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
-
-  EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(14, 14, 792, 792), grand_child1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500),
-            grand_child2->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(30, 30, 776, 776), leaf_node1->drawable_content_rect());
-  EXPECT_EQ(gfx::Rect(21, 21, 1491, 1491), leaf_node2->drawable_content_rect());
-}
-
-TEST_F(LayerTreeHostCommonTest,
        VisibleContentRectsForClippedSurfaceWithEmptyClip) {
   LayerImpl* root = root_layer_for_testing();
   LayerImpl* child1 = AddChild<LayerImpl>(root);
@@ -6140,109 +5431,6 @@
   EXPECT_FALSE(GetRenderSurface(child3));
 }
 
-TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
-  FakeImplTaskRunnerProvider task_runner_provider;
-  TestTaskGraphRunner task_graph_runner;
-  FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner);
-
-  std::unique_ptr<LayerImpl> root =
-      LayerImpl::Create(host_impl.active_tree(), 12345);
-  std::unique_ptr<LayerImpl> child1 =
-      LayerImpl::Create(host_impl.active_tree(), 123456);
-  std::unique_ptr<LayerImpl> child2 =
-      LayerImpl::Create(host_impl.active_tree(), 1234567);
-  std::unique_ptr<LayerImpl> child3 =
-      LayerImpl::Create(host_impl.active_tree(), 12345678);
-
-  gfx::Size bounds(100, 100);
-
-  root->SetBounds(bounds);
-  root->SetDrawsContent(true);
-
-  // This layer structure normally forces render surface due to preserves3d
-  // behavior.
-  child1->SetBounds(bounds);
-  child1->SetDrawsContent(true);
-  child1->test_properties()->should_flatten_transform = false;
-  child1->test_properties()->sorting_context_id = 1;
-  child2->SetBounds(bounds);
-  child2->SetDrawsContent(true);
-  child2->test_properties()->sorting_context_id = 1;
-  child3->SetBounds(bounds);
-  child3->SetDrawsContent(true);
-  child3->test_properties()->sorting_context_id = 1;
-
-  child2->test_properties()->AddChild(std::move(child3));
-  child1->test_properties()->AddChild(std::move(child2));
-  root->test_properties()->AddChild(std::move(child1));
-  LayerImpl* root_layer = root.get();
-  root_layer->layer_tree_impl()->SetRootLayerForTesting(std::move(root));
-
-  {
-    RenderSurfaceList render_surface_list;
-    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
-        root_layer, root_layer->bounds(), &render_surface_list);
-    inputs.can_render_to_separate_surface = true;
-    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
-
-    EXPECT_EQ(2u, render_surface_list.size());
-
-    int count_represents_target_render_surface = 0;
-    int count_represents_contributing_render_surface = 0;
-    int count_represents_itself = 0;
-    for (EffectTreeLayerListIterator it(host_impl.active_tree());
-         it.state() != EffectTreeLayerListIterator::State::END; ++it) {
-      if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
-        count_represents_target_render_surface++;
-      } else if (it.state() ==
-                 EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
-        count_represents_contributing_render_surface++;
-      } else {
-        count_represents_itself++;
-      }
-    }
-
-    // Two render surfaces.
-    EXPECT_EQ(2, count_represents_target_render_surface);
-    // Second render surface contributes to root render surface.
-    EXPECT_EQ(1, count_represents_contributing_render_surface);
-    // All 4 layers represent itself.
-    EXPECT_EQ(4, count_represents_itself);
-  }
-
-  {
-    RenderSurfaceList render_surface_list;
-    LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
-        root_layer, root_layer->bounds(), &render_surface_list);
-    inputs.can_render_to_separate_surface = false;
-    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
-
-    EXPECT_EQ(1u, render_surface_list.size());
-
-    int count_represents_target_render_surface = 0;
-    int count_represents_contributing_render_surface = 0;
-    int count_represents_itself = 0;
-    for (EffectTreeLayerListIterator it(host_impl.active_tree());
-         it.state() != EffectTreeLayerListIterator::State::END; ++it) {
-      if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
-        count_represents_target_render_surface++;
-      } else if (it.state() ==
-                 EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
-        count_represents_contributing_render_surface++;
-      } else {
-        count_represents_itself++;
-      }
-    }
-
-    // Only root layer has a render surface.
-    EXPECT_EQ(1, count_represents_target_render_surface);
-    // No layer contributes a render surface to root render surface.
-    EXPECT_EQ(0, count_represents_contributing_render_surface);
-    // All 4 layers represent itself.
-    EXPECT_EQ(4, count_represents_itself);
-  }
-}
-
 TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
   LayerImpl* root = root_layer_for_testing();
   LayerImpl* back_facing = AddChild<LayerImpl>(root);
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 1fe5871..33e17df 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1021,10 +1021,6 @@
     TRACE_EVENT2(
         "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties",
         "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_);
-    // TODO(crbug.com/692780): Remove this option entirely once this get to
-    // stable and proves it works.
-    bool can_render_to_separate_surface = true;
-
     // We verify visible rect calculations whenever we verify clip tree
     // calculations except when this function is explicitly passed a flag asking
     // us to skip it.
@@ -1035,7 +1031,6 @@
         InnerViewportScrollLayer(), OuterViewportScrollLayer(),
         elastic_overscroll()->Current(IsActiveTree()),
         OverscrollElasticityLayer(), resource_provider()->max_texture_size(),
-        can_render_to_separate_surface,
         settings().layer_transforms_should_scale_layer_contents,
         &render_surface_list_, &property_trees_);
     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 76298ec..fbedc16 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -1004,13 +1004,11 @@
   mask_layer_ids_.push_back(id);
 }
 
-void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl,
-                                      bool non_root_surfaces_enabled) {
+void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl) {
   for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) {
     EffectNode* effect_node = Node(id);
     bool needs_render_surface =
-        id == kContentsRootNodeId ||
-        (non_root_surfaces_enabled && effect_node->has_render_surface);
+        id == kContentsRootNodeId || effect_node->has_render_surface;
     if (needs_render_surface == !!render_surfaces_[id])
       continue;
 
@@ -1600,7 +1598,6 @@
 
 PropertyTrees::PropertyTrees()
     : needs_rebuild(true),
-      non_root_surfaces_enabled(true),
       can_adjust_raster_scales(true),
       changed(false),
       full_tree_damaged(false),
@@ -1631,7 +1628,6 @@
          full_tree_damaged == other.full_tree_damaged &&
          is_main_thread == other.is_main_thread &&
          is_active == other.is_active &&
-         non_root_surfaces_enabled == other.non_root_surfaces_enabled &&
          can_adjust_raster_scales == other.can_adjust_raster_scales &&
          sequence_number == other.sequence_number;
 }
@@ -1649,7 +1645,6 @@
   needs_rebuild = from.needs_rebuild;
   changed = from.changed;
   full_tree_damaged = from.full_tree_damaged;
-  non_root_surfaces_enabled = from.non_root_surfaces_enabled;
   can_adjust_raster_scales = from.can_adjust_raster_scales;
   sequence_number = from.sequence_number;
   is_main_thread = from.is_main_thread;
@@ -1681,7 +1676,6 @@
   needs_rebuild = true;
   full_tree_damaged = false;
   changed = false;
-  non_root_surfaces_enabled = true;
   can_adjust_raster_scales = true;
   sequence_number++;
 
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index 34abaa9..601cbaf 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -394,8 +394,7 @@
     return render_surfaces_[id].get();
   }
 
-  void UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl,
-                            bool non_root_surfaces_enabled);
+  void UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl);
 
   bool ContributesToDrawnSurface(int id);
 
@@ -654,7 +653,6 @@
   ClipTree clip_tree;
   ScrollTree scroll_tree;
   bool needs_rebuild;
-  bool non_root_surfaces_enabled;
   bool can_adjust_raster_scales;
   // Change tracking done on property trees needs to be preserved across commits
   // (when they are not rebuild). We cache a global bool which stores whether
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java
index 2465227c..f2a69ea 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/AudioTest.java
@@ -4,9 +4,20 @@
 
 package org.chromium.chrome.browser;
 
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -16,24 +27,26 @@
 /**
  * Simple HTML5 audio tests.
  */
-public class AudioTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AudioTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private EmbeddedTestServer mTestServer;
 
-    public AudioTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
@@ -42,24 +55,21 @@
      * @MediumTest
      */
     // TODO(jbudorick): Attempt to reenable this after the server switch has stabilized.
+    @Test
     @FlakyTest(message = "crbug.com/331122")
     public void testPlayMp3() throws InterruptedException, TimeoutException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         TabTitleObserver titleObserver = new TabTitleObserver(tab, "ready_to_play");
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/media/audio-play.html"));
+        mActivityTestRule.loadUrl(
+                mTestServer.getURL("/chrome/test/data/android/media/audio-play.html"));
         titleObserver.waitForTitleUpdate(5);
-        assertEquals("ready_to_play", tab.getTitle());
+        Assert.assertEquals("ready_to_play", tab.getTitle());
 
         titleObserver = new TabTitleObserver(tab, "ended");
         DOMUtils.clickNode(tab.getContentViewCore(), "button1");
 
         // Make sure that the audio playback "ended" and title is changed.
         titleObserver.waitForTitleUpdate(15);
-        assertEquals("ended", tab.getTitle());
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        Assert.assertEquals("ended", tab.getTitle());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
index 241589f..44cc7ab8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
@@ -5,12 +5,21 @@
 package org.chromium.chrome.browser;
 
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.test.MoreAsserts;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
@@ -21,7 +30,8 @@
 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.PrerenderTestHelper;
@@ -31,6 +41,7 @@
 import org.chromium.content.browser.test.ChildProcessAllocatorSettings;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -42,8 +53,14 @@
  * Integration tests for the BindingManager API. This test plants a mock BindingManager
  * implementation and verifies that the signals it relies on are correctly delivered.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class BindingManagerIntegrationTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class BindingManagerIntegrationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static class MockBindingManager implements BindingManager {
         // Maps pid to the last received visibility state of the renderer.
@@ -155,24 +172,21 @@
     private static final String SHARED_RENDERER_PAGE2_PATH =
             "/chrome/test/data/android/bindingmanager/shared_renderer2.html";
 
-    public BindingManagerIntegrationTest() {
-        super(ChromeActivity.class);
-    }
-
     /**
      * Verifies that the .setProcessInForeground() signal is called correctly as the tabs are
      * created and switched.
      */
+    @Test
     @LargeTest
     @Feature({"ProcessManagement"})
     public void testTabSwitching() throws InterruptedException {
         // Create two tabs and wait until they are loaded, so that their renderers are around.
         final Tab[] tabs = new Tab[2];
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Foreground tab.
-                TabCreator tabCreator = getActivity().getCurrentTabCreator();
+                TabCreator tabCreator = mActivityTestRule.getActivity().getCurrentTabCreator();
                 tabs[0] = tabCreator.createNewTab(
                         new LoadUrlParams(mTestServer.getURL(FILE_PATH)),
                                 TabLaunchType.FROM_CHROME_UI, null);
@@ -190,8 +204,8 @@
         ChromeTabUtils.waitForTabPageLoaded(tabs[1], mTestServer.getURL(FILE_PATH));
 
         // Wait for the new tab animations on phones to finish.
-        if (!DeviceFormFactor.isTablet(getActivity())) {
-            final ChromeActivity activity = getActivity();
+        if (!DeviceFormFactor.isTablet(mActivityTestRule.getActivity())) {
+            final ChromeActivity activity = mActivityTestRule.getActivity();
             CriteriaHelper.pollUiThread(new Criteria("Did not finish animation") {
                 @Override
                 public boolean isSatisfied() {
@@ -201,14 +215,14 @@
                 }
             });
         }
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Make sure that the renderers were spawned.
-                assertTrue(tabs[0].getContentViewCore().getCurrentRenderProcessId() > 0);
-                assertTrue(tabs[1].getContentViewCore().getCurrentRenderProcessId() > 0);
+                Assert.assertTrue(tabs[0].getContentViewCore().getCurrentRenderProcessId() > 0);
+                Assert.assertTrue(tabs[1].getContentViewCore().getCurrentRenderProcessId() > 0);
 
                 // Verify that the renderer of the foreground tab was signalled as visible.
                 mBindingManager.assertIsInForeground(
@@ -219,7 +233,8 @@
                         tabs[1].getContentViewCore().getCurrentRenderProcessId());
 
                 // Select tabs[1] and verify that the renderer visibility was flipped.
-                TabModelUtils.setIndex(getActivity().getCurrentTabModel(), indexOf(tabs[1]));
+                TabModelUtils.setIndex(
+                        mActivityTestRule.getActivity().getCurrentTabModel(), indexOf(tabs[1]));
                 mBindingManager.assertIsInBackground(
                         tabs[0].getContentViewCore().getCurrentRenderProcessId());
                 mBindingManager.assertIsInForeground(
@@ -233,17 +248,18 @@
      * crashed in background is restored in foreground. This is a regression test for
      * http://crbug.com/399521.
      */
+    @Test
     @DisabledTest(message = "crbug.com/543153")
     @LargeTest
     @Feature({"ProcessManagement"})
     public void testCrashInBackground() throws InterruptedException {
         // Create two tabs and wait until they are loaded, so that their renderers are around.
         final Tab[] tabs = new Tab[2];
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Foreground tab.
-                TabCreator tabCreator = getActivity().getCurrentTabCreator();
+                TabCreator tabCreator = mActivityTestRule.getActivity().getCurrentTabCreator();
                 tabs[0] = tabCreator.createNewTab(
                         new LoadUrlParams(mTestServer.getURL(FILE_PATH)),
                                 TabLaunchType.FROM_CHROME_UI, null);
@@ -261,8 +277,8 @@
         ChromeTabUtils.waitForTabPageLoaded(tabs[1], mTestServer.getURL(FILE_PATH));
 
         // Wait for the new tab animations on phones to finish.
-        if (!DeviceFormFactor.isTablet(getActivity())) {
-            final ChromeActivity activity = getActivity();
+        if (!DeviceFormFactor.isTablet(mActivityTestRule.getActivity())) {
+            final ChromeActivity activity = mActivityTestRule.getActivity();
             CriteriaHelper.pollUiThread(new Criteria("Did not finish animation") {
                 @Override
                 public boolean isSatisfied() {
@@ -272,14 +288,14 @@
                 }
             });
         }
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Make sure that the renderers were spawned.
-                assertTrue(tabs[0].getContentViewCore().getCurrentRenderProcessId() > 0);
-                assertTrue(tabs[1].getContentViewCore().getCurrentRenderProcessId() > 0);
+                Assert.assertTrue(tabs[0].getContentViewCore().getCurrentRenderProcessId() > 0);
+                Assert.assertTrue(tabs[1].getContentViewCore().getCurrentRenderProcessId() > 0);
 
                 // Verify that the renderer of the foreground tab was signalled as visible.
                 mBindingManager.assertIsInForeground(
@@ -292,7 +308,7 @@
         });
 
         // Kill the renderer and wait for the crash to be noted by the browser process.
-        assertTrue(ChildProcessLauncher.crashProcessForTesting(
+        Assert.assertTrue(ChildProcessLauncher.crashProcessForTesting(
                 tabs[1].getContentViewCore().getCurrentRenderProcessId()));
 
         CriteriaHelper.pollInstrumentationThread(
@@ -304,10 +320,11 @@
                 });
 
         // Switch to the tab that crashed in background.
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                TabModelUtils.setIndex(getActivity().getCurrentTabModel(), indexOf(tabs[1]));
+                TabModelUtils.setIndex(
+                        mActivityTestRule.getActivity().getCurrentTabModel(), indexOf(tabs[1]));
             }
         });
 
@@ -324,7 +341,7 @@
                 "isInForeground() was not called for the process.",
                 tabs[1].getContentViewCore().getCurrentRenderProcessId());
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Verify the visibility of the renderers.
@@ -340,6 +357,7 @@
      * Verifies that a renderer that crashes in foreground has the correct visibility when
      * recreated.
      */
+    @Test
     @LargeTest
     @Feature({"ProcessManagement"})
     public void testCrashInForeground() throws InterruptedException {
@@ -349,16 +367,17 @@
                 new Callable<Tab>() {
                     @Override
                     public Tab call() throws Exception {
-                        TabCreator tabCreator = getActivity().getCurrentTabCreator();
+                        TabCreator tabCreator =
+                                mActivityTestRule.getActivity().getCurrentTabCreator();
                         return tabCreator.createNewTab(
                                 new LoadUrlParams(testUrl), TabLaunchType.FROM_CHROME_UI, null);
                     }
                 });
         ChromeTabUtils.waitForTabPageLoaded(tab, testUrl);
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Kill the renderer and wait for the crash to be noted by the browser process.
-        assertTrue(ChildProcessLauncher.crashProcessForTesting(
+        Assert.assertTrue(ChildProcessLauncher.crashProcessForTesting(
                 tab.getContentViewCore().getCurrentRenderProcessId()));
 
         CriteriaHelper.pollInstrumentationThread(
@@ -370,7 +389,7 @@
                 });
 
         // Reload the tab, respawning the renderer.
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 tab.reload();
@@ -392,7 +411,7 @@
                 "isInForeground() was not called for the process.",
                 tab.getContentViewCore().getCurrentRenderProcessId());
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Verify the visibility of the renderer.
@@ -416,6 +435,7 @@
      * setInForeground(), but it can't be guaranteed because they are triggered from different
      * threads.
      */
+    @Test
     @LargeTest
     @Feature({"ProcessManagement"})
     public void testVisibilityDetermined() throws InterruptedException {
@@ -424,7 +444,8 @@
                 new Callable<Tab>() {
                     @Override
                     public Tab call() {
-                        TabCreator tabCreator = getActivity().getCurrentTabCreator();
+                        TabCreator tabCreator =
+                                mActivityTestRule.getActivity().getCurrentTabCreator();
                         return tabCreator.createNewTab(
                                 new LoadUrlParams(mTestServer.getURL(FILE_PATH)),
                                         TabLaunchType.FROM_CHROME_UI, null);
@@ -434,10 +455,11 @@
         // Ensure the following calls happened:
         //  - FG - setInForeground(true) - when the tab is created in the foreground
         //  - DETERMINED - visibilityDetermined() - after the initial navigation is committed
-        assertEquals("FG;DETERMINED;", mBindingManager.getVisibilityCalls(initialNavigationPid));
+        Assert.assertEquals(
+                "FG;DETERMINED;", mBindingManager.getVisibilityCalls(initialNavigationPid));
 
         // Navigate to about:version which requires a different renderer.
-        loadUrlInTab(ABOUT_VERSION_PATH, PageTransition.LINK, fgTab);
+        mActivityTestRule.loadUrlInTab(ABOUT_VERSION_PATH, PageTransition.LINK, fgTab);
         int secondNavigationPid = getRenderProcessId(fgTab);
         MoreAsserts.assertNotEqual(secondNavigationPid, initialNavigationPid);
         // Ensure the following calls happened:
@@ -448,15 +470,17 @@
         // visibilityDetermined() are triggered from different threads.
         mBindingManager.assertIsInForeground(secondNavigationPid);
         String visibilityCalls = mBindingManager.getVisibilityCalls(secondNavigationPid);
-        assertTrue(visibilityCalls, "BG;FG;DETERMINED;".equals(visibilityCalls)
-                || "BG;DETERMINED;FG;".equals(visibilityCalls));
+        Assert.assertTrue(visibilityCalls,
+                "BG;FG;DETERMINED;".equals(visibilityCalls)
+                        || "BG;DETERMINED;FG;".equals(visibilityCalls));
 
         // Open a tab in the background and load it.
         final Tab bgTab = ThreadUtils.runOnUiThreadBlockingNoException(
                 new Callable<Tab>() {
                     @Override
                     public Tab call() {
-                        TabCreator tabCreator = getActivity().getCurrentTabCreator();
+                        TabCreator tabCreator =
+                                mActivityTestRule.getActivity().getCurrentTabCreator();
                         Tab tab = tabCreator.createNewTab(
                                 new LoadUrlParams(mTestServer.getURL(FILE_PATH)),
                                         TabLaunchType.FROM_LONGPRESS_BACKGROUND, null);
@@ -471,7 +495,7 @@
         // Ensure the following calls happened:
         //  - BG - setInForeground(false) - when tab is created in the background
         //  - DETERMINED - visibilityDetermined() - after the navigation is committed
-        assertEquals("BG;DETERMINED;", mBindingManager.getVisibilityCalls(bgNavigationPid));
+        Assert.assertEquals("BG;DETERMINED;", mBindingManager.getVisibilityCalls(bgNavigationPid));
     }
 
     /**
@@ -479,36 +503,39 @@
      * process and discards its old render process. Test that visibilityDetermined() is called for
      * the swapped in render process.
      */
+    @Test
     @LargeTest
     @Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"ProcessManagement"})
     public void testVisibilityDeterminedNavigateToPrerenderedPage() throws InterruptedException {
-        loadUrl(mTestServer.getURL(FILE_PATH));
-        Tab tab = getActivity().getActivityTab();
+        mActivityTestRule.loadUrl(mTestServer.getURL(FILE_PATH));
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         int pid1 = getRenderProcessId(tab);
 
         String prerenderUrl = mTestServer.getURL(FILE_PATH2);
         PrerenderTestHelper.prerenderUrl(prerenderUrl, tab);
-        assertEquals(TabLoadStatus.FULL_PRERENDERED_PAGE_LOAD, loadUrl(prerenderUrl));
+        Assert.assertEquals(
+                TabLoadStatus.FULL_PRERENDERED_PAGE_LOAD, mActivityTestRule.loadUrl(prerenderUrl));
 
         int pid2 = getRenderProcessId(tab);
         MoreAsserts.assertNotEqual(pid1, pid2);
 
-        assertTrue(mBindingManager.getVisibilityCalls(pid1).contains("DETERMINED;"));
-        assertTrue(mBindingManager.getVisibilityCalls(pid2).contains("DETERMINED;"));
+        Assert.assertTrue(mBindingManager.getVisibilityCalls(pid1).contains("DETERMINED;"));
+        Assert.assertTrue(mBindingManager.getVisibilityCalls(pid2).contains("DETERMINED;"));
     }
 
     /**
      * Verifies that BindingManager.releaseAllModerateBindings() is called once all the sandboxed
      * services are allocated.
      */
+    @Test
     @ChildProcessAllocatorSettings(sandboxedServiceCount = 4)
     @LargeTest
     @Feature({"ProcessManagement"})
     public void testReleaseAllModerateBindings() throws InterruptedException {
-        final TabCreator tabCreator = getActivity().getCurrentTabCreator();
+        final TabCreator tabCreator = mActivityTestRule.getActivity().getCurrentTabCreator();
         final Tab[] tabs = new Tab[3];
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Foreground tab.
@@ -522,9 +549,9 @@
         ChromeTabUtils.waitForTabPageLoaded(tabs[0], "about:blank");
         ChromeTabUtils.waitForTabPageLoaded(tabs[1], "about:blank");
         // At this point 3 sanboxed services are allocated; the initial one + 2 new tabs.
-        assertFalse(mBindingManager.isReleaseAllModerateBindingsCalled());
+        Assert.assertFalse(mBindingManager.isReleaseAllModerateBindingsCalled());
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Foreground tab.
@@ -538,33 +565,34 @@
     }
 
     // Test crashes on tablets. See crbug.com/594407
+    @Test
     @LargeTest
     @Feature({"ProcessManagement"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     public void testRestoreSharedRenderer() throws Exception {
-        loadUrl(mTestServer.getURL(SHARED_RENDERER_PAGE_PATH));
+        mActivityTestRule.loadUrl(mTestServer.getURL(SHARED_RENDERER_PAGE_PATH));
 
         final Tab[] tabs = new Tab[2];
-        tabs[0] = getActivity().getActivityTab();
-        singleClickView(tabs[0].getView());
+        tabs[0] = mActivityTestRule.getActivity().getActivityTab();
+        TouchCommon.singleClickView(tabs[0].getView());
 
         CriteriaHelper.pollInstrumentationThread(new Criteria("Child tab isn't opened.") {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getCurrentTabModel().getCount() == 2
-                        && tabs[0] != getActivity().getActivityTab()
-                        && getActivity()
+                return mActivityTestRule.getActivity().getCurrentTabModel().getCount() == 2
+                        && tabs[0] != mActivityTestRule.getActivity().getActivityTab()
+                        && mActivityTestRule.getActivity()
                                    .getActivityTab()
                                    .getContentViewCore()
                                    .getCurrentRenderProcessId()
                         != 0;
             }
         });
-        tabs[1] = getActivity().getActivityTab();
-        assertEquals(tabs[0].getContentViewCore().getCurrentRenderProcessId(),
+        tabs[1] = mActivityTestRule.getActivity().getActivityTab();
+        Assert.assertEquals(tabs[0].getContentViewCore().getCurrentRenderProcessId(),
                 tabs[1].getContentViewCore().getCurrentRenderProcessId());
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Verify the visibility of the renderer.
@@ -573,7 +601,7 @@
             }
         });
 
-        assertTrue(ChildProcessLauncher.crashProcessForTesting(
+        Assert.assertTrue(ChildProcessLauncher.crashProcessForTesting(
                 tabs[1].getContentViewCore().getCurrentRenderProcessId()));
 
         CriteriaHelper.pollInstrumentationThread(
@@ -584,7 +612,7 @@
                     }
                 });
         // Reload the tab, respawning the renderer.
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 tabs[1].reload();
@@ -607,7 +635,7 @@
                 "setInForeground() was not called for the process.",
                 tabs[1].getContentViewCore().getCurrentRenderProcessId());
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // Verify the visibility of the renderer.
@@ -620,32 +648,27 @@
         });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         // Hook in the test binding manager.
         mBindingManager = new MockBindingManager();
         ChildProcessLauncher.setBindingManagerForTesting(mBindingManager);
 
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
      * @return the index of the given tab in the current tab model
      */
     private int indexOf(Tab tab) {
-        return getActivity().getCurrentTabModel().indexOf(tab);
+        return mActivityTestRule.getActivity().getCurrentTabModel().indexOf(tab);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
index 7055c59..66861f7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BluetoothChooserDialogTest.java
@@ -15,10 +15,19 @@
 import android.widget.Button;
 import android.widget.ListView;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.location.LocationUtils;
 import org.chromium.components.security_state.ConnectionSecurityLevel;
 import org.chromium.content.browser.test.util.Criteria;
@@ -35,8 +44,11 @@
 /**
  * Tests for the BluetoothChooserDialog class.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class BluetoothChooserDialogTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class BluetoothChooserDialogTest {
     /**
      * Works like the BluetoothChooserDialog class, but records calls to native methods instead of
      * calling back to C++.
@@ -54,8 +66,8 @@
         @Override
         void nativeOnDialogFinished(
                 long nativeBluetoothChooserAndroid, int eventType, String deviceId) {
-            assertEquals(nativeBluetoothChooserAndroid, mNativeBluetoothChooserDialogPtr);
-            assertEquals(mFinishedEventType, -1);
+            Assert.assertEquals(nativeBluetoothChooserAndroid, mNativeBluetoothChooserDialogPtr);
+            Assert.assertEquals(mFinishedEventType, -1);
             mFinishedEventType = eventType;
             mFinishedDeviceId = deviceId;
             // The native code calls closeDialog() when OnDialogFinished is called.
@@ -64,26 +76,26 @@
 
         @Override
         void nativeRestartSearch(long nativeBluetoothChooserAndroid) {
-            assertTrue(mNativeBluetoothChooserDialogPtr != 0);
+            Assert.assertTrue(mNativeBluetoothChooserDialogPtr != 0);
             mRestartSearchCount++;
         }
 
         @Override
         void nativeShowBluetoothOverviewLink(long nativeBluetoothChooserAndroid) {
             // We shouldn't be running native functions if the native class has been destroyed.
-            assertTrue(mNativeBluetoothChooserDialogPtr != 0);
+            Assert.assertTrue(mNativeBluetoothChooserDialogPtr != 0);
         }
 
         @Override
         void nativeShowBluetoothAdapterOffLink(long nativeBluetoothChooserAndroid) {
             // We shouldn't be running native functions if the native class has been destroyed.
-            assertTrue(mNativeBluetoothChooserDialogPtr != 0);
+            Assert.assertTrue(mNativeBluetoothChooserDialogPtr != 0);
         }
 
         @Override
         void nativeShowNeedLocationPermissionLink(long nativeBluetoothChooserAndroid) {
             // We shouldn't be running native functions if the native class has been destroyed.
-            assertTrue(mNativeBluetoothChooserDialogPtr != 0);
+            Assert.assertTrue(mNativeBluetoothChooserDialogPtr != 0);
         }
     }
 
@@ -91,15 +103,13 @@
     private FakeLocationUtils mLocationUtils;
     private BluetoothChooserDialogWithFakeNatives mChooserDialog;
 
-    public BluetoothChooserDialogTest() {
-        super(ChromeActivity.class);
-    }
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
-    // ChromeActivityTestCaseBase:
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         mLocationUtils = new FakeLocationUtils();
         LocationUtils.setFactory(new LocationUtils.Factory() {
             @Override
@@ -110,15 +120,9 @@
         mChooserDialog = createDialog();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         LocationUtils.setFactory(null);
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
     }
 
     private BluetoothChooserDialogWithFakeNatives createDialog() {
@@ -126,7 +130,7 @@
                 new Callable<BluetoothChooserDialogWithFakeNatives>() {
                     @Override
                     public BluetoothChooserDialogWithFakeNatives call() {
-                        mWindowAndroid = new ActivityWindowAndroid(getActivity());
+                        mWindowAndroid = new ActivityWindowAndroid(mActivityTestRule.getActivity());
                         BluetoothChooserDialogWithFakeNatives dialog =
                                 new BluetoothChooserDialogWithFakeNatives(mWindowAndroid,
                                         "https://origin.example.com/",
@@ -150,7 +154,7 @@
             }
         });
 
-        assertEquals("Not all items have a view; positions may be incorrect.",
+        Assert.assertEquals("Not all items have a view; positions may be incorrect.",
                 items.getChildCount(), items.getAdapter().getCount());
 
         // Verify first item selected gets selected.
@@ -181,11 +185,12 @@
         return message.replaceAll("</?[^>]*link[^>]*>", "");
     }
 
+    @Test
     @LargeTest
     public void testCancel() {
         ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog;
         Dialog dialog = itemChooser.getDialogForTesting();
-        assertTrue(dialog.isShowing());
+        Assert.assertTrue(dialog.isShowing());
 
         TextViewWithClickableSpans statusView =
                 (TextViewWithClickableSpans) dialog.findViewById(R.id.status);
@@ -194,10 +199,11 @@
 
         // Before we add items to the dialog, the 'searching' message should be
         // showing, the Commit button should be disabled and the list view hidden.
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_searching)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_searching)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.GONE, items.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.GONE, items.getVisibility());
 
         dialog.dismiss();
 
@@ -208,11 +214,12 @@
             }
         });
 
-        assertEquals(BluetoothChooserDialog.DIALOG_FINISHED_CANCELLED,
+        Assert.assertEquals(BluetoothChooserDialog.DIALOG_FINISHED_CANCELLED,
                 mChooserDialog.mFinishedEventType);
-        assertEquals("", mChooserDialog.mFinishedDeviceId);
+        Assert.assertEquals("", mChooserDialog.mFinishedDeviceId);
     }
 
+    @Test
     @LargeTest
     public void testSelectItem() {
         Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting();
@@ -245,38 +252,40 @@
         // the progress spinner should disappear, the Commit button should still
         // be disabled (since nothing's selected), and the list view should
         // show.
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_searching)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_searching)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.VISIBLE, items.getVisibility());
-        assertEquals(View.GONE, progress.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.VISIBLE, items.getVisibility());
+        Assert.assertEquals(View.GONE, progress.getVisibility());
 
         ItemChooserDialog.ItemAdapter itemAdapter =
                 mChooserDialog.mItemChooserDialog.getItemAdapterForTesting();
-        assertTrue(itemAdapter.getItem(0).hasSameContents(
+        Assert.assertTrue(itemAdapter.getItem(0).hasSameContents(
                 "id-1", "Name 1", null /* icon */, null /* iconDescription */));
-        assertTrue(itemAdapter.getItem(1).hasSameContents("id-2", "Name 2",
+        Assert.assertTrue(itemAdapter.getItem(1).hasSameContents("id-2", "Name 2",
                 mChooserDialog.mConnectedIcon, mChooserDialog.mConnectedIconDescription));
-        assertTrue(itemAdapter.getItem(2).hasSameContents("id-3", "Name 3",
+        Assert.assertTrue(itemAdapter.getItem(2).hasSameContents("id-3", "Name 3",
                 mChooserDialog.mSignalStrengthLevelIcon[1],
-                getActivity().getResources().getQuantityString(
+                mActivityTestRule.getActivity().getResources().getQuantityString(
                         R.plurals.signal_strength_level_n_bars, 1, 1)));
         // We show the connected icon even if the device has a signal strength.
-        assertTrue(itemAdapter.getItem(3).hasSameContents("id-4", "Name 4",
+        Assert.assertTrue(itemAdapter.getItem(3).hasSameContents("id-4", "Name 4",
                 mChooserDialog.mConnectedIcon, mChooserDialog.mConnectedIconDescription));
 
         selectItem(mChooserDialog, 2);
 
-        assertEquals(
+        Assert.assertEquals(
                 BluetoothChooserDialog.DIALOG_FINISHED_SELECTED, mChooserDialog.mFinishedEventType);
-        assertEquals("id-2", mChooserDialog.mFinishedDeviceId);
+        Assert.assertEquals("id-2", mChooserDialog.mFinishedDeviceId);
     }
 
+    @Test
     @LargeTest
     public void testNoLocationPermission() {
         ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog;
         Dialog dialog = itemChooser.getDialogForTesting();
-        assertTrue(dialog.isShowing());
+        Assert.assertTrue(dialog.isShowing());
 
         final TextViewWithClickableSpans statusView =
                 (TextViewWithClickableSpans) dialog.findViewById(R.id.status);
@@ -298,15 +307,16 @@
             }
         });
 
-        assertEquals(removeLinkTags(
-                             getActivity().getString(R.string.bluetooth_need_location_permission)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_need_location_permission)),
                 errorView.getText().toString());
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off_help)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_adapter_off_help)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.VISIBLE, errorView.getVisibility());
-        assertEquals(View.GONE, items.getVisibility());
-        assertEquals(View.GONE, progress.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.VISIBLE, errorView.getVisibility());
+        Assert.assertEquals(View.GONE, items.getVisibility());
+        Assert.assertEquals(View.GONE, progress.getVisibility());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -318,7 +328,7 @@
         // Permission was requested.
         MoreAsserts.assertEquals(permissionDelegate.mPermissionsRequested,
                 new String[] {Manifest.permission.ACCESS_COARSE_LOCATION});
-        assertNotNull(permissionDelegate.mCallback);
+        Assert.assertNotNull(permissionDelegate.mCallback);
         // Grant permission.
         mLocationUtils.mLocationGranted = true;
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -330,17 +340,19 @@
             }
         });
 
-        assertEquals(1, mChooserDialog.mRestartSearchCount);
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_searching)),
+        Assert.assertEquals(1, mChooserDialog.mRestartSearchCount);
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_searching)),
                 statusView.getText().toString());
         mChooserDialog.closeDialog();
     }
 
+    @Test
     @LargeTest
     public void testNoLocationServices() {
         ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog;
         Dialog dialog = itemChooser.getDialogForTesting();
-        assertTrue(dialog.isShowing());
+        Assert.assertTrue(dialog.isShowing());
 
         final TextViewWithClickableSpans statusView =
                 (TextViewWithClickableSpans) dialog.findViewById(R.id.status);
@@ -366,16 +378,16 @@
             }
         });
 
-        assertEquals(removeLinkTags(
-                             getActivity().getString(R.string.bluetooth_need_location_services_on)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_need_location_services_on)),
                 errorView.getText().toString());
-        assertEquals(removeLinkTags(getActivity().getString(
-                             R.string.bluetooth_need_location_permission_help)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_need_location_permission_help)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.VISIBLE, errorView.getVisibility());
-        assertEquals(View.GONE, items.getVisibility());
-        assertEquals(View.GONE, progress.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.VISIBLE, errorView.getVisibility());
+        Assert.assertEquals(View.GONE, items.getVisibility());
+        Assert.assertEquals(View.GONE, progress.getVisibility());
 
         // Turn on Location Services.
         mLocationUtils.mSystemLocationSettingsEnabled = true;
@@ -383,12 +395,14 @@
             @Override
             public void run() {
                 mChooserDialog.mLocationModeBroadcastReceiver.onReceive(
-                        getActivity(), new Intent(LocationManager.MODE_CHANGED_ACTION));
+                        mActivityTestRule.getActivity(),
+                        new Intent(LocationManager.MODE_CHANGED_ACTION));
             }
         });
 
-        assertEquals(1, mChooserDialog.mRestartSearchCount);
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_searching)),
+        Assert.assertEquals(1, mChooserDialog.mRestartSearchCount);
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_searching)),
                 statusView.getText().toString());
 
         mChooserDialog.closeDialog();
@@ -396,11 +410,12 @@
 
     // TODO(jyasskin): Test when the user denies Chrome the ability to ask for permission.
 
+    @Test
     @LargeTest
     public void testTurnOnAdapter() {
         final ItemChooserDialog itemChooser = mChooserDialog.mItemChooserDialog;
         Dialog dialog = itemChooser.getDialogForTesting();
-        assertTrue(dialog.isShowing());
+        Assert.assertTrue(dialog.isShowing());
 
         final TextViewWithClickableSpans statusView =
                 (TextViewWithClickableSpans) dialog.findViewById(R.id.status);
@@ -418,14 +433,16 @@
             }
         });
 
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_adapter_off)),
                 errorView.getText().toString());
-        assertEquals(removeLinkTags(getActivity().getString(R.string.bluetooth_adapter_off_help)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.bluetooth_adapter_off_help)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.VISIBLE, errorView.getVisibility());
-        assertEquals(View.GONE, items.getVisibility());
-        assertEquals(View.GONE, progress.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.VISIBLE, errorView.getVisibility());
+        Assert.assertEquals(View.GONE, items.getVisibility());
+        Assert.assertEquals(View.GONE, progress.getVisibility());
 
         // Turn on adapter.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -435,9 +452,9 @@
             }
         });
 
-        assertEquals(View.GONE, errorView.getVisibility());
-        assertEquals(View.GONE, items.getVisibility());
-        assertEquals(View.VISIBLE, progress.getVisibility());
+        Assert.assertEquals(View.GONE, errorView.getVisibility());
+        Assert.assertEquals(View.GONE, items.getVisibility());
+        Assert.assertEquals(View.VISIBLE, progress.getVisibility());
 
         mChooserDialog.closeDialog();
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java
index 25c42d18..51d03315 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/CrashTest.java
@@ -6,31 +6,35 @@
 
 import android.support.test.filters.SmallTest;
 
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /**
  * The class contains a testcase that intentionally crashes.
  */
-public class CrashTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public CrashTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() {
-        // Don't launch activity automatically.
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class CrashTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
      * Intentionally crashing the test. The testcase should be
      * disabled the majority of time.
      */
+    @Test
     @DisabledTest
     @SmallTest
     public void testIntentionalBrowserCrash() throws Exception {
-        startMainActivityFromLauncher();
-        loadUrl("chrome://inducebrowsercrashforrealz");
+        mActivityTestRule.startMainActivityFromLauncher();
+        mActivityTestRule.loadUrl("chrome://inducebrowsercrashforrealz");
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java
index faa46e0..d7281f9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java
@@ -6,12 +6,21 @@
 
 import static org.chromium.content.browser.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL;
 
+import android.support.test.InstrumentationRegistry;
 import android.view.KeyEvent;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -22,7 +31,14 @@
 /**
  * Tests for zooming into & out of a selected & deselected editable text field.
  */
-public class FocusedEditableTextFieldZoomTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class FocusedEditableTextFieldZoomTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final int TEST_TIMEOUT = 5000;
     private static final String TEXTFIELD_DOM_ID = "textfield";
     private static final float FLOAT_DELTA = 0.01f;
@@ -30,20 +46,18 @@
 
     private EmbeddedTestServer mTestServer;
 
-    public FocusedEditableTextFieldZoomTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws Exception {
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(
+                mTestServer.getURL("/chrome/test/data/android/focused_editable_zoom.html"));
+        waitForInitialZoom();
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     void waitForInitialZoom() {
@@ -51,7 +65,8 @@
         // the initial value problematic. We solve this by explicitly specifying the initial zoom
         // level via the viewport tag and waiting for the zoom level to reach that value before we
         // proceed with the rest of the test.
-        final ContentViewCore contentViewCore = getActivity().getActivityTab().getContentViewCore();
+        final ContentViewCore contentViewCore =
+                mActivityTestRule.getActivity().getActivityTab().getContentViewCore();
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -73,11 +88,12 @@
     /*
      * @LargeTest
      */
+    @Test
     @DisabledTest(message = "Broken by subpixel precision changes crbug.com/371119")
     @Feature({"TabContents"})
     public void testZoomInToSelected() throws Throwable {
         // This should focus the text field and initiate a zoom in.
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         final ContentViewCore contentViewCore = tab.getContentViewCore();
         float initialZoomLevel = contentViewCore.getScale();
 
@@ -90,10 +106,11 @@
     /*
      * @LargeTest
      */
+    @Test
     @DisabledTest(message = "Broken by subpixel precision changes crbug.com/371119")
     @Feature({"TabContents"})
     public void testZoomOutOfSelectedIfOnlyBackPressed() throws Throwable {
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
         final ContentViewCore contentViewCore = tab.getContentViewCore();
         final float initialZoomLevel = contentViewCore.getScale();
 
@@ -103,7 +120,8 @@
         // Wait for the zoom in to complete.
         waitForZoomIn(contentViewCore, initialZoomLevel);
 
-        KeyUtils.singleKeyEventView(getInstrumentation(), tab.getView(), KeyEvent.KEYCODE_BACK);
+        KeyUtils.singleKeyEventView(
+                InstrumentationRegistry.getInstrumentation(), tab.getView(), KeyEvent.KEYCODE_BACK);
 
         // We should zoom out to the previous zoom level.
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
@@ -113,11 +131,4 @@
             }
         }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL);
     }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(mTestServer.getURL(
-                "/chrome/test/data/android/focused_editable_zoom.html"));
-        waitForInitialZoom();
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java
index b227281..db3903b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java
@@ -13,17 +13,26 @@
 import android.widget.CheckBox;
 import android.widget.EditText;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.R;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content_public.browser.GestureStateListener;
 
 import java.util.concurrent.Callable;
@@ -33,8 +42,15 @@
 /**
  * Test suite for displaying and functioning of modal dialogs.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class ModalDialogTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ModalDialogTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TAG = "ModalDialogTest";
     private static final String EMPTY_PAGE = UrlUtils.encodeHtmlDataUri(
             "<html><title>Modal Dialog Test</title><p>Testcase.</p></title></html>");
@@ -43,19 +59,16 @@
                     + "return 'Are you sure?';"
                     + "};</script></head></html>");
 
-    public ModalDialogTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(EMPTY_PAGE);
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityWithURL(EMPTY_PAGE);
     }
 
     /**
      * Verifies modal alert-dialog appearance and that JavaScript execution is
      * able to continue after dismissal.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testAlertModalDialog()
@@ -64,16 +77,17 @@
                 executeJavaScriptAndWaitForDialog("alert('Hello Android!');");
 
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         clickOk(jsDialog);
-        assertTrue("JavaScript execution should continue after closing prompt.",
+        Assert.assertTrue("JavaScript execution should continue after closing prompt.",
                 scriptEvent.waitUntilHasValue());
     }
 
     /**
      * Verifies that clicking on a button twice doesn't crash.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testAlertModalDialogWithTwoClicks()
@@ -81,12 +95,12 @@
         OnEvaluateJavaScriptResultHelper scriptEvent =
                 executeJavaScriptAndWaitForDialog("alert('Hello Android');");
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         clickOk(jsDialog);
         clickOk(jsDialog);
 
-        assertTrue("JavaScript execution should continue after closing prompt.",
+        Assert.assertTrue("JavaScript execution should continue after closing prompt.",
                 scriptEvent.waitUntilHasValue());
     }
 
@@ -94,6 +108,7 @@
      * Verifies that modal confirm-dialogs display, two buttons are visible and
      * the return value of [Ok] equals true, [Cancel] equals false.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testConfirmModalDialog()
@@ -102,41 +117,43 @@
                 executeJavaScriptAndWaitForDialog("confirm('Android');");
 
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest());
-        assertNotNull("No cancel button in confirm dialog.", buttons[0]);
-        assertEquals("Cancel button is not visible.", View.VISIBLE, buttons[0].getVisibility());
+        Assert.assertNotNull("No cancel button in confirm dialog.", buttons[0]);
+        Assert.assertEquals(
+                "Cancel button is not visible.", View.VISIBLE, buttons[0].getVisibility());
         if (buttons[1] != null) {
-            assertNotSame("Neutral button visible when it should not.",
-                    View.VISIBLE, buttons[1].getVisibility());
+            Assert.assertNotSame("Neutral button visible when it should not.", View.VISIBLE,
+                    buttons[1].getVisibility());
         }
-        assertNotNull("No OK button in confirm dialog.", buttons[2]);
-        assertEquals("OK button is not visible.", View.VISIBLE, buttons[2].getVisibility());
+        Assert.assertNotNull("No OK button in confirm dialog.", buttons[2]);
+        Assert.assertEquals("OK button is not visible.", View.VISIBLE, buttons[2].getVisibility());
 
         clickOk(jsDialog);
-        assertTrue("JavaScript execution should continue after closing dialog.",
+        Assert.assertTrue("JavaScript execution should continue after closing dialog.",
                 scriptEvent.waitUntilHasValue());
 
         String resultString = scriptEvent.getJsonResultAndClear();
-        assertEquals("Invalid return value.", "true", resultString);
+        Assert.assertEquals("Invalid return value.", "true", resultString);
 
         // Try again, pressing cancel this time.
         scriptEvent = executeJavaScriptAndWaitForDialog("confirm('Android');");
         jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         clickCancel(jsDialog);
-        assertTrue("JavaScript execution should continue after closing dialog.",
+        Assert.assertTrue("JavaScript execution should continue after closing dialog.",
                 scriptEvent.waitUntilHasValue());
 
         resultString = scriptEvent.getJsonResultAndClear();
-        assertEquals("Invalid return value.", "false", resultString);
+        Assert.assertEquals("Invalid return value.", "false", resultString);
     }
 
     /**
      * Verifies that modal prompt-dialogs display and the result is returned.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testPromptModalDialog()
@@ -146,7 +163,7 @@
                 executeJavaScriptAndWaitForDialog("prompt('Android', 'default');");
 
         final JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         // Set the text in the prompt field of the dialog.
         boolean result = ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
@@ -159,14 +176,14 @@
                 return true;
             }
         });
-        assertTrue("Failed to find prompt view in prompt dialog.", result);
+        Assert.assertTrue("Failed to find prompt view in prompt dialog.", result);
 
         clickOk(jsDialog);
-        assertTrue("JavaScript execution should continue after closing prompt.",
+        Assert.assertTrue("JavaScript execution should continue after closing prompt.",
                 scriptEvent.waitUntilHasValue());
 
         String resultString = scriptEvent.getJsonResultAndClear();
-        assertEquals("Invalid return value.", '"' + promptText + '"', resultString);
+        Assert.assertEquals("Invalid return value.", '"' + promptText + '"', resultString);
     }
 
     private static class TapGestureStateListener extends GestureStateListener {
@@ -192,9 +209,10 @@
     private void tapViewAndWait() throws InterruptedException, TimeoutException {
         final TapGestureStateListener tapGestureStateListener = new TapGestureStateListener();
         int callCount = tapGestureStateListener.getCallCount();
-        getActivity().getCurrentContentViewCore().addGestureStateListener(tapGestureStateListener);
+        mActivityTestRule.getActivity().getCurrentContentViewCore().addGestureStateListener(
+                tapGestureStateListener);
 
-        singleClickView(getActivity().getActivityTab().getView());
+        TouchCommon.singleClickView(mActivityTestRule.getActivity().getActivityTab().getView());
         tapGestureStateListener.waitForTap(callCount);
     }
 
@@ -202,26 +220,30 @@
      * Verifies beforeunload dialogs are shown and they block/allow navigation
      * as appropriate.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testBeforeUnloadDialog()
             throws InterruptedException, TimeoutException, ExecutionException {
-        loadUrl(BEFORE_UNLOAD_URL);
+        mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL);
         // JavaScript onbeforeunload dialogs require a user gesture.
         tapViewAndWait();
         executeJavaScriptAndWaitForDialog("history.back();");
 
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
         checkButtonPresenceVisibilityText(jsDialog, 0, R.string.cancel, "Cancel");
         clickCancel(jsDialog);
 
-        assertEquals(BEFORE_UNLOAD_URL, getActivity().getCurrentContentViewCore()
-                .getWebContents().getUrl());
+        Assert.assertEquals(BEFORE_UNLOAD_URL,
+                mActivityTestRule.getActivity()
+                        .getCurrentContentViewCore()
+                        .getWebContents()
+                        .getUrl());
         executeJavaScriptAndWaitForDialog("history.back();");
 
         jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
         checkButtonPresenceVisibilityText(jsDialog, 2, R.string.leave, "Leave");
 
         final TestCallbackHelperContainer.OnPageFinishedHelper onPageLoaded =
@@ -229,25 +251,29 @@
         int callCount = onPageLoaded.getCallCount();
         clickOk(jsDialog);
         onPageLoaded.waitForCallback(callCount);
-        assertEquals(EMPTY_PAGE, getActivity().getCurrentContentViewCore()
-                .getWebContents().getUrl());
+        Assert.assertEquals(EMPTY_PAGE,
+                mActivityTestRule.getActivity()
+                        .getCurrentContentViewCore()
+                        .getWebContents()
+                        .getUrl());
     }
 
     /**
      * Verifies that when showing a beforeunload dialogs as a result of a page
      * reload, the correct UI strings are used.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testBeforeUnloadOnReloadDialog()
             throws InterruptedException, TimeoutException, ExecutionException {
-        loadUrl(BEFORE_UNLOAD_URL);
+        mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL);
         // JavaScript onbeforeunload dialogs require a user gesture.
         tapViewAndWait();
         executeJavaScriptAndWaitForDialog("window.location.reload();");
 
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         checkButtonPresenceVisibilityText(jsDialog, 0, R.string.cancel, "Cancel");
         checkButtonPresenceVisibilityText(jsDialog, 2, R.string.reload, "Reload");
@@ -257,6 +283,7 @@
      * Verifies that repeated dialogs give the option to disable dialogs
      * altogether and then that disabling them works.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testDisableRepeatedDialogs()
@@ -266,7 +293,7 @@
 
         // Show a dialog once.
         JavascriptAppModalDialog jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
 
         clickCancel(jsDialog);
         scriptEvent.waitUntilHasValue();
@@ -274,7 +301,7 @@
         // Show it again, it should have the option to suppress subsequent dialogs.
         scriptEvent = executeJavaScriptAndWaitForDialog("alert('Android');");
         jsDialog = getCurrentDialog();
-        assertNotNull("No dialog showing.", jsDialog);
+        Assert.assertNotNull("No dialog showing.", jsDialog);
         final AlertDialog dialog = jsDialog.getDialogForTest();
         String errorMessage = ThreadUtils.runOnUiThreadBlocking(new Callable<String>() {
             @Override
@@ -289,14 +316,15 @@
                 return null;
             }
         });
-        assertNull(errorMessage, errorMessage);
+        Assert.assertNull(errorMessage, errorMessage);
         clickCancel(jsDialog);
         scriptEvent.waitUntilHasValue();
 
         scriptEvent.evaluateJavaScriptForTests(
-                getActivity().getCurrentContentViewCore().getWebContents(),
+                mActivityTestRule.getActivity().getCurrentContentViewCore().getWebContents(),
                 "alert('Android');");
-        assertTrue("No further dialog boxes should be shown.", scriptEvent.waitUntilHasValue());
+        Assert.assertTrue(
+                "No further dialog boxes should be shown.", scriptEvent.waitUntilHasValue());
     }
 
     /**
@@ -304,6 +332,7 @@
      * to accept the dialog. Verifies that the dialog is dismissed when the tab
      * is closed.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     public void testDialogDismissedAfterClosingTab() {
@@ -312,7 +341,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                ChromeActivity activity = getActivity();
+                ChromeActivity activity = mActivityTestRule.getActivity();
                 activity.getCurrentTabModel().closeTab(activity.getActivityTab());
             }
         });
@@ -337,7 +366,7 @@
     private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog(
             final OnEvaluateJavaScriptResultHelper helper, String script) {
         helper.evaluateJavaScriptForTests(
-                getActivity().getCurrentContentViewCore().getWebContents(),
+                mActivityTestRule.getActivity().getCurrentContentViewCore().getWebContents(),
                 script);
         CriteriaHelper.pollInstrumentationThread(new JavascriptAppModalDialogShownCriteria(
                 "Could not spawn or locate a modal dialog.", true));
@@ -429,16 +458,16 @@
             int expectedTextResourceId, String readableName) throws ExecutionException {
         final Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest());
         final Button button = buttons[buttonIndex];
-        assertNotNull("No '" + readableName + "' button in confirm dialog.", button);
-        assertEquals("'" + readableName + "' button is not visible.",
-                View.VISIBLE,
+        Assert.assertNotNull("No '" + readableName + "' button in confirm dialog.", button);
+        Assert.assertEquals("'" + readableName + "' button is not visible.", View.VISIBLE,
                 button.getVisibility());
-        assertEquals("'" + readableName + "' button has wrong text",
-                getActivity().getResources().getString(expectedTextResourceId),
+        Assert.assertEquals("'" + readableName + "' button has wrong text",
+                mActivityTestRule.getActivity().getResources().getString(expectedTextResourceId),
                 button.getText().toString());
     }
 
     private TestCallbackHelperContainer getActiveTabTestCallbackHelperContainer() {
-        return new TestCallbackHelperContainer(getActivity().getCurrentContentViewCore());
+        return new TestCallbackHelperContainer(
+                mActivityTestRule.getActivity().getCurrentContentViewCore());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
index 682f709..d50d9ee5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
@@ -8,12 +8,20 @@
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.LoadUrlParams;
@@ -21,23 +29,27 @@
 import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.content_public.browser.NavigationHistory;
 
+import java.util.concurrent.atomic.AtomicReference;
+
 /**
  * Tests for the navigation popup.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class NavigationPopupTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class NavigationPopupTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final int INVALID_NAVIGATION_INDEX = -1;
 
     private Profile mProfile;
 
-    public NavigationPopupTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -46,11 +58,6 @@
         });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
     // Exists solely to expose protected methods to this test.
     private static class TestNavigationHistory extends NavigationHistory {
         @Override
@@ -223,19 +230,25 @@
         public void setEntryExtraData(int index, String key, String value) {}
     }
 
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testFaviconFetching() {
         final TestNavigationController controller = new TestNavigationController();
-        final NavigationPopup popup = new NavigationPopup(
-                mProfile, getActivity(), controller, true);
-        popup.setWidth(300);
-        popup.setHeight(300);
-        popup.setAnchorView(getActivity().getCurrentContentViewCore().getContainerView());
+        final AtomicReference<NavigationPopup> popupReference = new AtomicReference<>();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
+                NavigationPopup popup = new NavigationPopup(
+                        mProfile, mActivityTestRule.getActivity(), controller, true);
+                popup.setWidth(300);
+                popup.setHeight(300);
+                popup.setAnchorView(mActivityTestRule.getActivity()
+                                            .getCurrentContentViewCore()
+                                            .getContainerView());
+
                 popup.show();
+                popupReference.set(popup);
             }
         });
 
@@ -255,37 +268,43 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                popup.dismiss();
+                popupReference.get().dismiss();
             }
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"Navigation"})
     public void testItemSelection() {
         final TestNavigationController controller = new TestNavigationController();
-        final NavigationPopup popup =
-                new NavigationPopup(mProfile, getActivity(), controller, true);
-        popup.setWidth(300);
-        popup.setHeight(300);
-        popup.setAnchorView(getActivity().getCurrentContentViewCore().getContainerView());
+        final AtomicReference<NavigationPopup> popupReference = new AtomicReference<>();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
+                NavigationPopup popup = new NavigationPopup(
+                        mProfile, mActivityTestRule.getActivity(), controller, true);
+                popup.setWidth(300);
+                popup.setHeight(300);
+                popup.setAnchorView(mActivityTestRule.getActivity()
+                                            .getCurrentContentViewCore()
+                                            .getContainerView());
+
                 popup.show();
+                popupReference.set(popup);
             }
         });
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                popup.performItemClick(1);
+                popupReference.get().performItemClick(1);
             }
         });
 
-        assertFalse("Popup did not hide as expected.", popup.isShowing());
-        assertEquals("Popup attempted to navigate to the wrong index", 5,
-                controller.mNavigatedIndex);
+        Assert.assertFalse("Popup did not hide as expected.", popupReference.get().isShowing());
+        Assert.assertEquals(
+                "Popup attempted to navigate to the wrong index", 5, controller.mNavigatedIndex);
     }
 
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java
index a5f0706b..2e157e6b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java
@@ -8,11 +8,17 @@
 import android.support.test.filters.MediumTest;
 import android.test.MoreAsserts;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -31,7 +37,14 @@
  * Integration test to ensure that OSK resizes only the visual viewport.
  */
 
-public class OSKOverscrollTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OSKOverscrollTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String FIXED_FOOTER_PAGE = UrlUtils.encodeHtmlDataUri(""
             + "<html>"
             + "<head>"
@@ -65,23 +78,15 @@
     // point. Need some buffer for error.
     private static final int ERROR_EPS_PIX = 1;
 
-    public OSKOverscrollTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() {
-        // Don't launch activity automatically.
-    }
-
     private void waitForKeyboard() {
         // Wait until the keyboard is showing.
         CriteriaHelper.pollUiThread(new Criteria("Keyboard was never shown.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(
-                        getActivity(),
-                        getActivity().getCurrentContentViewCore().getContainerView());
+                return UiUtils.isKeyboardShowing(mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity()
+                                .getCurrentContentViewCore()
+                                .getContainerView());
             }
         });
     }
@@ -93,7 +98,7 @@
             MoreAsserts.assertNotEqual(jsonText.trim().toLowerCase(Locale.US), "null");
             return Integer.parseInt(jsonText);
         } catch (Exception ex) {
-            fail(ex.toString());
+            Assert.fail(ex.toString());
         }
         return -1;
     }
@@ -109,19 +114,20 @@
      * @throws TimeoutException
      * @throws ExecutionException
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add({ChromeSwitches.ENABLE_OSK_OVERSCROLL})
     @RetryOnFailure
     public void testOnlyVisualViewportResizes()
             throws InterruptedException, TimeoutException, ExecutionException {
-        startMainActivityWithURL(FIXED_FOOTER_PAGE);
+        mActivityTestRule.startMainActivityWithURL(FIXED_FOOTER_PAGE);
 
         final AtomicReference<ContentViewCore> viewCoreRef = new AtomicReference<ContentViewCore>();
         final AtomicReference<WebContents> webContentsRef = new AtomicReference<WebContents>();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                viewCoreRef.set(getActivity().getCurrentContentViewCore());
+                viewCoreRef.set(mActivityTestRule.getActivity().getCurrentContentViewCore());
                 webContentsRef.set(viewCoreRef.get().getWebContents());
             }
         });
@@ -143,7 +149,7 @@
         // Get the position of the footer after bringing up the OSK. This should be the same as the
         // position before because only the visual viewport should have resized.
         Rect footerPositionAfter = DOMUtils.getNodeBounds(webContentsRef.get(), "footer");
-        assertEquals(footerPositionBefore, footerPositionAfter);
+        Assert.assertEquals(footerPositionBefore, footerPositionAfter);
 
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
             @Override
@@ -151,7 +157,9 @@
                 // Verify that the size of the viewport before the OSK show is equal to the size of
                 // the viewport after the OSK show plus the size of the keyboard.
                 int viewportHeightAfterCss = getViewportHeight(webContentsRef.get());
-                int keyboardHeight = getActivity().getActivityTab().getSystemWindowInsetBottom();
+                int keyboardHeight = mActivityTestRule.getActivity()
+                                             .getActivityTab()
+                                             .getSystemWindowInsetBottom();
 
                 int priorHeight = (int) (viewportHeightBeforeCss * cssToDevicePixFactor);
                 int afterHeightPlusKeyboard =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PopularUrlsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PopularUrlsTest.java
index 0909c29..680c61f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/PopularUrlsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PopularUrlsTest.java
@@ -7,15 +7,25 @@
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
 import android.os.Environment;
+import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
 import android.util.Log;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Manual;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.PageTransition;
 
@@ -39,7 +49,13 @@
  * page load. When aborted, they save the last opened URL in /sdcard/test_status.txt, so that they
  * can continue opening the next URL when they are restarted.
  */
-public class PopularUrlsTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class PopularUrlsTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TAG = "PopularUrlsTest";
     private static final String NEW_LINE = System.getProperty("line.separator");
@@ -61,29 +77,19 @@
     private boolean mFailed;
     private boolean mDoShortWait;
 
-    public PopularUrlsTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         mStatus = new RunStatus(STATUS_FILE);
         mFailed = false;
         mDoShortWait = checkDoShortWait();
-        super.setUp();
+        mActivityTestRule.startMainActivityFromLauncher();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (mStatus != null) {
             mStatus.cleanUp();
         }
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityFromLauncher();
     }
 
     private BufferedReader getInputStream(File inputFile) throws FileNotFoundException {
@@ -224,7 +230,7 @@
      */
     public void loadUrl(final String url, OutputStreamWriter failureWriter)
             throws InterruptedException, IOException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         final CallbackHelper loadedCallback = new CallbackHelper();
         final CallbackHelper failedCallback = new CallbackHelper();
         final CallbackHelper crashedCallback = new CallbackHelper();
@@ -246,10 +252,10 @@
             }
         });
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                Tab tab = getActivity().getActivityTab();
+                Tab tab = mActivityTestRule.getActivity().getActivityTab();
                 int pageTransition = PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR;
                 tab.loadUrl(new LoadUrlParams(url, pageTransition));
             }
@@ -304,13 +310,13 @@
             mFailed = true;
         }
         // Try to stop page load.
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                getActivity().getActivityTab().stopLoading();
+                mActivityTestRule.getActivity().getActivityTab().stopLoading();
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     /**
@@ -360,7 +366,7 @@
                 loadUrl(page, failureWriter);
                 long stopTime = System.currentTimeMillis();
 
-                String currentUrl = getActivity().getActivityTab().getUrl();
+                String currentUrl = mActivityTestRule.getActivity().getActivityTab().getUrl();
                 Log.i(TAG, "Finish: " + currentUrl);
                 logToStream(page + "|" + (stopTime - startTime) + NEW_LINE, outputWriter);
                 mStatus.incrementPage();
@@ -388,7 +394,7 @@
             int loopCount = perf ? PERF_LOOPCOUNT : STABILITY_LOOPCOUNT;
             try {
                 loopUrls(bufferedReader, outputWriter, failureWriter, true, loopCount);
-                assertFalse(
+                Assert.assertFalse(
                         String.format("Failed to load all pages. Take a look at %s", FAILURE_FILE),
                         mFailed);
             } finally {
@@ -398,7 +404,7 @@
             }
         } catch (FileNotFoundException fnfe) {
             Log.e(TAG, fnfe.getMessage(), fnfe);
-            fail(String.format("URL file %s is not found.", INPUT_FILE));
+            Assert.fail(String.format("URL file %s is not found.", INPUT_FILE));
         } finally {
             if (outputWriter != null) {
                 outputWriter.close();
@@ -412,6 +418,7 @@
     /**
      * Repeats loading all URLs by PERF_LOOPCOUNT times, and records the time each load takes.
      */
+    @Test
     @Manual
     public void testLoadPerformance() throws IOException, InterruptedException {
         loadPages(true);
@@ -420,6 +427,7 @@
     /**
      * Loads all URLs.
      */
+    @Test
     @Manual
     public void testStability() throws IOException, InterruptedException {
         loadPages(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java
index 8e53cfd..20ff6ab 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PopupTest.java
@@ -4,17 +4,27 @@
 
 package org.chromium.chrome.browser;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.text.TextUtils;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.infobar.InfoBar;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TouchCommon;
@@ -26,51 +36,50 @@
 /**
  * Tests whether popup windows appear.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class PopupTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class PopupTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String POPUP_HTML_PATH = "/chrome/test/data/android/popup_test.html";
 
     private String mPopupHtmlUrl;
     private EmbeddedTestServer mTestServer;
 
-    public PopupTest() {
-        super(ChromeActivity.class);
-    }
-
     private int getNumInfobarsShowing() {
-        return getInfoBars().size();
+        return mActivityTestRule.getInfoBars().size();
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                assertTrue(getNumInfobarsShowing() == 0);
+                Assert.assertTrue(getNumInfobarsShowing() == 0);
             }
         });
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mPopupHtmlUrl = mTestServer.getURL(POPUP_HTML_PATH);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @MediumTest
     @Feature({"Popup"})
     public void testPopupInfobarAppears() throws Exception {
-        loadUrl(mPopupHtmlUrl);
+        mActivityTestRule.loadUrl(mPopupHtmlUrl);
         CriteriaHelper.pollUiThread(Criteria.equals(1, new Callable<Integer>() {
             @Override
             public Integer call() {
@@ -79,22 +88,23 @@
         }));
     }
 
+    @Test
     @MediumTest
     @Feature({"Popup"})
     public void testPopupWindowsAppearWhenAllowed() throws Exception {
-        final TabModelSelector selector = getActivity().getTabModelSelector();
+        final TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector();
 
-        loadUrl(mPopupHtmlUrl);
+        mActivityTestRule.loadUrl(mPopupHtmlUrl);
         CriteriaHelper.pollUiThread(Criteria.equals(1, new Callable<Integer>() {
             @Override
             public Integer call() {
                 return getNumInfobarsShowing();
             }
         }));
-        assertEquals(1, selector.getTotalTabCount());
+        Assert.assertEquals(1, selector.getTotalTabCount());
         final InfoBarContainer container = selector.getCurrentTab().getInfoBarContainer();
         ArrayList<InfoBar> infobars = container.getInfoBarsForTesting();
-        assertEquals(1, infobars.size());
+        Assert.assertEquals(1, infobars.size());
 
         // Wait until the animations are done, then click the "open popups" button.
         final InfoBar infobar = infobars.get(0);
@@ -116,11 +126,11 @@
             }
         }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
 
-        assertEquals(4, selector.getTotalTabCount());
+        Assert.assertEquals(4, selector.getTotalTabCount());
         int currentTabId = selector.getCurrentTab().getId();
 
         // Test that revisiting the original page makes popup windows immediately.
-        loadUrl(mPopupHtmlUrl);
+        mActivityTestRule.loadUrl(mPopupHtmlUrl);
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -129,6 +139,6 @@
                 return TextUtils.equals("Three", selector.getCurrentTab().getTitle());
             }
         }, 7500, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
-        assertNotSame(currentTabId, selector.getCurrentTab().getId());
+        Assert.assertNotSame(currentTabId, selector.getCurrentTab().getId());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java
index bc21ffe..513f2cd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java
@@ -7,11 +7,19 @@
 import android.support.test.filters.MediumTest;
 import android.text.TextUtils;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.BuildInfo;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -22,29 +30,33 @@
 /**
  * Test to make sure browser and renderer are seperated process.
  */
-public class ProcessIsolationTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-    public ProcessIsolationTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ProcessIsolationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
      * Verifies that process isolation works, i.e., that the browser and
      * renderer processes use different user IDs.
      * @throws InterruptedException
      */
+    @Test
     @MediumTest
     @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/517611")
     @Feature({"Browser", "Security"})
     @RetryOnFailure
     public void testProcessIsolationForRenderers() throws InterruptedException {
-        int tabsCount = getActivity().getCurrentTabModel().getCount();
+        int tabsCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
         // The ActivityManager can be used to retrieve the current processes, but the reported UID
         // in the RunningAppProcessInfo for isolated processes is the same as the parent process
         // (see b/7724486, closed as "Working as intended").
         // So we have to resort to parsing the ps output.
         String packageName = BuildInfo.getPackageName();
-        assertFalse("Failed to retrieve package name for current version of Chrome.",
-                    TextUtils.isEmpty(packageName));
+        Assert.assertFalse("Failed to retrieve package name for current version of Chrome.",
+                TextUtils.isEmpty(packageName));
 
         ArrayList<String> uids = new ArrayList<String>();
         BufferedReader reader = null;
@@ -55,7 +67,7 @@
             Process psProcess = Runtime.getRuntime().exec("ps");
             reader = new BufferedReader(new InputStreamReader(psProcess.getInputStream()));
             String line = reader.readLine();
-            assertNotNull(line);
+            Assert.assertNotNull(line);
             final String[] lineSections = line.split("\\s+");
             int pidIndex = -1;
             for (int index = 0; index < lineSections.length; index++) {
@@ -64,13 +76,13 @@
                     break;
                 }
             }
-            assertNotSame(-1, pidIndex);
+            Assert.assertNotSame(-1, pidIndex);
 
             while ((line = reader.readLine()) != null) {
                 sb.append(line).append('\n');
                 if (line.indexOf(packageName) != -1) {
                     final String uid = line.split("\\s+")[pidIndex];
-                    assertNotNull("Failed to retrieve UID from " + line, uid);
+                    Assert.assertNotNull("Failed to retrieve UID from " + line, uid);
                     if (line.indexOf("sandboxed_process") != -1) {
                         // Renderer process.
                         uids.add(uid);
@@ -91,7 +103,7 @@
                 }
             }
         } catch (IOException ioe) {
-            fail("Failed to read ps output.");
+            Assert.fail("Failed to read ps output.");
         } finally {
             if (reader != null) {
                 try {
@@ -101,22 +113,21 @@
                 }
             }
         }
-        assertTrue("Browser process not found in ps output: \n" + sb.toString(),
-                 hasBrowserProcess);
+        Assert.assertTrue(
+                "Browser process not found in ps output: \n" + sb.toString(), hasBrowserProcess);
 
         // We should have the same number of process as tabs count. Sometimes
         // there can be extra utility sandbox process so we check for greater than.
-        assertTrue(
-                "Renderer processes not found in ps output: \n" + sb.toString(),
+        Assert.assertTrue("Renderer processes not found in ps output: \n" + sb.toString(),
                 rendererProcessesCount >= tabsCount);
 
-        assertEquals("Found at least two processes with the same UID in ps output: \n"
-                + sb.toString(),
+        Assert.assertEquals(
+                "Found at least two processes with the same UID in ps output: \n" + sb.toString(),
                 uids.size(), new HashSet<String>(uids).size());
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityFromLauncher();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityFromLauncher();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
index 3865d5d..ad01067 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
@@ -4,15 +4,25 @@
 
 package org.chromium.chrome.browser;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v7.app.AlertDialog;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
@@ -25,54 +35,55 @@
 /**
  * Integration tests verifying that form resubmission dialogs are correctly displayed and handled.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class RepostFormWarningTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class RepostFormWarningTest {
     // Active tab.
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private Tab mTab;
     // Callback helper that manages waiting for pageloads to finish.
     private TestCallbackHelperContainer mCallbackHelper;
 
     private EmbeddedTestServer mTestServer;
 
-    public RepostFormWarningTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
-        mTab = getActivity().getActivityTab();
+        mTab = mActivityTestRule.getActivity().getActivityTab();
         mCallbackHelper = new TestCallbackHelperContainer(mTab.getContentViewCore());
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /** Verifies that the form resubmission warning is not displayed upon first POST navigation. */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testFormFirstNavigation() throws Throwable {
         // Load the url posting data for the first time.
         postNavigation();
         mCallbackHelper.getOnPageFinishedHelper().waitForCallback(0);
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // Verify that the form resubmission warning was not shown.
-        assertNull("Form resubmission warning shown upon first load.",
+        Assert.assertNull("Form resubmission warning shown upon first load.",
                 RepostFormWarningDialog.getCurrentDialogForTesting());
     }
 
     /** Verifies that confirming the form reload performs the reload. */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testFormResubmissionContinue() throws Throwable {
@@ -89,7 +100,7 @@
         mCallbackHelper.getOnPageFinishedHelper().waitForCallback(1);
 
         // Verify that the reference to the dialog in RepostFormWarningDialog was cleared.
-        assertNull("Form resubmission warning dialog was not dismissed correctly.",
+        Assert.assertNull("Form resubmission warning dialog was not dismissed correctly.",
                 RepostFormWarningDialog.getCurrentDialogForTesting());
     }
 
@@ -98,6 +109,7 @@
      * after the "Cancel" button is clicked to verify that the load was not triggered, which blocks
      * for CallbackHelper's default timeout upon each execution.
      */
+    @Test
     @SmallTest
     @Feature({"Navigation"})
     public void testFormResubmissionCancel() throws Throwable {
@@ -117,16 +129,17 @@
         } catch (TimeoutException ex) {
             timedOut = true;
         }
-        assertTrue("Page was reloaded despite selecting Cancel.", timedOut);
+        Assert.assertTrue("Page was reloaded despite selecting Cancel.", timedOut);
 
         // Verify that the reference to the dialog in RepostFormWarningDialog was cleared.
-        assertNull("Form resubmission warning dialog was not dismissed correctly.",
+        Assert.assertNull("Form resubmission warning dialog was not dismissed correctly.",
                 RepostFormWarningDialog.getCurrentDialogForTesting());
     }
 
     /**
      * Verifies that destroying the Tab dismisses the form resubmission dialog.
      */
+    @Test
     @SmallTest
     @Feature({"Navigation"})
     public void testFormResubmissionTabDestroyed() throws Throwable {
@@ -141,7 +154,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().getCurrentTabModel().closeTab(mTab);
+                mActivityTestRule.getActivity().getCurrentTabModel().closeTab(mTab);
             }
         });
 
@@ -175,7 +188,7 @@
         final String url = "/chrome/test/data/android/test.html";
         final byte[] postData = new byte[] { 42 };
 
-        runTestOnUiThread(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 mTab.loadUrl(LoadUrlParams.createLoadHttpPostParams(
@@ -186,7 +199,7 @@
 
     /** Reloads mTab. */
     private void reload() throws Throwable {
-        runTestOnUiThread(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 mTab.reload();
@@ -196,7 +209,7 @@
 
     /** Clicks the given button in the given dialog. */
     private void clickButton(final AlertDialog dialog, final int buttonId) throws Throwable {
-        runTestOnUiThread(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 dialog.getButton(buttonId).performClick();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
index ac8125f..fbe0293e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SelectFileDialogTest.java
@@ -11,11 +11,19 @@
 import android.provider.MediaStore;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -26,7 +34,14 @@
 /**
  * Integration test for select file dialog used for <input type="file" />
  */
-public class SelectFileDialogTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SelectFileDialogTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
             "<html><head><meta name=\"viewport\""
             + "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>"
@@ -77,31 +92,29 @@
     private ContentViewCore mContentViewCore;
     private ActivityWindowAndroidForTest mActivityWindowAndroidForTest;
 
-    public SelectFileDialogTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(DATA_URL);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mActivityTestRule.startMainActivityWithURL(DATA_URL);
 
-        mActivityWindowAndroidForTest = new ActivityWindowAndroidForTest(getActivity());
-        SelectFileDialog.setWindowAndroidForTests(mActivityWindowAndroidForTest);
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mActivityWindowAndroidForTest =
+                        new ActivityWindowAndroidForTest(mActivityTestRule.getActivity());
+                SelectFileDialog.setWindowAndroidForTests(mActivityWindowAndroidForTest);
 
-        mContentViewCore = getActivity().getCurrentContentViewCore();
-        // TODO(aurimas) remove this wait once crbug.com/179511 is fixed.
-        assertWaitForPageScaleFactorMatch(2);
+                mContentViewCore = mActivityTestRule.getActivity().getCurrentContentViewCore();
+                // TODO(aurimas) remove this wait once crbug.com/179511 is fixed.
+                mActivityTestRule.assertWaitForPageScaleFactorMatch(2);
+            }
+        });
         DOMUtils.waitForNonZeroNodeBounds(mContentViewCore.getWebContents(), "input_file");
     }
 
     /**
      * Tests that clicks on <input type="file" /> trigger intent calls to ActivityWindowAndroid.
      */
+    @Test
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     @MediumTest
     @Feature({"TextInput", "Main"})
@@ -110,67 +123,67 @@
         {
             DOMUtils.clickNode(mContentViewCore, "input_file");
             CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-            assertEquals(
+            Assert.assertEquals(
                     Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction());
             Intent contentIntent =
                     (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(
                             Intent.EXTRA_INTENT);
-            assertNotNull(contentIntent);
-            assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
+            Assert.assertNotNull(contentIntent);
+            Assert.assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
             resetActivityWindowAndroidForTest();
         }
 
         {
             DOMUtils.clickNode(mContentViewCore, "input_text");
             CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-            assertEquals(
+            Assert.assertEquals(
                     Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction());
             Intent contentIntent =
                     (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(
                             Intent.EXTRA_INTENT);
-            assertNotNull(contentIntent);
-            assertTrue(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
+            Assert.assertNotNull(contentIntent);
+            Assert.assertTrue(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
             resetActivityWindowAndroidForTest();
         }
 
         {
             DOMUtils.clickNode(mContentViewCore, "input_any");
             CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-            assertEquals(
+            Assert.assertEquals(
                     Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction());
             Intent contentIntent =
                     (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(
                             Intent.EXTRA_INTENT);
-            assertNotNull(contentIntent);
-            assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
+            Assert.assertNotNull(contentIntent);
+            Assert.assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
             resetActivityWindowAndroidForTest();
         }
 
         {
             DOMUtils.clickNode(mContentViewCore, "input_file_multiple");
             CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-            assertEquals(
+            Assert.assertEquals(
                     Intent.ACTION_CHOOSER, mActivityWindowAndroidForTest.lastIntent.getAction());
             Intent contentIntent =
                     (Intent) mActivityWindowAndroidForTest.lastIntent.getParcelableExtra(
                             Intent.EXTRA_INTENT);
-            assertNotNull(contentIntent);
-            assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
+            Assert.assertNotNull(contentIntent);
+            Assert.assertFalse(contentIntent.hasCategory(Intent.CATEGORY_OPENABLE));
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-                assertTrue(contentIntent.hasExtra(Intent.EXTRA_ALLOW_MULTIPLE));
+                Assert.assertTrue(contentIntent.hasExtra(Intent.EXTRA_ALLOW_MULTIPLE));
             }
             resetActivityWindowAndroidForTest();
         }
 
         DOMUtils.clickNode(mContentViewCore, "input_image");
         CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-        assertEquals(MediaStore.ACTION_IMAGE_CAPTURE,
+        Assert.assertEquals(MediaStore.ACTION_IMAGE_CAPTURE,
                 mActivityWindowAndroidForTest.lastIntent.getAction());
         resetActivityWindowAndroidForTest();
 
         DOMUtils.clickNode(mContentViewCore, "input_audio");
         CriteriaHelper.pollInstrumentationThread(new IntentSentCriteria());
-        assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION,
+        Assert.assertEquals(MediaStore.Audio.Media.RECORD_SOUND_ACTION,
                 mActivityWindowAndroidForTest.lastIntent.getAction());
         resetActivityWindowAndroidForTest();
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SmartClipProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SmartClipProviderTest.java
index 74e29521..66b84d6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/SmartClipProviderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SmartClipProviderTest.java
@@ -17,11 +17,20 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.lang.reflect.Method;
 import java.util.concurrent.TimeoutException;
@@ -29,11 +38,18 @@
 /**
  * Tests for the SmartClipProvider.
  */
-public class SmartClipProviderTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> implements Handler.Callback {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SmartClipProviderTest implements Handler.Callback {
     // This is a key for meta-data in the package manifest. It should NOT
     // change, as OEMs will use it when they look for the SmartClipProvider
     // interface.
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String SMART_CLIP_PROVIDER_KEY =
             "org.chromium.content.browser.SMART_CLIP_PROVIDER";
 
@@ -82,26 +98,17 @@
     private Method mSetSmartClipResultHandlerMethod;
     private Method mExtractSmartClipDataMethod;
 
-    public SmartClipProviderTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mActivity = mActivityTestRule.getActivity();
         mCallbackHelper = new MyCallbackHelper();
         mHandlerThread = new HandlerThread("ContentViewTest thread");
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper(), this);
 
         mSmartClipProviderClass = getSmartClipProviderClass();
-        assertNotNull(mSmartClipProviderClass);
+        Assert.assertNotNull(mSmartClipProviderClass);
         mSetSmartClipResultHandlerMethod = mSmartClipProviderClass.getDeclaredMethod(
                 "setSmartClipResultHandler", new Class[] { Handler.class });
         mExtractSmartClipDataMethod = mSmartClipProviderClass.getDeclaredMethod(
@@ -109,17 +116,13 @@
                 new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE });
     }
 
+    @After
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-    @Override
     public void tearDown() throws Exception {
-        try {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-                mHandlerThread.quitSafely();
-            } else {
-                mHandlerThread.quit();
-            }
-        } finally {
-            super.tearDown();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            mHandlerThread.quitSafely();
+        } else {
+            mHandlerThread.quit();
         }
     }
 
@@ -127,7 +130,7 @@
     @Override
     public boolean handleMessage(Message msg) {
         Bundle bundle = msg.getData();
-        assertNotNull(bundle);
+        Assert.assertNotNull(bundle);
         String url = bundle.getString("url");
         String title = bundle.getString("title");
         String text = bundle.getString("text");
@@ -144,7 +147,7 @@
                 mActivity.getPackageName(), PackageManager.GET_META_DATA);
         Bundle bundle = ai.metaData;
         String className = bundle.getString(SMART_CLIP_PROVIDER_KEY);
-        assertNotNull(className);
+        Assert.assertNotNull(className);
         return Class.forName(className);
     }
 
@@ -164,6 +167,7 @@
         return null;
     }
 
+    @Test
     @MediumTest
     @Feature({"SmartClip"})
     @RetryOnFailure
@@ -175,31 +179,32 @@
                 // This emulates what OEM will be doing when they want to call
                 // functions on SmartClipProvider through view hierarchy.
 
-                Object scp =
-                        findSmartClipProvider(getActivity().findViewById(android.R.id.content));
-                assertNotNull(scp);
+                Object scp = findSmartClipProvider(
+                        mActivityTestRule.getActivity().findViewById(android.R.id.content));
+                Assert.assertNotNull(scp);
                 try {
                     mSetSmartClipResultHandlerMethod.invoke(scp, mHandler);
                     mExtractSmartClipDataMethod.invoke(
                             scp, rect.left, rect.top, rect.width(), rect.height());
                 } catch (Exception e) {
                     e.printStackTrace();
-                    fail();
+                    Assert.fail();
                 }
             }
         });
         mCallbackHelper.waitForCallback(0, 1);  // call count: 0 --> 1
-        assertEquals("about:blank", mCallbackHelper.getTitle());
-        assertEquals("about:blank", mCallbackHelper.getUrl());
-        assertNotNull(mCallbackHelper.getText());
-        assertNotNull(mCallbackHelper.getHtml());
-        assertNotNull(mCallbackHelper.getRect());
-        assertEquals(rect.left, mCallbackHelper.getRect().left);
-        assertEquals(rect.top, mCallbackHelper.getRect().top);
-        assertEquals(rect.width(), mCallbackHelper.getRect().width());
-        assertEquals(rect.height(), mCallbackHelper.getRect().height());
+        Assert.assertEquals("about:blank", mCallbackHelper.getTitle());
+        Assert.assertEquals("about:blank", mCallbackHelper.getUrl());
+        Assert.assertNotNull(mCallbackHelper.getText());
+        Assert.assertNotNull(mCallbackHelper.getHtml());
+        Assert.assertNotNull(mCallbackHelper.getRect());
+        Assert.assertEquals(rect.left, mCallbackHelper.getRect().left);
+        Assert.assertEquals(rect.top, mCallbackHelper.getRect().top);
+        Assert.assertEquals(rect.width(), mCallbackHelper.getRect().width());
+        Assert.assertEquals(rect.height(), mCallbackHelper.getRect().height());
     }
 
+    @Test
     @MediumTest
     @Feature({"SmartClip"})
     @RetryOnFailure
@@ -207,9 +212,9 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                Object scp =
-                        findSmartClipProvider(getActivity().findViewById(android.R.id.content));
-                assertNotNull(scp);
+                Object scp = findSmartClipProvider(
+                        mActivityTestRule.getActivity().findViewById(android.R.id.content));
+                Assert.assertNotNull(scp);
                 try {
                     // Galaxy Note 4 has a bug where it doesn't always set the handler first; in
                     // that case, we shouldn't crash: http://crbug.com/710147
@@ -221,7 +226,7 @@
                     mExtractSmartClipDataMethod.invoke(scp, 10, 20, 100, 70);
                 } catch (Exception e) {
                     e.printStackTrace();
-                    fail();
+                    Assert.fail();
                 }
             }
         });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
index 802c3ea1..1b430e0b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabTest.java
@@ -5,17 +5,26 @@
 package org.chromium.chrome.browser;
 
 import android.app.Activity;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ApplicationTestUtils;
 import org.chromium.components.security_state.ConnectionSecurityLevel;
 import org.chromium.content.browser.test.util.Criteria;
@@ -24,8 +33,15 @@
 /**
  * Tests for Tab class.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class TabTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class TabTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private Tab mTab;
     private CallbackHelper mOnTitleUpdatedHelper;
 
@@ -36,46 +52,39 @@
         }
     };
 
-    public TabTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTab = getActivity().getActivityTab();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTab = mActivityTestRule.getActivity().getActivityTab();
         mTab.addObserver(mTabObserver);
         mOnTitleUpdatedHelper = new CallbackHelper();
     }
 
+    @Test
     @SmallTest
     @Feature({"Tab"})
     public void testTabContext() throws Throwable {
-        assertFalse("The tab context cannot be an activity",
+        Assert.assertFalse("The tab context cannot be an activity",
                 mTab.getContentViewCore().getContext() instanceof Activity);
-        assertNotSame("The tab context's theme should have been updated",
+        Assert.assertNotSame("The tab context's theme should have been updated",
                 mTab.getContentViewCore().getContext().getTheme(),
-                getActivity().getApplication().getTheme());
+                mActivityTestRule.getActivity().getApplication().getTheme());
     }
 
+    @Test
     @SmallTest
     @Feature({"Tab"})
     public void testTitleDelayUpdate() throws Throwable {
         final String oldTitle = "oldTitle";
         final String newTitle = "newTitle";
 
-        loadUrl("data:text/html;charset=utf-8,<html><head><title>"
-                + oldTitle + "</title></head><body/></html>");
-        assertEquals("title does not match initial title", oldTitle, mTab.getTitle());
+        mActivityTestRule.loadUrl("data:text/html;charset=utf-8,<html><head><title>" + oldTitle
+                + "</title></head><body/></html>");
+        Assert.assertEquals("title does not match initial title", oldTitle, mTab.getTitle());
         int currentCallCount = mOnTitleUpdatedHelper.getCallCount();
-        runJavaScriptCodeInCurrentTab("document.title='" + newTitle + "';");
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("document.title='" + newTitle + "';");
         mOnTitleUpdatedHelper.waitForCallback(currentCallCount);
-        assertEquals("title does not update", newTitle, mTab.getTitle());
+        Assert.assertEquals("title does not update", newTitle, mTab.getTitle());
     }
 
     /**
@@ -84,6 +93,7 @@
      * Note that document mode is explicitly disabled, as the document activity
      * may be fully recreated if its contents is killed while in the background.
      */
+    @Test
     @SmallTest
     @Feature({"Tab"})
     public void testTabRestoredIfKilledWhileActivityStopped() throws Exception {
@@ -95,12 +105,13 @@
             }
         });
 
-        assertFalse(mTab.needsReload());
-        assertFalse(mTab.isHidden());
-        assertFalse(mTab.isShowingSadTab());
+        Assert.assertFalse(mTab.needsReload());
+        Assert.assertFalse(mTab.isHidden());
+        Assert.assertFalse(mTab.isShowingSadTab());
 
         // Stop the activity and simulate a killed renderer.
-        ApplicationTestUtils.fireHomeScreenIntent(getInstrumentation().getTargetContext());
+        ApplicationTestUtils.fireHomeScreenIntent(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -114,10 +125,11 @@
                 return mTab.isHidden();
             }
         });
-        assertTrue(mTab.needsReload());
-        assertFalse(mTab.isShowingSadTab());
+        Assert.assertTrue(mTab.needsReload());
+        Assert.assertFalse(mTab.isShowingSadTab());
 
-        ApplicationTestUtils.launchChrome(getInstrumentation().getTargetContext());
+        ApplicationTestUtils.launchChrome(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
 
         // The tab should be restored and visible.
         CriteriaHelper.pollUiThread(new Criteria() {
@@ -126,17 +138,18 @@
                 return !mTab.isHidden();
             }
         });
-        assertFalse(mTab.needsReload());
-        assertFalse(mTab.isShowingSadTab());
+        Assert.assertFalse(mTab.needsReload());
+        Assert.assertFalse(mTab.isShowingSadTab());
     }
 
+    @Test
     @SmallTest
     @Feature({"Tab"})
     public void testTabSecurityLevel() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertEquals(ConnectionSecurityLevel.NONE, mTab.getSecurityLevel());
+                Assert.assertEquals(ConnectionSecurityLevel.NONE, mTab.getSecurityLevel());
             }
         });
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabThemeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabThemeTest.java
index 7115e4b..4842e1e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabThemeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabThemeTest.java
@@ -4,16 +4,25 @@
 
 package org.chromium.chrome.browser;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.net.test.EmbeddedTestServer;
 
@@ -24,7 +33,13 @@
 /**
  * Tests related to the Tab's theme color.
  */
-public class TabThemeTest extends ChromeActivityTestCaseBase<ChromeTabbedActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class TabThemeTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEST_PAGE = "/chrome/test/data/android/simple.html";
     private static final String THEMED_TEST_PAGE =
@@ -59,36 +74,32 @@
         }
     }
 
-    public TabThemeTest() {
-        super(ChromeTabbedActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * AssertEquals two colors as strings so the text output shows their hex value.
      */
     private void assertColorsEqual(int color1, int color2) {
-        assertEquals(Integer.toHexString(color1), Integer.toHexString(color2));
+        Assert.assertEquals(Integer.toHexString(color1), Integer.toHexString(color2));
     }
 
     /**
      * Test that the toolbar has the correct color set.
      */
+    @Test
     @Feature({"Toolbar-Theme-Color"})
     @MediumTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @RetryOnFailure
     public void testThemeColorIsCorrect()
             throws ExecutionException, InterruptedException, TimeoutException {
-
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
 
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         ThemeColorWebContentsObserver colorObserver = new ThemeColorWebContentsObserver();
         CallbackHelper themeColorHelper = colorObserver.getCallbackHelper();
@@ -96,12 +107,12 @@
 
         // Navigate to a themed page.
         int curCallCount = themeColorHelper.getCallCount();
-        loadUrl(testServer.getURL(THEMED_TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(THEMED_TEST_PAGE));
         themeColorHelper.waitForCallback(curCallCount, 1);
         assertColorsEqual(THEME_COLOR, tab.getThemeColor());
 
         // Navigate to a native page from a themed page.
-        loadUrl("chrome://newtab");
+        mActivityTestRule.loadUrl("chrome://newtab");
         // WebContents does not set theme color for native pages, so don't wait for the call.
         int nativePageThemeColor = ThreadUtils.runOnUiThreadBlocking(new Callable<Integer>() {
             @Override
@@ -113,21 +124,21 @@
 
         // Navigate to a themed page from a native page.
         curCallCount = themeColorHelper.getCallCount();
-        loadUrl(testServer.getURL(THEMED_TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(THEMED_TEST_PAGE));
         themeColorHelper.waitForCallback(curCallCount, 1);
         assertColorsEqual(THEME_COLOR, colorObserver.getColor());
         assertColorsEqual(THEME_COLOR, tab.getThemeColor());
 
         // Navigate to a non-native non-themed page.
         curCallCount = themeColorHelper.getCallCount();
-        loadUrl(testServer.getURL(TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(TEST_PAGE));
         themeColorHelper.waitForCallback(curCallCount, 1);
         assertColorsEqual(tab.getDefaultThemeColor(), colorObserver.getColor());
         assertColorsEqual(tab.getDefaultThemeColor(), tab.getThemeColor());
 
         // Navigate to a themed page from a non-native page.
         curCallCount = themeColorHelper.getCallCount();
-        loadUrl(testServer.getURL(THEMED_TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(THEMED_TEST_PAGE));
         themeColorHelper.waitForCallback(curCallCount, 1);
         assertColorsEqual(THEME_COLOR, colorObserver.getColor());
         assertColorsEqual(THEME_COLOR, tab.getThemeColor());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java
index 87fa65d..3f475ee 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/UrlSchemeTest.java
@@ -7,14 +7,24 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.Environment;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.TestFileUtil;
 import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.TestContentProvider;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -26,30 +36,35 @@
 import java.util.concurrent.Callable;
 
 /** Test suite for different Android URL schemes. */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class UrlSchemeTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class UrlSchemeTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String SIMPLE_SRC = "simple.html";
     private static final String SIMPLE_IMAGE = "google.png";
 
     private EmbeddedTestServer mTestServer;
 
-    public UrlSchemeTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        TestContentProvider.resetResourceRequestCounts(getInstrumentation().getTargetContext());
-        TestContentProvider.setDataFilePath(getInstrumentation().getTargetContext(),
+        mActivityTestRule.startMainActivityFromLauncher();
+        TestContentProvider.resetResourceRequestCounts(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+        TestContentProvider.setDataFilePath(
+                InstrumentationRegistry.getInstrumentation().getTargetContext(),
                 UrlUtils.getTestFilePath(""));
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
@@ -57,6 +72,7 @@
      * This is to make sure that attempts to access the content provider
      * will be detected.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentProviderResourceRequestCount() throws IOException {
@@ -64,11 +80,11 @@
         ensureResourceRequestCountInContentProvider(resource, 0);
         // Make a request to the content provider.
         Uri uri = Uri.parse(createContentUrl(resource));
-        Context context = getInstrumentation().getContext();
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
         InputStream inputStream = null;
         try {
             inputStream = context.getContentResolver().openInputStream(uri);
-            assertNotNull(inputStream);
+            Assert.assertNotNull(inputStream);
         } finally {
             if (inputStream != null) inputStream.close();
         }
@@ -78,11 +94,12 @@
     /**
      * Make sure content URL access works.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlAccess() throws InterruptedException {
         String resource = SIMPLE_SRC;
-        loadUrl(createContentUrl(resource));
+        mActivityTestRule.loadUrl(createContentUrl(resource));
         ensureResourceRequestCountInContentProviderNotLessThan(resource, 1);
     }
 
@@ -90,6 +107,7 @@
      * Make sure a Content url *CANNOT* access the contents of an iframe that is loaded as a
      * content URL.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlIframeAccessFromContentUrl() throws Throwable {
@@ -104,24 +122,25 @@
                 + "  document.title = 'fail';"
                 + "}";
 
-        loadUrl(createContentUrl(resource));
+        mActivityTestRule.loadUrl(createContentUrl(resource));
 
         // Make sure iframe is really loaded by verifying the title
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getActivityTab().getTitle().equals("iframe loaded");
+                return mActivityTestRule.getActivity().getActivityTab().getTitle().equals(
+                        "iframe loaded");
             }
         });
         // Make sure that content provider was asked to provide the content.
         ensureResourceRequestCountInContentProviderNotLessThan(iframe, 1);
-        runJavaScriptCodeInCurrentTab(script);
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(script);
 
         // Make sure content access failed by verifying that title is set to fail.
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getActivityTab().getTitle().equals("fail");
+                return mActivityTestRule.getActivity().getActivityTab().getTitle().equals("fail");
             }
         });
     }
@@ -129,6 +148,7 @@
     /**
      * Test that a content URL is *ALLOWED* to access an image provided by a content URL.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlImageFromContentUrl() throws Throwable {
@@ -138,6 +158,7 @@
     /**
      * Test that a HTTP URL is *NOT ALLOWED* to access an image provided by a content URL.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlImageFromHttpUrl() throws Throwable {
@@ -154,13 +175,14 @@
                 + "  img.onload = function() { document.title = 'success' };"
                 + "  img.src = '" + createContentUrl(resource) + "';"
                 + "  document.body.appendChild(img);";
-        loadUrl(url);
-        runJavaScriptCodeInCurrentTab(script);
+        mActivityTestRule.loadUrl(url);
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(script);
 
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getActivityTab().getTitle().equals(expectedTitle);
+                return mActivityTestRule.getActivity().getActivityTab().getTitle().equals(
+                        expectedTitle);
             }
         });
         ensureResourceRequestCountInContentProviderNotLessThan(resource, expectedLoadCount);
@@ -169,18 +191,20 @@
     /**
      * Test that a content URL is not allowed within a data URL.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlFromData() throws InterruptedException {
         final String target = SIMPLE_IMAGE;
-        loadUrl(UrlUtils.encodeHtmlDataUri(
-                "<img src=\"" + createContentUrl(target) + "\">"));
+        mActivityTestRule.loadUrl(
+                UrlUtils.encodeHtmlDataUri("<img src=\"" + createContentUrl(target) + "\">"));
         ensureResourceRequestCountInContentProvider(target, 0);
     }
 
     /**
      * Test that a content URL is not allowed within a local file.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testContentUrlFromFile() throws InterruptedException, IOException {
@@ -189,7 +213,7 @@
         try {
             TestFileUtil.createNewHtmlFile(
                     file, target, "<img src=\"" + createContentUrl(target) + "\">");
-            loadUrl("file:///" + file.getAbsolutePath());
+            mActivityTestRule.loadUrl("file:///" + file.getAbsolutePath());
             ensureResourceRequestCountInContentProvider(target, 0);
         } finally {
             TestFileUtil.deleteFile(file);
@@ -200,7 +224,7 @@
         return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<String>() {
             @Override
             public String call() throws Exception {
-                return getActivity().getActivityTab().getTitle();
+                return mActivityTestRule.getActivity().getActivityTab().getTitle();
             }
         });
     }
@@ -208,6 +232,7 @@
     /**
      * Test that the browser can be navigated to a file URL.
      */
+    @Test
     @MediumTest
     @Feature({"Navigation"})
     public void testFileUrlNavigation() throws InterruptedException, IOException {
@@ -216,8 +241,8 @@
 
         try {
             TestFileUtil.createNewHtmlFile(file, "File", null);
-            loadUrl("file://" + file.getAbsolutePath());
-            assertEquals("File", getTitleOnUiThread());
+            mActivityTestRule.loadUrl("file://" + file.getAbsolutePath());
+            Assert.assertEquals("File", getTitleOnUiThread());
         } finally {
             TestFileUtil.deleteFile(file);
         }
@@ -229,9 +254,9 @@
      * @param expectedCount Expected resource requests count
      */
     private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) {
-        Context context = getInstrumentation().getTargetContext();
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
-        assertEquals(expectedCount, actualCount);
+        Assert.assertEquals(expectedCount, actualCount);
     }
 
     /**
@@ -241,18 +266,13 @@
      */
     private void ensureResourceRequestCountInContentProviderNotLessThan(
             String resource, int expectedMinimalCount) {
-        Context context = getInstrumentation().getTargetContext();
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
-        assertTrue("Minimal expected: " + expectedMinimalCount + ", actual: " + actualCount,
+        Assert.assertTrue("Minimal expected: " + expectedMinimalCount + ", actual: " + actualCount,
                 actualCount >= expectedMinimalCount);
     }
 
     private String createContentUrl(final String target) {
         return TestContentProvider.createContentUrl(target);
     }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityFromLauncher();
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/UsbChooserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/UsbChooserDialogTest.java
index 3ded6e6..df062e81 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/UsbChooserDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/UsbChooserDialogTest.java
@@ -10,10 +10,18 @@
 import android.widget.Button;
 import android.widget.ListView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.security_state.ConnectionSecurityLevel;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -25,12 +33,20 @@
 /**
  * Tests for the UsbChooserDialog class.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class UsbChooserDialogTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class UsbChooserDialogTest {
     /**
      * Works like the UsbChooserDialog class, but records calls to native methods instead of
      * calling back to C++.
      */
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     static class UsbChooserDialogWithFakeNatives extends UsbChooserDialog {
         String mSelectedDeviceId = "";
 
@@ -52,23 +68,14 @@
 
     private UsbChooserDialogWithFakeNatives mChooserDialog;
 
-    public UsbChooserDialogTest() {
-        super(ChromeActivity.class);
-    }
-
     // ChromeActivityTestCaseBase:
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         mChooserDialog = createDialog();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
     private UsbChooserDialogWithFakeNatives createDialog() {
         return ThreadUtils.runOnUiThreadBlockingNoException(
                 new Callable<UsbChooserDialogWithFakeNatives>() {
@@ -76,7 +83,7 @@
                     public UsbChooserDialogWithFakeNatives call() {
                         UsbChooserDialogWithFakeNatives dialog =
                                 new UsbChooserDialogWithFakeNatives();
-                        dialog.show(getActivity(), "https://origin.example.com/",
+                        dialog.show(mActivityTestRule.getActivity(), "https://origin.example.com/",
                                 ConnectionSecurityLevel.SECURE);
                         return dialog;
                     }
@@ -127,17 +134,18 @@
                 "</?link2>", "").replaceAll("</?link>", "");
     }
 
+    @Test
     @LargeTest
     public void testCancel() {
         Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting();
-        assertTrue(dialog.isShowing());
+        Assert.assertTrue(dialog.isShowing());
 
         final ListView items = (ListView) dialog.findViewById(R.id.items);
         final Button button = (Button) dialog.findViewById(R.id.positive);
 
         // The 'Connect' button should be disabled and the list view should be hidden.
-        assertFalse(button.isEnabled());
-        assertEquals(View.GONE, items.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.GONE, items.getVisibility());
 
         dialog.dismiss();
 
@@ -149,6 +157,7 @@
         });
     }
 
+    @Test
     @LargeTest
     public void testSelectItem() throws InterruptedException {
         Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting();
@@ -174,14 +183,14 @@
         // After adding items to the dialog, the help message should be showing,
         // the 'Connect' button should still be disabled (since nothing's selected),
         // and the list view should show.
-        assertEquals(removeLinkTags(getActivity().getString(
-                R.string.usb_chooser_dialog_footnote_text)),
+        Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
+                                    R.string.usb_chooser_dialog_footnote_text)),
                 statusView.getText().toString());
-        assertFalse(button.isEnabled());
-        assertEquals(View.VISIBLE, items.getVisibility());
+        Assert.assertFalse(button.isEnabled());
+        Assert.assertEquals(View.VISIBLE, items.getVisibility());
 
         selectItem(mChooserDialog, position);
 
-        assertEquals("device_id_1", mChooserDialog.mSelectedDeviceId);
+        Assert.assertEquals("device_id_1", mChooserDialog.mSelectedDeviceId);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
index 341dfd4..eac5d19 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
@@ -7,20 +7,37 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.v7.app.AlertDialog;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.share.ShareHelper;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.net.test.EmbeddedTestServer;
 
 /** Test suite for Web Share (navigator.share) functionality. */
-public class WebShareTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class WebShareTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_FILE = "/content/test/data/android/webshare.html";
 
     private EmbeddedTestServer mTestServer;
@@ -43,7 +60,7 @@
 
         @Override
         public void onTitleUpdated(Tab tab) {
-            String title = getActivity().getActivityTab().getTitle();
+            String title = mActivityTestRule.getActivity().getActivityTab().getTitle();
             // Wait until the title indicates either success or failure.
             if (!title.equals("Success") && !title.startsWith("Fail:")) return;
             mStatus = title;
@@ -56,27 +73,24 @@
         }
     }
 
-    public WebShareTest() {
-        super(ChromeActivity.class);
-    }
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
 
         mUrl = mTestServer.getURL(TEST_FILE);
 
-        mTab = getActivity().getActivityTab();
+        mTab = mActivityTestRule.getActivity().getActivityTab();
         mUpdateWaiter = new WebShareUpdateWaiter();
         mTab.addObserver(mUpdateWaiter);
 
         mReceivedIntent = null;
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTab.removeObserver(mUpdateWaiter);
         mTestServer.stopAndDestroyServer();
 
@@ -84,32 +98,33 @@
         ShareHelper.setForceCustomChooserForTesting(false);
         ShareHelper.setFakeIntentReceiverForTesting(null);
 
-        super.tearDown();
     }
 
     /**
      * Verify that WebShare is missing by default (without a flag).
      * @throws Exception
      */
+    @Test
     @MediumTest
     @Feature({"WebShare"})
     public void testWebShareMissingWithoutFlag() throws Exception {
-        loadUrl(mUrl);
-        runJavaScriptCodeInCurrentTab("initiate_share()");
-        assertEquals("Fail: navigator.share === undefined", mUpdateWaiter.waitForUpdate());
+        mActivityTestRule.loadUrl(mUrl);
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("initiate_share()");
+        Assert.assertEquals("Fail: navigator.share === undefined", mUpdateWaiter.waitForUpdate());
     }
 
     /**
      * Verify that WebShare fails if called without a user gesture.
      * @throws Exception
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("enable-blink-features=WebShare")
     @Feature({"WebShare"})
     public void testWebShareNoUserGesture() throws Exception {
-        loadUrl(mUrl);
-        runJavaScriptCodeInCurrentTab("initiate_share()");
-        assertEquals(
+        mActivityTestRule.loadUrl(mUrl);
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("initiate_share()");
+        Assert.assertEquals(
                 "Fail: SecurityError: Must be handling a user gesture to perform a share request.",
                 mUpdateWaiter.waitForUpdate());
     }
@@ -118,20 +133,23 @@
      * Verify that WebShare fails if the origin trial is disabled.
      * @throws Exception
      */
+    @Test
     @MediumTest
-    @CommandLineFlags.Add({
-            "enable-blink-features=WebShare", "origin-trial-disabled-features=WebShare"})
+    @CommandLineFlags.Add({"enable-blink-features=WebShare",
+            "origin-trial-disabled-features=WebShare"})
     @Feature({"WebShare"})
     public void testWebShareOriginTrialDisabled() throws Exception {
-        loadUrl(mUrl);
-        singleClickView(mTab.getView());
-        assertEquals("Fail: SecurityError: WebShare is disabled.", mUpdateWaiter.waitForUpdate());
+        mActivityTestRule.loadUrl(mUrl);
+        TouchCommon.singleClickView(mTab.getView());
+        Assert.assertEquals(
+                "Fail: SecurityError: WebShare is disabled.", mUpdateWaiter.waitForUpdate());
     }
 
     /**
      * Verify WebShare fails if share is called from a user gesture, and canceled.
      * @throws Exception
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("enable-blink-features=WebShare")
     @Feature({"WebShare"})
@@ -150,20 +168,21 @@
                 // Click again to start another share. This is necessary to work around
                 // https://crbug.com/636274 (callback is not canceled until next share is
                 // initiated). This also serves as a regression test for https://crbug.com/640324.
-                singleClickView(mTab.getView());
+                TouchCommon.singleClickView(mTab.getView());
             }
         });
 
-        loadUrl(mUrl);
+        mActivityTestRule.loadUrl(mUrl);
         // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
-        singleClickView(mTab.getView());
-        assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
+        TouchCommon.singleClickView(mTab.getView());
+        Assert.assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
     }
 
     /**
      * Verify WebShare succeeds if share is called from a user gesture, and app chosen.
      * @throws Exception
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("enable-blink-features=WebShare")
     @Feature({"WebShare"})
@@ -193,22 +212,23 @@
             }
         });
 
-        loadUrl(mUrl);
+        mActivityTestRule.loadUrl(mUrl);
         // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
-        singleClickView(mTab.getView());
-        assertEquals("Success", mUpdateWaiter.waitForUpdate());
+        TouchCommon.singleClickView(mTab.getView());
+        Assert.assertEquals("Success", mUpdateWaiter.waitForUpdate());
 
         // The actual intent to be delivered to the target is in the EXTRA_INTENT of the chooser
         // intent.
-        assertNotNull(mReceivedIntent);
-        assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_INTENT));
+        Assert.assertNotNull(mReceivedIntent);
+        Assert.assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_INTENT));
         Intent innerIntent = mReceivedIntent.getParcelableExtra(Intent.EXTRA_INTENT);
-        assertNotNull(innerIntent);
-        assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
-        assertTrue(innerIntent.hasExtra(Intent.EXTRA_SUBJECT));
-        assertEquals("Test Title", innerIntent.getStringExtra(Intent.EXTRA_SUBJECT));
-        assertTrue(innerIntent.hasExtra(Intent.EXTRA_TEXT));
-        assertEquals("Test Text https://test.url/", innerIntent.getStringExtra(Intent.EXTRA_TEXT));
+        Assert.assertNotNull(innerIntent);
+        Assert.assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
+        Assert.assertTrue(innerIntent.hasExtra(Intent.EXTRA_SUBJECT));
+        Assert.assertEquals("Test Title", innerIntent.getStringExtra(Intent.EXTRA_SUBJECT));
+        Assert.assertTrue(innerIntent.hasExtra(Intent.EXTRA_TEXT));
+        Assert.assertEquals(
+                "Test Text https://test.url/", innerIntent.getStringExtra(Intent.EXTRA_TEXT));
     }
 
     /**
@@ -218,6 +238,7 @@
      *
      * @throws Exception
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("enable-blink-features=WebShare")
     @Feature({"WebShare"})
@@ -235,10 +256,10 @@
 
         ShareHelper.setForceCustomChooserForTesting(true);
 
-        loadUrl(mUrl);
+        mActivityTestRule.loadUrl(mUrl);
         // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
-        singleClickView(mTab.getView());
-        assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
+        TouchCommon.singleClickView(mTab.getView());
+        Assert.assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
     }
 
     /**
@@ -248,6 +269,7 @@
      *
      * @throws Exception
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("enable-blink-features=WebShare")
     @Feature({"WebShare"})
@@ -270,22 +292,17 @@
 
         ShareHelper.setForceCustomChooserForTesting(true);
 
-        loadUrl(mUrl);
+        mActivityTestRule.loadUrl(mUrl);
         // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
-        singleClickView(mTab.getView());
-        assertEquals("Success", mUpdateWaiter.waitForUpdate());
+        TouchCommon.singleClickView(mTab.getView());
+        Assert.assertEquals("Success", mUpdateWaiter.waitForUpdate());
 
-        assertNotNull(mReceivedIntent);
-        assertEquals(Intent.ACTION_SEND, mReceivedIntent.getAction());
-        assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_SUBJECT));
-        assertEquals("Test Title", mReceivedIntent.getStringExtra(Intent.EXTRA_SUBJECT));
-        assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_TEXT));
-        assertEquals("Test Text https://test.url/",
-                     mReceivedIntent.getStringExtra(Intent.EXTRA_TEXT));
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        Assert.assertNotNull(mReceivedIntent);
+        Assert.assertEquals(Intent.ACTION_SEND, mReceivedIntent.getAction());
+        Assert.assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_SUBJECT));
+        Assert.assertEquals("Test Title", mReceivedIntent.getStringExtra(Intent.EXTRA_SUBJECT));
+        Assert.assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_TEXT));
+        Assert.assertEquals(
+                "Test Text https://test.url/", mReceivedIntent.getStringExtra(Intent.EXTRA_TEXT));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java
index 470592cd..d8bc7697 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java
@@ -6,6 +6,7 @@
 
 import android.app.Activity;
 import android.content.pm.ActivityInfo;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.view.KeyEvent;
 import android.view.MenuItem;
@@ -13,15 +14,24 @@
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -31,8 +41,15 @@
 /**
  * Tests AppMenu popup
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AppMenuTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AppMenuTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_URL = UrlUtils.encodeHtmlDataUri("<html>foo</html>");
 
     private AppMenu mAppMenu;
@@ -59,19 +76,10 @@
         }
     }
 
-    public AppMenuTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(TEST_URL);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         // We need list selection; ensure we are not in touch mode.
-        getInstrumentation().setInTouchMode(false);
+        InstrumentationRegistry.getInstrumentation().setInTouchMode(false);
 
         ChromeActivity.setAppMenuHandlerFactoryForTesting(
                 new ChromeActivity.AppMenuHandlerFactory() {
@@ -84,10 +92,10 @@
                     }
                 });
 
-        super.setUp();
+        mActivityTestRule.startMainActivityWithURL(TEST_URL);
 
         showAppMenuAndAssertMenuShown();
-        mAppMenu = getActivity().getAppMenuHandler().getAppMenu();
+        mAppMenu = mActivityTestRule.getActivity().getAppMenuHandler().getAppMenu();
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -100,19 +108,21 @@
                 return getCurrentFocusedRow();
             }
         }));
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     /**
      * Verify opening a new tab from the menu.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testMenuNewTab() throws InterruptedException {
-        final int tabCountBefore = getActivity().getCurrentTabModel().getCount();
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(), (ChromeTabbedActivity) getActivity());
-        final int tabCountAfter = getActivity().getCurrentTabModel().getCount();
-        assertTrue("Expected: " + (tabCountBefore + 1) + " Got: " + tabCountAfter,
+        final int tabCountBefore = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(),
+                (ChromeTabbedActivity) mActivityTestRule.getActivity());
+        final int tabCountAfter = mActivityTestRule.getActivity().getCurrentTabModel().getCount();
+        Assert.assertTrue("Expected: " + (tabCountBefore + 1) + " Got: " + tabCountAfter,
                 tabCountBefore + 1 == tabCountAfter);
     }
 
@@ -120,20 +130,22 @@
      * Test bounds when accessing the menu through the keyboard.
      * Make sure that the menu stays open when trying to move past the first and last items.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardMenuBoundaries() {
         moveToBoundary(false, true);
-        assertEquals(getCount() - 1, getCurrentFocusedRow());
+        Assert.assertEquals(getCount() - 1, getCurrentFocusedRow());
         moveToBoundary(true, true);
-        assertEquals(0, getCurrentFocusedRow());
+        Assert.assertEquals(0, getCurrentFocusedRow());
         moveToBoundary(false, true);
-        assertEquals(getCount() - 1, getCurrentFocusedRow());
+        Assert.assertEquals(getCount() - 1, getCurrentFocusedRow());
     }
 
     /**
      * Test that typing ENTER immediately opening the menu works.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardMenuEnterOnOpen() {
@@ -143,11 +155,12 @@
     /**
      * Test that hitting ENTER past the top item doesn't crash Chrome.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardEnterAfterMovePastTopItem() {
         moveToBoundary(true, true);
-        assertEquals(0, getCurrentFocusedRow());
+        Assert.assertEquals(0, getCurrentFocusedRow());
         hitEnterAndAssertAppMenuDismissed();
     }
 
@@ -155,11 +168,12 @@
      * Test that hitting ENTER past the bottom item doesn't crash Chrome.
      * Catches regressions for http://crbug.com/181067
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardEnterAfterMovePastBottomItem() {
         moveToBoundary(false, true);
-        assertEquals(getCount() - 1, getCurrentFocusedRow());
+        Assert.assertEquals(getCount() - 1, getCurrentFocusedRow());
         hitEnterAndAssertAppMenuDismissed();
     }
 
@@ -167,26 +181,30 @@
      * Test that hitting ENTER on the top item actually triggers the top item.
      * Catches regressions for https://crbug.com/191239 for shrunken menus.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardMenuEnterOnTopItemLandscape() {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         showAppMenuAndAssertMenuShown();
         moveToBoundary(true, false);
-        assertEquals(0, getCurrentFocusedRow());
+        Assert.assertEquals(0, getCurrentFocusedRow());
         hitEnterAndAssertAppMenuDismissed();
     }
 
     /**
      * Test that hitting ENTER on the top item doesn't crash Chrome.
      */
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     public void testKeyboardMenuEnterOnTopItemPortrait() {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         showAppMenuAndAssertMenuShown();
         moveToBoundary(true, false);
-        assertEquals(0, getCurrentFocusedRow());
+        Assert.assertEquals(0, getCurrentFocusedRow());
         hitEnterAndAssertAppMenuDismissed();
     }
 
@@ -197,11 +215,14 @@
     @SmallTest
     @Feature({"Browser", "Main"})
     */
+    @Test
     @DisabledTest(message = "crbug.com/458193")
     public void testChangingOrientationHidesMenu() {
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         showAppMenuAndAssertMenuShown();
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        mActivityTestRule.getActivity().setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         CriteriaHelper.pollInstrumentationThread(new Criteria("AppMenu did not dismiss") {
             @Override
             public boolean isSatisfied() {
@@ -226,7 +247,7 @@
     }
 
     private void hitEnterAndAssertAppMenuDismissed() {
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         pressKey(KeyEvent.KEYCODE_ENTER);
         CriteriaHelper.pollInstrumentationThread(new Criteria("AppMenu did not dismiss") {
             @Override
@@ -264,7 +285,7 @@
         }
 
         // The menu should stay open.
-        assertTrue(mAppMenu.isShowing());
+        Assert.assertTrue(mAppMenu.isShowing());
     }
 
     private void pressKey(final int keycode) {
@@ -276,7 +297,7 @@
                 view.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keycode));
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     private int getCurrentFocusedRow() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java
index 902b468..69f05afe 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java
@@ -6,22 +6,37 @@
 
 import android.app.Activity;
 import android.support.test.filters.SmallTest;
-import android.test.UiThreadTest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /**
  * Tests the Data Saver AppMenu footer
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class DataSaverAppMenuTest extends ChromeActivityTestCaseBase<ChromeTabbedActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class DataSaverAppMenuTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private AppMenuHandlerForTest mAppMenuHandler;
 
     /**
@@ -44,17 +59,8 @@
         }
     }
 
-    public DataSaverAppMenuTest() {
-        super(ChromeTabbedActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         ChromeTabbedActivity.setAppMenuHandlerFactoryForTesting(
                 new ChromeTabbedActivity.AppMenuHandlerFactory() {
                     @Override
@@ -66,76 +72,91 @@
                     }
                 });
 
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * Verify the Data Saver item does not show when the feature isn't on, and the proxy is enabled.
      */
+    @Test
     @SmallTest
-    @UiThreadTest
     @CommandLineFlags.Add("disable-field-trial-config")
     @Feature({"Browser", "Main"})
-    public void testMenuDataSaverNoFeature() {
-        ContextUtils.getAppSharedPreferences().edit().clear().apply();
-        assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
-        DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                getActivity().getApplicationContext(), true);
-        assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+    public void testMenuDataSaverNoFeature() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                ContextUtils.getAppSharedPreferences().edit().clear().apply();
+                Assert.assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity().getApplicationContext(), true);
+                Assert.assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+            }
+        });
     }
 
     /**
      * Verify the Data Saver footer shows with the flag when the proxy is on.
      */
+    @Test
     @SmallTest
-    @UiThreadTest
     @CommandLineFlags.Add({"enable-features=DataReductionProxyMainMenu",
             "disable-field-trial-config"})
     @Feature({"Browser", "Main"})
-    public void testMenuDataSaver() {
-        ContextUtils.getAppSharedPreferences().edit().clear().apply();
-        // Data Saver hasn't been turned on, the footer shouldn't show.
-        assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+    public void testMenuDataSaver() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                ContextUtils.getAppSharedPreferences().edit().clear().apply();
+                // Data Saver hasn't been turned on, the footer shouldn't show.
+                Assert.assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
 
-        // Turn Data Saver on, the footer should show.
-        DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                getActivity().getApplicationContext(), true);
-        assertEquals(R.layout.data_reduction_main_menu_footer,
-                mAppMenuHandler.getDelegate().getFooterResourceId());
+                // Turn Data Saver on, the footer should show.
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity().getApplicationContext(), true);
+                Assert.assertEquals(R.layout.data_reduction_main_menu_footer,
+                        mAppMenuHandler.getDelegate().getFooterResourceId());
 
-        // Ensure the footer is removed if the proxy is turned off.
-        DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                getActivity().getApplicationContext(), false);
-        assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+                // Ensure the footer is removed if the proxy is turned off.
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity().getApplicationContext(), false);
+                Assert.assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+            }
+        });
     }
 
     /**
      * Verify the Data Saver footer shows with the flag when the proxy turns on and remains in the
      * main menu.
      */
+    @Test
     @SmallTest
-    @UiThreadTest
     @CommandLineFlags.Add({"enable-features=DataReductionProxyMainMenu<DataReductionProxyMainMenu",
             "force-fieldtrials=DataReductionProxyMainMenu/Enabled",
             "force-fieldtrial-params=DataReductionProxyMainMenu.Enabled:"
                     + "persistent_menu_item_enabled/true",
             "disable-field-trial-config"})
     @Feature({"Browser", "Main"})
-    public void testMenuDataSaverPersistent() {
-        ContextUtils.getAppSharedPreferences().edit().clear().apply();
-        // Data Saver hasn't been turned on, the footer shouldn't show.
-        assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
+    public void testMenuDataSaverPersistent() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                ContextUtils.getAppSharedPreferences().edit().clear().apply();
+                // Data Saver hasn't been turned on, the footer shouldn't show.
+                Assert.assertEquals(0, mAppMenuHandler.getDelegate().getFooterResourceId());
 
-        // Turn Data Saver on, the footer should show.
-        DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                getActivity().getApplicationContext(), true);
-        assertEquals(R.layout.data_reduction_main_menu_footer,
-                mAppMenuHandler.getDelegate().getFooterResourceId());
+                // Turn Data Saver on, the footer should show.
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity().getApplicationContext(), true);
+                Assert.assertEquals(R.layout.data_reduction_main_menu_footer,
+                        mAppMenuHandler.getDelegate().getFooterResourceId());
 
-        // Ensure the footer remains if the proxy is turned off.
-        DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                getActivity().getApplicationContext(), false);
-        assertEquals(R.layout.data_reduction_main_menu_footer,
-                mAppMenuHandler.getDelegate().getFooterResourceId());
+                // Ensure the footer remains if the proxy is turned off.
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity().getApplicationContext(), false);
+                Assert.assertEquals(R.layout.data_reduction_main_menu_footer,
+                        mAppMenuHandler.getDelegate().getFooterResourceId());
+            }
+        });
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java
index be60094..b8313e57 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java
@@ -10,6 +10,11 @@
 import android.view.ViewGroup;
 import android.widget.HorizontalScrollView;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
@@ -20,7 +25,8 @@
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -36,9 +42,16 @@
 /**
  * Integration tests for autofill keyboard accessory.
  */
-@CommandLineFlags.Add({ChromeSwitches.ENABLE_AUTOFILL_KEYBOARD_ACCESSORY})
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AutofillKeyboardAccessoryTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.ENABLE_AUTOFILL_KEYBOARD_ACCESSORY,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AutofillKeyboardAccessoryTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private final AtomicReference<ContentViewCore> mViewCoreRef =
             new AtomicReference<ContentViewCore>();
     private final AtomicReference<WebContents> mWebContentsRef = new AtomicReference<WebContents>();
@@ -46,18 +59,10 @@
     private final AtomicReference<ViewGroup> mKeyboardAccessoryRef =
             new AtomicReference<ViewGroup>();
 
-    public AutofillKeyboardAccessoryTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {}
-
     private void loadTestPage(boolean isRtl) throws InterruptedException, ExecutionException,
             TimeoutException {
-        startMainActivityWithURL(UrlUtils.encodeHtmlDataUri("<html"
-                + (isRtl ? " dir=\"rtl\"" : "")
-                + "><head>"
+        mActivityTestRule.startMainActivityWithURL(UrlUtils.encodeHtmlDataUri("<html"
+                + (isRtl ? " dir=\"rtl\"" : "") + "><head>"
                 + "<meta name=\"viewport\""
                 + "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>"
                 + "<body><form method=\"POST\">"
@@ -90,11 +95,12 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mViewCoreRef.set(getActivity().getCurrentContentViewCore());
+                mViewCoreRef.set(mActivityTestRule.getActivity().getCurrentContentViewCore());
                 mWebContentsRef.set(mViewCoreRef.get().getWebContents());
                 mContainerRef.set(mViewCoreRef.get().getContainerView());
-                mKeyboardAccessoryRef.set(
-                        getActivity().getWindowAndroid().getKeyboardAccessoryView());
+                mKeyboardAccessoryRef.set(mActivityTestRule.getActivity()
+                                                  .getWindowAndroid()
+                                                  .getKeyboardAccessoryView());
             }
         });
         DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), "fn");
@@ -103,42 +109,49 @@
     /**
      * Autofocused fields should not show a keyboard accessory.
      */
+    @Test
     @MediumTest
     @Feature({"keyboard-accessory"})
-    public void testAutofocusedFieldDoesNotShowKeyboardAccessory() throws InterruptedException,
-           ExecutionException, TimeoutException {
+    public void testAutofocusedFieldDoesNotShowKeyboardAccessory()
+            throws InterruptedException, ExecutionException, TimeoutException {
         loadTestPage(false);
-        assertTrue("Keyboard accessory should be hidden.",
-                ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-                    @Override
-                    public Boolean call() {
-                        return mKeyboardAccessoryRef.get().getVisibility() == View.GONE;
-                    }
-                }).booleanValue());
+        Assert.assertTrue("Keyboard accessory should be hidden.",
+                ThreadUtils
+                        .runOnUiThreadBlocking(new Callable<Boolean>() {
+                            @Override
+                            public Boolean call() {
+                                return mKeyboardAccessoryRef.get().getVisibility() == View.GONE;
+                            }
+                        })
+                        .booleanValue());
     }
 
     /**
      * Tapping on an input field should show a keyboard and its keyboard accessory.
      */
+    @Test
     @MediumTest
     @Feature({"keyboard-accessory"})
-    public void testTapInputFieldShowsKeyboardAccessory() throws ExecutionException,
-             InterruptedException, TimeoutException {
+    public void testTapInputFieldShowsKeyboardAccessory()
+            throws ExecutionException, InterruptedException, TimeoutException {
         loadTestPage(false);
         DOMUtils.clickNode(mViewCoreRef.get(), "fn");
         CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get());
+                return UiUtils.isKeyboardShowing(
+                        mActivityTestRule.getActivity(), mContainerRef.get());
             }
         });
-        assertTrue("Keyboard accessory should be showing.",
-                ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-                    @Override
-                    public Boolean call() {
-                        return mKeyboardAccessoryRef.get().getVisibility() == View.VISIBLE;
-                    }
-                }).booleanValue());
+        Assert.assertTrue("Keyboard accessory should be showing.",
+                ThreadUtils
+                        .runOnUiThreadBlocking(new Callable<Boolean>() {
+                            @Override
+                            public Boolean call() {
+                                return mKeyboardAccessoryRef.get().getVisibility() == View.VISIBLE;
+                            }
+                        })
+                        .booleanValue());
     }
 
     /**
@@ -148,15 +161,17 @@
     @MediumTest
     @Feature({"keyboard-accessory"})
     */
+    @Test
     @FlakyTest(message = "https://crbug.com/563640")
-    public void testSwitchFieldsRescrollsKeyboardAccessory() throws ExecutionException,
-             InterruptedException, TimeoutException {
+    public void testSwitchFieldsRescrollsKeyboardAccessory()
+            throws ExecutionException, InterruptedException, TimeoutException {
         loadTestPage(false);
         DOMUtils.clickNode(mViewCoreRef.get(), "fn");
         CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get());
+                return UiUtils.isKeyboardShowing(
+                        mActivityTestRule.getActivity(), mContainerRef.get());
             }
         });
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -197,17 +212,19 @@
      * RTL is only supported on Jelly Bean MR 1+.
      * http://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html
      */
+    @Test
     @MediumTest
     @Feature({"keyboard-accessory"})
     @MinAndroidSdkLevel(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    public void testSwitchFieldsRescrollsKeyboardAccessoryRtl() throws ExecutionException,
-             InterruptedException, TimeoutException {
+    public void testSwitchFieldsRescrollsKeyboardAccessoryRtl()
+            throws ExecutionException, InterruptedException, TimeoutException {
         loadTestPage(true);
         DOMUtils.clickNode(mViewCoreRef.get(), "fn");
         CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get());
+                return UiUtils.isKeyboardShowing(
+                        mActivityTestRule.getActivity(), mContainerRef.get());
             }
         });
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -251,16 +268,18 @@
      * Selecting a keyboard accessory suggestion should hide the keyboard and its keyboard
      * accessory.
      */
+    @Test
     @MediumTest
     @Feature({"keyboard-accessory"})
-    public void testSelectSuggestionHidesKeyboardAccessory() throws ExecutionException,
-             InterruptedException, TimeoutException {
+    public void testSelectSuggestionHidesKeyboardAccessory()
+            throws ExecutionException, InterruptedException, TimeoutException {
         loadTestPage(false);
         DOMUtils.clickNode(mViewCoreRef.get(), "fn");
         CriteriaHelper.pollUiThread(new Criteria("Keyboard should be showing.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get());
+                return UiUtils.isKeyboardShowing(
+                        mActivityTestRule.getActivity(), mContainerRef.get());
             }
         });
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -275,16 +294,19 @@
         CriteriaHelper.pollUiThread(new Criteria("Keyboard should be hidden.") {
             @Override
             public boolean isSatisfied() {
-                return !UiUtils.isKeyboardShowing(getActivity(), mContainerRef.get());
+                return !UiUtils.isKeyboardShowing(
+                        mActivityTestRule.getActivity(), mContainerRef.get());
             }
         });
-        assertTrue("Keyboard accessory should be hidden.",
-                ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-                    @Override
-                    public Boolean call() {
-                        return mKeyboardAccessoryRef.get().getVisibility() == View.GONE;
-                    }
-                }).booleanValue());
+        Assert.assertTrue("Keyboard accessory should be hidden.",
+                ThreadUtils
+                        .runOnUiThreadBlocking(new Callable<Boolean>() {
+                            @Override
+                            public Boolean call() {
+                                return mKeyboardAccessoryRef.get().getVisibility() == View.GONE;
+                            }
+                        })
+                        .booleanValue());
     }
 
     private View getSuggestionAt(int index) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
index 6f193c5..9c4540d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
@@ -9,12 +9,21 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill.AutofillPopup;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.input.ChromiumBaseInputConnection;
@@ -35,8 +44,14 @@
 /**
  * Integration tests for the AutofillPopup.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AutofillPopupTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AutofillPopupTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String FIRST_NAME = "John";
     private static final String LAST_NAME = "Smith";
@@ -122,18 +137,8 @@
     private AutofillTestHelper mHelper;
     private List<AutofillLogger.LogEntry> mAutofillLoggedEntries;
 
-    public AutofillPopupTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Don't launch activity automatically.
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         mAutofillLoggedEntries = new ArrayList<AutofillLogger.LogEntry>();
         AutofillLogger.setLoggerForTesting(
                 new AutofillLogger.Logger() {
@@ -148,12 +153,13 @@
     private void loadAndFillForm(
             final String formDataUrl, final String inputText)
             throws InterruptedException, ExecutionException, TimeoutException {
-        startMainActivityWithURL(formDataUrl);
+        mActivityTestRule.startMainActivityWithURL(formDataUrl);
         mHelper = new AutofillTestHelper();
 
         // The TestInputMethodManagerWrapper intercepts showSoftInput so that a keyboard is never
         // brought up.
-        final ContentViewCore viewCore = getActivity().getCurrentContentViewCore();
+        final ContentViewCore viewCore =
+                mActivityTestRule.getActivity().getCurrentContentViewCore();
         final WebContents webContents = viewCore.getWebContents();
         final ViewGroup view = viewCore.getContainerView();
         final TestInputMethodManagerWrapper immw =
@@ -168,7 +174,7 @@
                 ZIP_CODE, SORTING_CODE, COUNTRY, PHONE_NUMBER, EMAIL,
                 LANGUAGE_CODE);
         mHelper.setProfile(profile);
-        assertEquals(1, mHelper.getNumberOfProfilesToSuggest());
+        Assert.assertEquals(1, mHelper.getNumberOfProfilesToSuggest());
 
         // Click the input field for the first name.
         DOMUtils.waitForNonZeroNodeBounds(webContents, "fn");
@@ -188,7 +194,7 @@
         waitForAnchorViewAdd(view);
         View anchorView = view.findViewById(R.id.dropdown_popup_window);
 
-        assertTrue(anchorView.getTag() instanceof AutofillPopup);
+        Assert.assertTrue(anchorView.getTag() instanceof AutofillPopup);
         final AutofillPopup popup = (AutofillPopup) anchorView.getTag();
 
         waitForAutofillPopopShow(popup);
@@ -202,39 +208,39 @@
      * Tests that bringing up an Autofill and clicking on the first entry fills out the expected
      * Autofill information.
      */
+    @Test
     @MediumTest
     @Feature({"autofill"})
     public void testClickAutofillPopupSuggestion()
             throws InterruptedException, ExecutionException, TimeoutException {
         loadAndFillForm(BASIC_PAGE_DATA, "J");
-        final ContentViewCore viewCore = getActivity().getCurrentContentViewCore();
+        final ContentViewCore viewCore =
+                mActivityTestRule.getActivity().getCurrentContentViewCore();
         final WebContents webContents = viewCore.getWebContents();
 
-        assertEquals("First name did not match",
-                FIRST_NAME, DOMUtils.getNodeValue(webContents, "fn"));
-        assertEquals("Last name did not match",
-                LAST_NAME, DOMUtils.getNodeValue(webContents, "ln"));
-        assertEquals("Street address (textarea) did not match",
-                STREET_ADDRESS_TEXTAREA, DOMUtils.getNodeValue(webContents, "sa"));
-        assertEquals("Address line 1 did not match",
-                ADDRESS_LINE1, DOMUtils.getNodeValue(webContents, "a1"));
-        assertEquals("Address line 2 did not match",
-                ADDRESS_LINE2, DOMUtils.getNodeValue(webContents, "a2"));
-        assertEquals("City did not match",
-                CITY, DOMUtils.getNodeValue(webContents, "ct"));
-        assertEquals("Zip code did not match",
-                ZIP_CODE, DOMUtils.getNodeValue(webContents, "zc"));
-        assertEquals("Country did not match",
-                COUNTRY, DOMUtils.getNodeValue(webContents, "co"));
-        assertEquals("Email did not match",
-                EMAIL, DOMUtils.getNodeValue(webContents, "em"));
-        assertEquals("Phone number did not match",
-                PHONE_NUMBER, DOMUtils.getNodeValue(webContents, "ph"));
+        Assert.assertEquals(
+                "First name did not match", FIRST_NAME, DOMUtils.getNodeValue(webContents, "fn"));
+        Assert.assertEquals(
+                "Last name did not match", LAST_NAME, DOMUtils.getNodeValue(webContents, "ln"));
+        Assert.assertEquals("Street address (textarea) did not match", STREET_ADDRESS_TEXTAREA,
+                DOMUtils.getNodeValue(webContents, "sa"));
+        Assert.assertEquals("Address line 1 did not match", ADDRESS_LINE1,
+                DOMUtils.getNodeValue(webContents, "a1"));
+        Assert.assertEquals("Address line 2 did not match", ADDRESS_LINE2,
+                DOMUtils.getNodeValue(webContents, "a2"));
+        Assert.assertEquals("City did not match", CITY, DOMUtils.getNodeValue(webContents, "ct"));
+        Assert.assertEquals(
+                "Zip code did not match", ZIP_CODE, DOMUtils.getNodeValue(webContents, "zc"));
+        Assert.assertEquals(
+                "Country did not match", COUNTRY, DOMUtils.getNodeValue(webContents, "co"));
+        Assert.assertEquals("Email did not match", EMAIL, DOMUtils.getNodeValue(webContents, "em"));
+        Assert.assertEquals("Phone number did not match", PHONE_NUMBER,
+                DOMUtils.getNodeValue(webContents, "ph"));
 
         final String profileFullName = FIRST_NAME + " " + LAST_NAME;
         final int loggedEntries = 10;
-        assertEquals("Mismatched number of logged entries",
-                loggedEntries, mAutofillLoggedEntries.size());
+        Assert.assertEquals("Mismatched number of logged entries", loggedEntries,
+                mAutofillLoggedEntries.size());
         assertLogged(FIRST_NAME, profileFullName);
         assertLogged(LAST_NAME, profileFullName);
         assertLogged(STREET_ADDRESS_TEXTAREA, profileFullName);
@@ -251,6 +257,7 @@
      * Tests that bringing up an Autofill and clicking on the partially filled first
      * element will still fill the entire form (including the initiating element itself).
      */
+    @Test
     @MediumTest
     @Feature({"autofill"})
     public void testLoggingInitiatedElementFilled()
@@ -258,8 +265,8 @@
         loadAndFillForm(INITIATING_ELEMENT_FILLED, "o");
         final String profileFullName = FIRST_NAME + " " + LAST_NAME;
         final int loggedEntries = 4;
-        assertEquals("Mismatched number of logged entries",
-                loggedEntries, mAutofillLoggedEntries.size());
+        Assert.assertEquals("Mismatched number of logged entries", loggedEntries,
+                mAutofillLoggedEntries.size());
         assertLogged(FIRST_NAME, profileFullName);
         assertLogged(LAST_NAME, profileFullName);
         assertLogged(EMAIL, profileFullName);
@@ -270,6 +277,7 @@
      * Tests that bringing up an Autofill and clicking on the empty first element
      * will fill the all other elements except the previously filled email.
      */
+    @Test
     @MediumTest
     @Feature({"autofill"})
     public void testLoggingAnotherElementFilled()
@@ -277,8 +285,8 @@
         loadAndFillForm(ANOTHER_ELEMENT_FILLED, "J");
         final String profileFullName = FIRST_NAME + " " + LAST_NAME;
         final int loggedEntries = 3;
-        assertEquals("Mismatched number of logged entries",
-                loggedEntries, mAutofillLoggedEntries.size());
+        Assert.assertEquals("Mismatched number of logged entries", loggedEntries,
+                mAutofillLoggedEntries.size());
         assertLogged(FIRST_NAME, profileFullName);
         assertLogged(LAST_NAME, profileFullName);
         assertLogged(COUNTRY, profileFullName);
@@ -288,6 +296,7 @@
     /**
      * Tests that selecting a value not present in <option> will not be filled.
      */
+    @Test
     @MediumTest
     @Feature({"autofill"})
     public void testNotLoggingInvalidOption()
@@ -295,8 +304,8 @@
         loadAndFillForm(INVALID_OPTION, "o");
         final String profileFullName = FIRST_NAME + " " + LAST_NAME;
         final int loggedEntries = 3;
-        assertEquals("Mismatched number of logged entries",
-                loggedEntries, mAutofillLoggedEntries.size());
+        Assert.assertEquals("Mismatched number of logged entries", loggedEntries,
+                mAutofillLoggedEntries.size());
         assertLogged(FIRST_NAME, profileFullName);
         assertLogged(LAST_NAME, profileFullName);
         assertLogged(EMAIL, profileFullName);
@@ -362,6 +371,6 @@
                 return;
             }
         }
-        fail("Logged entry not found [" + autofilledValue + "," + profileFullName + "]");
+        Assert.fail("Logged entry not found [" + autofilledValue + "," + profileFullName + "]");
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java
index 3d29ccf..448aa1cc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupWithKeyboardTest.java
@@ -7,13 +7,21 @@
 import android.support.test.filters.MediumTest;
 import android.view.ViewGroup;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill.AutofillPopup;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
@@ -31,26 +39,24 @@
 /**
  * Integration tests for interaction of the AutofillPopup and a keyboard.
  */
-public class AutofillPopupWithKeyboardTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public AutofillPopupWithKeyboardTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Don't launch activity automatically.
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AutofillPopupWithKeyboardTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
      * Test that showing autofill popup and keyboard will not hide the autofill popup.
      */
+    @Test
     @MediumTest
     @Feature({"autofill-keyboard"})
     @RetryOnFailure
     public void testShowAutofillPopupAndKeyboardimultaneously()
             throws InterruptedException, ExecutionException, TimeoutException {
-        startMainActivityWithURL(UrlUtils.encodeHtmlDataUri("<html><head>"
+        mActivityTestRule.startMainActivityWithURL(UrlUtils.encodeHtmlDataUri("<html><head>"
                 + "<meta name=\"viewport\""
                 + "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>"
                 + "<body><form method=\"POST\">"
@@ -79,7 +85,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                viewCoreRef.set(getActivity().getCurrentContentViewCore());
+                viewCoreRef.set(mActivityTestRule.getActivity().getCurrentContentViewCore());
                 webContentsRef.set(viewCoreRef.get().getWebContents());
                 viewRef.set(viewCoreRef.get().getContainerView());
             }
@@ -95,9 +101,10 @@
         CriteriaHelper.pollUiThread(new Criteria("Keyboard was never shown.") {
             @Override
             public boolean isSatisfied() {
-                return UiUtils.isKeyboardShowing(
-                        getActivity(),
-                        getActivity().getCurrentContentViewCore().getContainerView());
+                return UiUtils.isKeyboardShowing(mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity()
+                                .getCurrentContentViewCore()
+                                .getContainerView());
             }
         });
 
@@ -115,7 +122,7 @@
                 return viewRef.get().findViewById(R.id.dropdown_popup_window).getTag();
             }
         });
-        assertTrue(popupObject instanceof AutofillPopup);
+        Assert.assertTrue(popupObject instanceof AutofillPopup);
         final AutofillPopup popup = (AutofillPopup) popupObject;
         CriteriaHelper.pollUiThread(new Criteria("Autofill Popup was never shown.") {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
index ab3aa5f..8a7d9e17 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
@@ -4,18 +4,27 @@
 
 package org.chromium.chrome.browser.autofill;
 
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
 import android.graphics.Color;
 import android.support.test.filters.SmallTest;
 import android.view.View;
 
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill.AutofillDelegate;
 import org.chromium.components.autofill.AutofillPopup;
 import org.chromium.components.autofill.AutofillSuggestion;
@@ -33,29 +42,26 @@
  * Tests the Autofill's java code for creating the AutofillPopup object, opening and selecting
  * popups.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AutofillTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private AutofillPopup mAutofillPopup;
     private WindowAndroid mWindowAndroid;
     private MockAutofillCallback mMockAutofillCallback;
 
-    public AutofillTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Before
     @SuppressFBWarnings("URF_UNREAD_FIELD")
-    @Override
     public void setUp() throws Exception {
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         mMockAutofillCallback = new MockAutofillCallback();
-        final ChromeActivity activity = getActivity();
+        final ChromeActivity activity = mActivityTestRule.getActivity();
         final ViewAndroidDelegate viewDelegate =
                 ViewAndroidDelegate.createBasicDelegate(
                         activity.getCurrentContentViewCore().getContainerView());
@@ -154,26 +160,28 @@
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"autofill"})
     public void testAutofillWithDifferentNumberSuggestions() throws Exception {
         openAutofillPopupAndWaitUntilReady(createTwoAutofillSuggestionArray());
-        assertEquals(2, mAutofillPopup.getListView().getCount());
+        Assert.assertEquals(2, mAutofillPopup.getListView().getCount());
 
         openAutofillPopupAndWaitUntilReady(createFiveAutofillSuggestionArray());
-        assertEquals(5, mAutofillPopup.getListView().getCount());
+        Assert.assertEquals(5, mAutofillPopup.getListView().getCount());
     }
 
+    @Test
     @SmallTest
     @Feature({"autofill"})
     public void testAutofillClickFirstSuggestion() throws Exception {
         AutofillSuggestion[] suggestions = createTwoAutofillSuggestionArray();
         openAutofillPopupAndWaitUntilReady(suggestions);
-        assertEquals(2, mAutofillPopup.getListView().getCount());
+        Assert.assertEquals(2, mAutofillPopup.getListView().getCount());
 
         TouchCommon.singleClickView(mAutofillPopup.getListView().getChildAt(0));
         mMockAutofillCallback.waitForCallback();
 
-        assertEquals(0, mMockAutofillCallback.mListIndex);
+        Assert.assertEquals(0, mMockAutofillCallback.mListIndex);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
index e98e844c..aae99a9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v7.widget.RecyclerView;
@@ -13,16 +14,24 @@
 import android.view.ViewGroup;
 import android.widget.TextView;
 
-import junit.framework.Assert;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ActivityUtils;
 import org.chromium.chrome.test.util.BookmarkTestUtil;
 import org.chromium.chrome.test.util.ChromeTabUtils;
@@ -40,12 +49,14 @@
 /**
  * Tests for the bookmark manager.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
 @RetryOnFailure
-public class BookmarkTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public BookmarkTest() {
-        super(ChromeActivity.class);
-    }
+public class BookmarkTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEST_PAGE_URL_GOOGLE = "/chrome/test/data/android/google.html";
     private static final String TEST_PAGE_TITLE_GOOGLE = "The Google";
@@ -59,41 +70,41 @@
     private String mTestPageFoo;
     private EmbeddedTestServer mTestServer;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityFromLauncher();
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mBookmarkModel = new BookmarkModel(
+                        mActivityTestRule.getActivity().getActivityTab().getProfile());
+            }
+        });
+        BookmarkTestUtil.waitForBookmarkModelLoaded();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mTestPage = mTestServer.getURL(TEST_PAGE_URL_GOOGLE);
         mTestPageFoo = mTestServer.getURL(TEST_PAGE_URL_FOO);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityFromLauncher();
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mBookmarkModel = new BookmarkModel(getActivity().getActivityTab().getProfile());
-            }
-        });
-        BookmarkTestUtil.waitForBookmarkModelLoaded();
+    @After
+    public void tearDown() throws Exception {
+        if (mTestServer != null) {
+            mTestServer.stopAndDestroyServer();
+        }
     }
 
     private void openBookmarkManager() throws InterruptedException {
-        if (DeviceFormFactor.isTablet(getActivity())) {
-            loadUrl(UrlConstants.BOOKMARKS_URL);
-            mItemsContainer = (RecyclerView) getActivity().findViewById(R.id.recycler_view);
+        if (DeviceFormFactor.isTablet(mActivityTestRule.getActivity())) {
+            mActivityTestRule.loadUrl(UrlConstants.BOOKMARKS_URL);
+            mItemsContainer =
+                    (RecyclerView) mActivityTestRule.getActivity().findViewById(R.id.recycler_view);
         } else {
             // phone
-            BookmarkActivity activity = ActivityUtils.waitForActivity(getInstrumentation(),
-                    BookmarkActivity.class, new MenuUtils.MenuActivityTrigger(
-                            getInstrumentation(), getActivity(), R.id.all_bookmarks_menu_id));
+            BookmarkActivity activity = ActivityUtils.waitForActivity(
+                    InstrumentationRegistry.getInstrumentation(), BookmarkActivity.class,
+                    new MenuUtils.MenuActivityTrigger(InstrumentationRegistry.getInstrumentation(),
+                            mActivityTestRule.getActivity(), R.id.all_bookmarks_menu_id));
             mItemsContainer = (RecyclerView) activity.findViewById(R.id.recycler_view);
         }
     }
@@ -117,67 +128,75 @@
         });
     }
 
+    @Test
     @SmallTest
     public void testAddBookmark() throws InterruptedException {
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
         // Click star button to bookmark the curent tab.
-        MenuUtils.invokeCustomMenuActionSync(getInstrumentation(), getActivity(),
-                R.id.bookmark_this_page_id);
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), R.id.bookmark_this_page_id);
         // All actions with BookmarkModel needs to run on UI thread.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                long bookmarkIdLong = getActivity().getActivityTab().getUserBookmarkId();
+                long bookmarkIdLong =
+                        mActivityTestRule.getActivity().getActivityTab().getUserBookmarkId();
                 BookmarkId id = new BookmarkId(bookmarkIdLong, BookmarkType.NORMAL);
-                assertTrue("The test page is not added as bookmark: ",
+                Assert.assertTrue("The test page is not added as bookmark: ",
                         mBookmarkModel.doesBookmarkExist(id));
                 BookmarkItem item = mBookmarkModel.getBookmarkById(id);
-                assertEquals(mBookmarkModel.getDefaultFolder(), item.getParentId());
-                assertEquals(mTestPage, item.getUrl());
-                assertEquals(TEST_PAGE_TITLE_GOOGLE, item.getTitle());
+                Assert.assertEquals(mBookmarkModel.getDefaultFolder(), item.getParentId());
+                Assert.assertEquals(mTestPage, item.getUrl());
+                Assert.assertEquals(TEST_PAGE_TITLE_GOOGLE, item.getTitle());
             }
         });
     }
 
+    @Test
     @SmallTest
     public void testOpenBookmark() throws InterruptedException, ExecutionException {
         addBookmark(TEST_PAGE_TITLE_GOOGLE, mTestPage);
         openBookmarkManager();
-        assertTrue("Grid view does not contain added bookmark: ",
+        Assert.assertTrue("Grid view does not contain added bookmark: ",
                 isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE));
         final View tile = getViewWithText(mItemsContainer, TEST_PAGE_TITLE_GOOGLE);
-        ChromeTabUtils.waitForTabPageLoaded(getActivity().getActivityTab(), new Runnable() {
-            @Override
-            public void run() {
-                TouchCommon.singleClickView(tile);
-            }
-        });
-        assertEquals(TEST_PAGE_TITLE_GOOGLE, getActivity().getActivityTab().getTitle());
+        ChromeTabUtils.waitForTabPageLoaded(
+                mActivityTestRule.getActivity().getActivityTab(), new Runnable() {
+                    @Override
+                    public void run() {
+                        TouchCommon.singleClickView(tile);
+                    }
+                });
+        Assert.assertEquals(TEST_PAGE_TITLE_GOOGLE,
+                mActivityTestRule.getActivity().getActivityTab().getTitle());
     }
 
+    @Test
     @SmallTest
     public void testUrlComposition() {
         BookmarkId mobileId = mBookmarkModel.getMobileFolderId();
         BookmarkId bookmarkBarId = mBookmarkModel.getDesktopFolderId();
         BookmarkId otherId = mBookmarkModel.getOtherFolderId();
-        assertEquals("chrome-native://bookmarks/folder/" + mobileId,
+        Assert.assertEquals("chrome-native://bookmarks/folder/" + mobileId,
                 BookmarkUIState.createFolderUrl(mobileId).toString());
-        assertEquals("chrome-native://bookmarks/folder/" + bookmarkBarId,
+        Assert.assertEquals("chrome-native://bookmarks/folder/" + bookmarkBarId,
                 BookmarkUIState.createFolderUrl(bookmarkBarId).toString());
-        assertEquals("chrome-native://bookmarks/folder/" + otherId,
+        Assert.assertEquals("chrome-native://bookmarks/folder/" + otherId,
                 BookmarkUIState.createFolderUrl(otherId).toString());
     }
 
+    @Test
     @SmallTest
     public void testOpenBookmarkManager() throws InterruptedException {
         openBookmarkManager();
         BookmarkDelegate delegate =
                 ((BookmarkItemsAdapter) mItemsContainer.getAdapter()).getDelegateForTesting();
-        assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
-        assertEquals("chrome-native://bookmarks/folder/3",
-                BookmarkUtils.getLastUsedUrl(getActivity()));
+        Assert.assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
+        Assert.assertEquals("chrome-native://bookmarks/folder/3",
+                BookmarkUtils.getLastUsedUrl(mActivityTestRule.getActivity()));
     }
 
+    @Test
     @MediumTest
     public void testTopLevelFolders() throws InterruptedException {
         openBookmarkManager();
@@ -193,9 +212,9 @@
             }
         });
 
-        assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_BACK,
+        Assert.assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_BACK,
                 toolbar.getNavigationButtonForTests());
-        assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible());
+        Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible());
 
         // Call BookmarkActionBar#onClick() to activate the navigation button.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -206,12 +225,13 @@
         });
 
         // Check that we are in the root folder.
-        assertEquals("Bookmarks", toolbar.getTitle());
-        assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_NONE,
+        Assert.assertEquals("Bookmarks", toolbar.getTitle());
+        Assert.assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_NONE,
                 toolbar.getNavigationButtonForTests());
-        assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible());
+        Assert.assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible());
     }
 
+    @Test
     @MediumTest
     public void testSearchBookmarks() throws Exception {
         BookmarkPromoHeader.setShouldShowForTests();
@@ -222,7 +242,7 @@
         BookmarkItemsAdapter adapter = ((BookmarkItemsAdapter) mItemsContainer.getAdapter());
         final BookmarkDelegate delegate = adapter.getDelegateForTesting();
 
-        assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
+        Assert.assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
         assertBookmarkItems("Wrong number of items before starting search.", 3, adapter, delegate);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -232,7 +252,7 @@
             }
         });
 
-        assertEquals(BookmarkUIState.STATE_SEARCHING, delegate.getCurrentState());
+        Assert.assertEquals(BookmarkUIState.STATE_SEARCHING, delegate.getCurrentState());
         assertBookmarkItems(
                 "Wrong number of items after showing search UI. The promo should be hidden.", 2,
                 adapter, delegate);
@@ -261,7 +281,7 @@
         });
         assertBookmarkItems("Wrong number of items after closing search UI.", 3,
                 mItemsContainer.getAdapter(), delegate);
-        assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
+        Assert.assertEquals(BookmarkUIState.STATE_FOLDER, delegate.getCurrentState());
     }
 
     /**
@@ -277,11 +297,11 @@
         // TODO(twellington): Remove after bookmarks redesign is complete.
         // The +1 for large devices stems from the divider being added to the state folder for now,
         // which will offset all counts by one.
-        final int expectedCount = DeviceFormFactor.isLargeTablet(getActivity())
+        final int expectedCount = DeviceFormFactor.isLargeTablet(mActivityTestRule.getActivity())
                         && BookmarkUIState.STATE_FOLDER == delegate.getCurrentState()
                 ? exepectedOnRegularDevice + 1
                 : exepectedOnRegularDevice;
-        assertEquals(errorMessage, expectedCount, adapter.getItemCount());
+        Assert.assertEquals(errorMessage, expectedCount, adapter.getItemCount());
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java
index 5564481..8b7ee07 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java
@@ -8,15 +8,24 @@
 import android.os.AsyncTask;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge;
 import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge.OnClearBrowsingDataListener;
 import org.chromium.chrome.browser.webapps.TestFetchStorageCallback;
 import org.chromium.chrome.browser.webapps.WebappRegistry;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 
@@ -32,7 +41,14 @@
  * those backends that live in the Java code, it is not possible to test whether deletions were
  * successful in its own unit tests. This test can do so.
  */
-public class BrowsingDataRemoverIntegrationTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class BrowsingDataRemoverIntegrationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private boolean mCallbackCalled;
 
     private class CallbackCriteria extends Criteria {
@@ -50,13 +66,9 @@
         }
     }
 
-    public BrowsingDataRemoverIntegrationTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     private void registerWebapp(final String webappId, final String webappUrl) throws Exception {
@@ -79,6 +91,7 @@
      * TODO(msramek): Expose more granular datatypes to the Java code, so we can directly test
      * BrowsingDataRemover::RemoveDataMask::REMOVE_WEBAPP_DATA instead of BrowsingDataType.COOKIES.
      */
+    @Test
     @MediumTest
     @RetryOnFailure
     public void testUnregisteringWebapps() throws Exception {
@@ -91,7 +104,7 @@
         for (final Map.Entry<String, String> app : apps.entrySet()) {
             registerWebapp(app.getKey(), app.getValue());
         }
-        assertEquals(apps.keySet(), WebappRegistry.getRegisteredWebappIdsForTesting());
+        Assert.assertEquals(apps.keySet(), WebappRegistry.getRegisteredWebappIdsForTesting());
 
         // Clear cookies and site data excluding the registrable domain "google.com".
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -115,7 +128,7 @@
         CriteriaHelper.pollUiThread(new CallbackCriteria());
 
         // The last two webapps should have been unregistered.
-        assertEquals(new HashSet<String>(Arrays.asList("webapp1")),
+        Assert.assertEquals(new HashSet<String>(Arrays.asList("webapp1")),
                 WebappRegistry.getRegisteredWebappIdsForTesting());
 
         // Clear cookies and site data with no url filter.
@@ -136,6 +149,6 @@
         CriteriaHelper.pollUiThread(new CallbackCriteria());
 
         // All webapps should have been unregistered.
-        assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
+        Assert.assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUiTest.java
index 9ddeb0a..92d2316 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUiTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUiTest.java
@@ -10,12 +10,21 @@
 import android.view.View;
 import android.widget.TextView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.CollectionUtil;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.common.Referrer;
 
 import java.util.ArrayList;
@@ -27,10 +36,13 @@
  * A class to checkout the TabularContextMenuUi. This confirms the the UI represents items and
  * groups.
  */
-public class TabularContextMenuUiTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-    public TabularContextMenuUiTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class TabularContextMenuUiTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static class MockMenuParams extends ContextMenuParams {
         private String mUrl = "";
@@ -53,11 +65,12 @@
         }
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
+    @Test
     @SmallTest
     @Feature({"CustomContextMenu"})
     public void testViewDisplaysSingleItemProperly() throws ExecutionException {
@@ -71,14 +84,16 @@
         View view = ThreadUtils.runOnUiThreadBlocking(new Callable<View>() {
             @Override
             public View call() {
-                return dialog.createPagerView(getActivity(), new MockMenuParams(url), itemGroups);
+                return dialog.createPagerView(
+                        mActivityTestRule.getActivity(), new MockMenuParams(url), itemGroups);
             }
         });
 
         TabLayout layout = (TabLayout) view.findViewById(R.id.tab_layout);
-        assertEquals(layout.getVisibility(), View.GONE);
+        Assert.assertEquals(layout.getVisibility(), View.GONE);
     }
 
+    @Test
     @SmallTest
     @Feature({"CustomContextMenu"})
     public void testViewDisplaysViewPagerForMultipleItems() throws ExecutionException {
@@ -93,14 +108,16 @@
         View view = ThreadUtils.runOnUiThreadBlocking(new Callable<View>() {
             @Override
             public View call() {
-                return dialog.createPagerView(getActivity(), new MockMenuParams(url), itemGroups);
+                return dialog.createPagerView(
+                        mActivityTestRule.getActivity(), new MockMenuParams(url), itemGroups);
             }
         });
 
         TabLayout layout = (TabLayout) view.findViewById(R.id.tab_layout);
-        assertEquals(layout.getVisibility(), View.VISIBLE);
+        Assert.assertEquals(layout.getVisibility(), View.VISIBLE);
     }
 
+    @Test
     @SmallTest
     @Feature({"CustomContextMenu"})
     public void testURLIsShownOnContextMenu() throws ExecutionException {
@@ -112,15 +129,16 @@
         View view = ThreadUtils.runOnUiThreadBlocking(new Callable<View>() {
             @Override
             public View call() {
-                return dialog.createContextMenuPageUi(
-                        getActivity(), new MockMenuParams(expectedUrl), item, false, item.size());
+                return dialog.createContextMenuPageUi(mActivityTestRule.getActivity(),
+                        new MockMenuParams(expectedUrl), item, false, item.size());
             }
         });
 
         TextView textView = (TextView) view.findViewById(R.id.context_header_text);
-        assertEquals(expectedUrl, String.valueOf(textView.getText()));
+        Assert.assertEquals(expectedUrl, String.valueOf(textView.getText()));
     }
 
+    @Test
     @SmallTest
     @Feature({"CustomContextMenu"})
     public void testHeaderIsNotShownWhenThereIsNoParams() throws ExecutionException {
@@ -131,15 +149,16 @@
         View view = ThreadUtils.runOnUiThreadBlocking(new Callable<View>() {
             @Override
             public View call() {
-                return dialog.createContextMenuPageUi(
-                        getActivity(), new MockMenuParams(""), item, false, item.size());
+                return dialog.createContextMenuPageUi(mActivityTestRule.getActivity(),
+                        new MockMenuParams(""), item, false, item.size());
             }
         });
 
-        assertEquals(view.findViewById(R.id.context_header_text).getVisibility(), View.GONE);
-        assertEquals(view.findViewById(R.id.context_divider).getVisibility(), View.GONE);
+        Assert.assertEquals(view.findViewById(R.id.context_header_text).getVisibility(), View.GONE);
+        Assert.assertEquals(view.findViewById(R.id.context_divider).getVisibility(), View.GONE);
     }
 
+    @Test
     @SmallTest
     @Feature({"CustomContextMenu"})
     public void testLinkShowsMultipleLinesWhenClicked() throws ExecutionException {
@@ -150,7 +169,7 @@
         View view = ThreadUtils.runOnUiThreadBlocking(new Callable<View>() {
             @Override
             public View call() {
-                return dialog.createContextMenuPageUi(getActivity(),
+                return dialog.createContextMenuPageUi(mActivityTestRule.getActivity(),
                         new MockMenuParams("http://google.com"), item, false, item.size());
             }
         });
@@ -158,8 +177,8 @@
         final TextView headerTextView = (TextView) view.findViewById(R.id.context_header_text);
         int expectedMaxLines = 1;
         int actualMaxLines = headerTextView.getMaxLines();
-        assertEquals("Expected a different number of default maximum lines.", expectedMaxLines,
-                actualMaxLines);
+        Assert.assertEquals("Expected a different number of default maximum lines.",
+                expectedMaxLines, actualMaxLines);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -170,7 +189,8 @@
 
         expectedMaxLines = Integer.MAX_VALUE;
         actualMaxLines = headerTextView.getMaxLines();
-        assertEquals("Expected a different number of maximum lines when the header is clicked.",
+        Assert.assertEquals(
+                "Expected a different number of maximum lines when the header is clicked.",
                 expectedMaxLines, actualMaxLines);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 7b8c14b..cb4421c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -16,12 +16,20 @@
 import android.content.SharedPreferences;
 import android.graphics.Point;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.text.TextUtils;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
@@ -34,6 +42,7 @@
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentProgressObserver;
@@ -54,7 +63,8 @@
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.FullscreenTestUtils;
@@ -84,10 +94,17 @@
  * Tests the Contextual Search Manager using instrumentation tests.
  */
 // NOTE: Disable online detection so we we'll default to online on test bots with no network.
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+        ContextualSearchFieldTrial.ONLINE_DETECTION_DISABLED})
 @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
-@CommandLineFlags.Add(ContextualSearchFieldTrial.ONLINE_DETECTION_DISABLED)
 @RetryOnFailure
-public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+public class ContextualSearchManagerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PAGE =
             "/chrome/test/data/android/contextualsearch/tap_test.html";
     private static final int TEST_TIMEOUT = 15000;
@@ -116,14 +133,11 @@
     // State for an individual test.
     FakeSlowResolveSearch mLatestSlowResolveSearch;
 
-    public ContextualSearchManagerTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         // We have to set up the test server before starting the activity.
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -131,11 +145,14 @@
                 FirstRunStatus.setFirstRunFlowComplete(true);
             }
         });
-        super.setUp();
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_PAGE));
+        // There's a problem with immediate startup that causes flakes due to the page not being
+        // ready, so specify a startup-delay of 1000 for legacy behavior.  See crbug.com/635661.
+        // TODO(donnd): find a better way to wait for page-ready, or at least reduce the delay!
+        Thread.sleep(ACTIVITY_STARTUP_DELAY_MS);
+        mManager = mActivityTestRule.getActivity().getContextualSearchManager();
 
-        mManager = getActivity().getContextualSearchManager();
-
-        assertNotNull(mManager);
+        Assert.assertNotNull(mManager);
         mPanel = mManager.getContextualSearchPanel();
 
         mSelectionController = mManager.getSelectionController();
@@ -145,7 +162,7 @@
 
         mFakeServer = new ContextualSearchFakeServer(mPolicy, this, mManager,
                 mManager.getOverlayContentDelegate(), new OverlayContentProgressObserver(),
-                getActivity());
+                mActivityTestRule.getActivity());
 
         mPanel.setOverlayPanelContentFactory(mFakeServer);
         mManager.setNetworkCommunicator(mFakeServer);
@@ -155,14 +172,14 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
         filter.addCategory(Intent.CATEGORY_BROWSABLE);
         filter.addDataScheme("market");
-        mActivityMonitor = getInstrumentation().addMonitor(
+        mActivityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor(
                 filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true);
 
-        mDpToPx = getActivity().getResources().getDisplayMetrics().density;
+        mDpToPx = mActivityTestRule.getActivity().getResources().getDisplayMetrics().density;
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -170,7 +187,6 @@
                 FirstRunStatus.setFirstRunFlowComplete(false);
             }
         });
-        super.tearDown();
     }
 
     /**
@@ -183,7 +199,7 @@
             throws InterruptedException, TimeoutException {
         mFakeServer.setIsOnline(isOnline);
         final String testUrl = mTestServer.getURL(TEST_PAGE);
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -204,7 +220,7 @@
      */
     public void longPressNodeWithoutWaiting(String nodeId)
             throws InterruptedException, TimeoutException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         DOMUtils.longPressNode(tab.getContentViewCore(), nodeId);
     }
 
@@ -222,7 +238,7 @@
      * @param nodeId A string containing the node ID.
      */
     public void clickNode(String nodeId) throws InterruptedException, TimeoutException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
         DOMUtils.clickNode(tab.getContentViewCore(), nodeId);
     }
 
@@ -292,16 +308,7 @@
      * @param runnable The Runnable.
      */
     public void runOnMainSync(Runnable runnable) {
-        getInstrumentation().runOnMainSync(runnable);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(mTestServer.getURL(TEST_PAGE));
-        // There's a problem with immediate startup that causes flakes due to the page not being
-        // ready, so specify a startup-delay of 1000 for legacy behavior.  See crbug.com/635661.
-        // TODO(donnd): find a better way to wait for page-ready, or at least reduce the delay!
-        Thread.sleep(ACTIVITY_STARTUP_DELAY_MS);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
     }
 
     //============================================================================================
@@ -460,10 +467,10 @@
             int startAdjust, int endAdjust, String contextLanguage, String thumbnailUrl,
             String caption, String quickActionUri, int quickActionCategory) {
         if (mFakeServer.getSearchTermRequested() != null) {
-            getInstrumentation().runOnMainSync(new FakeResponseOnMainThread(isNetworkUnavailable,
-                    responseCode, searchTerm, displayText, alternateTerm, mid, doPreventPreload,
-                    startAdjust, endAdjust, contextLanguage, thumbnailUrl, caption,
-                    quickActionUri, quickActionCategory));
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new FakeResponseOnMainThread(
+                    isNetworkUnavailable, responseCode, searchTerm, displayText, alternateTerm, mid,
+                    doPreventPreload, startAdjust, endAdjust, contextLanguage, thumbnailUrl,
+                    caption, quickActionUri, quickActionCategory));
         }
     }
 
@@ -491,28 +498,28 @@
      * Asserts that the Panel's ContentViewCore is created.
      */
     private void assertContentViewCoreCreated() {
-        assertNotNull(getPanelContentViewCore());
+        Assert.assertNotNull(getPanelContentViewCore());
     }
 
     /**
      * Asserts that the Panel's ContentViewCore is not created.
      */
     private void assertNoContentViewCore() {
-        assertNull(getPanelContentViewCore());
+        Assert.assertNull(getPanelContentViewCore());
     }
 
     /**
      * Asserts that the Panel's ContentViewCore is visible.
      */
     private void assertContentViewCoreVisible() {
-        assertTrue(isContentViewCoreVisible());
+        Assert.assertTrue(isContentViewCoreVisible());
     }
 
     /**
      * Asserts that the Panel's ContentViewCore onShow() method was never called.
      */
     private void assertNeverCalledContentViewCoreOnShow() {
-        assertFalse(mFakeServer.didEverCallContentViewCoreOnShow());
+        Assert.assertFalse(mFakeServer.didEverCallContentViewCoreOnShow());
     }
 
     /**
@@ -520,7 +527,7 @@
      */
     private void assertContentViewCoreCreatedButNeverMadeVisible() {
         assertContentViewCoreCreated();
-        assertFalse(isContentViewCoreVisible());
+        Assert.assertFalse(isContentViewCoreVisible());
         assertNeverCalledContentViewCoreOnShow();
     }
 
@@ -578,7 +585,8 @@
      * @param keycode The key's code.
      */
     private void pressKey(int keycode) {
-        KeyUtils.singleKeyEventActivity(getInstrumentation(), getActivity(), keycode);
+        KeyUtils.singleKeyEventActivity(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), keycode);
     }
 
     /**
@@ -605,14 +613,15 @@
         doesMatch = loadedUrl != null && loadedUrl.contains("q=" + searchTerm);
         String message = loadedUrl == null ? "but there was no loaded URL!"
                                            : "in URL: " + loadedUrl;
-        assertTrue("Expected to find searchTerm '" + searchTerm + "', " + message, doesMatch);
+        Assert.assertTrue(
+                "Expected to find searchTerm '" + searchTerm + "', " + message, doesMatch);
     }
 
     /**
      * Asserts that the given parameters are present in the most recently loaded URL.
      */
     private void assertContainsParameters(String searchTerm, String alternateTerm) {
-        assertTrue(mFakeServer.getSearchTermRequested() == null
+        Assert.assertTrue(mFakeServer.getSearchTermRequested() == null
                 || mFakeServer.getLoadedUrl().contains(searchTerm)
                         && mFakeServer.getLoadedUrl().contains(alternateTerm));
     }
@@ -621,14 +630,14 @@
      * Asserts that a Search Term has been requested.
      */
     private void assertSearchTermRequested() {
-        assertNotNull(mFakeServer.getSearchTermRequested());
+        Assert.assertNotNull(mFakeServer.getSearchTermRequested());
     }
 
     /**
      * Asserts that there has not been any Search Term requested.
      */
     private void assertSearchTermNotRequested() {
-        assertNull(mFakeServer.getSearchTermRequested());
+        Assert.assertNull(mFakeServer.getSearchTermRequested());
     }
 
     /**
@@ -642,21 +651,21 @@
             PanelState panelState = mPanel.getPanelState();
             success = panelState == PanelState.CLOSED || panelState == PanelState.UNDEFINED;
         }
-        assertTrue(success);
+        Assert.assertTrue(success);
     }
 
     /**
      * Asserts that the panel is currently in the "peeking" state (just showing the Bar).
      */
     private void assertPanelPeeked() {
-        assertTrue(mPanel.getPanelState() == PanelState.PEEKED);
+        Assert.assertTrue(mPanel.getPanelState() == PanelState.PEEKED);
     }
 
     /**
      * Asserts that no URL has been loaded in the Overlay Panel.
      */
     private void assertLoadedNoUrl() {
-        assertTrue("Requested a search or preload when none was expected!",
+        Assert.assertTrue("Requested a search or preload when none was expected!",
                 mFakeServer.getLoadedUrl() == null);
     }
 
@@ -666,9 +675,10 @@
     private void assertLoadedLowPriorityUrl() {
         String message = "Expected a low priority search request URL, but got "
                 + (mFakeServer.getLoadedUrl() != null ? mFakeServer.getLoadedUrl() : "null");
-        assertTrue(message, mFakeServer.getLoadedUrl() != null
-                && mFakeServer.getLoadedUrl().contains(LOW_PRIORITY_SEARCH_ENDPOINT));
-        assertTrue("Low priority request does not have the required prefetch parameter!",
+        Assert.assertTrue(message,
+                mFakeServer.getLoadedUrl() != null
+                        && mFakeServer.getLoadedUrl().contains(LOW_PRIORITY_SEARCH_ENDPOINT));
+        Assert.assertTrue("Low priority request does not have the required prefetch parameter!",
                 mFakeServer.getLoadedUrl() != null
                         && mFakeServer.getLoadedUrl().contains(CONTEXTUAL_SEARCH_PREFETCH_PARAM));
     }
@@ -680,10 +690,11 @@
     private void assertLoadedLowPriorityInvalidUrl() {
         String message = "Expected a low priority invalid search request URL, but got "
                 + (String.valueOf(mFakeServer.getLoadedUrl()));
-        assertTrue(message, mFakeServer.getLoadedUrl() != null
+        Assert.assertTrue(message,
+                mFakeServer.getLoadedUrl() != null
                         && mFakeServer.getLoadedUrl().contains(
                                    LOW_PRIORITY_INVALID_SEARCH_ENDPOINT));
-        assertTrue("Low priority request does not have the required prefetch parameter!",
+        Assert.assertTrue("Low priority request does not have the required prefetch parameter!",
                 mFakeServer.getLoadedUrl() != null
                         && mFakeServer.getLoadedUrl().contains(CONTEXTUAL_SEARCH_PREFETCH_PARAM));
     }
@@ -694,9 +705,11 @@
     private void assertLoadedNormalPriorityUrl() {
         String message = "Expected a normal priority search request URL, but got "
                 + (mFakeServer.getLoadedUrl() != null ? mFakeServer.getLoadedUrl() : "null");
-        assertTrue(message, mFakeServer.getLoadedUrl() != null
-                && mFakeServer.getLoadedUrl().contains(NORMAL_PRIORITY_SEARCH_ENDPOINT));
-        assertTrue("Normal priority request should not have the prefetch parameter, but did!",
+        Assert.assertTrue(message,
+                mFakeServer.getLoadedUrl() != null
+                        && mFakeServer.getLoadedUrl().contains(NORMAL_PRIORITY_SEARCH_ENDPOINT));
+        Assert.assertTrue(
+                "Normal priority request should not have the prefetch parameter, but did!",
                 mFakeServer.getLoadedUrl() != null
                         && !mFakeServer.getLoadedUrl().contains(CONTEXTUAL_SEARCH_PREFETCH_PARAM));
     }
@@ -705,7 +718,7 @@
      * Asserts that no URLs have been loaded in the Overlay Panel since the last {@link reset}.
      */
     private void assertNoSearchesLoaded() {
-        assertEquals(0, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(0, mFakeServer.getLoadedUrlCount());
         assertLoadedNoUrl();
     }
 
@@ -713,16 +726,16 @@
      * Asserts that the tap triggered promo counter is enabled and at the specified count.
      */
     private void assertTapPromoCounterEnabledAt(int expectedCount) {
-        assertTrue(mPolicy.getPromoTapCounter().isEnabled());
-        assertEquals(expectedCount, mPolicy.getPromoTapCounter().getCount());
+        Assert.assertTrue(mPolicy.getPromoTapCounter().isEnabled());
+        Assert.assertEquals(expectedCount, mPolicy.getPromoTapCounter().getCount());
     }
 
     /**
      * Asserts that the tap triggered promo counter is disabled and at the specified count.
      */
     private void assertTapPromoCounterDisabledAt(int expectedCount) {
-        assertFalse(mPolicy.getPromoTapCounter().isEnabled());
-        assertEquals(expectedCount, mPolicy.getPromoTapCounter().getCount());
+        Assert.assertFalse(mPolicy.getPromoTapCounter().isEnabled());
+        Assert.assertEquals(expectedCount, mPolicy.getPromoTapCounter().getCount());
     }
 
     /**
@@ -796,7 +809,7 @@
             Thread.sleep(DEFAULT_POLLING_INTERVAL);
             didChangeState = mPanel.getPanelState() != initialState;
         }
-        assertFalse(didChangeState);
+        Assert.assertFalse(didChangeState);
     }
 
     /**
@@ -825,7 +838,7 @@
         waitForGestureProcessing();
         waitForPanelToClose();
         assertPanelClosedOrUndefined();
-        assertTrue(TextUtils.isEmpty(getSelectedText()));
+        Assert.assertTrue(TextUtils.isEmpty(getSelectedText()));
     }
 
     /**
@@ -866,15 +879,16 @@
      */
     private void fling(float startX, float startY, float endX, float endY, int stepCount) {
         Point size = new Point();
-        getActivity().getWindowManager().getDefaultDisplay().getSize(size);
+        mActivityTestRule.getActivity().getWindowManager().getDefaultDisplay().getSize(size);
         float dragStartX = size.x * startX;
         float dragEndX = size.x * endX;
         float dragStartY = size.y * startY;
         float dragEndY = size.y * endY;
         long downTime = SystemClock.uptimeMillis();
-        dragStart(dragStartX, dragStartY, downTime);
-        dragTo(dragStartX, dragEndX, dragStartY, dragEndY, stepCount, downTime);
-        dragEnd(dragEndX, dragEndY, downTime);
+        TouchCommon.dragStart(mActivityTestRule.getActivity(), dragStartX, dragStartY, downTime);
+        TouchCommon.dragTo(mActivityTestRule.getActivity(), dragStartX, dragEndX, dragStartY,
+                dragEndY, stepCount, downTime);
+        TouchCommon.dragEnd(mActivityTestRule.getActivity(), dragEndX, dragEndY, downTime);
     }
 
     /**
@@ -883,19 +897,21 @@
      */
     private void swipe(float startX, float startY, float endX, float endY, int stepCount) {
         Point size = new Point();
-        getActivity().getWindowManager().getDefaultDisplay().getSize(size);
+        mActivityTestRule.getActivity().getWindowManager().getDefaultDisplay().getSize(size);
         float dragStartX = size.x * startX;
         float dragEndX = size.x * endX;
         float dragStartY = size.y * startY;
         float dragEndY = size.y * endY;
         int halfCount = stepCount / 2;
         long downTime = SystemClock.uptimeMillis();
-        dragStart(dragStartX, dragStartY, downTime);
-        dragTo(dragStartX, dragEndX, dragStartY, dragEndY, halfCount, downTime);
+        TouchCommon.dragStart(mActivityTestRule.getActivity(), dragStartX, dragStartY, downTime);
+        TouchCommon.dragTo(mActivityTestRule.getActivity(), dragStartX, dragEndX, dragStartY,
+                dragEndY, halfCount, downTime);
         // Generate events in the stationary end position in order to simulate a "pause" in
         // the movement, therefore preventing this gesture from being interpreted as a fling.
-        dragTo(dragEndX, dragEndX, dragEndY, dragEndY, halfCount, downTime);
-        dragEnd(dragEndX, dragEndY, downTime);
+        TouchCommon.dragTo(mActivityTestRule.getActivity(), dragEndX, dragEndX, dragEndY, dragEndY,
+                halfCount, downTime);
+        TouchCommon.dragEnd(mActivityTestRule.getActivity(), dragEndX, dragEndY, downTime);
     }
 
     /**
@@ -949,7 +965,7 @@
      * Taps the base page at the given x, y position.
      */
     private void tapBasePage(float x, float y) {
-        View root = getActivity().getWindow().getDecorView().getRootView();
+        View root = mActivityTestRule.getActivity().getWindow().getDecorView().getRootView();
         x *= root.getWidth();
         y *= root.getHeight();
         TouchCommon.singleClickView(root, (int) x, (int) y);
@@ -977,7 +993,7 @@
      * TODO(donnd): Replace this method with panelBarClick since this appears to be unreliable.
      */
     private void clickPanelBar() {
-        View root = getActivity().getWindow().getDecorView().getRootView();
+        View root = mActivityTestRule.getActivity().getWindow().getDecorView().getRootView();
         float tapX = ((mPanel.getOffsetX() + mPanel.getWidth()) / 2f) * mDpToPx;
         float tapY = (mPanel.getOffsetY() + (mPanel.getBarContainerHeight() / 2f)) * mDpToPx;
 
@@ -1057,7 +1073,7 @@
      * @throws InterruptedException
      */
     private void forcePanelToHandleBarClick() throws InterruptedException {
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // TODO(donnd): provide better time and x,y data to make this more broadly useful.
@@ -1071,7 +1087,7 @@
      * @throws InterruptedException
      */
     private void closePanel() throws InterruptedException {
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 mPanel.closePanel(StateChangeReason.UNKNOWN, false);
@@ -1095,16 +1111,18 @@
      */
     //@SmallTest
     //@Feature({"ContextualSearch"})
+    @Test
     @DisabledTest
     public void testHidesWhenOmniboxFocused() throws InterruptedException, TimeoutException {
         clickWordNode("intelligence");
 
-        assertEquals("Intelligence", mFakeServer.getSearchTermRequested());
+        Assert.assertEquals("Intelligence", mFakeServer.getSearchTermRequested());
         fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", false);
         assertContainsParameters("Intelligence", "alternate-term");
         waitForPanelToPeek();
 
-        OmniboxTestUtils.toggleUrlBarFocus((UrlBar) getActivity().findViewById(R.id.url_bar), true);
+        OmniboxTestUtils.toggleUrlBarFocus(
+                (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar), true);
 
         assertPanelClosedOrUndefined();
     }
@@ -1112,53 +1130,56 @@
     /**
      * Tests the doesContainAWord method.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testDoesContainAWord() {
-        assertTrue(mSelectionController.doesContainAWord("word"));
-        assertTrue(mSelectionController.doesContainAWord("word "));
-        assertFalse("Emtpy string should not be considered a word!",
+        Assert.assertTrue(mSelectionController.doesContainAWord("word"));
+        Assert.assertTrue(mSelectionController.doesContainAWord("word "));
+        Assert.assertFalse("Emtpy string should not be considered a word!",
                 mSelectionController.doesContainAWord(""));
-        assertFalse("Special symbols should not be considered a word!",
+        Assert.assertFalse("Special symbols should not be considered a word!",
                 mSelectionController.doesContainAWord("@"));
-        assertFalse("White space should not be considered a word",
+        Assert.assertFalse("White space should not be considered a word",
                 mSelectionController.doesContainAWord(" "));
-        assertTrue(mSelectionController.doesContainAWord("Q2"));
-        assertTrue(mSelectionController.doesContainAWord("123"));
+        Assert.assertTrue(mSelectionController.doesContainAWord("Q2"));
+        Assert.assertTrue(mSelectionController.doesContainAWord("123"));
     }
 
     /**
      * Tests the isValidSelection method.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testIsValidSelection() {
-        StubbedContentViewCore stubbedCvc = new StubbedContentViewCore(
-                getActivity().getBaseContext());
-        assertTrue(mSelectionController.isValidSelection("valid", stubbedCvc));
-        assertFalse(mSelectionController.isValidSelection(" ", stubbedCvc));
+        StubbedContentViewCore stubbedCvc =
+                new StubbedContentViewCore(mActivityTestRule.getActivity().getBaseContext());
+        Assert.assertTrue(mSelectionController.isValidSelection("valid", stubbedCvc));
+        Assert.assertFalse(mSelectionController.isValidSelection(" ", stubbedCvc));
         stubbedCvc.setIsFocusedNodeEditableForTest(true);
-        assertFalse(mSelectionController.isValidSelection("editable", stubbedCvc));
+        Assert.assertFalse(mSelectionController.isValidSelection("editable", stubbedCvc));
         stubbedCvc.setIsFocusedNodeEditableForTest(false);
         String numberString = "0123456789";
         StringBuilder longStringBuilder = new StringBuilder();
         for (int i = 0; i < 11; i++) {
             longStringBuilder.append(numberString);
         }
-        assertTrue(mSelectionController.isValidSelection(numberString, stubbedCvc));
-        assertFalse(mSelectionController.isValidSelection(longStringBuilder.toString(),
-                stubbedCvc));
+        Assert.assertTrue(mSelectionController.isValidSelection(numberString, stubbedCvc));
+        Assert.assertFalse(
+                mSelectionController.isValidSelection(longStringBuilder.toString(), stubbedCvc));
     }
 
     /**
      * Tests a simple Tap.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTap() throws InterruptedException, TimeoutException {
         clickWordNode("intelligence");
 
-        assertEquals("Intelligence", mFakeServer.getSearchTermRequested());
+        Assert.assertEquals("Intelligence", mFakeServer.getSearchTermRequested());
         fakeResponse(false, 200, "Intelligence", "display-text", "alternate-term", false);
         assertContainsParameters("Intelligence", "alternate-term");
         waitForPanelToPeek();
@@ -1168,12 +1189,13 @@
     /**
      * Tests a simple Long-Press gesture, without opening the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLongPress() throws InterruptedException, TimeoutException {
         longPressNode("states");
 
-        assertNull(mFakeServer.getSearchTermRequested());
+        Assert.assertNull(mFakeServer.getSearchTermRequested());
         waitForPanelToPeek();
         assertLoadedNoUrl();
         assertNoContentViewCore();
@@ -1182,6 +1204,7 @@
     /**
      * Tests swiping the overlay open, after an initial tap that activates the peeking card.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1194,13 +1217,13 @@
         fakeResponse(false, 200, "Intelligence", "United States Intelligence", "alternate-term",
                 false);
         assertContainsParameters("Intelligence", "alternate-term");
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         assertLoadedLowPriorityUrl();
 
         waitForPanelToPeek();
         flingPanelUp();
         waitForPanelToExpand();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         assertLoadedLowPriorityUrl();
     }
 
@@ -1210,6 +1233,7 @@
      * This test also verifies that we don't create any {@link ContentViewCore} or load any URL
      * until the panel is opened.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1221,17 +1245,18 @@
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreCreated();
         assertLoadedNormalPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // tap the base page to close.
         closePanel();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         assertNoContentViewCore();
     }
 
     /**
      * Tests that only a single low-priority request is issued for a Tap/Open sequence.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapCausesOneLowPriorityRequest() throws InterruptedException, TimeoutException {
@@ -1240,26 +1265,27 @@
 
         // We should not make a second-request until we get a good response from the first-request.
         assertLoadedNoUrl();
-        assertEquals(0, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(0, mFakeServer.getLoadedUrlCount());
         fakeResponse(false, 200, "states", "United States Intelligence", "alternate-term", false);
         assertLoadedLowPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // When the second request succeeds, we should not issue a new request.
         fakeContentViewDidNavigate(false);
         assertLoadedLowPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // When the bar opens, we should not make any additional request.
         tapPeekingBarToExpandAndAssert();
         assertLoadedLowPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         assertLoadedLowPriorityUrl();
     }
 
     /**
      * Tests that a failover for a prefetch request is issued after the panel is opened.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testPrefetchFailoverRequestMadeAfterOpen()
@@ -1269,26 +1295,27 @@
 
         // We should not make a SERP request until we get a good response from the resolve request.
         assertLoadedNoUrl();
-        assertEquals(0, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(0, mFakeServer.getLoadedUrlCount());
         fakeResponse(false, 200, "states", "United States Intelligence", "alternate-term", false);
         assertLoadedLowPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // When the second request fails, we should not automatically issue a new request.
         fakeContentViewDidNavigate(true);
         assertLoadedLowPriorityUrl();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Once the bar opens, we make a new request at normal priority.
         tapPeekingBarToExpandAndAssert();
         assertLoadedNormalPriorityUrl();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests that a live request that fails (for an invalid URL) does a failover to a
      * normal priority request once the user triggers the failover by opening the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLivePrefetchFailoverRequestMadeAfterOpen()
@@ -1297,10 +1324,10 @@
         mFakeServer.setLowPriorityPathInvalid();
         simulateTapSearch("search");
         assertLoadedLowPriorityInvalidUrl();
-        assertTrue(mFakeServer.didAttemptLoadInvalidUrl());
+        Assert.assertTrue(mFakeServer.didAttemptLoadInvalidUrl());
 
         // we should not automatically issue a new request.
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Fake a navigation error if offline.
         // When connected to the Internet this error may already have happened due to actually
@@ -1314,12 +1341,13 @@
         // Once the bar opens, we make a new request at normal priority.
         tapPeekingBarToExpandAndAssert();
         waitForNormalPriorityUrlLoaded();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests a simple Tap with disable-preload set.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapDisablePreload() throws InterruptedException, TimeoutException {
@@ -1335,11 +1363,12 @@
     /**
      * Tests that long-press selects text, and a subsequent tap will unselect text.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLongPressGestureSelects() throws InterruptedException, TimeoutException {
         longPressNode("intelligence");
-        assertEquals("Intelligence", getSelectedText());
+        Assert.assertEquals("Intelligence", getSelectedText());
         fakeResponse(false, 200, "Intelligence", "Intelligence", "alternate-term", false);
         assertContainsParameters("Intelligence", "alternate-term");
         waitForPanelToPeek();
@@ -1347,37 +1376,39 @@
         clickNode("question-mark");
         waitForGestureProcessing();
         waitForPanelToCloseAndSelectionEmpty();
-        assertTrue(TextUtils.isEmpty(getSelectedText()));
+        Assert.assertTrue(TextUtils.isEmpty(getSelectedText()));
         assertLoadedNoUrl();
     }
 
     /**
      * Tests that a Tap gesture selects the expected text.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGestureSelects() throws InterruptedException, TimeoutException {
         clickWordNode("intelligence");
-        assertEquals("Intelligence", getSelectedText());
+        Assert.assertEquals("Intelligence", getSelectedText());
         fakeResponse(false, 200, "Intelligence", "Intelligence", "alternate-term", false);
         assertContainsParameters("Intelligence", "alternate-term");
         waitForPanelToPeek();
         assertLoadedLowPriorityUrl();
         clickNode("question-mark");
         waitForPanelToClose();
-        assertNull(getSelectedText());
+        Assert.assertNull(getSelectedText());
     }
 
     /**
      * Tests that a Tap gesture on a special character does not select or show the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGestureOnSpecialCharacterDoesntSelect()
             throws InterruptedException, TimeoutException {
         clickNode("question-mark");
         waitForGestureProcessing();
-        assertNull(getSelectedText());
+        Assert.assertNull(getSelectedText());
         assertPanelClosedOrUndefined();
         assertLoadedNoUrl();
     }
@@ -1385,6 +1416,7 @@
     /**
      * Tests that a Tap gesture followed by scrolling clears the selection.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGestureFollowedByScrollClearsSelection()
@@ -1396,12 +1428,13 @@
         assertLoadedLowPriorityUrl();
         scrollBasePage();
         assertPanelClosedOrUndefined();
-        assertTrue(TextUtils.isEmpty(mSelectionController.getSelectedText()));
+        Assert.assertTrue(TextUtils.isEmpty(mSelectionController.getSelectedText()));
     }
 
     /**
      * Tests that a Tap gesture followed by tapping an invalid character doesn't select.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGestureFollowedByInvalidTextTapCloses()
@@ -1410,7 +1443,7 @@
         waitForPanelToPeek();
         clickNode("question-mark");
         waitForPanelToClose();
-        assertNull(mSelectionController.getSelectedText());
+        Assert.assertNull(mSelectionController.getSelectedText());
     }
 
     /**
@@ -1419,6 +1452,7 @@
      * @Feature({"ContextualSearch"})
      * crbug.com/665633
      */
+    @Test
     @DisabledTest
     public void testTapGestureFollowedByNonTextTap() throws InterruptedException, TimeoutException {
         clickWordNode("states-far");
@@ -1430,30 +1464,32 @@
     /**
      * Tests that a Tap gesture far away toggles selecting text.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGestureFarAwayTogglesSelecting()
             throws InterruptedException, TimeoutException {
         clickWordNode("states");
-        assertEquals("States", getSelectedText());
+        Assert.assertEquals("States", getSelectedText());
         waitForPanelToPeek();
         clickNode("states-far");
         waitForPanelToClose();
-        assertNull(getSelectedText());
+        Assert.assertNull(getSelectedText());
         clickNode("states-far");
         waitForGestureProcessing();
         waitForPanelToPeek();
-        assertEquals("States", getSelectedText());
+        Assert.assertEquals("States", getSelectedText());
     }
 
     /**
      * Tests that sequential Tap gestures nearby keep selecting.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapGesturesNearbyKeepSelecting() throws InterruptedException, TimeoutException {
         clickWordNode("states");
-        assertEquals("States", getSelectedText());
+        Assert.assertEquals("States", getSelectedText());
         waitForPanelToPeek();
         // Avoid issues with double-tap detection by ensuring sequential taps
         // aren't treated as such. Double-tapping can also select words much as
@@ -1474,6 +1510,7 @@
     /**
      * Tests that a long-press gesture followed by scrolling does not clear the selection.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLongPressGestureFollowedByScrollMaintainsSelection()
@@ -1482,13 +1519,14 @@
         waitForPanelToPeek();
         scrollBasePage();
         assertPanelClosedOrUndefined();
-        assertEquals("Intelligence", getSelectedText());
+        Assert.assertEquals("Intelligence", getSelectedText());
         assertLoadedNoUrl();
     }
 
     /**
      * Tests that a long-press gesture followed by a tap does not select.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLongPressGestureFollowedByTapDoesntSelect()
@@ -1503,18 +1541,20 @@
     /**
      * Tests that the panel closes when its base page crashes.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testContextualSearchDismissedOnForegroundTabCrash()
             throws InterruptedException, TimeoutException {
         clickWordNode("states");
-        assertEquals("States", getSelectedText());
+        Assert.assertEquals("States", getSelectedText());
         waitForPanelToPeek();
 
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                getActivity().getActivityTab().simulateRendererKilledForTesting(true);
+                mActivityTestRule.getActivity().getActivityTab().simulateRendererKilledForTesting(
+                        true);
             }
         });
 
@@ -1533,25 +1573,27 @@
     /**
      * Test the the panel does not close when some background tab crashes.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testContextualSearchNotDismissedOnBackgroundTabCrash()
             throws InterruptedException, TimeoutException {
-        ChromeTabUtils.newTabFromMenu(getInstrumentation(),
-                (ChromeTabbedActivity) getActivity());
-        final Tab tab2 = TabModelUtils.getCurrentTab(getActivity().getCurrentTabModel());
+        ChromeTabUtils.newTabFromMenu(InstrumentationRegistry.getInstrumentation(),
+                (ChromeTabbedActivity) mActivityTestRule.getActivity());
+        final Tab tab2 =
+                TabModelUtils.getCurrentTab(mActivityTestRule.getActivity().getCurrentTabModel());
 
         // TODO(donnd): consider using runOnUiThreadBlocking, won't need to waitForIdleSync?
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                TabModelUtils.setIndex(getActivity().getCurrentTabModel(), 0);
+                TabModelUtils.setIndex(mActivityTestRule.getActivity().getCurrentTabModel(), 0);
             }
         });
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         clickWordNode("states");
-        assertEquals("States", getSelectedText());
+        Assert.assertEquals("States", getSelectedText());
         waitForPanelToPeek();
 
         ThreadUtils.runOnUiThread(new Runnable() {
@@ -1568,6 +1610,7 @@
      * Test that tapping on the Search Bar before having a resolved search term does not
      * promote to a tab, and that after the resolution it does promote to a tab.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapSearchBarPromotesToTab() throws InterruptedException, TimeoutException {
@@ -1581,7 +1624,7 @@
                 tabCreatedHelper.notifyCalled();
             }
         };
-        getActivity().getTabModelSelector().addObserver(observer);
+        mActivityTestRule.getActivity().getTabModelSelector().addObserver(observer);
 
         // -------- TEST ---------
         // Start a slow-resolve search and maximize the Panel.
@@ -1608,12 +1651,13 @@
         tabCreatedHelper.waitForCallback(tabCreatedHelperCallCount);
 
         // -------- CLEAN UP ---------
-        getActivity().getTabModelSelector().removeObserver(observer);
+        mActivityTestRule.getActivity().getTabModelSelector().removeObserver(observer);
     }
 
     /**
      * Tests that a Tap gesture on an element with an ARIA role does not trigger.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapOnRoleIgnored() throws InterruptedException, TimeoutException {
@@ -1626,6 +1670,7 @@
      * Tests that a Tap gesture on an element with an ARIA attribute does not trigger.
      * http://crbug.com/542874
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapOnARIAIgnored() throws InterruptedException, TimeoutException {
@@ -1637,6 +1682,7 @@
     /**
      * Tests that a Tap gesture on an element that is focusable does not trigger.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapOnFocusableIgnored() throws InterruptedException, TimeoutException {
@@ -1648,6 +1694,7 @@
     /**
      * Tests that taps can be resolve and prefetch limited for decided users.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1677,6 +1724,7 @@
     /**
      * Tests that taps can be resolve-limited for undecided users.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1709,6 +1757,7 @@
      * Tests expanding the panel before the search term has resolved, verifies that nothing
      * loads until the resolve completes and that it's now a normal priority URL.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testExpandBeforeSearchTermResolution()
@@ -1732,6 +1781,7 @@
      * Tests that an error from the Search Term Resolution request causes a fallback to a
      * search request for the literal selection.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testSearchTermResolutionError() throws InterruptedException, TimeoutException {
@@ -1750,6 +1800,7 @@
     /**
      * Tests that HTTPS does not resolve in the opt-out model before the user accepts.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testHttpsBeforeAcceptForOptOut() throws InterruptedException, TimeoutException {
@@ -1764,6 +1815,7 @@
     /**
      * Tests that HTTPS does resolve in the opt-out model after the user accepts.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testHttpsAfterAcceptForOptOut() throws InterruptedException, TimeoutException {
@@ -1776,6 +1828,7 @@
     /**
      * Tests that HTTP does resolve in the opt-out model before the user accepts.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testHttpBeforeAcceptForOptOut() throws InterruptedException, TimeoutException {
@@ -1787,6 +1840,7 @@
     /**
      * Tests that HTTP does resolve in the opt-out model after the user accepts.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testHttpAfterAcceptForOptOut() throws InterruptedException, TimeoutException {
@@ -1814,7 +1868,9 @@
                 Criteria.equals(isVisible, new Callable<Boolean>() {
                     @Override
                     public Boolean call() {
-                        return getActivity().getAppMenuHandler().isAppMenuShowing();
+                        return mActivityTestRule.getActivity()
+                                .getAppMenuHandler()
+                                .isAppMenuShowing();
                     }
                 }));
     }
@@ -1822,6 +1878,7 @@
     /**
      * Tests that the App Menu gets suppressed when Search Panel is expanded.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1842,6 +1899,7 @@
     /**
      * Tests that the App Menu gets suppressed when Search Panel is maximized.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testAppMenuSuppressedWhenMaximized() throws InterruptedException, TimeoutException {
@@ -1868,6 +1926,7 @@
      * the user has never ever opened the panel.  Once the panel is opened, this limiting-feature
      * is permanently disabled.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testPromoTapCount() throws InterruptedException, TimeoutException {
@@ -1912,6 +1971,7 @@
     /**
      * Tests the promo open counter.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1921,25 +1981,26 @@
 
         // A simple click / resolve / prefetch sequence without open should not change the counter.
         clickToTriggerPrefetch();
-        assertEquals(0, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(0, mPolicy.getPromoOpenCount());
 
         // An open should count.
         clickToExpandAndClosePanel();
-        assertEquals(1, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(1, mPolicy.getPromoOpenCount());
 
         // Another open should count.
         clickToExpandAndClosePanel();
-        assertEquals(2, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(2, mPolicy.getPromoOpenCount());
 
         // Once the user has decided, we should stop counting.
         mPolicy.overrideDecidedStateForTesting(true);
         clickToExpandAndClosePanel();
-        assertEquals(2, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(2, mPolicy.getPromoOpenCount());
     }
 
     /**
      * Tests the promo open counter.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -1949,7 +2010,7 @@
 
         // An open should not count for decided users.
         clickToExpandAndClosePanel();
-        assertEquals(0, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(0, mPolicy.getPromoOpenCount());
     }
 
     // --------------------------------------------------------------------------------------------
@@ -1960,21 +2021,22 @@
      * @SmallTest
      * @Feature({"ContextualSearch"})
      */
+    @Test
     @FlakyTest
     public void testTapCount() throws InterruptedException, TimeoutException {
-        assertEquals(0, mPolicy.getTapCount());
+        Assert.assertEquals(0, mPolicy.getTapCount());
 
         // A simple Tap should change the counter.
         clickToTriggerPrefetch();
-        assertEquals(1, mPolicy.getTapCount());
+        Assert.assertEquals(1, mPolicy.getTapCount());
 
         // Another Tap should increase the counter.
         clickToTriggerPrefetch();
-        assertEquals(2, mPolicy.getTapCount());
+        Assert.assertEquals(2, mPolicy.getTapCount());
 
         // An open should reset the counter.
         clickToExpandAndClosePanel();
-        assertEquals(0, mPolicy.getTapCount());
+        Assert.assertEquals(0, mPolicy.getTapCount());
     }
 
     // --------------------------------------------------------------------------------------------
@@ -1996,6 +2058,7 @@
      * Tests that ContextualSearchObserver gets notified when user brings up contextual search
      * panel via long press and then dismisses the panel by tapping on the base page.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2004,16 +2067,17 @@
         TestContextualSearchObserver observer = new TestContextualSearchObserver();
         mManager.addObserver(observer);
         longPressNode("states");
-        assertEquals(0, observer.hideCount);
+        Assert.assertEquals(0, observer.hideCount);
 
         tapBasePageToClosePanel();
-        assertEquals(1, observer.hideCount);
+        Assert.assertEquals(1, observer.hideCount);
     }
 
     /**
      * Tests that ContextualSearchObserver gets notified when user brings up contextual search
      * panel via tap and then dismisses the panel by tapping on the base page.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2021,10 +2085,10 @@
         TestContextualSearchObserver observer = new TestContextualSearchObserver();
         mManager.addObserver(observer);
         clickWordNode("states");
-        assertEquals(0, observer.hideCount);
+        Assert.assertEquals(0, observer.hideCount);
 
         tapBasePageToClosePanel();
-        assertEquals(1, observer.hideCount);
+        Assert.assertEquals(1, observer.hideCount);
     }
 
     /**
@@ -2037,7 +2101,9 @@
         CriteriaHelper.pollUiThread(Criteria.equals(visible, new Callable<Boolean>() {
             @Override
             public Boolean call() {
-                return getActivity().getActivityTab().getContentViewCore()
+                return mActivityTestRule.getActivity()
+                        .getActivityTab()
+                        .getContentViewCore()
                         .isSelectActionBarShowing();
             }
         }));
@@ -2047,6 +2113,7 @@
      * Tests that ContextualSearchObserver gets notified when user brings up contextual search
      * panel via long press and then dismisses the panel by tapping copy (hide select action mode).
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testNotifyObserverHideOnClearSelectionAfterTap()
@@ -2054,10 +2121,11 @@
         TestContextualSearchObserver observer = new TestContextualSearchObserver();
         mManager.addObserver(observer);
         longPressNode("states");
-        assertEquals(0, observer.hideCount);
+        Assert.assertEquals(0, observer.hideCount);
 
         // Dismiss select action mode.
-        final ContentViewCore contentViewCore = getActivity().getActivityTab().getContentViewCore();
+        final ContentViewCore contentViewCore =
+                mActivityTestRule.getActivity().getActivityTab().getContentViewCore();
         assertWaitForSelectActionBarVisible(true);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -2068,7 +2136,7 @@
         assertWaitForSelectActionBarVisible(false);
 
         waitForPanelToClose();
-        assertEquals(1, observer.hideCount);
+        Assert.assertEquals(1, observer.hideCount);
     }
 
     /**
@@ -2076,6 +2144,7 @@
      * modified after the user has taken an action to explicitly dismiss the panel. Also tests
      * that the panel reappears when a new selection is made.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testPreventHandlingCurrentSelectionModification()
@@ -2084,7 +2153,7 @@
 
         // Dismiss the Contextual Search panel.
         closePanel();
-        assertEquals("Search", getSelectedText());
+        Assert.assertEquals("Search", getSelectedText());
 
         // Simulate a selection change event and assert that the panel has not reappeared.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -2108,6 +2177,7 @@
      * We've had reliability problems with a sequence of simple taps, due to async dissolving
      * of selection bounds, so this helps prevent a regression with that.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapALot() throws InterruptedException, TimeoutException {
@@ -2124,36 +2194,37 @@
      * Tests ContextualSearchManager#shouldInterceptNavigation for a case that an external
      * navigation has a user gesture.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testExternalNavigationWithUserGesture() {
         final ExternalNavigationHandler externalNavHandler =
-                new ExternalNavigationHandler(getActivity().getActivityTab());
+                new ExternalNavigationHandler(mActivityTestRule.getActivity().getActivityTab());
         final NavigationParams navigationParams = new NavigationParams(
                 "intent://test/#Intent;scheme=test;package=com.chrome.test;end", "",
                 false /* isPost */, true /* hasUserGesture */, PageTransition.LINK,
                 false /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */,
                 false /* hasUserGestureCarryover */);
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                assertFalse(
-                        mManager.getOverlayContentDelegate().shouldInterceptNavigation(
-                                externalNavHandler, navigationParams));
+                Assert.assertFalse(mManager.getOverlayContentDelegate().shouldInterceptNavigation(
+                        externalNavHandler, navigationParams));
             }
         });
-        assertEquals(1, mActivityMonitor.getHits());
+        Assert.assertEquals(1, mActivityMonitor.getHits());
     }
 
     /**
      * Tests ContextualSearchManager#shouldInterceptNavigation for a case that an initial
      * navigation has a user gesture but the redirected external navigation doesn't.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testRedirectedExternalNavigationWithUserGesture() {
         final ExternalNavigationHandler externalNavHandler =
-                new ExternalNavigationHandler(getActivity().getActivityTab());
+                new ExternalNavigationHandler(mActivityTestRule.getActivity().getActivityTab());
 
         final NavigationParams initialNavigationParams = new NavigationParams("http://test.com", "",
                 false /* isPost */, true /* hasUserGesture */, PageTransition.LINK,
@@ -2165,44 +2236,45 @@
                 true /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */,
                 false /* hasUserGestureCarryover */);
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 OverlayContentDelegate delegate = mManager.getOverlayContentDelegate();
-                assertTrue(delegate.shouldInterceptNavigation(
+                Assert.assertTrue(delegate.shouldInterceptNavigation(
                         externalNavHandler, initialNavigationParams));
-                assertFalse(delegate.shouldInterceptNavigation(
+                Assert.assertFalse(delegate.shouldInterceptNavigation(
                         externalNavHandler, redirectedNavigationParams));
             }
         });
-        assertEquals(1, mActivityMonitor.getHits());
+        Assert.assertEquals(1, mActivityMonitor.getHits());
     }
 
     /**
      * Tests ContextualSearchManager#shouldInterceptNavigation for a case that an external
      * navigation doesn't have a user gesture.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testExternalNavigationWithoutUserGesture() {
         final ExternalNavigationHandler externalNavHandler =
-                new ExternalNavigationHandler(getActivity().getActivityTab());
+                new ExternalNavigationHandler(mActivityTestRule.getActivity().getActivityTab());
         final NavigationParams navigationParams = new NavigationParams(
                 "intent://test/#Intent;scheme=test;package=com.chrome.test;end", "",
                 false /* isPost */, false /* hasUserGesture */, PageTransition.LINK,
                 false /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */,
                 false /* hasUserGestureCarryover */);
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                assertFalse(
-                        mManager.getOverlayContentDelegate().shouldInterceptNavigation(
-                                externalNavHandler, navigationParams));
+                Assert.assertFalse(mManager.getOverlayContentDelegate().shouldInterceptNavigation(
+                        externalNavHandler, navigationParams));
             }
         });
-        assertEquals(0, mActivityMonitor.getHits());
+        Assert.assertEquals(0, mActivityMonitor.getHits());
     }
 
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testSelectionExpansionOnSearchTermResolution()
@@ -2219,6 +2291,7 @@
     /**
      * Tests that long-press triggers the Peek Promo, and expanding the Panel dismisses it.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2229,21 +2302,21 @@
         // Must be in undecided state in order to trigger the Peek Promo.
         mPolicy.overrideDecidedStateForTesting(false);
         // Must have never opened the Panel in order to trigger the Peek Promo.
-        assertEquals(0, mPolicy.getPromoOpenCount());
+        Assert.assertEquals(0, mPolicy.getPromoOpenCount());
 
         // Long press and make sure the Promo shows.
         longPressNode("intelligence");
         waitForPanelToPeek();
-        assertTrue(mPanel.isPeekPromoVisible());
+        Assert.assertTrue(mPanel.isPeekPromoVisible());
 
         // After expanding the Panel the Promo should be invisible.
         flingPanelUp();
         waitForPanelToExpand();
-        assertFalse(mPanel.isPeekPromoVisible());
+        Assert.assertFalse(mPanel.isPeekPromoVisible());
 
         // After closing the Panel the Promo should still be invisible.
         tapBasePageToClosePanel();
-        assertFalse(mPanel.isPeekPromoVisible());
+        Assert.assertFalse(mPanel.isPeekPromoVisible());
 
         // Click elsewhere to clear the selection.
         clickNode("question-mark");
@@ -2252,7 +2325,7 @@
         // Now that the Panel was opened at least once, the Promo should not show again.
         longPressNode("intelligence");
         waitForPanelToPeek();
-        assertFalse(mPanel.isPeekPromoVisible());
+        Assert.assertFalse(mPanel.isPeekPromoVisible());
     }
 
     //============================================================================================
@@ -2262,6 +2335,7 @@
     /**
      * Tests that tap followed by expand makes Content visible.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2283,6 +2357,7 @@
      * Tests that long press followed by expand creates Content and makes it visible.
      *
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2305,6 +2380,7 @@
     /**
      * Tests swiping panel up and down after a tap search will only load the Content once.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2313,33 +2389,34 @@
         // Simulate a tap and make sure Content is not visible.
         simulateTapSearch("search");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Expanding the Panel should make the Content visible.
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Swiping the Panel down should not change the visibility or load content again.
         swipePanelDown();
         waitForPanelToPeek();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Expanding the Panel should not change the visibility or load content again.
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Closing the Panel should destroy the Content.
         tapBasePageToClosePanel();
         assertNoContentViewCore();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests swiping panel up and down after a long press search will only load the Content once.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -2354,35 +2431,36 @@
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreCreated();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Swiping the Panel down should not change the visibility or load content again.
         swipePanelDown();
         waitForPanelToPeek();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Expanding the Panel should not change the visibility or load content again.
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Closing the Panel should destroy the Content.
         tapBasePageToClosePanel();
         assertNoContentViewCore();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests that chained tap searches create new Content.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testChainedSearchCreatesNewContent() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
         simulateTapSearch("search");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         ContentViewCore cvc1 = getPanelContentViewCore();
 
         waitToPreventDoubleTapRecognition();
@@ -2390,28 +2468,29 @@
         // Simulate a new tap and make sure a new Content is created.
         simulateTapSearch("term");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
         ContentViewCore cvc2 = getPanelContentViewCore();
-        assertNotSame(cvc1, cvc2);
+        Assert.assertNotSame(cvc1, cvc2);
 
         waitToPreventDoubleTapRecognition();
 
         // Simulate a new tap and make sure a new Content is created.
         simulateTapSearch("resolution");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(3, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(3, mFakeServer.getLoadedUrlCount());
         ContentViewCore cvc3 = getPanelContentViewCore();
-        assertNotSame(cvc2, cvc3);
+        Assert.assertNotSame(cvc2, cvc3);
 
         // Closing the Panel should destroy the Content.
         closePanel();
         assertNoContentViewCore();
-        assertEquals(3, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(3, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests that chained searches load correctly.
      */
+    @Test
     @DisabledTest(message = "crbug.com/551711")
     @SmallTest
     @Feature({"ContextualSearch"})
@@ -2421,19 +2500,19 @@
         // Simulate a tap and make sure Content is not visible.
         simulateTapSearch("search");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         ContentViewCore cvc1 = getPanelContentViewCore();
 
         // Expanding the Panel should make the Content visible.
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Swiping the Panel down should not change the visibility or load content again.
         swipePanelDown();
         waitForPanelToPeek();
         assertContentViewCoreVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         waitToPreventDoubleTapRecognition();
 
@@ -2444,27 +2523,28 @@
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreCreated();
         assertContentViewCoreVisible();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
         assertLoadedSearchTermMatches("Resolution");
         ContentViewCore cvc2 = getPanelContentViewCore();
-        assertNotSame(cvc1, cvc2);
+        Assert.assertNotSame(cvc1, cvc2);
 
         // Closing the Panel should destroy the Content.
         tapBasePageToClosePanel();
         assertNoContentViewCore();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
     }
 
     /**
      * Tests that chained searches make Content visible when opening the Panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testChainedSearchContentVisibility() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
         simulateTapSearch("search");
         assertContentViewCoreCreatedButNeverMadeVisible();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         ContentViewCore cvc1 = getPanelContentViewCore();
 
         waitToPreventDoubleTapRecognition();
@@ -2472,16 +2552,16 @@
         // Now simulate a long press, leaving the Panel peeking.
         simulateLongPressSearch("resolution");
         assertNeverCalledContentViewCoreOnShow();
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
 
         // Expanding the Panel should load and display the new search.
         tapPeekingBarToExpandAndAssert();
         assertContentViewCoreCreated();
         assertContentViewCoreVisible();
-        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(2, mFakeServer.getLoadedUrlCount());
         assertLoadedSearchTermMatches("Resolution");
         ContentViewCore cvc2 = getPanelContentViewCore();
-        assertNotSame(cvc1, cvc2);
+        Assert.assertNotSame(cvc1, cvc2);
     }
 
     //============================================================================================
@@ -2491,31 +2571,33 @@
     /**
      * Tests that a tap followed by closing the Panel removes the loaded URL from history.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapCloseRemovedFromHistory() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure a URL was loaded.
         simulateTapSearch("search");
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         String url = mFakeServer.getLoadedUrl();
 
         // Close the Panel without seeing the Content.
         tapBasePageToClosePanel();
 
         // Now check that the URL has been removed from history.
-        assertTrue(mFakeServer.hasRemovedUrl(url));
+        Assert.assertTrue(mFakeServer.hasRemovedUrl(url));
     }
 
     /**
      * Tests that a tap followed by opening the Panel does not remove the loaded URL from history.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     public void testTapExpandNotRemovedFromHistory() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure a URL was loaded.
         simulateTapSearch("search");
-        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        Assert.assertEquals(1, mFakeServer.getLoadedUrlCount());
         String url = mFakeServer.getLoadedUrl();
 
         // Expand Panel so that the Content becomes visible.
@@ -2525,42 +2607,43 @@
         tapBasePageToClosePanel();
 
         // Now check that the URL has not been removed from history, since the Content was seen.
-        assertFalse(mFakeServer.hasRemovedUrl(url));
+        Assert.assertFalse(mFakeServer.hasRemovedUrl(url));
     }
 
     /**
      * Tests that chained searches without opening the Panel removes all loaded URLs from history.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testChainedTapsRemovedFromHistory() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure a URL was loaded.
         simulateTapSearch("search");
         String url1 = mFakeServer.getLoadedUrl();
-        assertNotNull(url1);
+        Assert.assertNotNull(url1);
 
         waitToPreventDoubleTapRecognition();
 
         // Simulate another tap and make sure another URL was loaded.
         simulateTapSearch("term");
         String url2 = mFakeServer.getLoadedUrl();
-        assertNotSame(url1, url2);
+        Assert.assertNotSame(url1, url2);
 
         waitToPreventDoubleTapRecognition();
 
         // Simulate another tap and make sure another URL was loaded.
         simulateTapSearch("resolution");
         String url3 = mFakeServer.getLoadedUrl();
-        assertNotSame(url2, url3);
+        Assert.assertNotSame(url2, url3);
 
         // Close the Panel without seeing any Content.
         closePanel();
 
         // Now check that all three URLs have been removed from history.
-        assertEquals(3, mFakeServer.getLoadedUrlCount());
-        assertTrue(mFakeServer.hasRemovedUrl(url1));
-        assertTrue(mFakeServer.hasRemovedUrl(url2));
-        assertTrue(mFakeServer.hasRemovedUrl(url3));
+        Assert.assertEquals(3, mFakeServer.getLoadedUrlCount());
+        Assert.assertTrue(mFakeServer.hasRemovedUrl(url1));
+        Assert.assertTrue(mFakeServer.hasRemovedUrl(url2));
+        Assert.assertTrue(mFakeServer.hasRemovedUrl(url3));
     }
 
     //============================================================================================
@@ -2570,6 +2653,7 @@
     /**
      * Tests that a simple Tap with language determination triggers translation.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapWithLanguage() throws InterruptedException, TimeoutException {
@@ -2577,7 +2661,7 @@
         simulateTapSearch("german");
 
         // Make sure we tried to trigger translate.
-        assertTrue("Translation was not forced with the current request URL: "
+        Assert.assertTrue("Translation was not forced with the current request URL: "
                         + mManager.getRequest().getSearchUrl(),
                 mManager.getRequest().isTranslationForced());
     }
@@ -2585,6 +2669,7 @@
     /**
      * Tests translation with a simple Tap can be disabled.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @CommandLineFlags.Add(ContextualSearchFieldTrial.DISABLE_TRANSLATION + "=true")
@@ -2593,12 +2678,13 @@
         simulateTapSearch("german");
 
         // Make sure we did not try to trigger translate.
-        assertFalse(mManager.getRequest().isTranslationForced());
+        Assert.assertFalse(mManager.getRequest().isTranslationForced());
     }
 
     /**
      * Tests that a simple Tap without language determination does not trigger translation.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testTapWithoutLanguage() throws InterruptedException, TimeoutException {
@@ -2606,12 +2692,13 @@
         simulateTapSearch("search");
 
         // Make sure we did not try to trigger translate.
-        assertFalse(mManager.getRequest().isTranslationForced());
+        Assert.assertFalse(mManager.getRequest().isTranslationForced());
     }
 
     /**
      * Tests that a long-press does trigger translation.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testLongpressTranslates() throws InterruptedException, TimeoutException {
@@ -2619,12 +2706,13 @@
         simulateLongPressSearch("search");
 
         // Make sure we did try to trigger translate.
-        assertTrue(mManager.getRequest().isTranslationForced());
+        Assert.assertTrue(mManager.getRequest().isTranslationForced());
     }
 
     /**
      * Tests that a long-press does NOT trigger translation when disabled.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @CommandLineFlags.Add(ContextualSearchFieldTrial.DISABLE_TRANSLATION + "=true")
@@ -2634,7 +2722,7 @@
         simulateLongPressSearch("search");
 
         // Make sure we did not try to trigger translate.
-        assertFalse(mManager.getRequest().isTranslationForced());
+        Assert.assertFalse(mManager.getRequest().isTranslationForced());
     }
 
     /**
@@ -2642,22 +2730,25 @@
      * peeks the panel, expanding the bar results in the bar ending at the correct spot in the page
      * and tapping the base page closes the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     public void testTapContentAndExpandPanelInFullscreen()
             throws InterruptedException, TimeoutException {
         // Toggle tab to fulllscreen.
-        FullscreenTestUtils.togglePersistentFullscreenAndAssert(getActivity().getActivityTab(),
-                true, getActivity());
+        FullscreenTestUtils.togglePersistentFullscreenAndAssert(
+                mActivityTestRule.getActivity().getActivityTab(), true,
+                mActivityTestRule.getActivity());
 
         // Simulate a tap and assert that the panel peeks.
         simulateTapSearch("search");
 
         // Expand the panel and assert that it ends up in the right place.
         tapPeekingBarToExpandAndAssert();
-        assertEquals(mManager.getContextualSearchPanel().getHeight(),
-                mManager.getContextualSearchPanel().getPanelHeightFromState(PanelState.EXPANDED));
+        Assert.assertEquals(mManager.getContextualSearchPanel().getHeight(),
+                mManager.getContextualSearchPanel().getPanelHeightFromState(PanelState.EXPANDED),
+                0);
 
         // Tap the base page and assert that the panel is closed.
         tapBasePageToClosePanel();
@@ -2666,6 +2757,7 @@
     /**
      * Tests that the Contextual Search panel is dismissed when entering or exiting fullscreen.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testPanelDismissedOnToggleFullscreen()
@@ -2674,8 +2766,9 @@
         simulateTapSearch("search");
 
         // Toggle tab to fullscreen.
-        Tab tab = getActivity().getActivityTab();
-        FullscreenTestUtils.togglePersistentFullscreenAndAssert(tab, true, getActivity());
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
+        FullscreenTestUtils.togglePersistentFullscreenAndAssert(
+                tab, true, mActivityTestRule.getActivity());
 
         // Assert that the panel is closed.
         waitForPanelToClose();
@@ -2684,7 +2777,8 @@
         simulateTapSearch("search");
 
         // Toggle tab to non-fullscreen.
-        FullscreenTestUtils.togglePersistentFullscreenAndAssert(tab, false, getActivity());
+        FullscreenTestUtils.togglePersistentFullscreenAndAssert(
+                tab, false, mActivityTestRule.getActivity());
 
         // Assert that the panel is closed.
         waitForPanelToClose();
@@ -2694,6 +2788,7 @@
      * Tests that ContextualSearchImageControl correctly sets either the icon sprite or thumbnail
      * as visible.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testImageControl() throws InterruptedException, TimeoutException {
@@ -2701,8 +2796,8 @@
 
         final ContextualSearchImageControl imageControl = mPanel.getImageControl();
 
-        assertFalse(imageControl.getThumbnailVisible());
-        assertTrue(TextUtils.isEmpty(imageControl.getThumbnailUrl()));
+        Assert.assertFalse(imageControl.getThumbnailVisible());
+        Assert.assertTrue(TextUtils.isEmpty(imageControl.getThumbnailUrl()));
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -2712,8 +2807,8 @@
             }
         });
 
-        assertTrue(imageControl.getThumbnailVisible());
-        assertEquals(imageControl.getThumbnailUrl(), "http://someimageurl.com/image.png");
+        Assert.assertTrue(imageControl.getThumbnailVisible());
+        Assert.assertEquals(imageControl.getThumbnailUrl(), "http://someimageurl.com/image.png");
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -2722,8 +2817,8 @@
             }
         });
 
-        assertFalse(imageControl.getThumbnailVisible());
-        assertTrue(TextUtils.isEmpty(imageControl.getThumbnailUrl()));
+        Assert.assertFalse(imageControl.getThumbnailVisible());
+        Assert.assertTrue(TextUtils.isEmpty(imageControl.getThumbnailUrl()));
     }
 
     // TODO(twellington): Add an end-to-end integration test for fetching a thumbnail based on a
@@ -2732,6 +2827,7 @@
     /**
      * Tests that Contextual Search is fully disabled when offline.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     // NOTE: Remove the flag so we will run just this test with onLine detection enabled.
@@ -2757,6 +2853,7 @@
      * Tests that the quick action caption is set correctly when one is available. Also tests that
      * the caption gets changed when the panel is expanded and reset when the panel is closed.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testQuickActionCaptionAndImage() throws InterruptedException, TimeoutException {
@@ -2777,12 +2874,12 @@
         ContextualSearchImageControl imageControl = mPanel.getImageControl();
 
         // Check that the peeking bar is showing the quick action data.
-        assertTrue(quickActionControl.hasQuickAction());
-        assertTrue(barControl.getCaptionVisible());
-        assertEquals(getActivity().getResources().getString(
-                R.string.contextual_search_quick_action_caption_phone),
+        Assert.assertTrue(quickActionControl.hasQuickAction());
+        Assert.assertTrue(barControl.getCaptionVisible());
+        Assert.assertEquals(mActivityTestRule.getActivity().getResources().getString(
+                                    R.string.contextual_search_quick_action_caption_phone),
                 barControl.getCaptionText());
-        assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage());
+        Assert.assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage(), 0);
 
         // Expand the bar.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -2794,36 +2891,37 @@
         waitForPanelToExpand();
 
         // Check that the expanded bar is showing the correct image and caption.
-        assertTrue(barControl.getCaptionVisible());
-        assertEquals(getActivity().getResources().getString(
-                ContextualSearchCaptionControl.EXPANED_CAPTION_ID),
+        Assert.assertTrue(barControl.getCaptionVisible());
+        Assert.assertEquals(mActivityTestRule.getActivity().getResources().getString(
+                                    ContextualSearchCaptionControl.EXPANED_CAPTION_ID),
                 barControl.getCaptionText());
-        assertEquals(0.f, imageControl.getCustomImageVisibilityPercentage());
+        Assert.assertEquals(0.f, imageControl.getCustomImageVisibilityPercentage(), 0);
 
         // Go back to peeking.
         swipePanelDown();
         waitForPanelToPeek();
 
         // Assert that the quick action data is showing.
-        assertTrue(barControl.getCaptionVisible());
-        assertEquals(getActivity().getResources().getString(
-                R.string.contextual_search_quick_action_caption_phone),
+        Assert.assertTrue(barControl.getCaptionVisible());
+        Assert.assertEquals(mActivityTestRule.getActivity().getResources().getString(
+                                    R.string.contextual_search_quick_action_caption_phone),
                 barControl.getCaptionText());
-        assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage());
+        Assert.assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage(), 0);
     }
 
     /**
      * Tests that an intent is sent when the bar is tapped and a quick action is available.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testQuickActionIntent() throws InterruptedException, TimeoutException {
         // Add a new filter to the activity monitor that matches the intent that should be fired.
         IntentFilter quickActionFilter = new IntentFilter(Intent.ACTION_VIEW);
         quickActionFilter.addDataScheme("tel");
-        mActivityMonitor = getInstrumentation().addMonitor(
-                quickActionFilter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null),
-                true);
+        mActivityMonitor =
+                InstrumentationRegistry.getInstrumentation().addMonitor(quickActionFilter,
+                        new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true);
 
         // Simulate a tap to show the Bar, then set the quick action data.
         simulateTapSearch("search");
@@ -2839,13 +2937,14 @@
         clickPanelBar();
 
         // Assert that an intent was fired.
-        assertEquals(1, mActivityMonitor.getHits());
+        Assert.assertEquals(1, mActivityMonitor.getHits());
     }
 
     /**
      * Tests that the current tab is navigated to the quick action URI for
      * QuickActionCategory#WEBSITE.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testQuickActionUrl() throws InterruptedException, TimeoutException {
@@ -2864,12 +2963,14 @@
         clickPanelBar();
 
         // Assert that the URL was loaded.
-        ChromeTabUtils.waitForTabPageLoaded(getActivity().getActivityTab(), testUrl);
+        ChromeTabUtils.waitForTabPageLoaded(
+                mActivityTestRule.getActivity().getActivityTab(), testUrl);
     }
 
     /**
      * Tests accessibility mode: Tap and Long-press don't activate CS.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testAccesibilityMode() throws InterruptedException, TimeoutException {
@@ -2889,6 +2990,7 @@
     /**
      * Tests that the Manager cycles through all the expected Internal States on Tap that Resolves.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testAllInternalStatesVisitedResolvingTap()
@@ -2901,17 +3003,20 @@
 
         // Simulate a tap that resolves to show the Bar.
         simulateTapSearch("search");
-        assertEquals(InternalState.SHOWING_TAP_SEARCH, internalStateControllerWrapper.getState());
+        Assert.assertEquals(
+                InternalState.SHOWING_TAP_SEARCH, internalStateControllerWrapper.getState());
 
-        assertEquals(internalStateControllerWrapper.getStartedStates(),
+        Assert.assertEquals(internalStateControllerWrapper.getStartedStates(),
                 internalStateControllerWrapper.getFinishedStates());
-        assertEquals(ContextualSearchInternalStateControllerWrapper.EXPECTED_TAP_RESOLVE_SEQUENCE,
+        Assert.assertEquals(
+                ContextualSearchInternalStateControllerWrapper.EXPECTED_TAP_RESOLVE_SEQUENCE,
                 internalStateControllerWrapper.getFinishedStates());
     }
 
     /**
      * Tests that the Manager cycles through all the expected Internal States on a Long-press.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     public void testAllInternalStatesVisitedLongpress()
@@ -2925,9 +3030,10 @@
         // Simulate a Long-press to show the Bar.
         simulateLongPressSearch("search");
 
-        assertEquals(internalStateControllerWrapper.getStartedStates(),
+        Assert.assertEquals(internalStateControllerWrapper.getStartedStates(),
                 internalStateControllerWrapper.getFinishedStates());
-        assertEquals(ContextualSearchInternalStateControllerWrapper.EXPECTED_LONGPRESS_SEQUENCE,
+        Assert.assertEquals(
+                ContextualSearchInternalStateControllerWrapper.EXPECTED_LONGPRESS_SEQUENCE,
                 internalStateControllerWrapper.getFinishedStates());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
index 1f18857..a8d8225 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
@@ -4,19 +4,23 @@
 
 package org.chromium.chrome.browser.contextualsearch;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
 import android.content.Context;
 import android.net.Uri;
 import android.support.test.filters.SmallTest;
 import android.widget.LinearLayout;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.WebContentsFactory;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManagerWrapper;
@@ -24,7 +28,8 @@
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchInternalStateController.InternalState;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchSelectionController.SelectionType;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.SelectionClient;
 import org.chromium.content.browser.SelectionPopupController;
@@ -37,7 +42,15 @@
 /**
  * Mock touch events with Contextual Search to test behavior of its panel and manager.
  */
-public class ContextualSearchTapEventTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
+})
+public class ContextualSearchTapEventTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private ContextualSearchManagerWrapper mContextualSearchManager;
     private ContextualSearchPanel mPanel;
@@ -249,15 +262,10 @@
 
     // --------------------------------------------------------------------------------------------
 
-    public ContextualSearchTapEventTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        final ChromeActivity activity = getActivity();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        final ChromeActivity activity = mActivityTestRule.getActivity();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -276,51 +284,48 @@
         });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL("about:blank");
-    }
-
     /**
      * Tests that a Tap gesture followed by tapping empty space closes the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     public void testLongpressFollowedByNonTextTap() {
-        assertTrue(mPanelManager.getRequestPanelShowCount() == 0);
+        Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 0);
 
         // Fake a selection event.
         mockLongpressText("text");
 
-        assertThat(mPanelManager.getRequestPanelShowCount(), is(1));
-        assertThat(mPanelManager.getPanelHideCount(), is(0));
-        assertThat(mContextualSearchManager.getSelectionController().getSelectedText(),
-                equalTo("text"));
+        Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 1);
+        Assert.assertEquals(mPanelManager.getPanelHideCount(), 0);
+        Assert.assertEquals(mContextualSearchManager.getSelectionController().getSelectedText(),
+                "text");
 
         // Fake tap on non-text.
         mockTapEmptySpace();
 
-        assertThat(mPanelManager.getRequestPanelShowCount(), is(1));
-        assertThat(mPanelManager.getPanelHideCount(), is(1));
-        assertNull(mContextualSearchManager.getSelectionController().getSelectedText());
+        Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 1);
+        Assert.assertEquals(mPanelManager.getPanelHideCount(), 1);
+        Assert.assertNull(mContextualSearchManager.getSelectionController().getSelectedText());
     }
 
     /**
      * Tests that a Tap gesture followed by tapping empty space closes the panel.
      */
+    @Test
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     public void testTextTapFollowedByNonTextTap() {
-        assertTrue(mPanelManager.getRequestPanelShowCount() == 0);
+        Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 0);
 
         // Fake a Tap event.
         mockTapText("text");
         // Right now the tap-processing sequence will stall at selectWordAroundCaret, so we need
         // to prod it forward with a manual hack:
         mockSelectWordAroundCaretAck("text");
-        assertThat(mPanelManager.getRequestPanelShowCount(), is(1));
-        assertThat(mPanelManager.getPanelHideCount(), is(0));
+        Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 1);
+        Assert.assertEquals(mPanelManager.getPanelHideCount(), 0);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java
index 8a780b4..245cc44 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java
@@ -4,15 +4,24 @@
 
 package org.chromium.chrome.browser.dom_distiller;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.compositor.bottombar.readermode.ReaderModePanel;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper;
 import org.chromium.content.browser.test.util.TestWebContentsObserver;
@@ -23,49 +32,51 @@
 /**
  * Tests for making sure the distillability service is communicating correctly.
  */
-@CommandLineFlags.Add({"enable-dom-distiller", "reader-mode-heuristics=alwaystrue"})
-public class DistillabilityServiceTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"enable-dom-distiller", "reader-mode-heuristics=alwaystrue",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class DistillabilityServiceTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEST_PAGE = "/chrome/test/data/android/simple.html";
 
-    public DistillabilityServiceTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * Make sure that Reader Mode appears after navigating from a native page.
      */
+    @Test
     @Feature({"Distillability-Service"})
     @MediumTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @DisabledTest
-    public void testServiceAliveAfterNativePage()
-            throws InterruptedException, TimeoutException {
-
+    public void testServiceAliveAfterNativePage() throws InterruptedException, TimeoutException {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
 
-        final ReaderModePanel panel = getActivity().getReaderModeManager().getPanelForTesting();
+        final ReaderModePanel panel =
+                mActivityTestRule.getActivity().getReaderModeManager().getPanelForTesting();
 
-        TestWebContentsObserver observer =
-                new TestWebContentsObserver(getActivity().getActivityTab().getWebContents());
+        TestWebContentsObserver observer = new TestWebContentsObserver(
+                mActivityTestRule.getActivity().getActivityTab().getWebContents());
         OnPageFinishedHelper finishHelper = observer.getOnPageFinishedHelper();
 
         // Navigate to a native page.
         int curCallCount = finishHelper.getCallCount();
-        loadUrl("chrome://history");
+        mActivityTestRule.loadUrl("chrome://history");
         finishHelper.waitForCallback(curCallCount, 1);
-        assertFalse(panel.isShowing());
+        Assert.assertFalse(panel.isShowing());
 
         // Navigate to a normal page.
         curCallCount = finishHelper.getCallCount();
-        loadUrl(testServer.getURL(TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(TEST_PAGE));
         finishHelper.waitForCallback(curCallCount, 1);
-        assertTrue(panel.isShowing());
+        Assert.assertTrue(panel.isShowing());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java
index 8c4924f..77b9c75a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java
@@ -5,29 +5,41 @@
 package org.chromium.chrome.browser.download;
 
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.util.concurrent.Callable;
 
 /**
  * Tests for ChromeDownloadDelegate class.
  */
-public class ChromeDownloadDelegateTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ChromeDownloadDelegateTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
-    public ChromeDownloadDelegateTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
@@ -47,36 +59,40 @@
      * Test to make sure {@link ChromeDownloadDelegate#shouldInterceptContextMenuDownload}
      * returns true only for ".dd" or ".dm" extensions with http/https scheme.
      */
+    @Test
     @SmallTest
     @Feature({"Download"})
     @RetryOnFailure
     public void testShouldInterceptContextMenuDownload() throws InterruptedException {
-        final Tab tab = getActivity().getActivityTab();
-        loadUrl("about:blank");
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
+        mActivityTestRule.loadUrl("about:blank");
         ChromeDownloadDelegate delegate = ThreadUtils.runOnUiThreadBlockingNoException(
                 new Callable<ChromeDownloadDelegate>() {
                     @Override
                     public ChromeDownloadDelegate call() {
                         return new MockChromeDownloadDelegate(
-                                getInstrumentation().getTargetContext(), tab);
+                                InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                                tab);
                     }
                 });
-        assertFalse(delegate.shouldInterceptContextMenuDownload("file://test/test.html"));
-        assertFalse(delegate.shouldInterceptContextMenuDownload("http://test/test.html"));
-        assertFalse(delegate.shouldInterceptContextMenuDownload("ftp://test/test.dm"));
-        assertFalse(delegate.shouldInterceptContextMenuDownload("data://test.dd"));
-        assertFalse(delegate.shouldInterceptContextMenuDownload("http://test.dd"));
-        assertFalse(delegate.shouldInterceptContextMenuDownload("http://test/test.dd"));
-        assertTrue(delegate.shouldInterceptContextMenuDownload("https://test/test.dm"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("file://test/test.html"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("http://test/test.html"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("ftp://test/test.dm"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("data://test.dd"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("http://test.dd"));
+        Assert.assertFalse(delegate.shouldInterceptContextMenuDownload("http://test/test.dd"));
+        Assert.assertTrue(delegate.shouldInterceptContextMenuDownload("https://test/test.dm"));
     }
 
+    @Test
     @SmallTest
     @Feature({"Download"})
     public void testGetFileExtension() {
-        assertEquals("ext", ChromeDownloadDelegate.getFileExtension("", "file.ext"));
-        assertEquals("ext", ChromeDownloadDelegate.getFileExtension("http://file.ext", ""));
-        assertEquals("txt", ChromeDownloadDelegate.getFileExtension("http://file.ext", "file.txt"));
-        assertEquals("txt", ChromeDownloadDelegate.getFileExtension(
-                "http://file.ext", "file name.txt"));
+        Assert.assertEquals("ext", ChromeDownloadDelegate.getFileExtension("", "file.ext"));
+        Assert.assertEquals("ext", ChromeDownloadDelegate.getFileExtension("http://file.ext", ""));
+        Assert.assertEquals(
+                "txt", ChromeDownloadDelegate.getFileExtension("http://file.ext", "file.txt"));
+        Assert.assertEquals(
+                "txt", ChromeDownloadDelegate.getFileExtension("http://file.ext", "file name.txt"));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java
index 140f3f72..af36673f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/engagement/SiteEngagementServiceTest.java
@@ -5,61 +5,84 @@
 package org.chromium.chrome.browser.engagement;
 
 import android.support.test.filters.SmallTest;
-import android.test.UiThreadTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /**
  * Test for the Site Engagement Service Java binding.
  */
-public class SiteEngagementServiceTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public SiteEngagementServiceTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SiteEngagementServiceTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
      * Verify that setting the engagement score for a URL and reading it back it works.
      */
+    @Test
     @SmallTest
-    @UiThreadTest
     @Feature({"Engagement"})
-    public void testSettingAndRetrievingScore() {
-        final String url = "https://www.google.com";
-        SiteEngagementService service = SiteEngagementService.getForProfile(
-                getActivity().getActivityTab().getProfile());
+    public void testSettingAndRetrievingScore() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final String url = "https://www.google.com";
+                SiteEngagementService service = SiteEngagementService.getForProfile(
+                        mActivityTestRule.getActivity().getActivityTab().getProfile());
 
-        assertEquals(0.0, service.getScore(url));
-        service.resetBaseScoreForUrl(url, 5.0);
-        assertEquals(5.0, service.getScore(url));
+                Assert.assertEquals(0.0, service.getScore(url), 0);
+                service.resetBaseScoreForUrl(url, 5.0);
+                Assert.assertEquals(5.0, service.getScore(url), 0);
 
-        service.resetBaseScoreForUrl(url, 2.0);
-        assertEquals(2.0, service.getScore(url));
+                service.resetBaseScoreForUrl(url, 2.0);
+                Assert.assertEquals(2.0, service.getScore(url), 0);
+            }
+        });
     }
 
     /**
      * Verify that repeatedly fetching and throwing away the SiteEngagementService works.
      */
+    @Test
     @SmallTest
-    @UiThreadTest
     @Feature({"Engagement"})
-    public void testRepeatedlyGettingService() {
-        final String url = "https://www.google.com";
-        Profile profile = getActivity().getActivityTab().getProfile();
+    public void testRepeatedlyGettingService() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final String url = "https://www.google.com";
+                Profile profile = mActivityTestRule.getActivity().getActivityTab().getProfile();
 
-        assertEquals(0.0, SiteEngagementService.getForProfile(profile).getScore(url));
-        SiteEngagementService.getForProfile(profile).resetBaseScoreForUrl(url, 5.0);
-        assertEquals(5.0, SiteEngagementService.getForProfile(profile).getScore(url));
+                Assert.assertEquals(
+                        0.0, SiteEngagementService.getForProfile(profile).getScore(url), 0);
+                SiteEngagementService.getForProfile(profile).resetBaseScoreForUrl(url, 5.0);
+                Assert.assertEquals(
+                        5.0, SiteEngagementService.getForProfile(profile).getScore(url), 0);
 
-        SiteEngagementService.getForProfile(profile).resetBaseScoreForUrl(url, 2.0);
-        assertEquals(2.0, SiteEngagementService.getForProfile(profile).getScore(url));
+                SiteEngagementService.getForProfile(profile).resetBaseScoreForUrl(url, 2.0);
+                Assert.assertEquals(
+                        2.0, SiteEngagementService.getForProfile(profile).getScore(url), 0);
+            }
+        });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java
index a9094d8..eb51fff9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImplTest.java
@@ -9,9 +9,18 @@
 import android.content.pm.ResolveInfo;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -20,34 +29,43 @@
 /**
  * Instrumentation tests for {@link ExternalNavigationHandler}.
  */
-public class ExternalNavigationDelegateImplTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public ExternalNavigationDelegateImplTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ExternalNavigationDelegateImplTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static List<ResolveInfo> makeResolveInfos(ResolveInfo... infos) {
         return Arrays.asList(infos);
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_NoResolveInfo() {
         String packageName = "";
         List<ResolveInfo> resolveInfos = new ArrayList<ResolveInfo>();
-        assertEquals(0, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(0,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_NoPathOrAuthority() {
         String packageName = "";
         ResolveInfo info = new ResolveInfo();
         info.filter = new IntentFilter();
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
-        assertEquals(0, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(0,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_WithPath() {
         String packageName = "";
@@ -55,10 +73,13 @@
         info.filter = new IntentFilter();
         info.filter.addDataPath("somepath", 2);
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
-        assertEquals(1, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(1,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_WithAuthority() {
         String packageName = "";
@@ -66,10 +87,13 @@
         info.filter = new IntentFilter();
         info.filter.addDataAuthority("http://www.google.com", "80");
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
-        assertEquals(1, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(1,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_WithTargetPackage_Matching() {
         String packageName = "com.android.chrome";
@@ -79,10 +103,13 @@
         info.activityInfo = new ActivityInfo();
         info.activityInfo.packageName = packageName;
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
-        assertEquals(1, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(1,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializedHandler_WithTargetPackage_NotMatching() {
         String packageName = "com.android.chrome";
@@ -92,10 +119,13 @@
         info.activityInfo = new ActivityInfo();
         info.activityInfo.packageName = "com.foo.bar";
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
-        assertEquals(0, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                                resolveInfos, packageName).size());
+        Assert.assertEquals(0,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsPackageSpecializeHandler_withEphemeralResolver() {
         String packageName = "";
@@ -107,28 +137,31 @@
         info.activityInfo.packageName = "com.google.android.gms";
         List<ResolveInfo> resolveInfos = makeResolveInfos(info);
         // Ephemeral resolver is not counted as a specialized handler.
-        assertEquals(0, ExternalNavigationDelegateImpl.getSpecializedHandlersWithFilter(
-                resolveInfos, packageName).size());
+        Assert.assertEquals(0,
+                ExternalNavigationDelegateImpl
+                        .getSpecializedHandlersWithFilter(resolveInfos, packageName)
+                        .size());
     }
 
+    @Test
     @SmallTest
     public void testIsDownload_noSystemDownloadManager() throws Exception {
         ExternalNavigationDelegateImpl delegate = new ExternalNavigationDelegateImpl(
-                getActivity().getActivityTab());
-        assertTrue("pdf should be a download, no viewer in Android Chrome",
+                mActivityTestRule.getActivity().getActivityTab());
+        Assert.assertTrue("pdf should be a download, no viewer in Android Chrome",
                 delegate.isPdfDownload("http://somesampeleurldne.com/file.pdf"));
-        assertFalse("URL is not a file, but web page",
+        Assert.assertFalse("URL is not a file, but web page",
                 delegate.isPdfDownload("http://somesampleurldne.com/index.html"));
-        assertFalse("URL is not a file url",
+        Assert.assertFalse("URL is not a file url",
                 delegate.isPdfDownload("http://somesampeleurldne.com/not.a.real.extension"));
-        assertFalse("URL is an image, can be viewed in Chrome",
+        Assert.assertFalse("URL is an image, can be viewed in Chrome",
                 delegate.isPdfDownload("http://somesampleurldne.com/image.jpg"));
-        assertFalse("URL is a text file can be viewed in Chrome",
+        Assert.assertFalse("URL is a text file can be viewed in Chrome",
                 delegate.isPdfDownload("http://somesampleurldne.com/copy.txt"));
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
index 39363a6e..859228e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -12,23 +12,35 @@
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.text.TextUtils;
 import android.util.Base64;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.OverrideUrlLoadingResult;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.ui.base.PageTransition;
@@ -41,7 +53,14 @@
 /**
  * Test suite for verifying the behavior of various URL overriding actions.
  */
-public class UrlOverridingTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class UrlOverridingTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String BASE_PATH = "/chrome/test/data/android/url_overriding/";
     private static final String NAVIGATION_FROM_TIMEOUT_PAGE =
             BASE_PATH + "navigation_from_timer.html";
@@ -102,25 +121,21 @@
     private ActivityMonitor mActivityMonitor;
     private EmbeddedTestServer mTestServer;
 
-    public UrlOverridingTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
         filter.addCategory(Intent.CATEGORY_BROWSABLE);
         filter.addDataScheme("market");
-        mActivityMonitor = getInstrumentation().addMonitor(
+        mActivityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor(
                 filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true);
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     private void loadUrlAndWaitForIntentUrl(final String url, boolean needClick,
@@ -135,23 +150,24 @@
         final CallbackHelper failCallback = new CallbackHelper();
         final CallbackHelper newTabCallback = new CallbackHelper();
 
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
         final Tab[] latestTabHolder = new Tab[1];
         latestTabHolder[0] = tab;
         tab.addObserver(new TestTabObserver(finishCallback, failCallback));
         if (expectedNewTabCount > 0) {
-            getActivity().getTabModelSelector().addObserver(new EmptyTabModelSelectorObserver() {
-                @Override
-                public void onNewTabCreated(Tab newTab) {
-                    newTabCallback.notifyCalled();
-                    newTab.addObserver(new TestTabObserver(finishCallback, failCallback));
-                    latestTabHolder[0] = newTab;
-                }
-            });
+            mActivityTestRule.getActivity().getTabModelSelector().addObserver(
+                    new EmptyTabModelSelectorObserver() {
+                        @Override
+                        public void onNewTabCreated(Tab newTab) {
+                            newTabCallback.notifyCalled();
+                            newTab.addObserver(new TestTabObserver(finishCallback, failCallback));
+                            latestTabHolder[0] = newTab;
+                        }
+                    });
         }
 
-        getActivity().onUserInteraction();
-        getInstrumentation().runOnMainSync(new Runnable() {
+        mActivityTestRule.getActivity().onUserInteraction();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 tab.loadUrl(new LoadUrlParams(url, PageTransition.LINK));
@@ -162,22 +178,22 @@
             try {
                 finishCallback.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
             } catch (TimeoutException ex) {
-                fail();
+                Assert.fail();
                 return;
             }
         }
 
         SystemClock.sleep(1);
-        getActivity().onUserInteraction();
+        mActivityTestRule.getActivity().onUserInteraction();
         if (needClick) {
-            singleClickView(tab.getView());
+            TouchCommon.singleClickView(tab.getView());
         }
 
         if (failCallback.getCallCount() == 0) {
             try {
                 failCallback.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
             } catch (TimeoutException ex) {
-                fail("Haven't received navigation failure of intents.");
+                Assert.fail("Haven't received navigation failure of intents.");
                 return;
             }
         }
@@ -190,13 +206,13 @@
                 try {
                     finishCallback.waitForCallback(1, 1, 20, TimeUnit.SECONDS);
                 } catch (TimeoutException ex) {
-                    fail("Fallback URL is not loaded");
+                    Assert.fail("Fallback URL is not loaded");
                     return;
                 }
             }
         }
 
-        assertEquals(expectedNewTabCount, newTabCallback.getCallCount());
+        Assert.assertEquals(expectedNewTabCount, newTabCallback.getCallCount());
         // For sub frames, the |loadFailCallback| run through different threads
         // from the ExternalNavigationHandler. As a result, there is no guarantee
         // when url override result would come.
@@ -229,10 +245,11 @@
                         return mActivityMonitor.getHits();
                     }
                 }));
-        assertEquals(1 + (hasFallbackUrl ? 1 : 0), finishCallback.getCallCount());
-        assertEquals(1, failCallback.getCallCount());
+        Assert.assertEquals(1 + (hasFallbackUrl ? 1 : 0), finishCallback.getCallCount());
+        Assert.assertEquals(1, failCallback.getCallCount());
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromTimer() throws InterruptedException {
@@ -240,6 +257,7 @@
                 mTestServer.getURL(NAVIGATION_FROM_TIMEOUT_PAGE), false, false, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromTimerInSubFrame() throws InterruptedException {
@@ -248,6 +266,7 @@
                 false, false);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromUserGesture() throws InterruptedException {
@@ -255,6 +274,7 @@
                 mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PAGE), true, true, true);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromUserGestureInSubFrame() throws InterruptedException {
         loadUrlAndWaitForIntentUrl(
@@ -262,6 +282,7 @@
                 true, false);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromXHRCallback() throws InterruptedException {
@@ -269,6 +290,7 @@
                 mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PAGE), true, true, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromXHRCallbackInSubFrame() throws InterruptedException {
@@ -277,6 +299,7 @@
                 true, false);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromXHRCallbackAndShortTimeout() throws InterruptedException {
@@ -285,6 +308,7 @@
                 true, true, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationFromXHRCallbackAndLongTimeout() throws InterruptedException {
@@ -293,6 +317,7 @@
                 true, false, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationWithFallbackURL()
@@ -305,6 +330,7 @@
         loadUrlAndWaitForIntentUrl(originalUrl, true, 0, false, fallbackUrl, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testNavigationWithFallbackURLInSubFrame()
@@ -332,6 +358,7 @@
         loadUrlAndWaitForIntentUrl(originalUrl, true, false, false);
     }
 
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
     public void testOpenWindowFromUserGesture() throws InterruptedException {
@@ -339,12 +366,13 @@
                 true, 1, true, null, true);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testRedirectionFromIntent() {
         Intent intent = new Intent(Intent.ACTION_VIEW,
                 Uri.parse(mTestServer.getURL(NAVIGATION_FROM_JAVA_REDIRECTION_PAGE)));
-        Context targetContext = getInstrumentation().getTargetContext();
+        Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
         intent.setClassName(targetContext, ChromeLauncherActivity.class.getName());
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         targetContext.startActivity(intent);
@@ -356,9 +384,4 @@
             }
         }));
     }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java
index 4f1bbeb..9e1a7997 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java
@@ -7,15 +7,25 @@
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.UiUtils;
 import org.chromium.net.ConnectionType;
 
@@ -32,8 +42,15 @@
 /**
  * Test for {@link FeedbackCollector}.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class FeedbackCollectorTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class FeedbackCollectorTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final int CONNECTIVITY_TASK_TIMEOUT_MS = 10;
 
     private ChromeActivity mActivity;
@@ -41,10 +58,6 @@
     private TestFeedbackCollector mCollector;
     private TestConnectivityTask mTestConnectivityTask;
 
-    public FeedbackCollectorTest() {
-        super(ChromeActivity.class);
-    }
-
     /**
      * Class for facilitating testing of {@link FeedbackCollector}. All public methods are
      * automatically run on the UI thread, to simplify testing code.
@@ -189,10 +202,10 @@
         }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mActivity = mActivityTestRule.getActivity();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -201,11 +214,7 @@
         });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     @Feature({"Feedback"})
     public void testGatheringOfData() {
@@ -218,15 +227,16 @@
         mCollector.setScreenshot(bitmap);
 
         Bundle bundle = mCollector.getBundle();
-        assertEquals("http://www.example.com/", bundle.getString(FeedbackCollector.URL_KEY));
-        assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
-        assertEquals("some description", mCollector.getDescription());
-        assertEquals("bar", bundle.getString("foo"));
-        assertEquals(bitmap, mCollector.getScreenshot());
-        assertEquals("false",
+        Assert.assertEquals("http://www.example.com/", bundle.getString(FeedbackCollector.URL_KEY));
+        Assert.assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
+        Assert.assertEquals("some description", mCollector.getDescription());
+        Assert.assertEquals("bar", bundle.getString("foo"));
+        Assert.assertEquals(bitmap, mCollector.getScreenshot());
+        Assert.assertEquals("false",
                 bundle.getString(DataReductionProxySettings.DATA_REDUCTION_PROXY_ENABLED_KEY));
     }
 
+    @Test
     @SmallTest
     @Feature({"Feedback"})
     public void testGatheringOfDataWithCallback() throws InterruptedException {
@@ -240,27 +250,29 @@
             }
         };
         mCollector = createCollector("http://www.example.com/", callback);
-        assertFalse("Result should not be ready directly after creation.", hasResult.get());
+        Assert.assertFalse("Result should not be ready directly after creation.", hasResult.get());
         ConnectivityTask.FeedbackData feedbackData = createFeedbackData();
         mCollector.onResult(feedbackData);
-        assertFalse("Result should not be ready after connectivity data.", hasResult.get());
+        Assert.assertFalse("Result should not be ready after connectivity data.", hasResult.get());
         mCollector.setDescription("some description");
         mCollector.add("foo", "bar");
         Bitmap bitmap = createBitmap();
         mCollector.onGotBitmap(bitmap);
 
         // Wait until the callback has been called.
-        assertTrue("Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
-        assertTrue("Result should be ready after retrieving all data.", hasResult.get());
+        Assert.assertTrue(
+                "Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
+        Assert.assertTrue("Result should be ready after retrieving all data.", hasResult.get());
 
         Bundle bundle = mCollector.getBundle();
-        assertEquals("http://www.example.com/", bundle.getString(FeedbackCollector.URL_KEY));
-        assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
-        assertEquals("some description", mCollector.getDescription());
-        assertEquals("bar", bundle.getString("foo"));
-        assertEquals(bitmap, mCollector.getScreenshot());
+        Assert.assertEquals("http://www.example.com/", bundle.getString(FeedbackCollector.URL_KEY));
+        Assert.assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
+        Assert.assertEquals("some description", mCollector.getDescription());
+        Assert.assertEquals("bar", bundle.getString("foo"));
+        Assert.assertEquals(bitmap, mCollector.getScreenshot());
     }
 
+    @Test
     @SmallTest
     @Feature({"Feedback"})
     public void testGatheringOfDataTimesOut() throws InterruptedException {
@@ -274,28 +286,30 @@
             }
         };
         mCollector = createCollector(null, callback);
-        assertFalse("Result should not be ready directly after creation.", hasResult.get());
+        Assert.assertFalse("Result should not be ready directly after creation.", hasResult.get());
         ConnectivityTask.FeedbackData feedbackData = createFeedbackData();
         // Set the feedback data on the connectivity task instead of through callback.
         mTestConnectivityTask.setFeedbackData(feedbackData);
-        assertFalse("Result should not be ready after connectivity data.", hasResult.get());
+        Assert.assertFalse("Result should not be ready after connectivity data.", hasResult.get());
         Bitmap bitmap = createBitmap();
         mCollector.onGotBitmap(bitmap);
 
         // This timeout task should trigger the callback.
         mCollector.setTimedOut(true);
         mCollector.maybePostResult();
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
         // Wait until the callback has been called.
-        assertTrue("Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
-        assertTrue("Result should be ready after retrieving all data.", hasResult.get());
+        Assert.assertTrue(
+                "Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
+        Assert.assertTrue("Result should be ready after retrieving all data.", hasResult.get());
 
         Bundle bundle = mCollector.getBundle();
-        assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
-        assertEquals(bitmap, mCollector.getScreenshot());
+        Assert.assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
+        Assert.assertEquals(bitmap, mCollector.getScreenshot());
     }
 
+    @Test
     @SmallTest
     @Feature({"Feedback"})
     public void testGatheringOfDataAlwaysWaitForScreenshot() throws InterruptedException {
@@ -309,29 +323,30 @@
             }
         };
         mCollector = createCollector(null, callback);
-        assertFalse("Result should not be ready directly after creation.", hasResult.get());
+        Assert.assertFalse("Result should not be ready directly after creation.", hasResult.get());
         ConnectivityTask.FeedbackData feedbackData = createFeedbackData();
         mCollector.onResult(feedbackData);
-        assertFalse("Result should not be ready after connectivity data.", hasResult.get());
+        Assert.assertFalse("Result should not be ready after connectivity data.", hasResult.get());
 
         // This timeout task should not trigger the callback.
         mCollector.setTimedOut(true);
         mCollector.maybePostResult();
-        UiUtils.settleDownUI(getInstrumentation());
-        assertFalse("Result should not be ready after timeout.", hasResult.get());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+        Assert.assertFalse("Result should not be ready after timeout.", hasResult.get());
 
         // Trigger callback by finishing taking the screenshot.
         Bitmap bitmap = createBitmap();
         mCollector.onGotBitmap(bitmap);
 
         // Wait until the callback has been called.
-        assertTrue("Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
-        assertTrue("Result should be ready after retrieving all data.", hasResult.get());
+        Assert.assertTrue(
+                "Failed to acquire semaphore.", semaphore.tryAcquire(1, TimeUnit.SECONDS));
+        Assert.assertTrue("Result should be ready after retrieving all data.", hasResult.get());
 
         Bundle bundle = mCollector.getBundle();
         // The FeedbackData should have been gathered from the ConnectivityTask directly.
-        assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
-        assertEquals(bitmap, mCollector.getScreenshot());
+        Assert.assertEquals("CONNECTED", bundle.getString(ConnectivityTask.CHROME_HTTPS_KEY));
+        Assert.assertEquals(bitmap, mCollector.getScreenshot());
     }
 
     private static ConnectivityTask.FeedbackData createFeedbackData() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
index b02ac03a..66dccb517 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarContainerTest.java
@@ -6,19 +6,30 @@
 
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.TextView;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.InfoBarUtil;
 import org.chromium.content.browser.test.util.Criteria;
@@ -33,8 +44,15 @@
 /**
  * Tests for the InfoBarContainer.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class InfoBarContainerTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class InfoBarContainerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String MESSAGE_TEXT = "Ding dong. Woof. Translate french? Bears!";
 
     private static final class TestListener implements SimpleConfirmInfoBarBuilder.Listener {
@@ -61,51 +79,47 @@
     private InfoBarTestAnimationListener mListener;
     private EmbeddedTestServer mTestServer;
 
-    public InfoBarContainerTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         // Register for animation notifications
         InfoBarContainer container =
-                getActivity().getActivityTab().getInfoBarContainer();
+                mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
         mListener =  new InfoBarTestAnimationListener();
         container.addAnimationListener(mListener);
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     // Adds an infobar to the currrent tab. Blocks until the infobar has been added.
     private TestListener addInfoBarToCurrentTab(final boolean expires)
             throws InterruptedException, TimeoutException {
-        List<InfoBar> infoBars = getInfoBars();
+        List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
         int previousCount = infoBars.size();
 
         final TestListener testListener = new TestListener();
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                SimpleConfirmInfoBarBuilder.create(getActivity().getActivityTab(),
-                        testListener, InfoBarIdentifier.TEST_INFOBAR, 0,
-                        MESSAGE_TEXT, null, null, expires);
+                SimpleConfirmInfoBarBuilder.create(mActivityTestRule.getActivity().getActivityTab(),
+                        testListener, InfoBarIdentifier.TEST_INFOBAR, 0, MESSAGE_TEXT, null, null,
+                        expires);
             }
         });
         mListener.addInfoBarAnimationFinished("InfoBar not added.");
 
         // Verify it's really there.
-        assertEquals(previousCount + 1, infoBars.size());
+        Assert.assertEquals(previousCount + 1, infoBars.size());
         TextView message =
                 (TextView) infoBars.get(previousCount).getView().findViewById(R.id.infobar_message);
-        assertEquals(MESSAGE_TEXT, message.getText().toString());
+        Assert.assertEquals(MESSAGE_TEXT, message.getText().toString());
 
         return testListener;
     }
@@ -116,8 +130,8 @@
      */
     private void dismissInfoBar(final InfoBar infoBar, TestListener listener)
             throws Exception {
-        assertEquals(0, listener.dismissedCallback.getCallCount());
-        getInstrumentation().runOnMainSync(new Runnable() {
+        Assert.assertEquals(0, listener.dismissedCallback.getCallCount());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 infoBar.onCloseButtonClicked();
@@ -125,14 +139,15 @@
         });
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
         listener.dismissedCallback.waitForCallback(0, 1);
-        assertEquals(0, listener.primaryButtonCallback.getCallCount());
-        assertEquals(0, listener.secondaryButtonCallback.getCallCount());
-        getInstrumentation().waitForIdleSync();
+        Assert.assertEquals(0, listener.primaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, listener.secondaryButtonCallback.getCallCount());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     /**
      * Verifies that infobars added from Java expire or not as expected.
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testInfoBarExpiration() throws Exception {
@@ -140,23 +155,23 @@
         TestListener infobarListener = addInfoBarToCurrentTab(true);
 
         // Now navigate, it should expire.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/google.html"));
+        mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/google.html"));
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertTrue(getInfoBars().isEmpty());
-        assertEquals(0, infobarListener.dismissedCallback.getCallCount());
-        assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
-        assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
+        Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty());
+        Assert.assertEquals(0, infobarListener.dismissedCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
 
         // Now test a non-expiring infobar.
         TestListener persistentListener = addInfoBarToCurrentTab(false);
 
         // Navigate, it should still be there.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/about.html"));
-        List<InfoBar> infoBars = getInfoBars();
-        assertEquals(1, infoBars.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/about.html"));
+        List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertEquals(1, infoBars.size());
         TextView message =
                 (TextView) infoBars.get(0).getView().findViewById(R.id.infobar_message);
-        assertEquals(MESSAGE_TEXT, message.getText().toString());
+        Assert.assertEquals(MESSAGE_TEXT, message.getText().toString());
 
         // Close the infobar.
         dismissInfoBar(infoBars.get(0), persistentListener);
@@ -178,6 +193,7 @@
      * The behavior when prerender is on/off is different as in the prerender case the infobars are
      * added when we swap tabs.
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testInfoBarExpirationNoPrerender() throws Exception {
@@ -203,80 +219,89 @@
      * Tests that adding and then immediately dismissing an infobar works as expected (and does not
      * assert).
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testQuickAddOneAndDismiss() throws Exception {
         final TestListener infobarListener = addInfoBarToCurrentTab(false);
-        assertEquals(1, getInfoBars().size());
-        final InfoBar infoBar = getInfoBars().get(0);
+        Assert.assertEquals(1, mActivityTestRule.getInfoBars().size());
+        final InfoBar infoBar = mActivityTestRule.getInfoBars().get(0);
         dismissInfoBar(infoBar, infobarListener);
-        assertTrue(getInfoBars().isEmpty());
+        Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty());
     }
 
     /**
      * Tests that we don't assert when a tab is getting closed while an infobar is being shown and
      * had been removed.
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testCloseTabOnAdd() throws Exception {
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/google.html"));
+        mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/google.html"));
 
         final TestListener infobarListener = addInfoBarToCurrentTab(false);
-        assertEquals(1, getInfoBars().size());
-        final InfoBar infoBar = getInfoBars().get(0);
+        Assert.assertEquals(1, mActivityTestRule.getInfoBars().size());
+        final InfoBar infoBar = mActivityTestRule.getInfoBars().get(0);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertEquals(0, infobarListener.dismissedCallback.getCallCount());
+                Assert.assertEquals(0, infobarListener.dismissedCallback.getCallCount());
                 infoBar.onCloseButtonClicked();
-                getActivity().getTabModelSelector().closeTab(getActivity().getActivityTab());
+                mActivityTestRule.getActivity().getTabModelSelector().closeTab(
+                        mActivityTestRule.getActivity().getActivityTab());
             }
         });
 
         infobarListener.dismissedCallback.waitForCallback(0, 1);
-        assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
-        assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
     }
 
     /**
      * Tests that the x button in the infobar does close the infobar and that the event is not
      * propagated to the ContentView.
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testCloseButton() throws Exception {
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/click_listener.html"));
+        mActivityTestRule.loadUrl(
+                mTestServer.getURL("/chrome/test/data/android/click_listener.html"));
         TestListener infobarListener = addInfoBarToCurrentTab(false);
 
         // Now press the close button.
-        assertEquals(0, infobarListener.dismissedCallback.getCallCount());
-        assertTrue("Close button wasn't found", InfoBarUtil.clickCloseButton(getInfoBars().get(0)));
+        Assert.assertEquals(0, infobarListener.dismissedCallback.getCallCount());
+        Assert.assertTrue("Close button wasn't found",
+                InfoBarUtil.clickCloseButton(mActivityTestRule.getInfoBars().get(0)));
         mListener.removeInfoBarAnimationFinished("Infobar not removed.");
         infobarListener.dismissedCallback.waitForCallback(0, 1);
-        assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
-        assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.primaryButtonCallback.getCallCount());
+        Assert.assertEquals(0, infobarListener.secondaryButtonCallback.getCallCount());
 
         // The page should not have received the click.
-        assertTrue("The page recieved the click.",
-                !Boolean.parseBoolean(runJavaScriptCodeInCurrentTab("wasClicked")));
+        Assert.assertTrue("The page recieved the click.",
+                !Boolean.parseBoolean(
+                        mActivityTestRule.runJavaScriptCodeInCurrentTab("wasClicked")));
     }
 
     /**
      * Tests that adding and removing correctly manages the transparent region, which allows for
      * optimizations in SurfaceFlinger (less overlays).
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     public void testAddAndDismissSurfaceFlingerOverlays() throws Exception {
-        final ViewGroup decorView = (ViewGroup)  getActivity().getWindow().getDecorView();
+        final ViewGroup decorView =
+                (ViewGroup) mActivityTestRule.getActivity().getWindow().getDecorView();
         final InfoBarContainer infoBarContainer =
-                getActivity().getActivityTab().getInfoBarContainer();
+                mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
 
         // Detect layouts. Note this doesn't actually need to be atomic (just final).
         final AtomicInteger layoutCount = new AtomicInteger();
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 decorView.getViewTreeObserver().addOnGlobalLayoutListener(
@@ -291,8 +316,8 @@
 
         // First add an infobar.
         TestListener infobarListener = addInfoBarToCurrentTab(false);
-        assertEquals(1, getInfoBars().size());
-        final InfoBar infoBar = getInfoBars().get(0);
+        Assert.assertEquals(1, mActivityTestRule.getInfoBars().size());
+        final InfoBar infoBar = mActivityTestRule.getInfoBars().get(0);
 
         // A layout must occur to recalculate the transparent region.
         CriteriaHelper.pollUiThread(
@@ -307,7 +332,7 @@
         final Rect fullDisplayFrameMinusContainer = new Rect();
         final Rect containerDisplayFrame = new Rect();
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 decorView.getWindowVisibleDisplayFrame(fullDisplayFrame);
@@ -324,7 +349,7 @@
                 // The InfoBarContainer subtracts itself from the transparent region.
                 Region transparentRegion = new Region(fullDisplayFrame);
                 infoBarContainer.gatherTransparentRegion(transparentRegion);
-                assertEquals(transparentRegion.getBounds(), fullDisplayFrameMinusContainer);
+                Assert.assertEquals(transparentRegion.getBounds(), fullDisplayFrameMinusContainer);
             }
         });
 
@@ -341,7 +366,7 @@
                     }
                 });
 
-        getInstrumentation().runOnMainSync(new Runnable() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 // The InfoBarContainer should no longer be subtracted from the transparent region.
@@ -352,7 +377,7 @@
                 decorView.gatherTransparentRegion(transparentRegion);
                 Region opaqueRegion = new Region(fullDisplayFrame);
                 opaqueRegion.op(transparentRegion, Region.Op.DIFFERENCE);
-                assertFalse(opaqueRegion.getBounds().intersect(containerDisplayFrame));
+                Assert.assertFalse(opaqueRegion.getBounds().intersect(containerDisplayFrame));
             }
         });
 
@@ -360,9 +385,4 @@
         // - adb shell dumpsys SurfaceFlinger
         // - Observe that Clank's overlay size changes (or disappears if URLbar is also gone).
     }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
index 0aeb31a..312e703 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
@@ -7,8 +7,15 @@
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
-import android.test.UiThreadTest;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
@@ -24,7 +31,8 @@
 import org.chromium.chrome.browser.WebContentsFactory;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
 import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.InfoBarUtil;
 import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil;
@@ -38,7 +46,14 @@
 import java.util.concurrent.TimeoutException;
 
 /** Tests for the InfoBars. */
-public class InfoBarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class InfoBarTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final long MAX_TIMEOUT = scaleTimeout(2000);
     private static final int CHECK_INTERVAL = 500;
     private static final String GEOLOCATION_PAGE =
@@ -61,124 +76,124 @@
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                List<InfoBar> infobars = getInfoBars();
+                List<InfoBar> infobars = mActivityTestRule.getInfoBars();
                 if (infobars.size() != 1) return false;
                 return infobars.get(0) instanceof DataReductionPromoInfoBar;
             }
         });
     }
 
-    public InfoBarTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         // Register for animation notifications
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                if (getActivity().getActivityTab() == null) return false;
-                if (getActivity().getActivityTab().getInfoBarContainer() == null) return false;
+                if (mActivityTestRule.getActivity().getActivityTab() == null) return false;
+                if (mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer()
+                        == null) {
+                    return false;
+                }
                 return true;
             }
         });
-        InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
+        InfoBarContainer container =
+                mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
         mListener =  new InfoBarTestAnimationListener();
         container.addAnimationListener(mListener);
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
 
         // Using an AdvancedMockContext allows us to use a fresh in-memory SharedPreference.
-        Context context = new AdvancedMockContext(
-                getInstrumentation().getTargetContext().getApplicationContext());
+        Context context = new AdvancedMockContext(InstrumentationRegistry.getInstrumentation()
+                                                          .getTargetContext()
+                                                          .getApplicationContext());
         ContextUtils.initApplicationContextForTests(context);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
+        if (mTestServer != null) {
+            mTestServer.stopAndDestroyServer();
+        }
     }
 
     /**
      * Verify PopUp InfoBar.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @DisabledTest(message = "crbug.com/593003")
     public void testInfoBarForPopUp() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(POPUP_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(POPUP_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not added");
 
-        List<InfoBar> infoBars = getInfoBars();
-        assertEquals("Wrong infobar count", 1, infoBars.size());
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertFalse(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
+        List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertEquals("Wrong infobar count", 1, infoBars.size());
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
+        Assert.assertFalse(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
         InfoBarUtil.clickPrimaryButton(infoBars.get(0));
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertEquals("Wrong infobar count", 0, infoBars.size());
-        assertNotNull(infoBars.get(0).getSnackbarManager());
+        Assert.assertEquals("Wrong infobar count", 0, infoBars.size());
+        Assert.assertNotNull(infoBars.get(0).getSnackbarManager());
 
         // A second load should not show the infobar.
-        loadUrl(mTestServer.getURL(POPUP_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(POPUP_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar added when it should not");
     }
 
     /**
      * Verify Geolocation creates an InfoBar.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @RetryOnFailure
     public void testInfoBarForGeolocation() throws InterruptedException, TimeoutException {
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
-        loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not added");
 
         // Make sure it has OK/Cancel buttons.
-        List<InfoBar> infoBars = getInfoBars();
-        assertEquals("Wrong infobar count", 1, infoBars.size());
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
+        List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertEquals("Wrong infobar count", 1, infoBars.size());
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
+        Assert.assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
 
-        loadUrl(HELLO_WORLD_URL);
+        mActivityTestRule.loadUrl(HELLO_WORLD_URL);
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertTrue("Wrong infobar count", getInfoBars().isEmpty());
+        Assert.assertTrue("Wrong infobar count", mActivityTestRule.getInfoBars().isEmpty());
     }
 
 
     /**
      * Verify Geolocation creates an InfoBar and that it's destroyed when navigating back.
      */
+    @Test
     @MediumTest
     @Feature({"Browser"})
     @RetryOnFailure
     public void testInfoBarForGeolocationDisappearsOnBack()
             throws InterruptedException, TimeoutException {
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
-        loadUrl(HELLO_WORLD_URL);
-        loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
+        mActivityTestRule.loadUrl(HELLO_WORLD_URL);
+        mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not added.");
 
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
 
         // Navigate back and ensure the InfoBar has been removed.
-        getInstrumentation().runOnMainSync(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        getActivity().getActivityTab().goBack();
-                    }
-                });
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mActivityTestRule.getActivity().getActivityTab().goBack();
+            }
+        });
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
     }
 
@@ -186,6 +201,7 @@
      * Verify the Data Reduction Promo infobar is shown and clicking the primary button dismisses
      * it.
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("force-fieldtrials=DataCompressionProxyPromoVisibility/Enabled")
     @Feature({"Browser", "Main"})
@@ -194,7 +210,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse("Data Reduction Proxy enabled",
+                Assert.assertFalse("Data Reduction Proxy enabled",
                         DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
                 // Fake the FRE or second run promo being shown in M51.
                 DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
@@ -203,17 +219,18 @@
                         .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, M51_VERSION)
                         .apply();
                 // Add an infobar.
-                assertTrue(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                        getActivity(), getActivity().getActivityTab().getWebContents(),
+                Assert.assertTrue(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         "http://google.com", false, false, HttpURLConnection.HTTP_OK));
             }
         });
 
         waitUntilDataReductionPromoInfoBarAppears();
-        final List<InfoBar> infoBars = getInfoBars();
-        assertTrue("InfoBar does not have primary button",
+        final List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertTrue("InfoBar does not have primary button",
                 InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertTrue("InfoBar does not have secondary button",
+        Assert.assertTrue("InfoBar does not have secondary button",
                 InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -224,20 +241,21 @@
         });
 
         // The renderer should have been killed and the infobar removed.
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertTrue("Data Reduction Proxy not enabled",
+                Assert.assertTrue("Data Reduction Proxy not enabled",
                         DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
                 // Turn Data Saver off so the promo can be reshown.
-                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(getActivity(),
-                        false);
+                DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
+                        mActivityTestRule.getActivity(), false);
                 // Try to add an infobar. Infobar should not be added since it has already been
                 // shown.
-                assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                        getActivity(), getActivity().getActivityTab().getWebContents(),
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         "http://google.com", false, false, HttpURLConnection.HTTP_OK));
             }
         });
@@ -247,6 +265,7 @@
      * Verify the Data Reduction Promo infobar is shown and clicking the secondary button dismisses
      * it.
      */
+    @Test
     @MediumTest
     @CommandLineFlags.Add("force-fieldtrials=DataCompressionProxyPromoVisibility/Enabled")
     @Feature({"Browser", "Main"})
@@ -255,7 +274,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse("Data Reduction Proxy enabled",
+                Assert.assertFalse("Data Reduction Proxy enabled",
                         DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
                 // Fake the first run experience or second run promo being shown in M51.
                 DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
@@ -264,17 +283,18 @@
                         .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, M51_VERSION)
                         .apply();
                 // Add an infobar.
-                assertTrue(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                        getActivity(), getActivity().getActivityTab().getWebContents(),
+                Assert.assertTrue(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         "http://google.com", false, false, HttpURLConnection.HTTP_OK));
             }
         });
 
         waitUntilDataReductionPromoInfoBarAppears();
-        final List<InfoBar> infoBars = getInfoBars();
-        assertTrue("InfoBar does not have primary button",
+        final List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertTrue("InfoBar does not have primary button",
                 InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertTrue("InfoBar does not have secondary button",
+        Assert.assertTrue("InfoBar does not have secondary button",
                 InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -285,17 +305,18 @@
         });
 
         // The renderer should have been killed and the infobar removed.
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse("Data Reduction Proxy enabled",
+                Assert.assertFalse("Data Reduction Proxy enabled",
                         DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
                 // Try to add an infobar. Infobar should not be added since the user clicked
                 // dismiss.
-                assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                        getActivity(), getActivity().getActivityTab().getWebContents(),
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         "http://google.com", false, false, HttpURLConnection.HTTP_OK));
             }
         });
@@ -305,82 +326,98 @@
      * Verify the Data Reduction Promo infobar is not shown when the fre or second run promo version
      * was not stored and the package was installed after M48.
      */
-    @UiThreadTest
+    @Test
     @MediumTest
     @CommandLineFlags.Add("force-fieldtrials=DataCompressionProxyPromoVisibility/Enabled")
     @Feature({"Browser", "Main"})
-    public void testDataReductionPromoInfoBarPostM48Install() {
-        assertFalse("Data Reduction Proxy enabled",
-                DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
-        // Fake the first run experience or second run promo being shown.
-        DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
-        // Remove the version. Versions prior to M51 will not have the version pref.
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, "")
-                .apply();
-        // Add an infobar. Infobar should not be added since the first run experience or second run
-        // promo version was not shown and the package was installed after M48.
-        assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                getActivity(), getActivity().getActivityTab().getWebContents(),
-                "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+    public void testDataReductionPromoInfoBarPostM48Install() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Assert.assertFalse("Data Reduction Proxy enabled",
+                        DataReductionProxySettings.getInstance().isDataReductionProxyEnabled());
+                // Fake the first run experience or second run promo being shown.
+                DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
+                // Remove the version. Versions prior to M51 will not have the version pref.
+                ContextUtils.getAppSharedPreferences()
+                        .edit()
+                        .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, "")
+                        .apply();
+                // Add an infobar. Infobar should not be added since the first run experience
+                // or second run promo version was not shown and the package was installed
+                // after M48.
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
+                        "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+            }
+        });
     }
 
     /**
      * Verify that the Data Reduction Promo infobar is not shown if the first run experience or
      * Infobar promo hasn't been shown or if it hasn't been two versions since the promo was shown.
      */
-    @UiThreadTest
+    @Test
     @MediumTest
     @CommandLineFlags.Add("force-fieldtrials=DataCompressionProxyPromoVisibility/Enabled")
     @Feature({"Browser", "Main"})
     @RetryOnFailure
-    public void testDataReductionPromoInfoBarFreOptOut() {
-        // Try to add an infobar. Infobar should not be added since the first run experience or
-        // second run promo hasn't been shown.
-        assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                getActivity(), getActivity().getActivityTab().getWebContents(),
-                "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+    public void testDataReductionPromoInfoBarFreOptOut() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Try to add an infobar. Infobar should not be added since the first run
+                // experience or second run promo hasn't been shown.
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
+                        "http://google.com", false, false, HttpURLConnection.HTTP_OK));
 
-        // Fake showing the FRE.
-        DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
+                // Fake showing the FRE.
+                DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
 
-        // Try to add an infobar. Infobar should not be added since the first run experience was
-        // just shown.
-        assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                getActivity(), getActivity().getActivityTab().getWebContents(),
-                "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+                // Try to add an infobar. Infobar should not be added since the
+                // first run experience was just shown.
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
+                        "http://google.com", false, false, HttpURLConnection.HTTP_OK));
 
-        // Fake the first run experience or second run promo being shown in M51.
-        DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
-        ContextUtils.getAppSharedPreferences()
-                .edit()
-                .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, M51_VERSION)
-                .apply();
-        DataReductionPromoUtils.saveFrePromoOptOut(true);
+                // Fake the first run experience or second run promo being shown in M51.
+                DataReductionPromoUtils.saveFreOrSecondRunPromoDisplayed();
+                ContextUtils.getAppSharedPreferences()
+                        .edit()
+                        .putString(SHARED_PREF_DISPLAYED_FRE_OR_SECOND_PROMO_VERSION, M51_VERSION)
+                        .apply();
+                DataReductionPromoUtils.saveFrePromoOptOut(true);
 
-        // Try to add an infobar. Infobar should not be added since the user opted out on the
-        // first run experience.
-        assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
-                getActivity(), getActivity().getActivityTab().getWebContents(),
-                "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+                // Try to add an infobar. Infobar should not be added since the user opted
+                // out on the first run experience.
+                Assert.assertFalse(DataReductionPromoInfoBar.maybeLaunchPromoInfoBar(
+                        mActivityTestRule.getActivity(),
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
+                        "http://google.com", false, false, HttpURLConnection.HTTP_OK));
+            }
+        });
     }
 
     /**
      * Verifies the unresponsive renderer notification creates an InfoBar.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @RetryOnFailure
     public void testInfoBarForHungRenderer() throws InterruptedException, TimeoutException {
-        loadUrl(HELLO_WORLD_URL);
+        mActivityTestRule.loadUrl(HELLO_WORLD_URL);
 
         // Fake an unresponsive renderer signal.
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 CommandLine.getInstance().appendSwitch(ChromeSwitches.ENABLE_HUNG_RENDERER_INFOBAR);
-                getActivity()
+                mActivityTestRule.getActivity()
                         .getActivityTab()
                         .getTabWebContentsDelegateAndroid()
                         .rendererUnresponsive();
@@ -389,41 +426,42 @@
         mListener.addInfoBarAnimationFinished("InfoBar not added");
 
         // Make sure it has Kill/Wait buttons.
-        List<InfoBar> infoBars = getInfoBars();
-        assertEquals("Wrong infobar count", 1, infoBars.size());
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
+        List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertEquals("Wrong infobar count", 1, infoBars.size());
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
+        Assert.assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
 
         // Fake a responsive renderer signal.
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                getActivity()
+                mActivityTestRule.getActivity()
                         .getActivityTab()
                         .getTabWebContentsDelegateAndroid()
                         .rendererResponsive();
             }
         });
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertTrue("Wrong infobar count", getInfoBars().isEmpty());
+        Assert.assertTrue("Wrong infobar count", mActivityTestRule.getInfoBars().isEmpty());
     }
 
     /**
      * Verifies the hung renderer InfoBar can kill the hung renderer.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @RetryOnFailure
     public void testInfoBarForHungRendererCanKillRenderer()
             throws InterruptedException, TimeoutException {
-        loadUrl(HELLO_WORLD_URL);
+        mActivityTestRule.loadUrl(HELLO_WORLD_URL);
 
         // Fake an unresponsive renderer signal.
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 CommandLine.getInstance().appendSwitch(ChromeSwitches.ENABLE_HUNG_RENDERER_INFOBAR);
-                getActivity()
+                mActivityTestRule.getActivity()
                         .getActivityTab()
                         .getTabWebContentsDelegateAndroid()
                         .rendererUnresponsive();
@@ -432,10 +470,10 @@
         mListener.addInfoBarAnimationFinished("InfoBar not added");
 
         // Make sure it has Kill/Wait buttons.
-        final List<InfoBar> infoBars = getInfoBars();
-        assertEquals("Wrong infobar count", 1, infoBars.size());
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
-        assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
+        final List<InfoBar> infoBars = mActivityTestRule.getInfoBars();
+        Assert.assertEquals("Wrong infobar count", 1, infoBars.size());
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBars.get(0)));
+        Assert.assertTrue(InfoBarUtil.hasSecondaryButton(infoBars.get(0)));
 
         // Activite the Kill button.
         ThreadUtils.runOnUiThread(new Runnable() {
@@ -447,11 +485,11 @@
 
         // The renderer should have been killed and the InfoBar removed.
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertTrue("Wrong infobar count", getInfoBars().isEmpty());
+        Assert.assertTrue("Wrong infobar count", mActivityTestRule.getInfoBars().isEmpty());
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getActivityTab().isShowingSadTab();
+                return mActivityTestRule.getActivity().getActivityTab().isShowingSadTab();
             }
         }, MAX_TIMEOUT, CHECK_INTERVAL);
     }
@@ -459,6 +497,7 @@
     /**
      * Verify InfoBarContainers swap the WebContents they are monitoring properly.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @RetryOnFailure
@@ -466,29 +505,32 @@
             throws InterruptedException, TimeoutException {
         // Add an infobar.
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
-        loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not added");
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
 
         // Swap out the WebContents and send the user somewhere so that the InfoBar gets removed.
         InfoBarTestAnimationListener removeListener = new InfoBarTestAnimationListener();
-        getActivity().getActivityTab().getInfoBarContainer().addAnimationListener(removeListener);
+        mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer().addAnimationListener(
+                removeListener);
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 WebContents newContents = WebContentsFactory.createWebContents(false, false);
-                getActivity().getActivityTab().swapWebContents(newContents, false, false);
+                mActivityTestRule.getActivity().getActivityTab().swapWebContents(
+                        newContents, false, false);
             }
         });
-        loadUrl(HELLO_WORLD_URL);
+        mActivityTestRule.loadUrl(HELLO_WORLD_URL);
         removeListener.removeInfoBarAnimationFinished("InfoBar not removed.");
-        assertEquals("Wrong infobar count", 0, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 0, mActivityTestRule.getInfoBars().size());
 
         // Revisiting the original page should make the InfoBar reappear.
         InfoBarTestAnimationListener addListener = new InfoBarTestAnimationListener();
-        getActivity().getActivityTab().getInfoBarContainer().addAnimationListener(addListener);
-        loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
+        mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer().addAnimationListener(
+                addListener);
+        mActivityTestRule.loadUrl(mTestServer.getURL(GEOLOCATION_PAGE));
         addListener.addInfoBarAnimationFinished("InfoBar not added");
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
index 248e48d..6fafb5e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
@@ -4,16 +4,26 @@
 
 package org.chromium.chrome.browser.infobar;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.SearchGeolocationDisclosureTabHelper;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.InfoBarUtil;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -21,8 +31,10 @@
 import java.util.concurrent.TimeoutException;
 
 /** Tests for the SearchGeolocationDisclosureInfobar. */
-public class SearchGeolocationDisclosureInfoBarTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SearchGeolocationDisclosureInfoBarTest {
     private static final String SEARCH_PAGE = "/chrome/test/data/android/google.html";
     private static final String ENABLE_NEW_DISCLOSURE_FEATURE =
             "enable-features=ConsistentOmniboxGeolocation";
@@ -31,19 +43,16 @@
 
     private EmbeddedTestServer mTestServer;
 
-    public SearchGeolocationDisclosureInfoBarTest() {
-        super(ChromeActivity.class);
-    }
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -52,140 +61,164 @@
         });
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
+        if (mTestServer != null) mTestServer.stopAndDestroyServer();
     }
 
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE)
     public void testInfoBarAppears() throws InterruptedException, TimeoutException {
         SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting();
-        assertEquals("Wrong starting infobar count", 0, getInfoBars().size());
+        Assert.assertEquals(
+                "Wrong starting infobar count", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar should appear when doing the first search.
-        InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
+        InfoBarContainer container =
+                mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
         InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener();
         container.addAnimationListener(listener);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
         // Note: the number of infobars is checked immediately after the URL is loaded, unlike in
         // other infobar tests where it is checked after animations have completed. This is because
         // (a) in this case it should work, as these infobars are added as part of the URL loading
         // process, and
         // (b) if this doesn't work, it is important to catch it as otherwise the checks that
         // infobars haven't being shown are invalid.
-        assertEquals("Wrong infobar count after search", 1, getInfoBars().size());
+        Assert.assertEquals(
+                "Wrong infobar count after search", 1, mActivityTestRule.getInfoBars().size());
         listener.addInfoBarAnimationFinished("InfoBar not added.");
 
         // Infobar should not appear again on the same day.
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
         // There can be a delay from infobars being removed in the native InfobarManager and them
         // being removed in the Java container, so wait until the infobar has really gone.
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar should appear again the next day.
         SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(1);
         listener = new InfoBarTestAnimationListener();
         container.addAnimationListener(listener);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 1, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 1, mActivityTestRule.getInfoBars().size());
         listener.addInfoBarAnimationFinished("InfoBar not added.");
 
         // Infobar should not appear again on the same day.
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar should appear again the next day.
         SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(2);
         listener = new InfoBarTestAnimationListener();
         container.addAnimationListener(listener);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 1, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 1, mActivityTestRule.getInfoBars().size());
         listener.addInfoBarAnimationFinished("InfoBar not added.");
 
         // Infobar should not appear again on the same day.
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar has appeared three times now, it should not appear again.
         SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(3);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
 
         // Check histograms have been recorded.
-        assertEquals("Wrong pre-disclosure metric", 1,
+        Assert.assertEquals("Wrong pre-disclosure metric", 1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         "GeolocationDisclosure.PreDisclosureDSESetting", 1));
-        assertEquals("Wrong post-disclosure metric", 1,
+        Assert.assertEquals("Wrong post-disclosure metric", 1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         "GeolocationDisclosure.PostDisclosureDSESetting", 1));
     }
 
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE)
     public void testInfoBarDismiss() throws InterruptedException, TimeoutException {
         SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting();
-        assertEquals("Wrong starting infobar count", 0, getInfoBars().size());
+        Assert.assertEquals(
+                "Wrong starting infobar count", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar should appear when doing the first search.
-        InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
+        InfoBarContainer container =
+                mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
         InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener();
         container.addAnimationListener(listener);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 1, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 1, mActivityTestRule.getInfoBars().size());
         listener.addInfoBarAnimationFinished("InfoBar not added.");
 
         // Dismiss the infobar.
-        assertTrue(InfoBarUtil.clickCloseButton(getInfoBars().get(0)));
+        Assert.assertTrue(InfoBarUtil.clickCloseButton(mActivityTestRule.getInfoBars().get(0)));
 
         // Infobar should not appear again on the same day.
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(mActivityTestRule.getInfoBars());
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
 
         // Infobar should not appear the next day either, as it has been dismissed.
         SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(1);
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
     }
 
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE)
     public void testNoInfoBarForRandomUrl() throws InterruptedException, TimeoutException {
-        assertEquals("Wrong starting infobar count", 0, getInfoBars().size());
+        Assert.assertEquals(
+                "Wrong starting infobar count", 0, mActivityTestRule.getInfoBars().size());
 
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
     }
 
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE)
     public void testNoInfoBarInIncognito() throws InterruptedException, TimeoutException {
         SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting();
-        newIncognitoTabFromMenu();
-        assertEquals("Wrong starting infobar count", 0, getInfoBars().size());
+        mActivityTestRule.newIncognitoTabFromMenu();
+        Assert.assertEquals(
+                "Wrong starting infobar count", 0, mActivityTestRule.getInfoBars().size());
 
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
     }
 
+    @Test
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(DISABLE_NEW_DISCLOSURE_FEATURE)
     public void testInfoBarAppearsDoesntAppearWithoutFeature()
             throws InterruptedException, TimeoutException {
         SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting();
-        assertEquals("Wrong starting infobar count", 0, getInfoBars().size());
+        Assert.assertEquals(
+                "Wrong starting infobar count", 0, mActivityTestRule.getInfoBars().size());
 
-        loadUrl(mTestServer.getURL(SEARCH_PAGE));
-        assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        Assert.assertEquals(
+                "Wrong infobar count after search", 0, mActivityTestRule.getInfoBars().size());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
index 3bb348c..a64931a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
@@ -4,15 +4,24 @@
 
 package org.chromium.chrome.browser.input;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.WebContentsFactory;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.ContentView;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.Criteria;
@@ -26,7 +35,14 @@
 /**
  * Test the select popup and how it interacts with another ContentViewCore.
  */
-public class SelectPopupOtherContentViewTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SelectPopupOtherContentViewTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String SELECT_URL = UrlUtils.encodeHtmlDataUri(
             "<html><body>"
             + "Which animal is the strongest:<br/>"
@@ -48,34 +64,28 @@
 
         @Override
         public boolean isSatisfied() {
-            ContentViewCore contentViewCore = getActivity().getCurrentContentViewCore();
+            ContentViewCore contentViewCore =
+                    mActivityTestRule.getActivity().getCurrentContentViewCore();
             return contentViewCore.getSelectPopupForTest() != null;
         }
     }
 
-    public SelectPopupOtherContentViewTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Don't launch activity automatically.
-    }
-
     /**
      * Tests that the showing select popup does not get closed because an unrelated ContentView
      * gets destroyed.
      *
      */
+    @Test
     @LargeTest
     @Feature({"Browser"})
     @RetryOnFailure
     public void testPopupNotClosedByOtherContentView()
             throws InterruptedException, Exception, Throwable {
         // Load the test page.
-        startMainActivityWithURL(SELECT_URL);
+        mActivityTestRule.startMainActivityWithURL(SELECT_URL);
 
-        final ContentViewCore viewCore = getActivity().getCurrentContentViewCore();
+        final ContentViewCore viewCore =
+                mActivityTestRule.getActivity().getCurrentContentViewCore();
 
         // Once clicked, the popup should show up.
         DOMUtils.clickNode(viewCore, "select");
@@ -86,10 +96,13 @@
             @Override
             public void run() {
                 WebContents webContents = WebContentsFactory.createWebContents(false, false);
-                WindowAndroid windowAndroid = new ActivityWindowAndroid(getActivity());
+                WindowAndroid windowAndroid =
+                        new ActivityWindowAndroid(mActivityTestRule.getActivity());
 
-                ContentViewCore contentViewCore = new ContentViewCore(getActivity(), "");
-                ContentView cv = ContentView.createContentView(getActivity(), contentViewCore);
+                ContentViewCore contentViewCore =
+                        new ContentViewCore(mActivityTestRule.getActivity(), "");
+                ContentView cv = ContentView.createContentView(
+                        mActivityTestRule.getActivity(), contentViewCore);
                 contentViewCore.initialize(ViewAndroidDelegate.createBasicDelegate(cv), cv,
                         webContents, windowAndroid);
                 contentViewCore.destroy();
@@ -97,10 +110,11 @@
         });
 
         // Process some more events to give a chance to the dialog to hide if it were to.
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         // The popup should still be shown.
-        assertNotNull("The select popup got hidden by destroying of unrelated ContentViewCore.",
+        Assert.assertNotNull(
+                "The select popup got hidden by destroying of unrelated ContentViewCore.",
                 viewCore.getSelectPopupForTest());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java
index 756b9d73..1e0d714 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java
@@ -12,20 +12,38 @@
 import android.net.Uri;
 import android.nfc.NfcAdapter;
 import android.provider.Browser;
+import android.support.test.InstrumentationRegistry;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.ShortcutHelper;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.browser.WebContents;
 
 /**
  * Unit tests for {@link InstantAppsHandler}.
  */
-public class InstantAppsHandlerTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class InstantAppsHandlerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private TestInstantAppsHandler mHandler;
     private Context mContext;
 
@@ -33,19 +51,15 @@
     private static final String INSTANT_APP_URL = "http://sampleapp.com/boo";
     private static final Uri REFERRER_URI = Uri.parse("http://www.wikipedia.org/");
 
-    public InstantAppsHandlerTest() {
-        super(ChromeActivity.class);
-    }
-
     private Intent createViewIntent() {
         return new Intent(Intent.ACTION_VIEW, URI);
     }
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
-        mContext = getInstrumentation().getTargetContext();
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
         mHandler = new TestInstantAppsHandler();
 
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
@@ -55,56 +69,60 @@
         editor.apply();
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         ContextUtils.getAppSharedPreferences().edit().clear().apply();
-        super.tearDown();
     }
 
+    @Test
     @SmallTest
     public void testInstantAppsDisabled_incognito() {
         Intent i = createViewIntent();
         i.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
 
-        assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
     }
 
-
+    @Test
     @SmallTest
     public void testInstantAppsDisabled_doNotLaunch() {
         Intent i = createViewIntent();
         i.putExtra("com.google.android.gms.instantapps.DO_NOT_LAUNCH_INSTANT_APP", true);
 
-        assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
     }
 
+    @Test
     @SmallTest
     public void testInstantAppsDisabled_mainIntent() {
         Intent i = new Intent(Intent.ACTION_MAIN);
-        assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
     }
 
+    @Test
     @SmallTest
     public void testInstantAppsDisabled_intentOriginatingFromChrome() {
         Intent i = createViewIntent();
         i.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
 
-        assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
 
         Intent signedIntent = createViewIntent();
         signedIntent.setPackage(mContext.getPackageName());
         IntentHandler.addTrustedIntentExtras(signedIntent);
 
-        assertFalse(mHandler.handleIncomingIntent(mContext, signedIntent, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, signedIntent, false, true));
     }
 
+    @Test
     @SmallTest
     public void testInstantAppsDisabled_launchFromShortcut() {
         Intent i = createViewIntent();
         i.putExtra(ShortcutHelper.EXTRA_SOURCE, 1);
-        assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(mContext, i, false, true));
     }
 
+    @Test
     @SmallTest
     public void testChromeNotDefault() {
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
@@ -112,77 +130,91 @@
         editor.putBoolean("applink.chrome_default_browser", false);
         editor.apply();
 
-        assertFalse(mHandler.handleIncomingIntent(mContext, createViewIntent(), false, true));
+        Assert.assertFalse(
+                mHandler.handleIncomingIntent(mContext, createViewIntent(), false, true));
 
         // Even if Chrome is not default, launch Instant Apps for CustomTabs since those never
         // show disambiguation dialogs.
         Intent cti = createViewIntent()
                 .putExtra("android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS", true);
-        assertTrue(mHandler.handleIncomingIntent(mContext, cti, true, true));
+        Assert.assertTrue(mHandler.handleIncomingIntent(mContext, cti, true, true));
     }
 
+    @Test
     @SmallTest
     public void testInstantAppsEnabled() {
         Intent i = createViewIntent();
-        assertTrue(mHandler.handleIncomingIntent(getInstrumentation().getContext(), i, false,
-                true));
+        Assert.assertTrue(mHandler.handleIncomingIntent(
+                InstrumentationRegistry.getInstrumentation().getContext(), i, false, true));
 
         // Check that identical intent wouldn't be enabled for CustomTab flow.
-        assertFalse(mHandler.handleIncomingIntent(getInstrumentation().getContext(), i, true,
-                true));
+        Assert.assertFalse(mHandler.handleIncomingIntent(
+                InstrumentationRegistry.getInstrumentation().getContext(), i, true, true));
 
         // Add CustomTab specific extra and check it's now enabled.
         i.putExtra("android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS", true);
-        assertTrue(mHandler.handleIncomingIntent(getInstrumentation().getContext(), i, true,
-                true));
+        Assert.assertTrue(mHandler.handleIncomingIntent(
+                InstrumentationRegistry.getInstrumentation().getContext(), i, true, true));
     }
 
+    @Test
     @SmallTest
     public void testNfcIntent() {
         Intent i = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED);
         i.setData(Uri.parse("http://instantapp.com/"));
-        assertTrue(mHandler.handleIncomingIntent(getInstrumentation().getContext(), i, false,
-                true));
+        Assert.assertTrue(mHandler.handleIncomingIntent(
+                InstrumentationRegistry.getInstrumentation().getContext(), i, false, true));
     }
 
+    @Test
     @SmallTest
     public void testHandleNavigation_startAsyncCheck() {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse(mHandler.handleNavigation(mContext, INSTANT_APP_URL, REFERRER_URI,
-                        getActivity().getTabModelSelector().getCurrentTab().getWebContents()));
+                Assert.assertFalse(
+                        mHandler.handleNavigation(mContext, INSTANT_APP_URL, REFERRER_URI,
+                                mActivityTestRule.getActivity()
+                                        .getTabModelSelector()
+                                        .getCurrentTab()
+                                        .getWebContents()));
             }
         });
-        assertFalse(mHandler.mLaunchInstantApp);
-        assertTrue(mHandler.mStartedAsyncCall);
+        Assert.assertFalse(mHandler.mLaunchInstantApp);
+        Assert.assertTrue(mHandler.mStartedAsyncCall);
     }
 
+    @Test
     @SmallTest
     public void testLaunchFromBanner() {
         // Intent to supervisor
         final Intent i = new Intent(Intent.ACTION_MAIN);
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
-                new IntentFilter(Intent.ACTION_MAIN), null, true);
+        Instrumentation.ActivityMonitor monitor =
+                InstrumentationRegistry.getInstrumentation().addMonitor(
+                        new IntentFilter(Intent.ACTION_MAIN), null, true);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mHandler.launchFromBanner(new InstantAppsBannerData(
-                        "App", null, INSTANT_APP_URL, REFERRER_URI, i, "Launch",
-                        getActivity().getTabModelSelector().getCurrentTab().getWebContents()));
+                mHandler.launchFromBanner(new InstantAppsBannerData("App", null, INSTANT_APP_URL,
+                        REFERRER_URI, i, "Launch",
+                        mActivityTestRule.getActivity()
+                                .getTabModelSelector()
+                                .getCurrentTab()
+                                .getWebContents()));
             }
         });
 
         // Started instant apps intent
-        assertEquals(1, monitor.getHits());
+        Assert.assertEquals(1, monitor.getHits());
 
-        assertEquals(REFERRER_URI, i.getParcelableExtra(Intent.EXTRA_REFERRER));
-        assertTrue(i.getBooleanExtra(InstantAppsHandler.IS_REFERRER_TRUSTED_EXTRA, false));
-        assertTrue(i.getBooleanExtra(InstantAppsHandler.IS_USER_CONFIRMED_LAUNCH_EXTRA, false));
-        assertEquals(mContext.getPackageName(),
+        Assert.assertEquals(REFERRER_URI, i.getParcelableExtra(Intent.EXTRA_REFERRER));
+        Assert.assertTrue(i.getBooleanExtra(InstantAppsHandler.IS_REFERRER_TRUSTED_EXTRA, false));
+        Assert.assertTrue(
+                i.getBooleanExtra(InstantAppsHandler.IS_USER_CONFIRMED_LAUNCH_EXTRA, false));
+        Assert.assertEquals(mContext.getPackageName(),
                 i.getStringExtra(InstantAppsHandler.TRUSTED_REFERRER_PKG_EXTRA));
 
         // After a banner launch, test that the next launch happens automatically
@@ -190,17 +222,15 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertTrue(mHandler.handleNavigation(mContext, INSTANT_APP_URL, REFERRER_URI,
-                        getActivity().getTabModelSelector().getCurrentTab().getWebContents()));
+                Assert.assertTrue(mHandler.handleNavigation(mContext, INSTANT_APP_URL, REFERRER_URI,
+                        mActivityTestRule.getActivity()
+                                .getTabModelSelector()
+                                .getCurrentTab()
+                                .getWebContents()));
             }
         });
-        assertFalse(mHandler.mStartedAsyncCall);
-        assertTrue(mHandler.mLaunchInstantApp);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        Assert.assertFalse(mHandler.mStartedAsyncCall);
+        Assert.assertTrue(mHandler.mLaunchInstantApp);
     }
 
     static class TestInstantAppsHandler extends InstantAppsHandler {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java
index 80b64f1..a58bf2f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java
@@ -12,15 +12,25 @@
 import android.content.Intent;
 import android.content.SyncResult;
 import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.CommandLine;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.invalidation.PendingInvalidation;
 import org.chromium.components.signin.AccountManagerHelper;
 import org.chromium.components.sync.AndroidSyncSettings;
@@ -30,7 +40,14 @@
 /**
  * Tests for ChromeBrowserSyncAdapter.
  */
-public class ChromeBrowserSyncAdapterTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ChromeBrowserSyncAdapterTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final Account TEST_ACCOUNT =
             AccountManagerHelper.createAccountFromName("test@gmail.com");
     private static final long WAIT_FOR_LAUNCHER_MS = ScalableTimeout.scaleTimeout(10 * 1000);
@@ -65,25 +82,18 @@
         }
     }
 
-    public ChromeBrowserSyncAdapterTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mSyncAdapter = new TestSyncAdapter(
-                getInstrumentation().getTargetContext(), getActivity().getApplication());
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mSyncAdapter =
+                new TestSyncAdapter(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                        mActivityTestRule.getActivity().getApplication());
     }
 
     private void performSyncWithBundle(Bundle bundle) {
         mSyncAdapter.onPerformSync(TEST_ACCOUNT, bundle,
-                AndroidSyncSettings.getContractAuthority(getActivity()), null, new SyncResult());
+                AndroidSyncSettings.getContractAuthority(mActivityTestRule.getActivity()), null,
+                new SyncResult());
     }
 
     private void sendChromeToBackground(Activity activity) {
@@ -103,16 +113,18 @@
         return ApplicationStatus.hasVisibleActivities();
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     @RetryOnFailure
     public void testRequestSyncNoInvalidationData() {
         performSyncWithBundle(new Bundle());
-        assertTrue(mSyncAdapter.mInvalidatedAllTypes);
-        assertFalse(mSyncAdapter.mInvalidated);
-        assertTrue(CommandLine.isInitialized());
+        Assert.assertTrue(mSyncAdapter.mInvalidatedAllTypes);
+        Assert.assertFalse(mSyncAdapter.mInvalidated);
+        Assert.assertTrue(CommandLine.isInitialized());
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     public void testRequestSyncSpecificDataType() {
@@ -124,26 +136,28 @@
         performSyncWithBundle(
                 PendingInvalidation.createBundle(objectId, objectSource, version, payload));
 
-        assertFalse(mSyncAdapter.mInvalidatedAllTypes);
-        assertTrue(mSyncAdapter.mInvalidated);
-        assertEquals(objectSource, mSyncAdapter.mObjectSource);
-        assertEquals(objectId, mSyncAdapter.mObjectId);
-        assertEquals(version, mSyncAdapter.mVersion);
-        assertEquals(payload, mSyncAdapter.mPayload);
-        assertTrue(CommandLine.isInitialized());
+        Assert.assertFalse(mSyncAdapter.mInvalidatedAllTypes);
+        Assert.assertTrue(mSyncAdapter.mInvalidated);
+        Assert.assertEquals(objectSource, mSyncAdapter.mObjectSource);
+        Assert.assertEquals(objectId, mSyncAdapter.mObjectId);
+        Assert.assertEquals(version, mSyncAdapter.mVersion);
+        Assert.assertEquals(payload, mSyncAdapter.mPayload);
+        Assert.assertTrue(CommandLine.isInitialized());
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     @RetryOnFailure
     public void testRequestSyncWhenChromeInBackground() {
-        sendChromeToBackground(getActivity());
+        sendChromeToBackground(mActivityTestRule.getActivity());
         performSyncWithBundle(new Bundle());
-        assertFalse(mSyncAdapter.mInvalidatedAllTypes);
-        assertFalse(mSyncAdapter.mInvalidated);
-        assertTrue(CommandLine.isInitialized());
+        Assert.assertFalse(mSyncAdapter.mInvalidatedAllTypes);
+        Assert.assertFalse(mSyncAdapter.mInvalidated);
+        Assert.assertTrue(CommandLine.isInitialized());
     }
 
+    @Test
     @MediumTest
     @Feature({"Sync"})
     @RetryOnFailure
@@ -151,7 +165,7 @@
         Bundle extras = new Bundle();
         extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
         performSyncWithBundle(extras);
-        assertFalse(mSyncAdapter.mInvalidatedAllTypes);
-        assertFalse(mSyncAdapter.mInvalidated);
+        Assert.assertFalse(mSyncAdapter.mInvalidatedAllTypes);
+        Assert.assertFalse(mSyncAdapter.mInvalidated);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MediaRouterIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MediaRouterIntegrationTest.java
index ba254ed..b9d31ff 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MediaRouterIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MediaRouterIntegrationTest.java
@@ -8,10 +8,17 @@
 
 import android.app.Dialog;
 import android.os.StrictMode;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.view.View;
 
 import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -19,8 +26,10 @@
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.media.RouterTestUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.content.browser.test.util.ClickUtils;
 import org.chromium.content.browser.test.util.Criteria;
@@ -38,8 +47,14 @@
  *
  * TODO(jbudorick): Remove this when media_router_integration_browsertest runs on Android.
  */
-@CommandLineFlags.Add(ContentSwitches.DISABLE_GESTURE_REQUIREMENT_FOR_PRESENTATION)
-public class MediaRouterIntegrationTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ContentSwitches.DISABLE_GESTURE_REQUIREMENT_FOR_PRESENTATION,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class MediaRouterIntegrationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEST_PAGE =
             "/chrome/test/media_router/resources/basic_test.html?__is_android__=true";
@@ -70,13 +85,10 @@
 
     private EmbeddedTestServer mTestServer;
 
-    public MediaRouterIntegrationTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        ChromeMediaRouter.setRouteProviderBuilderForTest(new MockMediaRouteProvider.Builder());
+        mActivityTestRule.startMainActivityOnBlankPage();
         // Temporary until support library is updated, see http://crbug.com/576393.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -84,10 +96,11 @@
                 mOldPolicy = StrictMode.allowThreadDiskWrites();
             }
         });
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         // Temporary until support library is updated, see http://crbug.com/576393.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -97,7 +110,6 @@
             }
         });
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     // TODO(zqzhang): Move this to a util class?
@@ -169,11 +181,11 @@
             String unescapedResult = unescapeString(JavaScriptUtils
                     .executeJavaScriptAndWaitForResult(webContents, GET_RESULT_SCRIPT));
             JSONObject jsonResult = new JSONObject(unescapedResult);
-            assertTrue(jsonResult.getString("errorMessage"),
-                    jsonResult.getBoolean("passed"));
+            Assert.assertTrue(
+                    jsonResult.getString("errorMessage"), jsonResult.getBoolean("passed"));
         } catch (Exception e) {
             e.printStackTrace();
-            fail("caught exception while executing javascript:" + script);
+            Assert.fail("caught exception while executing javascript:" + script);
         }
     }
 
@@ -187,7 +199,7 @@
             return result;
         } catch (Exception e) {
             e.printStackTrace();
-            fail();
+            Assert.fail();
             return null;
         }
     }
@@ -197,163 +209,174 @@
         executeJavaScriptApi(webContents, script);
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        ChromeMediaRouter.setRouteProviderBuilderForTest(new MockMediaRouteProvider.Builder());
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     public void testBasic() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         executeJavaScriptApi(webContents, CHECK_SESSION_SCRIPT);
         String sessionId = getJavaScriptVariable(webContents, "startedConnection.id");
-        assertFalse(sessionId.length() == 0);
+        Assert.assertFalse(sessionId.length() == 0);
         String defaultRequestSessionId = getJavaScriptVariable(
                 webContents, "defaultRequestSessionId");
-        assertEquals(sessionId, defaultRequestSessionId);
+        Assert.assertEquals(sessionId, defaultRequestSessionId);
         executeJavaScriptApi(webContents, TERMINATE_SESSION_SCRIPT);
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     public void testSendAndOnMessage() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         executeJavaScriptApi(webContents, CHECK_SESSION_SCRIPT);
         String sessionId = getJavaScriptVariable(webContents, "startedConnection.id");
-        assertFalse(sessionId.length() == 0);
+        Assert.assertFalse(sessionId.length() == 0);
         executeJavaScriptApi(webContents,
                 String.format(SEND_MESSAGE_AND_EXPECT_RESPONSE_SCRIPT, "foo"));
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     @RetryOnFailure
     public void testOnClose() throws InterruptedException, TimeoutException {
         MockMediaRouteProvider.Builder.sProvider.setCloseRouteWithErrorOnSend(true);
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         executeJavaScriptApi(webContents, CHECK_SESSION_SCRIPT);
         String sessionId = getJavaScriptVariable(webContents, "startedConnection.id");
-        assertFalse(sessionId.length() == 0);
+        Assert.assertFalse(sessionId.length() == 0);
         executeJavaScriptApi(webContents,
                 SEND_MESSAGE_AND_EXPECT_CONNECTION_CLOSE_ON_ERROR_SCRIPT);
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     @RetryOnFailure
     public void testFailNoProvider() throws InterruptedException, TimeoutException {
         MockMediaRouteProvider.Builder.sProvider.setIsSupportsSource(false);
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         checkStartFailed(
                 webContents, "UnknownError", "No provider supports createRoute with source");
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     public void testFailCreateRoute() throws InterruptedException, TimeoutException {
         MockMediaRouteProvider.Builder.sProvider.setCreateRouteErrorMessage("Unknown sink");
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         checkStartFailed(
                 webContents, "UnknownError", "Unknown sink");
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     @RetryOnFailure
     public void testReconnectSession() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         executeJavaScriptApi(webContents, CHECK_SESSION_SCRIPT);
         String sessionId = getJavaScriptVariable(webContents, "startedConnection.id");
 
-        loadUrlInNewTab(mTestServer.getURL(TEST_PAGE));
-        WebContents newWebContents = getActivity().getActivityTab().getWebContents();
-        assertTrue(webContents != newWebContents);
+        mActivityTestRule.loadUrlInNewTab(mTestServer.getURL(TEST_PAGE));
+        WebContents newWebContents =
+                mActivityTestRule.getActivity().getActivityTab().getWebContents();
+        Assert.assertTrue(webContents != newWebContents);
         executeJavaScriptApi(newWebContents, String.format("reconnectSession(\'%s\');", sessionId));
         String reconnectedSessionId =
                 getJavaScriptVariable(newWebContents, "reconnectedSession.id");
-        assertEquals(sessionId, reconnectedSessionId);
+        Assert.assertEquals(sessionId, reconnectedSessionId);
         executeJavaScriptApi(webContents, TERMINATE_SESSION_SCRIPT);
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     @RetryOnFailure
     public void testFailReconnectSession() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         View testRouteButton = RouterTestUtils.waitForRouteButton(
-                getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        ClickUtils.mouseSingleClickView(getInstrumentation(), testRouteButton);
+                mActivityTestRule.getActivity(), TEST_SINK_NAME, VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        ClickUtils.mouseSingleClickView(
+                InstrumentationRegistry.getInstrumentation(), testRouteButton);
         executeJavaScriptApi(webContents, CHECK_SESSION_SCRIPT);
         String sessionId = getJavaScriptVariable(webContents, "startedConnection.id");
 
         MockMediaRouteProvider.Builder.sProvider.setJoinRouteErrorMessage("Unknown route");
-        loadUrlInNewTab(mTestServer.getURL(TEST_PAGE_RECONNECT_FAIL));
-        WebContents newWebContents = getActivity().getActivityTab().getWebContents();
-        assertTrue(webContents != newWebContents);
+        mActivityTestRule.loadUrlInNewTab(mTestServer.getURL(TEST_PAGE_RECONNECT_FAIL));
+        WebContents newWebContents =
+                mActivityTestRule.getActivity().getActivityTab().getWebContents();
+        Assert.assertTrue(webContents != newWebContents);
         executeJavaScriptApi(newWebContents,
                 String.format("checkReconnectSessionFails('%s');", sessionId));
     }
 
+    @Test
     @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @Feature({"MediaRouter"})
     @LargeTest
     @RetryOnFailure
     public void testFailStartCancelled() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TEST_PAGE));
-        WebContents webContents = getActivity().getActivityTab().getWebContents();
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+        WebContents webContents = mActivityTestRule.getActivity().getActivityTab().getWebContents();
         executeJavaScriptApi(webContents, WAIT_DEVICE_SCRIPT);
         executeJavaScriptApi(webContents, START_SESSION_SCRIPT);
         final Dialog routeSelectionDialog = RouterTestUtils.waitForDialog(
-                getActivity(), VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
-        assertNotNull(routeSelectionDialog);
+                mActivityTestRule.getActivity(), VIEW_TIMEOUT_MS, VIEW_RETRY_MS);
+        Assert.assertNotNull(routeSelectionDialog);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
                 @Override
                 public void run() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/AutoplayMutedNotificationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/AutoplayMutedNotificationTest.java
index 716c42b6..20e77d9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/AutoplayMutedNotificationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/AutoplayMutedNotificationTest.java
@@ -8,14 +8,25 @@
 
 import android.content.Context;
 import android.media.AudioManager;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.content.browser.test.util.JavaScriptUtils;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -23,21 +34,25 @@
 /**
  * Integration test that checks that autoplay muted doesn't show a notification nor take audio focus
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AutoplayMutedNotificationTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AutoplayMutedNotificationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PATH = "/content/test/data/media/session/autoplay-muted.html";
     private static final String VIDEO_ID = "video";
     private static final int AUDIO_FOCUS_CHANGE_TIMEOUT = 500;  // ms
 
     private EmbeddedTestServer mTestServer;
 
-    public AutoplayMutedNotificationTest() {
-        super(ChromeActivity.class);
-    }
-
     private AudioManager getAudioManager() {
-        return (AudioManager) getActivity().getApplicationContext().getSystemService(
-                Context.AUDIO_SERVICE);
+        return (AudioManager) mActivityTestRule.getActivity()
+                .getApplicationContext()
+                .getSystemService(Context.AUDIO_SERVICE);
     }
 
     private boolean isMediaNotificationVisible() {
@@ -60,7 +75,7 @@
             int result = getAudioManager().requestAudioFocus(
                     this, AudioManager.STREAM_MUSIC, focusType);
             if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
-                fail("Did not get audio focus");
+                Assert.fail("Did not get audio focus");
             } else {
                 mAudioFocusState = focusType;
             }
@@ -69,33 +84,31 @@
 
     private MockAudioFocusChangeListener mAudioFocusChangeListener;
 
-    @Override
-    protected void setUp() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mAudioFocusChangeListener = new MockAudioFocusChangeListener();
-        super.setUp();
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_PATH));
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(mTestServer.getURL(TEST_PATH));
-    }
-
+    @Test
     @SmallTest
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     public void testBasic() throws Exception {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // Taking audio focus.
-        assertEquals(AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
         mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN);
-        assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
 
         // The page will autoplay the video.
         DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID);
@@ -104,42 +117,49 @@
         Thread.sleep(AUDIO_FOCUS_CHANGE_TIMEOUT);
 
         // Audio focus was not taken and no notification is visible.
-        assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
-        assertFalse(isMediaNotificationVisible());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertFalse(isMediaNotificationVisible());
     }
 
+    @Test
     @SmallTest
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     public void testDoesNotReactToAudioFocus() throws Exception {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // The page will autoplay the video.
         DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID);
 
         // Taking audio focus.
-        assertEquals(AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
         mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN);
-        assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
 
         // Audio focus notification is OS-driven.
         Thread.sleep(AUDIO_FOCUS_CHANGE_TIMEOUT);
 
         // Video did not pause.
-        assertFalse(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
+        Assert.assertFalse(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
 
         // Still no notification.
-        assertFalse(isMediaNotificationVisible());
+        Assert.assertFalse(isMediaNotificationVisible());
     }
 
+    @Test
     @SmallTest
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
     public void testAutoplayMutedThenUnmute() throws Exception {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // Taking audio focus.
-        assertEquals(AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState());
         mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN);
-        assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
 
         // The page will autoplay the video.
         DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID);
@@ -154,16 +174,17 @@
         // Unmute from script.
         String result = JavaScriptUtils.executeJavaScriptAndWaitForResult(
                 tab.getWebContents(), sb.toString());
-        assertTrue(result.trim().equalsIgnoreCase("false"));
+        Assert.assertTrue(result.trim().equalsIgnoreCase("false"));
 
         // Video is paused.
-        assertTrue(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
+        Assert.assertTrue(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
 
         // Audio focus notification is OS-driven.
         Thread.sleep(AUDIO_FOCUS_CHANGE_TIMEOUT);
 
         // Audio focus was not taken and no notification is visible.
-        assertEquals(AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
-        assertFalse(isMediaNotificationVisible());
+        Assert.assertEquals(
+                AudioManager.AUDIOFOCUS_GAIN, mAudioFocusChangeListener.getAudioFocusState());
+        Assert.assertFalse(isMediaNotificationVisible());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java
index ddeeada..b0ceca5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/PauseOnHeadsetUnplugTest.java
@@ -6,14 +6,24 @@
 
 import android.content.Intent;
 import android.media.AudioManager;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.DOMUtils;
@@ -25,25 +35,29 @@
 /**
  * Tests for checking whether the media are paused when unplugging the headset
  */
-@CommandLineFlags.Add(MediaSwitches.IGNORE_AUTOPLAY_RESTRICTIONS_FOR_TESTS)
-public class PauseOnHeadsetUnplugTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({MediaSwitches.IGNORE_AUTOPLAY_RESTRICTIONS_FOR_TESTS,
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class PauseOnHeadsetUnplugTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PATH =
             "/content/test/data/media/session/media-session.html";
     private static final String VIDEO_ID = "long-video";
 
     private EmbeddedTestServer mTestServer;
 
-    public PauseOnHeadsetUnplugTest() {
-        super(ChromeActivity.class);
-    }
-
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testPause()
             throws IllegalArgumentException, InterruptedException, TimeoutException {
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
-        assertTrue(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
+        Assert.assertTrue(DOMUtils.isMediaPaused(tab.getWebContents(), VIDEO_ID));
         DOMUtils.playMedia(tab.getWebContents(), VIDEO_ID);
         DOMUtils.waitForMediaPlay(tab.getWebContents(), VIDEO_ID);
         waitForNotificationReady();
@@ -52,21 +66,16 @@
         DOMUtils.waitForMediaPauseBeforeEnd(tab.getWebContents(), VIDEO_ID);
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityWithURL(mTestServer.getURL(TEST_PATH));
+    @Before
+    public void setUp() throws Exception {
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(TEST_PATH));
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     private void waitForNotificationReady() {
@@ -80,10 +89,10 @@
     }
 
     private void simulateHeadsetUnplug() {
-        Intent i = new Intent(getInstrumentation().getTargetContext(),
-                              MediaNotificationManager.PlaybackListenerService.class);
+        Intent i = new Intent(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                MediaNotificationManager.PlaybackListenerService.class);
         i.setAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
 
-        getInstrumentation().getContext().startService(i);
+        InstrumentationRegistry.getInstrumentation().getContext().startService(i);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java
index c8ff4de..d718c7f0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/PageLoadMetricsTest.java
@@ -4,13 +4,24 @@
 
 package org.chromium.chrome.browser.metrics;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.net.test.EmbeddedTestServer;
 
@@ -20,11 +31,14 @@
 /**
  * Tests for {@link PageLoadMetrics}
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class PageLoadMetricsTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-    public PageLoadMetricsTest() {
-        super(ChromeActivity.class);
-    }
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class PageLoadMetricsTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final int PAGE_LOAD_METRICS_TIMEOUT_MS = 3000;
     private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
@@ -34,17 +48,19 @@
     private EmbeddedTestServer mTestServer;
     private PageLoadMetricsObserver mMetricsObserver;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mTestPage = mTestServer.getURL(TEST_PAGE);
 
-        mMetricsObserver = new PageLoadMetricsObserver(getActivity().getActivityTab());
+        mMetricsObserver =
+                new PageLoadMetricsObserver(mActivityTestRule.getActivity().getActivityTab());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -53,12 +69,6 @@
         });
 
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
     }
 
     private static class PageLoadMetricsObserver implements PageLoadMetrics.Observer {
@@ -96,10 +106,11 @@
         }
     }
 
+    @Test
     @SmallTest
     public void testPageLoadMetricEmitted() throws InterruptedException {
-        assertFalse("Tab shouldn't be loading anything before we add observer",
-                getActivity().getActivityTab().isLoading());
+        Assert.assertFalse("Tab shouldn't be loading anything before we add observer",
+                mActivityTestRule.getActivity().getActivityTab().isLoading());
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -107,11 +118,11 @@
             }
         });
 
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
 
-        assertTrue("First Contentful Paint should be reported",
+        Assert.assertTrue("First Contentful Paint should be reported",
                 mMetricsObserver.waitForFirstContentfulPaintEvent());
-        assertTrue("Load event start event should be reported",
+        Assert.assertTrue("Load event start event should be reported",
                 mMetricsObserver.waitForLoadEventStartEvent());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeIntentTest.java
index 5fd43d2..d8f07e43 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeIntentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeIntentTest.java
@@ -8,17 +8,24 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.preferences.website.SingleCategoryPreferences;
 import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ActivityUtils;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -30,9 +37,11 @@
  * that the responsibility for correct initialization, e.g. loading the native library, lies with
  * the code exercised by this test.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class NotificationPlatformBridgeIntentTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class NotificationPlatformBridgeIntentTest {
     /**
      * Name of the Intent extra holding the notification id. This is set by the framework when a
      * notification preferences intent has been triggered from there, which could be one of the
@@ -40,28 +49,22 @@
      */
     public static final String EXTRA_NOTIFICATION_ID = "notification_id";
 
-    public NotificationPlatformBridgeIntentTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        // Don't do anything here. The responsibility for correct initialization, e.g. loading the
-        // native library, lies with the code exercised by this test.
-    }
-
     /**
      * Tests the scenario where the user clicks "App settings" in the Android App notifications
      * screen. In this scenario the intent does not have the tag extra which holds the origin. This
      * means that the preferences cannot be shown for a specific site, and Chrome falls back to
      * showing the notification preferences for all sites.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Notifications"})
     public void testLaunchNotificationPreferencesForCategory() {
-        assertFalse("The native library should not be loaded yet", LibraryLoader.isInitialized());
+        Assert.assertFalse(
+                "The native library should not be loaded yet", LibraryLoader.isInitialized());
 
-        final Context context = getInstrumentation().getTargetContext().getApplicationContext();
+        final Context context = InstrumentationRegistry.getInstrumentation()
+                                        .getTargetContext()
+                                        .getApplicationContext();
 
         final Intent intent =
                 new Intent(Intent.ACTION_MAIN)
@@ -70,17 +73,17 @@
                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
         Preferences activity = ActivityUtils.waitForActivity(
-                getInstrumentation(), Preferences.class, new Runnable() {
+                InstrumentationRegistry.getInstrumentation(), Preferences.class, new Runnable() {
                     @Override
                     public void run() {
                         context.startActivity(intent);
                     }
                 });
-        assertNotNull("Could not find the Preferences activity", activity);
+        Assert.assertNotNull("Could not find the Preferences activity", activity);
 
         SingleCategoryPreferences fragment =
                 ActivityUtils.waitForFragmentToAttach(activity, SingleCategoryPreferences.class);
-        assertNotNull("Could not find the SingleCategoryPreferences fragment", fragment);
+        Assert.assertNotNull("Could not find the SingleCategoryPreferences fragment", fragment);
     }
 
     /**
@@ -88,12 +91,16 @@
      * through a long press. In this scenario the intent has the tag extra which holds the origin
      * that created the notification. Chrome will show the preferences for this specific site.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Notifications"})
     public void testLaunchNotificationPreferencesForWebsite() {
-        assertFalse("The native library should not be loaded yet", LibraryLoader.isInitialized());
+        Assert.assertFalse(
+                "The native library should not be loaded yet", LibraryLoader.isInitialized());
 
-        final Context context = getInstrumentation().getTargetContext().getApplicationContext();
+        final Context context = InstrumentationRegistry.getInstrumentation()
+                                        .getTargetContext()
+                                        .getApplicationContext();
 
         final Intent intent =
                 new Intent(Intent.ACTION_MAIN)
@@ -107,17 +114,17 @@
                                         null /* tag */));
 
         Preferences activity = ActivityUtils.waitForActivity(
-                getInstrumentation(), Preferences.class, new Runnable() {
+                InstrumentationRegistry.getInstrumentation(), Preferences.class, new Runnable() {
                     @Override
                     public void run() {
                         context.startActivity(intent);
                     }
                 });
-        assertNotNull("Could not find the Preferences activity", activity);
+        Assert.assertNotNull("Could not find the Preferences activity", activity);
 
         SingleWebsitePreferences fragment =
                 ActivityUtils.waitForFragmentToAttach(activity, SingleWebsitePreferences.class);
-        assertNotNull("Could not find the SingleWebsitePreferences fragment", fragment);
+        Assert.assertNotNull("Could not find the SingleWebsitePreferences fragment", fragment);
     }
 
     /**
@@ -128,13 +135,17 @@
      * The created intent does not carry significant data and is expected to fail, but has to be
      * sufficient for the Java code to trigger start-up of the browser process.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Notifications"})
     public void testLaunchProcessForNotificationActivation() throws Exception {
-        assertFalse("The native library should not be loaded yet", LibraryLoader.isInitialized());
-        assertNull(NotificationPlatformBridge.getInstanceForTests());
+        Assert.assertFalse(
+                "The native library should not be loaded yet", LibraryLoader.isInitialized());
+        Assert.assertNull(NotificationPlatformBridge.getInstanceForTests());
 
-        Context context = getInstrumentation().getTargetContext().getApplicationContext();
+        Context context = InstrumentationRegistry.getInstrumentation()
+                                  .getTargetContext()
+                                  .getApplicationContext();
 
         Intent intent = new Intent(NotificationConstants.ACTION_CLICK_NOTIFICATION);
         intent.setClass(context, NotificationService.Receiver.class);
@@ -158,7 +169,7 @@
             }
         });
 
-        assertTrue("The native library should be loaded now", LibraryLoader.isInitialized());
-        assertNotNull(NotificationPlatformBridge.getInstanceForTests());
+        Assert.assertTrue("The native library should be loaded now", LibraryLoader.isInitialized());
+        Assert.assertNotNull(NotificationPlatformBridge.getInstanceForTests());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
index 37a6b1f..8fd2267 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -5,16 +5,24 @@
 package org.chromium.chrome.browser.ntp.snippets;
 
 import android.graphics.BitmapFactory;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.util.TypedValue;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
 import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallback;
 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
@@ -32,7 +40,8 @@
 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle;
 import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
 import org.chromium.chrome.browser.widget.displaystyle.VerticalDisplayStyle;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.RenderUtils.ViewRenderer;
 import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
@@ -43,7 +52,14 @@
 /**
  * Tests for the appearance of Article Snippets.
  */
-public class ArticleSnippetsTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ArticleSnippetsTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private ViewRenderer mViewRenderer;
 
     private SuggestionsUiDelegate mUiDelegate;
@@ -54,10 +70,7 @@
     private FrameLayout mContentView;
     private UiConfig mUiConfig;
 
-    public ArticleSnippetsTest() {
-        super(ChromeActivity.class);
-    }
-
+    @Test
     @MediumTest
     @Feature({"ArticleSnippets", "RenderTest"})
     @RetryOnFailure
@@ -67,12 +80,12 @@
             public void run() {
                 setupTestData();
 
-                mContentView = new FrameLayout(getActivity());
+                mContentView = new FrameLayout(mActivityTestRule.getActivity());
                 mUiConfig = new UiConfig(mContentView);
 
-                getActivity().setContentView(mContentView);
+                mActivityTestRule.getActivity().setContentView(mContentView);
 
-                mRecyclerView = new SuggestionsRecyclerView(getActivity());
+                mRecyclerView = new SuggestionsRecyclerView(mActivityTestRule.getActivity());
                 mContentView.addView(mRecyclerView);
 
                 mAdapter = new NewTabPageAdapter(mUiDelegate, /* aboveTheFold = */ null, mUiConfig,
@@ -83,7 +96,7 @@
             }
         });
 
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         int first = mAdapter.getFirstCardPosition();
         mViewRenderer.renderAndCompare(mRecyclerView.getChildAt(first), "short_snippet");
@@ -112,7 +125,7 @@
             }
         });
 
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
         mViewRenderer.renderAndCompare(mRecyclerView.getChildAt(first), "short_snippet_narrow");
         mViewRenderer.renderAndCompare(mRecyclerView.getChildAt(first + 1), "long_snippet_narrow");
@@ -133,8 +146,9 @@
                 1466614774, // Publish timestamp
                 10f, // Score
                 1466634774); // Fetch timestamp
-        shortSnippet.setThumbnailBitmap(BitmapFactory.decodeResource(getActivity().getResources(),
-                R.drawable.signin_promo_illustration));
+        shortSnippet.setThumbnailBitmap(
+                BitmapFactory.decodeResource(mActivityTestRule.getActivity().getResources(),
+                        R.drawable.signin_promo_illustration));
 
         SnippetArticle longSnippet = new SnippetArticle(fullCategory, "id2",
                 new String(new char[20]).replace("\0", "Snippet "),
@@ -176,16 +190,11 @@
                 minimalCategory, Arrays.asList(minimalSnippet, minimalSnippet2));
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-        mViewRenderer = new ViewRenderer(getActivity(),
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mViewRenderer = new ViewRenderer(mActivityTestRule.getActivity(),
                 "chrome/test/data/android/render_tests", this.getClass().getSimpleName());
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
         mUiDelegate = new MockUiDelegate();
         mSnippetsSource = new FakeSuggestionsSource();
     }
@@ -207,8 +216,9 @@
                 public void run() {
                     // Return an arbitrary drawable.
                     faviconCallback.onFaviconAvailable(
-                            BitmapFactory.decodeResource(getActivity().getResources(),
-                            R.drawable.star_green),
+                            BitmapFactory.decodeResource(
+                                    mActivityTestRule.getActivity().getResources(),
+                                    R.drawable.star_green),
                             url);
                 }
             });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
index 9140668..c6a6038 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeTest.java
@@ -4,17 +4,27 @@
 
 package org.chromium.chrome.browser.offlinepages;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.Callback;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.offlinepages.DeletePageResult;
 import org.chromium.components.offlinepages.SavePageResult;
 import org.chromium.net.NetworkChangeNotifier;
@@ -30,8 +40,15 @@
 import java.util.concurrent.atomic.AtomicReference;
 
 /** Unit tests for {@link OfflinePageBridge}. */
-@CommandLineFlags.Add("enable-features=OfflineBookmarks")
-public class OfflinePageBridgeTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"enable-features=OfflineBookmarks",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OfflinePageBridgeTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PAGE = "/chrome/test/data/android/about.html";
     private static final int TIMEOUT_MS = 5000;
     private static final long POLLING_INTERVAL = 100;
@@ -42,10 +59,6 @@
     private EmbeddedTestServer mTestServer;
     private String mTestPage;
 
-    public OfflinePageBridgeTest() {
-        super(ChromeActivity.class);
-    }
-
     private void initializeBridgeForProfile(final boolean incognitoProfile)
             throws InterruptedException {
         final Semaphore semaphore = new Semaphore(0);
@@ -71,12 +84,12 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -91,37 +104,34 @@
 
         initializeBridgeForProfile(false);
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mTestPage = mTestServer.getURL(TEST_PAGE);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testLoadOfflinePagesWhenEmpty() throws Exception {
         List<OfflinePageItem> offlinePages = getAllPages();
-        assertEquals("Offline pages count incorrect.", 0, offlinePages.size());
+        Assert.assertEquals("Offline pages count incorrect.", 0, offlinePages.size());
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testAddOfflinePageAndLoad() throws Exception {
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
         List<OfflinePageItem> allPages = getAllPages();
         OfflinePageItem offlinePage = allPages.get(0);
-        assertEquals("Offline pages count incorrect.", 1, allPages.size());
-        assertEquals("Offline page item url incorrect.", mTestPage, offlinePage.getUrl());
+        Assert.assertEquals("Offline pages count incorrect.", 1, allPages.size());
+        Assert.assertEquals("Offline page item url incorrect.", mTestPage, offlinePage.getUrl());
 
         // We don't care about the exact file size of the mhtml file:
         // - exact file size is not something that the end user sees or cares about
@@ -133,33 +143,36 @@
         // OTOH, it still seems useful to assert that the file is not empty and that its size is in
         // the right ballpark.
         long size = offlinePage.getFileSize();
-        assertTrue("Offline page item size is incorrect: " + size, 600 < size && size < 800);
+        Assert.assertTrue("Offline page item size is incorrect: " + size, 600 < size && size < 800);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testGetPageByBookmarkId() throws Exception {
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
         OfflinePageItem offlinePage = getPageByClientId(BOOKMARK_ID);
-        assertEquals("Offline page item url incorrect.", mTestPage, offlinePage.getUrl());
-        assertNull("Offline page is not supposed to exist",
+        Assert.assertEquals("Offline page item url incorrect.", mTestPage, offlinePage.getUrl());
+        Assert.assertNull("Offline page is not supposed to exist",
                 getPageByClientId(new ClientId(OfflinePageBridge.BOOKMARK_NAMESPACE, "-42")));
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testDeleteOfflinePage() throws Exception {
         deletePage(BOOKMARK_ID, DeletePageResult.SUCCESS);
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
-        assertNotNull(
+        Assert.assertNotNull(
                 "Offline page should be available, but it is not.", getPageByClientId(BOOKMARK_ID));
         deletePage(BOOKMARK_ID, DeletePageResult.SUCCESS);
-        assertNull("Offline page should be gone, but it is available.",
+        Assert.assertNull("Offline page should be gone, but it is available.",
                 getPageByClientId(BOOKMARK_ID));
     }
 
+    @Test
     @CommandLineFlags.Add("disable-features=OfflinePagesSharing")
     @SmallTest
     @RetryOnFailure
@@ -167,17 +180,19 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertFalse("If offline page sharing is off, we should see the feature disabled",
+                Assert.assertFalse(
+                        "If offline page sharing is off, we should see the feature disabled",
                         OfflinePageBridge.isPageSharingEnabled());
             }
         });
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testCheckPagesExistOffline() throws Exception {
         // If we save a page, then it should exist in the result.
-        loadUrl(mTestPage);
+        mActivityTestRule.loadUrl(mTestPage);
         savePage(SavePageResult.SUCCESS, mTestPage);
         Set<String> testCases = new HashSet<>();
         testCases.add(mTestPage);
@@ -187,13 +202,14 @@
 
         Set<String> pages = checkPagesExistOffline(testCases);
 
-        assertEquals(
+        Assert.assertEquals(
                 "We only saved one page and queried for it, so the result should be one string.", 1,
                 pages.size());
-        assertTrue("The only page returned should be the page that was actually saved.",
+        Assert.assertTrue("The only page returned should be the page that was actually saved.",
                 pages.contains(mTestPage));
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testGetRequestsInQueue() throws Exception {
@@ -201,15 +217,15 @@
         String namespace = "custom_tabs";
         savePageLater(url, namespace);
         SavePageRequest[] requests = getRequestsInQueue();
-        assertEquals(1, requests.length);
-        assertEquals(namespace, requests[0].getClientId().getNamespace());
-        assertEquals(url, requests[0].getUrl());
+        Assert.assertEquals(1, requests.length);
+        Assert.assertEquals(namespace, requests[0].getClientId().getNamespace());
+        Assert.assertEquals(url, requests[0].getUrl());
 
         String url2 = "https://mail.google.com/";
         String namespace2 = "last_n";
         savePageLater(url2, namespace2);
         requests = getRequestsInQueue();
-        assertEquals(2, requests.length);
+        Assert.assertEquals(2, requests.length);
 
         HashSet<String> expectedUrls = new HashSet<>();
         expectedUrls.add(url);
@@ -220,20 +236,22 @@
         expectedNamespaces.add(namespace2);
 
         for (SavePageRequest request : requests) {
-            assertTrue(expectedNamespaces.contains(request.getClientId().getNamespace()));
+            Assert.assertTrue(expectedNamespaces.contains(request.getClientId().getNamespace()));
             expectedNamespaces.remove(request.getClientId().getNamespace());
-            assertTrue(expectedUrls.contains(request.getUrl()));
+            Assert.assertTrue(expectedUrls.contains(request.getUrl()));
             expectedUrls.remove(request.getUrl());
         }
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testOfflinePageBridgeDisabledInIncognito() throws Exception {
         initializeBridgeForProfile(true);
-        assertEquals(null, mOfflinePageBridge);
+        Assert.assertEquals(null, mOfflinePageBridge);
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testRemoveRequestsFromQueue() throws Exception {
@@ -246,22 +264,23 @@
         savePageLater(url2, namespace2);
 
         SavePageRequest[] requests = getRequestsInQueue();
-        assertEquals(2, requests.length);
+        Assert.assertEquals(2, requests.length);
 
         List<Long> requestsToRemove = new ArrayList<>();
         requestsToRemove.add(Long.valueOf(requests[1].getRequestId()));
 
         List<OfflinePageBridge.RequestRemovedResult> removed =
                 removeRequestsFromQueue(requestsToRemove);
-        assertEquals(requests[1].getRequestId(), removed.get(0).getRequestId());
-        assertEquals(org.chromium.components.offlinepages.background.UpdateRequestResult.SUCCESS,
+        Assert.assertEquals(requests[1].getRequestId(), removed.get(0).getRequestId());
+        Assert.assertEquals(
+                org.chromium.components.offlinepages.background.UpdateRequestResult.SUCCESS,
                 removed.get(0).getUpdateRequestResult());
 
         SavePageRequest[] remaining = getRequestsInQueue();
-        assertEquals(1, remaining.length);
+        Assert.assertEquals(1, remaining.length);
 
-        assertEquals(requests[0].getRequestId(), remaining[0].getRequestId());
-        assertEquals(requests[0].getUrl(), remaining[0].getUrl());
+        Assert.assertEquals(requests[0].getRequestId(), remaining[0].getRequestId());
+        Assert.assertEquals(requests[0].getUrl(), remaining[0].getUrl());
     }
 
     private void savePage(final int expectedResult, final String expectedUrl)
@@ -270,27 +289,29 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertNotNull("Tab is null", getActivity().getActivityTab());
-                assertEquals("URL does not match requested.", expectedUrl,
-                        getActivity().getActivityTab().getUrl());
-                assertNotNull("WebContents is null",
-                        getActivity().getActivityTab().getWebContents());
+                Assert.assertNotNull(
+                        "Tab is null", mActivityTestRule.getActivity().getActivityTab());
+                Assert.assertEquals("URL does not match requested.", expectedUrl,
+                        mActivityTestRule.getActivity().getActivityTab().getUrl());
+                Assert.assertNotNull("WebContents is null",
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents());
 
-                mOfflinePageBridge.savePage(getActivity().getActivityTab().getWebContents(),
+                mOfflinePageBridge.savePage(
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         BOOKMARK_ID, new SavePageCallback() {
                             @Override
                             public void onSavePageDone(
                                     int savePageResult, String url, long offlineId) {
-                                assertEquals(
+                                Assert.assertEquals(
                                         "Requested and returned URLs differ.", expectedUrl, url);
-                                assertEquals(
+                                Assert.assertEquals(
                                         "Save result incorrect.", expectedResult, savePageResult);
                                 semaphore.release();
                             }
                         });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
     private void deletePage(final ClientId bookmarkId, final int expectedResult)
@@ -309,8 +330,8 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertEquals("Delete result incorrect.", expectedResult, deletePageResultRef.get());
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertEquals("Delete result incorrect.", expectedResult, deletePageResultRef.get());
     }
 
     private List<OfflinePageItem> getAllPages() throws InterruptedException {
@@ -328,7 +349,7 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return result;
     }
 
@@ -362,7 +383,7 @@
                         });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return result[0];
     }
 
@@ -382,7 +403,7 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return result;
     }
 
@@ -411,7 +432,7 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return ref.get();
     }
 
@@ -434,7 +455,7 @@
                         });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return ref.get();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageRequestTest.java
index 6283b75..da04976 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageRequestTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageRequestTest.java
@@ -4,17 +4,26 @@
 
 package org.chromium.chrome.browser.offlinepages;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.offlinepages.SavePageResult;
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -23,8 +32,15 @@
 import java.util.concurrent.TimeUnit;
 
 /** Unit tests for offline page request handling. */
-@CommandLineFlags.Add("enable-features=OfflineBookmarks")
-public class OfflinePageRequestTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"enable-features=OfflineBookmarks",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OfflinePageRequestTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PAGE = "/chrome/test/data/android/test.html";
     private static final String ABOUT_PAGE = "/chrome/test/data/android/about.html";
     private static final int TIMEOUT_MS = 5000;
@@ -33,13 +49,9 @@
 
     private OfflinePageBridge mOfflinePageBridge;
 
-    public OfflinePageRequestTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         final Semaphore semaphore = new Semaphore(0);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -64,38 +76,29 @@
                 }
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testLoadOfflinePageOnDisconnectedNetwork() throws Exception {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
         String testUrl = testServer.getURL(TEST_PAGE);
         String aboutUrl = testServer.getURL(ABOUT_PAGE);
 
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // Load and save an offline page.
         savePage(testUrl);
-        assertFalse(isErrorPage(tab));
-        assertFalse(isOfflinePage(tab));
+        Assert.assertFalse(isErrorPage(tab));
+        Assert.assertFalse(isOfflinePage(tab));
 
         // Load another page.
-        loadUrl(aboutUrl);
-        assertFalse(isErrorPage(tab));
-        assertFalse(isOfflinePage(tab));
+        mActivityTestRule.loadUrl(aboutUrl);
+        Assert.assertFalse(isErrorPage(tab));
+        Assert.assertFalse(isOfflinePage(tab));
 
         // Stop the server and also disconnect the network.
         testServer.stopAndDestroyServer();
@@ -107,25 +110,26 @@
         });
 
         // Load the page that has an offline copy. The offline page should be shown.
-        loadUrl(testUrl);
-        assertFalse(isErrorPage(tab));
-        assertTrue(isOfflinePage(tab));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertFalse(isErrorPage(tab));
+        Assert.assertTrue(isOfflinePage(tab));
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testLoadOfflinePageWithFragmentOnDisconnectedNetwork() throws Exception {
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         String testUrl = testServer.getURL(TEST_PAGE);
         String testUrlWithFragment = testUrl + "#ref";
 
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // Load and save an offline page for the url with a fragment.
         savePage(testUrlWithFragment);
-        assertFalse(isErrorPage(tab));
-        assertFalse(isOfflinePage(tab));
+        Assert.assertFalse(isErrorPage(tab));
+        Assert.assertFalse(isOfflinePage(tab));
 
         // Stop the server and also disconnect the network.
         testServer.stopAndDestroyServer();
@@ -137,31 +141,32 @@
         });
 
         // Load the URL without the fragment. The offline page should be shown.
-        loadUrl(testUrl);
-        assertFalse(isErrorPage(tab));
-        assertTrue(isOfflinePage(tab));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertFalse(isErrorPage(tab));
+        Assert.assertTrue(isOfflinePage(tab));
     }
 
     private void savePage(String url) throws InterruptedException {
-        loadUrl(url);
+        mActivityTestRule.loadUrl(url);
 
         final Semaphore semaphore = new Semaphore(0);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mOfflinePageBridge.savePage(getActivity().getActivityTab().getWebContents(),
+                mOfflinePageBridge.savePage(
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         CLIENT_ID, new SavePageCallback() {
                             @Override
                             public void onSavePageDone(
                                     int savePageResult, String url, long offlineId) {
-                                assertEquals(
+                                Assert.assertEquals(
                                         "Save failed.", SavePageResult.SUCCESS, savePageResult);
                                 semaphore.release();
                             }
                         });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
     private boolean isOfflinePage(final Tab tab) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
index 0a9240f5..80d4450 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
@@ -10,6 +10,13 @@
 import android.text.TextUtils;
 import android.util.LongSparseArray;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
@@ -18,10 +25,12 @@
 import org.chromium.base.test.util.Manual;
 import org.chromium.base.test.util.TimeoutScale;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.offlinepages.evaluation.OfflinePageEvaluationBridge;
 import org.chromium.chrome.browser.offlinepages.evaluation.OfflinePageEvaluationBridge.OfflinePageEvaluationObserver;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.offlinepages.BackgroundSavePageResult;
 
 import java.io.BufferedReader;
@@ -33,7 +42,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
@@ -47,12 +55,19 @@
  * record metrics (failure rate, time elapsed etc.) by writing metrics to a file on external
  * storage. This will always use prerenderer.
  */
-@CommandLineFlags.Add({"disable-features=BackgroundLoader"})
-public class OfflinePageSavePageLaterEvaluationTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"disable-features=BackgroundLoader",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OfflinePageSavePageLaterEvaluationTest {
     /**
      * Class which is used to calculate time difference.
      */
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     static class TimeDelta {
         public void setStartTime(Long startTime) {
             mStartTime = startTime;
@@ -103,19 +118,15 @@
 
     private LongSparseArray<RequestMetadata> mRequestMetadata;
 
-    public OfflinePageSavePageLaterEvaluationTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         mRequestMetadata = new LongSparseArray<RequestMetadata>();
         mCount = 0;
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         NotificationManager notificationManager =
                 (NotificationManager) ContextUtils.getApplicationContext().getSystemService(
                         Context.NOTIFICATION_SERVICE);
@@ -146,12 +157,6 @@
                 "Timed out when clearing remaining requests!");
         mBridge.closeLog();
         mBridge.destroy();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
     }
 
     /**
@@ -212,7 +217,7 @@
     private void checkTrue(boolean condition, String message) {
         if (!condition) {
             log(TAG, message);
-            fail();
+            Assert.fail();
         }
     }
 
@@ -232,7 +237,7 @@
                 mBridge = new OfflinePageEvaluationBridge(
                         profile, useTestingScheduler, useBackgroundLoader);
                 if (mBridge == null) {
-                    fail("OfflinePageEvaluationBridge initialization failed!");
+                    Assert.fail("OfflinePageEvaluationBridge initialization failed!");
                     return;
                 }
                 if (mBridge.isOfflinePageModelLoaded()) {
@@ -332,7 +337,7 @@
 
     private void processUrls(List<String> urls) throws InterruptedException, IOException {
         if (mBridge == null) {
-            fail("Test initialization error, aborting. No results would be written.");
+            Assert.fail("Test initialization error, aborting. No results would be written.");
             return;
         }
         int count = 0;
@@ -369,7 +374,7 @@
             }
         } catch (FileNotFoundException e) {
             Log.e(TAG, e.getMessage(), e);
-            fail(String.format("URL file %s is not found.", inputFilePath));
+            Assert.fail(String.format("URL file %s is not found.", inputFilePath));
         }
     }
 
@@ -497,11 +502,11 @@
                     Boolean.parseBoolean(properties.getProperty("UseBackgroundLoader"));
         } catch (FileNotFoundException e) {
             Log.e(TAG, e.getMessage(), e);
-            fail(String.format(
+            Assert.fail(String.format(
                     "Config file %s is not found, aborting the test.", CONFIG_FILE_PATH));
         } catch (NumberFormatException e) {
             Log.e(TAG, e.getMessage(), e);
-            fail("Error parsing config file, aborting test.");
+            Assert.fail("Error parsing config file, aborting test.");
         } finally {
             if (inputStream != null) {
                 inputStream.close();
@@ -518,10 +523,10 @@
      * immediate processing also works on svelte devices. This flag will *not* affect normal
      * devices.
      */
+    @Test
     @Manual
     @TimeoutScale(4)
-    @CommandLineFlags
-            .Add({"enable-features=OfflinePagesSvelteConcurrentLoading"})
+    @CommandLineFlags.Add({"enable-features=OfflinePagesSvelteConcurrentLoading"})
     @CommandLineFlags.Remove({"disable-features=OfflinePagesSvelteConcurrentLoading"})
     public void testFailureRate() throws IOException, InterruptedException {
         parseConfigFile();
@@ -535,12 +540,12 @@
      * immediate processing also works on svelte devices. This flag will *not* affect normal
      * devices.
      */
+    @Test
     @Manual
     @TimeoutScale(4)
-    @CommandLineFlags
-            .Add({"enable-features=BackgroundLoader,OfflinePagesSvelteConcurrentLoading"})
-    @CommandLineFlags
-            .Remove({"disable-features=BackgroundLoader,OfflinePagesSvelteConcurrentLoading"})
+    @CommandLineFlags.Add({"enable-features=BackgroundLoaderOfflinePagesSvelteConcurrentLoading"})
+    @CommandLineFlags.Remove({
+            "disable-features=BackgroundLoaderOfflinePagesSvelteConcurrentLoading"})
     public void testBackgroundLoaderFailureRate() throws IOException, InterruptedException {
         testFailureRate();
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
index 307e7e9..fa4c93ea 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
@@ -5,19 +5,29 @@
 package org.chromium.chrome.browser.offlinepages;
 
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.Callback;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.SavePageCallback;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.offlinepages.SavePageResult;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -32,8 +42,15 @@
 import java.util.concurrent.TimeUnit;
 
 /** Unit tests for {@link OfflinePageUtils}. */
-@CommandLineFlags.Add({"enable-features=OfflineBookmarks", "enable-features=OfflinePagesSharing"})
-public class OfflinePageUtilsTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({"enable-features=OfflineBookmarks", "enable-features=OfflinePagesSharing",
+        ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OfflinePageUtilsTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PAGE = "/chrome/test/data/android/about.html";
     private static final int TIMEOUT_MS = 5000;
     private static final ClientId BOOKMARK_ID =
@@ -42,13 +59,9 @@
     private OfflinePageBridge mOfflinePageBridge;
     private EmbeddedTestServer mTestServer;
 
-    public OfflinePageUtilsTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         final Semaphore semaphore = new Semaphore(0);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -74,15 +87,15 @@
                 }
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
@@ -132,11 +145,7 @@
         }
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testShowOfflineSnackbarIfNecessary() throws Exception {
@@ -158,19 +167,22 @@
             }
         });
         String testUrl = mTestServer.getURL(TEST_PAGE);
-        loadUrl(testUrl);
+        mActivityTestRule.loadUrl(testUrl);
 
-        int tabId = getActivity().getActivityTab().getId();
+        int tabId = mActivityTestRule.getActivity().getActivityTab().getId();
 
         // Act.  This needs to be called from the UI thread.
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                OfflinePageTabObserver offlineObserver =
-                        new OfflinePageTabObserver(getActivity().getTabModelSelector(),
-                                getActivity().getSnackbarManager(), mockSnackbarController);
-                OfflinePageTabObserver.setObserverForTesting(getActivity(), offlineObserver);
-                OfflinePageUtils.showOfflineSnackbarIfNecessary(getActivity().getActivityTab());
+                OfflinePageTabObserver offlineObserver = new OfflinePageTabObserver(
+                        mActivityTestRule.getActivity().getTabModelSelector(),
+                        mActivityTestRule.getActivity().getSnackbarManager(),
+                        mockSnackbarController);
+                OfflinePageTabObserver.setObserverForTesting(
+                        mActivityTestRule.getActivity(), offlineObserver);
+                OfflinePageUtils.showOfflineSnackbarIfNecessary(
+                        mActivityTestRule.getActivity().getActivityTab());
 
                 // Pretend that we went online, this should cause the snackbar to show.
                 // This call will set the isConnected call to return true.
@@ -185,13 +197,13 @@
         mockSnackbarController.waitForSnackbarControllerToFinish();
 
         // Assert snackbar was shown.
-        assertEquals(tabId, mockSnackbarController.getLastTabId());
-        assertTrue(mockSnackbarController.getDismissed());
+        Assert.assertEquals(tabId, mockSnackbarController.getLastTabId());
+        Assert.assertTrue(mockSnackbarController.getDismissed());
     }
 
     private void loadPageAndSave() throws Exception {
         String testUrl = mTestServer.getURL(TEST_PAGE);
-        loadUrl(testUrl);
+        mActivityTestRule.loadUrl(testUrl);
         savePage(SavePageResult.SUCCESS, testUrl);
     }
 
@@ -203,21 +215,22 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mOfflinePageBridge.savePage(getActivity().getActivityTab().getWebContents(),
+                mOfflinePageBridge.savePage(
+                        mActivityTestRule.getActivity().getActivityTab().getWebContents(),
                         BOOKMARK_ID, new SavePageCallback() {
                             @Override
                             public void onSavePageDone(
                                     int savePageResult, String url, long offlineId) {
-                                assertEquals(
+                                Assert.assertEquals(
                                         "Requested and returned URLs differ.", expectedUrl, url);
-                                assertEquals(
+                                Assert.assertEquals(
                                         "Save result incorrect.", expectedResult, savePageResult);
                                 semaphore.release();
                             }
                         });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
     private List<OfflinePageItem> getAllPages() throws InterruptedException {
@@ -235,10 +248,11 @@
                 });
             }
         });
-        assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         return result;
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testCopyToShareableLocation() throws Exception {
@@ -255,21 +269,23 @@
         // Clear the directory before copying the file.
         clearSharedOfflineFilesAndWait();
 
-        File offlineSharingDir =
-                OfflinePageUtils.getDirectoryForOfflineSharing(getActivity().getBaseContext());
-        assertTrue("Offline sharing directory should exist.", offlineSharingDir != null);
+        File offlineSharingDir = OfflinePageUtils.getDirectoryForOfflineSharing(
+                mActivityTestRule.getActivity().getBaseContext());
+        Assert.assertTrue("Offline sharing directory should exist.", offlineSharingDir != null);
 
         File offlinePageShareable = new File(offlineSharingDir, offlinePageOriginal.getName());
-        assertFalse("File with the same name should not exist.", offlinePageShareable.exists());
+        Assert.assertFalse(
+                "File with the same name should not exist.", offlinePageShareable.exists());
 
-        assertTrue("Should be able to copy file to shareable location.",
+        Assert.assertTrue("Should be able to copy file to shareable location.",
                 OfflinePageUtils.copyToShareableLocation(
                         offlinePageOriginal, offlinePageShareable));
 
-        assertEquals("File copy result incorrect", offlinePageOriginal.length(),
+        Assert.assertEquals("File copy result incorrect", offlinePageOriginal.length(),
                 offlinePageShareable.length());
     }
 
+    @Test
     @SmallTest
     public void testDeleteSharedOfflineFiles() throws Exception {
         // Save an offline page.
@@ -282,15 +298,15 @@
 
         File offlinePageOriginal = new File(offlinePageFilePath);
 
-        final Context context = getActivity().getBaseContext();
+        final Context context = mActivityTestRule.getActivity().getBaseContext();
         final File offlineSharingDir = OfflinePageUtils.getDirectoryForOfflineSharing(context);
 
-        assertTrue("Should be able to create subdirectory in shareable directory.",
+        Assert.assertTrue("Should be able to create subdirectory in shareable directory.",
                 (offlineSharingDir != null));
 
         File offlinePageShareable = new File(offlineSharingDir, offlinePageOriginal.getName());
         if (!offlinePageShareable.exists()) {
-            assertTrue("Should be able to copy file to shareable location.",
+            Assert.assertTrue("Should be able to copy file to shareable location.",
                     OfflinePageUtils.copyToShareableLocation(
                             offlinePageOriginal, offlinePageShareable));
         }
@@ -300,7 +316,7 @@
     }
 
     private void clearSharedOfflineFilesAndWait() {
-        final Context context = getActivity().getBaseContext();
+        final Context context = mActivityTestRule.getActivity().getBaseContext();
         final File offlineSharingDir = OfflinePageUtils.getDirectoryForOfflineSharing(context);
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
index 1d003270..27d459e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java
@@ -8,6 +8,7 @@
 
 import android.os.Build;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v4.view.ViewCompat;
@@ -20,7 +21,14 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.EnormousTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.FlakyTest;
@@ -29,9 +37,11 @@
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.omnibox.AutocompleteController.OnSuggestionsReceivedListener;
 import org.chromium.chrome.browser.omnibox.LocationBarLayout.OmniboxSuggestionsList;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils.SuggestionsResult;
@@ -41,6 +51,7 @@
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.KeyUtils;
+import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content.browser.test.util.UiUtils;
 import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -56,15 +67,17 @@
 /**
  * Tests of the Omnibox.
  */
-public class OmniboxTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public OmniboxTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class OmniboxTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private void clearUrlBar() {
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
-        assertNotNull(urlBar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
+        Assert.assertNotNull(urlBar);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -78,40 +91,48 @@
      * Sanity check of Omnibox.  The problem in http://b/5021723 would
      * cause this to fail (hang or crash).
      */
+    @Test
     @EnormousTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testSimpleUse() throws InterruptedException {
-        typeInOmnibox("aaaaaaa", false);
+        mActivityTestRule.typeInOmnibox("aaaaaaa", false);
 
         final LocationBarLayout locationBar =
-                (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
+                (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar);
         OmniboxTestUtils.waitForOmniboxSuggestions(locationBar);
 
-        ChromeTabUtils.waitForTabPageLoadStart(getActivity().getActivityTab(), new Runnable() {
-            @Override
-            public void run() {
-                final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
-                KeyUtils.singleKeyEventView(getInstrumentation(), urlBar, KeyEvent.KEYCODE_ENTER);
-            }
-        }, ScalableTimeout.scaleTimeout(20));
+        ChromeTabUtils.waitForTabPageLoadStart(
+                mActivityTestRule.getActivity().getActivityTab(), new Runnable() {
+                    @Override
+                    public void run() {
+                        final UrlBar urlBar =
+                                (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
+                        KeyUtils.singleKeyEventView(InstrumentationRegistry.getInstrumentation(),
+                                urlBar, KeyEvent.KEYCODE_ENTER);
+                    }
+                }, ScalableTimeout.scaleTimeout(20));
     }
 
     /**
      * Test for checking whether soft input model switches with focus.
      */
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testFocusChangingSoftInputMode() throws InterruptedException {
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
 
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
         CriteriaHelper.pollInstrumentationThread(Criteria.equals(
                 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN, new Callable<Integer>() {
                     @Override
                     public Integer call() {
-                        return getActivity().getWindow().getAttributes().softInputMode;
+                        return mActivityTestRule.getActivity()
+                                .getWindow()
+                                .getAttributes()
+                                .softInputMode;
                     }
                 }));
 
@@ -120,7 +141,10 @@
                 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE, new Callable<Integer>() {
                     @Override
                     public Integer call() {
-                        return getActivity().getWindow().getAttributes().softInputMode;
+                        return mActivityTestRule.getActivity()
+                                .getWindow()
+                                .getAttributes()
+                                .softInputMode;
                     }
                 }));
     }
@@ -128,13 +152,14 @@
     /**
      * Tests that focusing a url bar starts a zero suggest request.
      */
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testRequestZeroSuggestOnFocus() throws Exception {
         final LocationBarLayout locationBar =
-                (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+                (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable(){
             @Override
@@ -152,7 +177,7 @@
                 locationBar.setAutocompleteController(controller);
             }
         });
-        assertEquals("Should not have any zero suggest requests yet", 0,
+        Assert.assertEquals("Should not have any zero suggest requests yet", 0,
                 controller.numZeroSuggestRequests());
 
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
@@ -164,23 +189,24 @@
             }
         }));
 
-        getInstrumentation().waitForIdleSync();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        assertFalse(controller.isStartAutocompleteCalled());
+        Assert.assertFalse(controller.isStartAutocompleteCalled());
     }
 
     /**
      * Tests that focusing a url bar starts a zero suggest request.
      */
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testRequestZeroSuggestAfterDelete() throws InterruptedException {
         final LocationBarLayout locationBar =
-                (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
-        final ImageButton deleteButton = (ImageButton) getActivity().findViewById(
-                R.id.delete_button);
+                (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
+        final ImageButton deleteButton =
+                (ImageButton) mActivityTestRule.getActivity().findViewById(R.id.delete_button);
 
         final OnSuggestionsReceivedListener emptySuggestionListener =
                 new OnSuggestionsReceivedListener() {
@@ -214,9 +240,9 @@
         // The click view below ends up clicking on the menu button underneath the delete button
         // for some time after the delete button appears. Wait for UI to settle down before
         // clicking.
-        UiUtils.settleDownUI(getInstrumentation());
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
-        singleClickView(deleteButton);
+        TouchCommon.singleClickView(deleteButton);
 
         CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable<Integer>() {
             @Override
@@ -226,12 +252,13 @@
         }));
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     public void testRequestZeroSuggestTypeAndBackspace() throws InterruptedException {
         final LocationBarLayout locationBar =
-                (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+                (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
 
         final OnSuggestionsReceivedListener emptySuggestionListener =
                 new OnSuggestionsReceivedListener() {
@@ -256,8 +283,9 @@
             }
         });
 
-        assertEquals("No calls to zero suggest yet", 0, controller.numZeroSuggestRequests());
-        KeyUtils.singleKeyEventView(getInstrumentation(), urlBar, KeyEvent.KEYCODE_DEL);
+        Assert.assertEquals("No calls to zero suggest yet", 0, controller.numZeroSuggestRequests());
+        KeyUtils.singleKeyEventView(
+                InstrumentationRegistry.getInstrumentation(), urlBar, KeyEvent.KEYCODE_DEL);
         CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable<Integer>() {
             @Override
             public Integer call() {
@@ -268,19 +296,21 @@
 
     // Sanity check that no text is displayed in the omnibox when on the NTP page and that the hint
     // text is correct.
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testDefaultText() throws InterruptedException {
-        startMainActivityFromLauncher();
+        mActivityTestRule.startMainActivityFromLauncher();
 
-        final UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+        final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
 
         // Omnibox on NTP shows the hint text.
-        assertNotNull(urlBar);
-        assertEquals("Location bar has text.", "", urlBar.getText().toString());
-        assertEquals("Location bar has incorrect hint.",
-                getActivity().getResources().getString(R.string.search_or_type_url),
+        Assert.assertNotNull(urlBar);
+        Assert.assertEquals("Location bar has text.", "", urlBar.getText().toString());
+        Assert.assertEquals("Location bar has incorrect hint.",
+                mActivityTestRule.getActivity().getResources().getString(
+                        R.string.search_or_type_url),
                 urlBar.getHint().toString());
 
         // Type something in the omnibox.
@@ -293,30 +323,32 @@
                 urlBar.setText("G");
             }
         });
-        assertEquals("Location bar should have text.", "G", urlBar.getText().toString());
+        Assert.assertEquals("Location bar should have text.", "G", urlBar.getText().toString());
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox", "Main"})
     @RetryOnFailure
-    public void testAutoCompleteAndCorrectionLandscape() throws ExecutionException,
-            InterruptedException {
+    public void testAutoCompleteAndCorrectionLandscape()
+            throws ExecutionException, InterruptedException {
         // Default orientation for tablets is landscape. Default for phones is portrait.
         int requestedOrientation = 1;
-        if (DeviceFormFactor.isTablet(getActivity())) {
+        if (DeviceFormFactor.isTablet(mActivityTestRule.getActivity())) {
             requestedOrientation = 0;
         }
         doTestAutoCompleteAndCorrectionForOrientation(requestedOrientation);
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox", "Main"})
     @RetryOnFailure
-    public void testAutoCompleteAndCorrectionPortrait() throws ExecutionException,
-            InterruptedException {
+    public void testAutoCompleteAndCorrectionPortrait()
+            throws ExecutionException, InterruptedException {
         // Default orientation for tablets is landscape. Default for phones is portrait.
         int requestedOrientation = 0;
-        if (DeviceFormFactor.isTablet(getActivity())) {
+        if (DeviceFormFactor.isTablet(mActivityTestRule.getActivity())) {
             requestedOrientation = 1;
         }
         doTestAutoCompleteAndCorrectionForOrientation(requestedOrientation);
@@ -324,8 +356,8 @@
 
     private void doTestAutoCompleteAndCorrectionForOrientation(
             int orientation) throws ExecutionException, InterruptedException {
-        getActivity().setRequestedOrientation(orientation);
-        UiUtils.settleDownUI(getInstrumentation());
+        mActivityTestRule.getActivity().setRequestedOrientation(orientation);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
 
         Map<String, List<SuggestionsResult>> suggestionsMap = buildSuggestionMap(
                 new TestSuggestionResultsBuilder()
@@ -361,6 +393,7 @@
         checkAutocompleteText(suggestionsMap, "mispellled", "mispellled", 10, 10);
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
@@ -390,6 +423,7 @@
         checkAutocompleteText(suggestionsMap, "test", "testing", 4, 7);
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
@@ -419,6 +453,7 @@
         checkAutocompleteText(suggestionsMap, "test", "testing for the win", 4, 19);
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
@@ -453,8 +488,8 @@
             final String textToType, final String expectedAutocompleteText,
             final int expectedAutocompleteStart, final int expectedAutocompleteEnd)
             throws InterruptedException, ExecutionException {
-
-        final TextView urlBarView = (TextView) getActivity().findViewById(R.id.url_bar);
+        final TextView urlBarView =
+                (TextView) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -464,7 +499,8 @@
         });
 
         final LocationBarLayout locationBar =
-                ((LocationBarLayout) getActivity().findViewById(R.id.location_bar));
+                ((LocationBarLayout) mActivityTestRule.getActivity().findViewById(
+                        R.id.location_bar));
 
         final Object suggestionsProcessedSignal = new Object();
         final AtomicInteger suggestionsLeft = new AtomicInteger(
@@ -480,7 +516,7 @@
                     if (remaining == 0) {
                         suggestionsProcessedSignal.notifyAll();
                     } else if (remaining < 0) {
-                        fail("Unexpected suggestions received");
+                        Assert.fail("Unexpected suggestions received");
                     }
                 }
             }
@@ -495,7 +531,8 @@
             }
         });
 
-        KeyUtils.typeTextIntoView(getInstrumentation(), urlBarView, textToType);
+        KeyUtils.typeTextIntoView(
+                InstrumentationRegistry.getInstrumentation(), urlBarView, textToType);
 
         synchronized (suggestionsProcessedSignal) {
             long endTime = SystemClock.uptimeMillis() + 3000;
@@ -512,10 +549,10 @@
                 return urlBarView.getText();
             }
         });
-        assertEquals("URL Bar text not autocompleted as expected.",
-                expectedAutocompleteText, urlText.toString());
-        assertEquals(expectedAutocompleteStart, Selection.getSelectionStart(urlText));
-        assertEquals(expectedAutocompleteEnd, Selection.getSelectionEnd(urlText));
+        Assert.assertEquals("URL Bar text not autocompleted as expected.", expectedAutocompleteText,
+                urlText.toString());
+        Assert.assertEquals(expectedAutocompleteStart, Selection.getSelectionStart(urlText));
+        Assert.assertEquals(expectedAutocompleteEnd, Selection.getSelectionEnd(urlText));
     }
 
     /**
@@ -534,18 +571,18 @@
 
         for (int i = 0; i < 2; ++i) {
             boolean instantOn = (i == 1);
-            setNetworkPredictionEnabled(instantOn);
+            mActivityTestRule.setNetworkPredictionEnabled(instantOn);
 
             for (int j = 0; j < 10; ++j) {
                 long before = System.currentTimeMillis();
-                typeInOmnibox(text, true);
+                mActivityTestRule.typeInOmnibox(text, true);
                 if (instantOn) {
                     instantAverage += System.currentTimeMillis() - before;
                 } else {
                     noInstantAverage += System.currentTimeMillis() - before;
                 }
                 clearUrlBar();
-                getInstrumentation().waitForIdleSync();
+                InstrumentationRegistry.getInstrumentation().waitForIdleSync();
             }
         }
         instantAverage /= 10;
@@ -560,41 +597,44 @@
      * Test to verify security-icon "lock or globe" on visiting http and secured Urls.
      * @EnormousTest
      */
+    @Test
     @FlakyTest(message = "crbug.com/414353")
     public void testSecurityIcon() throws InterruptedException {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
         try {
             final String testUrl = testServer.getURL("/chrome/test/data/android/omnibox/one.html");
             final String securedExternalUrl = "https://www.google.com";
 
-            ImageView navigationButton = (ImageView)
-                    getActivity().findViewById(R.id.navigation_button);
-            ImageButton securityButton = (ImageButton)
-                    getActivity().findViewById(R.id.security_button);
+            ImageView navigationButton = (ImageView) mActivityTestRule.getActivity().findViewById(
+                    R.id.navigation_button);
+            ImageButton securityButton = (ImageButton) mActivityTestRule.getActivity().findViewById(
+                    R.id.security_button);
 
-            loadUrl(testUrl);
+            mActivityTestRule.loadUrl(testUrl);
             final LocationBarLayout locationBar =
-                    (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
+                    (LocationBarLayout) mActivityTestRule.getActivity().findViewById(
+                            R.id.location_bar);
             boolean securityIcon = locationBar.isSecurityButtonShown();
-            assertFalse("Omnibox should not have a Security icon", securityIcon);
-            assertEquals("navigation_button with wrong resource-id",
-                    R.id.navigation_button, navigationButton.getId());
-            assertTrue(navigationButton.isShown());
-            assertFalse(securityButton.isShown());
+            Assert.assertFalse("Omnibox should not have a Security icon", securityIcon);
+            Assert.assertEquals("navigation_button with wrong resource-id", R.id.navigation_button,
+                    navigationButton.getId());
+            Assert.assertTrue(navigationButton.isShown());
+            Assert.assertFalse(securityButton.isShown());
 
-            loadUrl(securedExternalUrl);
+            mActivityTestRule.loadUrl(securedExternalUrl);
             securityIcon = locationBar.isSecurityButtonShown();
-            assertTrue("Omnibox should have a Security icon", securityIcon);
-            assertEquals("security_button with wrong resource-id",
-                    R.id.security_button, securityButton.getId());
-            assertTrue(securityButton.isShown());
-            assertFalse(navigationButton.isShown());
+            Assert.assertTrue("Omnibox should have a Security icon", securityIcon);
+            Assert.assertEquals("security_button with wrong resource-id", R.id.security_button,
+                    securityButton.getId());
+            Assert.assertTrue(securityButton.isShown());
+            Assert.assertFalse(navigationButton.isShown());
         } finally {
             testServer.stopAndDestroyServer();
         }
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testSplitPathFromUrlDisplayText() {
@@ -649,16 +689,18 @@
 
     private void verifySplitUrlAndPath(
             String expectedPrePath, String expectedPostPath, Pair<String, String> actualValues) {
-        assertEquals(expectedPrePath, actualValues.first);
-        assertEquals(expectedPostPath, actualValues.second);
+        Assert.assertEquals(expectedPrePath, actualValues.first);
+        Assert.assertEquals(expectedPostPath, actualValues.second);
     }
 
+    @Test
     @MediumTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     @MinAndroidSdkLevel(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public void testSuggestionDirectionSwitching() throws InterruptedException {
-        final TextView urlBarView = (TextView) getActivity().findViewById(R.id.url_bar);
+        final TextView urlBarView =
+                (TextView) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -668,7 +710,8 @@
         });
 
         final LocationBarLayout locationBar =
-                ((LocationBarLayout) getActivity().findViewById(R.id.location_bar));
+                ((LocationBarLayout) mActivityTestRule.getActivity().findViewById(
+                        R.id.location_bar));
 
         Map<String, List<SuggestionsResult>> suggestionsMap = buildSuggestionMap(
                 new TestSuggestionResultsBuilder()
@@ -729,35 +772,31 @@
         verifyOmniboxSuggestionAlignment(locationBar, 3, View.LAYOUT_DIRECTION_LTR);
     }
 
-    private void verifyOmniboxSuggestionAlignment(
-            final LocationBarLayout locationBar, final int expectedSuggestionCount,
-            final int expectedLayoutDirection) throws InterruptedException {
+    private void verifyOmniboxSuggestionAlignment(final LocationBarLayout locationBar,
+            final int expectedSuggestionCount, final int expectedLayoutDirection) {
         OmniboxTestUtils.waitForOmniboxSuggestions(locationBar, expectedSuggestionCount);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 OmniboxSuggestionsList suggestionsList = locationBar.getSuggestionList();
-                assertEquals(expectedSuggestionCount, suggestionsList.getChildCount());
+                Assert.assertEquals(expectedSuggestionCount, suggestionsList.getChildCount());
                 for (int i = 0; i < suggestionsList.getChildCount(); i++) {
                     SuggestionView suggestionView = (SuggestionView) suggestionsList.getChildAt(i);
-                    assertEquals(
-                            String.format(
-                                    Locale.getDefault(),
-                                    "Incorrect layout direction of suggestion at index %d",
-                                    i),
-                            expectedLayoutDirection,
-                            ViewCompat.getLayoutDirection(suggestionView));
+                    Assert.assertEquals(
+                            String.format(Locale.getDefault(),
+                                    "Incorrect layout direction of suggestion at index %d", i),
+                            expectedLayoutDirection, ViewCompat.getLayoutDirection(suggestionView));
                 }
             }
         });
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        if (getName().equals("testsplitPathFromUrlDisplayText")
-                || getName().equals("testDefaultText")) {
+    @Before
+    public void setUp() throws InterruptedException {
+        if (mActivityTestRule.getName().equals("testsplitPathFromUrlDisplayText")
+                || mActivityTestRule.getName().equals("testDefaultText")) {
             return;
         }
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
index e068f3e..477a15ec 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
@@ -11,21 +11,31 @@
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.view.KeyEvent;
 import android.view.inputmethod.BaseInputConnection;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils.StubAutocompleteController;
 import org.chromium.content.browser.test.util.Criteria;
@@ -41,20 +51,23 @@
 /**
  * Tests for the URL bar UI component.
  */
-public class UrlBarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class UrlBarTest {
     // 9000+ chars of goodness
+
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String HUGE_URL =
             "data:text/plain,H"
             + new String(new char[9000]).replace('\0', 'u')
             + "ge!";
 
-    public UrlBarTest() {
-        super(ChromeActivity.class);
-    }
-
     private UrlBar getUrlBar() {
-        return (UrlBar) getActivity().findViewById(R.id.url_bar);
+        return (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
     }
 
     private void stubLocationBarAutocomplete() {
@@ -66,7 +79,8 @@
             @Override
             public void run() {
                 LocationBarLayout locationBar =
-                        (LocationBarLayout) getActivity().findViewById(R.id.location_bar);
+                        (LocationBarLayout) mActivityTestRule.getActivity().findViewById(
+                                R.id.location_bar);
                 locationBar.cancelPendingAutocompleteStart();
                 locationBar.setAutocompleteController(controller);
             }
@@ -124,9 +138,9 @@
             }
         });
 
-        assertEquals(text, state.textWithoutAutocomplete);
-        assertEquals(text, state.textWithAutocomplete);
-        assertFalse(state.hasAutocomplete);
+        Assert.assertEquals(text, state.textWithoutAutocomplete);
+        Assert.assertEquals(text, state.textWithAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
     }
 
     private void setAutocomplete(final UrlBar urlBar,
@@ -138,9 +152,9 @@
             }
         });
 
-        assertEquals(userText, state.textWithoutAutocomplete);
-        assertEquals(userText + autocompleteText, state.textWithAutocomplete);
-        assertTrue(state.hasAutocomplete);
+        Assert.assertEquals(userText, state.textWithoutAutocomplete);
+        Assert.assertEquals(userText + autocompleteText, state.textWithAutocomplete);
+        Assert.assertTrue(state.hasAutocomplete);
     }
 
     private AutocompleteState setSelection(
@@ -153,21 +167,23 @@
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testRefocusing() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         UrlBar urlBar = getUrlBar();
-        assertFalse(OmniboxTestUtils.doesUrlBarHaveFocus(urlBar));
+        Assert.assertFalse(OmniboxTestUtils.doesUrlBarHaveFocus(urlBar));
         OmniboxTestUtils.checkUrlBarRefocus(urlBar, 5);
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testAutocompleteUpdatedOnSetText() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
         final UrlBar urlBar = getUrlBar();
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
@@ -186,9 +202,9 @@
                 urlBar.setText(urlBar.getText().replace(1, 2, "a"));
             }
         });
-        assertFalse(state.hasAutocomplete);
-        assertEquals("tasting is fun", state.textWithoutAutocomplete);
-        assertEquals("tasting is fun", state.textWithAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
+        Assert.assertEquals("tasting is fun", state.textWithoutAutocomplete);
+        Assert.assertEquals("tasting is fun", state.textWithAutocomplete);
 
         // Replace part of the autocomplete text and see that the autocomplete is cleared.
         setTextAndVerifyNoAutocomplete(urlBar, "test");
@@ -199,9 +215,9 @@
                 urlBar.setText(urlBar.getText().replace(8, 10, "no"));
             }
         });
-        assertFalse(state.hasAutocomplete);
-        assertEquals("testing no fun", state.textWithoutAutocomplete);
-        assertEquals("testing no fun", state.textWithAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
+        Assert.assertEquals("testing no fun", state.textWithoutAutocomplete);
+        Assert.assertEquals("testing no fun", state.textWithAutocomplete);
     }
 
     private void verifySelectionState(
@@ -233,25 +249,25 @@
         setAutocompleteController(controller);
 
         AutocompleteState state = setSelection(urlBar, selectionStart, selectionEnd);
-        assertEquals("Has autocomplete", expectedHasAutocomplete, state.hasAutocomplete);
-        assertEquals("Text w/o Autocomplete",
-                expectedTextWithoutAutocomplete, state.textWithoutAutocomplete);
-        assertEquals("Text w/ Autocomplete",
-                expectedTextWithAutocomplete, state.textWithAutocomplete);
+        Assert.assertEquals("Has autocomplete", expectedHasAutocomplete, state.hasAutocomplete);
+        Assert.assertEquals("Text w/o Autocomplete", expectedTextWithoutAutocomplete,
+                state.textWithoutAutocomplete);
+        Assert.assertEquals(
+                "Text w/ Autocomplete", expectedTextWithAutocomplete, state.textWithAutocomplete);
 
         autocompleteHelper.waitForCallback(0);
-        assertEquals("Prevent inline autocomplete",
-                expectedPreventInline, didPreventInlineAutocomplete.get());
-        assertEquals("Requested autocomplete text",
-                expectedRequestedAutocompleteText, requestedAutocompleteText.get());
+        Assert.assertEquals("Prevent inline autocomplete", expectedPreventInline,
+                didPreventInlineAutocomplete.get());
+        Assert.assertEquals("Requested autocomplete text", expectedRequestedAutocompleteText,
+                requestedAutocompleteText.get());
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
-    public void testAutocompleteUpdatedOnSelection()
-            throws InterruptedException, TimeoutException {
-        startMainActivityOnBlankPage();
+    public void testAutocompleteUpdatedOnSelection() throws InterruptedException, TimeoutException {
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
 
         final UrlBar urlBar = getUrlBar();
@@ -298,9 +314,9 @@
         setTextAndVerifyNoAutocomplete(urlBar, "test");
         setAutocomplete(urlBar, "test", "ing is fun");
         AutocompleteState state = setSelection(urlBar, 4, 14);
-        assertEquals("Has autocomplete", true, state.hasAutocomplete);
-        assertEquals("Text w/o Autocomplete", "test", state.textWithoutAutocomplete);
-        assertEquals("Text w/ Autocomplete", "testing is fun", state.textWithAutocomplete);
+        Assert.assertEquals("Has autocomplete", true, state.hasAutocomplete);
+        Assert.assertEquals("Text w/o Autocomplete", "test", state.textWithoutAutocomplete);
+        Assert.assertEquals("Text w/ Autocomplete", "testing is fun", state.textWithAutocomplete);
     }
 
     /**
@@ -312,12 +328,13 @@
      *
      * If we assume deletes happen any time the text gets shorter, then this would be prevented.
      */
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testAutocompleteAllowedWhenReplacingText()
             throws InterruptedException, TimeoutException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         final String textToBeEntered = "c";
 
@@ -349,20 +366,21 @@
             }
         });
         autocompleteHelper.waitForCallback(0);
-        assertFalse("Inline autocomplete incorrectly prevented.",
-                didPreventInlineAutocomplete.get());
+        Assert.assertFalse(
+                "Inline autocomplete incorrectly prevented.", didPreventInlineAutocomplete.get());
     }
 
     /**
      * Ensure that if the user deletes just the inlined autocomplete text that the suggestions are
      * regenerated.
      */
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testSuggestionsUpdatedWhenDeletingInlineAutocomplete()
             throws InterruptedException, TimeoutException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         stubLocationBarAutocomplete();
         final UrlBar urlBar = getUrlBar();
@@ -386,7 +404,8 @@
         };
         setAutocompleteController(controller);
 
-        KeyUtils.singleKeyEventView(getInstrumentation(), urlBar, KeyEvent.KEYCODE_DEL);
+        KeyUtils.singleKeyEventView(
+                InstrumentationRegistry.getInstrumentation(), urlBar, KeyEvent.KEYCODE_DEL);
 
         CriteriaHelper.pollUiThread(Criteria.equals("test", new Callable<String>() {
             @Override
@@ -396,15 +415,16 @@
         }));
 
         autocompleteHelper.waitForCallback(0);
-        assertTrue("Inline autocomplete incorrectly allowed after delete.",
+        Assert.assertTrue("Inline autocomplete incorrectly allowed after delete.",
                 didPreventInlineAutocomplete.get());
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testSelectionChangesIgnoredInBatchMode() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
         final UrlBar urlBar = getUrlBar();
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
@@ -420,9 +440,9 @@
         });
         // Ensure the autocomplete is not modified if in batch mode.
         AutocompleteState state = setSelection(urlBar, 1, 1);
-        assertTrue(state.hasAutocomplete);
-        assertEquals("test", state.textWithoutAutocomplete);
-        assertEquals("testing is fun", state.textWithAutocomplete);
+        Assert.assertTrue(state.hasAutocomplete);
+        Assert.assertEquals("test", state.textWithoutAutocomplete);
+        Assert.assertEquals("testing is fun", state.textWithAutocomplete);
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -433,16 +453,17 @@
         // Ensure that after batch mode has ended that the autocomplete is cleared due to the
         // invalid selection range.
         state = getAutocompleteState(urlBar, null);
-        assertFalse(state.hasAutocomplete);
-        assertEquals("test", state.textWithoutAutocomplete);
-        assertEquals("test", state.textWithAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
+        Assert.assertEquals("test", state.textWithoutAutocomplete);
+        Assert.assertEquals("test", state.textWithAutocomplete);
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testBatchModeChangesTriggerCorrectSuggestions() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         final AtomicReference<String> requestedAutocompleteText = new AtomicReference<String>();
         final StubAutocompleteController controller = new StubAutocompleteController() {
@@ -488,11 +509,12 @@
         }));
     }
 
+    @Test
     @SmallTest
     @Feature("Omnibox")
     @RetryOnFailure
     public void testAutocompleteCorrectlyPerservedOnBatchMode() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
 
         final UrlBar urlBar = getUrlBar();
@@ -512,9 +534,9 @@
                 urlBar.endBatchEdit();
             }
         });
-        assertTrue(state.hasAutocomplete);
-        assertEquals("google.com", state.textWithAutocomplete);
-        assertEquals("go", state.textWithoutAutocomplete);
+        Assert.assertTrue(state.hasAutocomplete);
+        Assert.assertEquals("google.com", state.textWithAutocomplete);
+        Assert.assertEquals("go", state.textWithoutAutocomplete);
 
         // Invalid case (cursor not at the end of the text)
         setAutocomplete(urlBar, "g", "oogle.com");
@@ -529,7 +551,7 @@
                 urlBar.endBatchEdit();
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         // Invalid case (next character did not match previous autocomplete)
         setAutocomplete(urlBar, "g", "oogle.com");
@@ -544,7 +566,7 @@
                 urlBar.endBatchEdit();
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         // Invalid case (multiple characters entered instead of 1)
         setAutocomplete(urlBar, "g", "oogle.com");
@@ -559,14 +581,15 @@
                 urlBar.endBatchEdit();
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
     }
 
+    @Test
     @SmallTest
     @Feature("Omnibox")
     @RetryOnFailure
     public void testAutocompleteSpanClearedOnNonMatchingCommitText() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
 
         stubLocationBarAutocomplete();
 
@@ -595,11 +618,12 @@
         }));
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testAutocompleteUpdatedOnDefocus() throws InterruptedException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
         final UrlBar urlBar = getUrlBar();
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
@@ -609,15 +633,16 @@
         setAutocomplete(urlBar, "test", "ing is fun");
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, false);
         AutocompleteState state = getAutocompleteState(urlBar, null);
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testAutocompleteClearedOnComposition()
             throws InterruptedException, ExecutionException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
         final UrlBar urlBar = getUrlBar();
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
@@ -626,36 +651,37 @@
         setTextAndVerifyNoAutocomplete(urlBar, "test");
         setAutocomplete(urlBar, "test", "ing is fun");
 
-        assertNotNull(urlBar.mInputConnection);
+        Assert.assertNotNull(urlBar.mInputConnection);
         AutocompleteState state = getAutocompleteState(urlBar, new Runnable() {
             @Override
             public void run() {
                 urlBar.mInputConnection.setComposingText("ing compose", 4);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         Editable urlText = getUrlBarText(urlBar);
-        assertEquals("testing compose", urlText.toString());
+        Assert.assertEquals("testing compose", urlText.toString());
         // TODO(tedchoc): Investigate why this fails on x86.
         //assertEquals(4, BaseInputConnection.getComposingSpanStart(urlText));
         //assertEquals(15, BaseInputConnection.getComposingSpanEnd(urlText));
     }
 
+    @Test
     @SmallTest
     @Feature("Omnibox")
     @RetryOnFailure
     @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE}) // crbug.com/635714
     public void testDelayedCompositionCorrectedWithAutocomplete()
             throws InterruptedException, ExecutionException {
-        startMainActivityOnBlankPage();
+        mActivityTestRule.startMainActivityOnBlankPage();
         stubLocationBarAutocomplete();
 
         final UrlBar urlBar = getUrlBar();
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
         OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true);
 
-        assertNotNull(urlBar.mInputConnection);
+        Assert.assertNotNull(urlBar.mInputConnection);
 
         // Test with a single autocomplete
 
@@ -669,12 +695,12 @@
                 urlBar.mInputConnection.setComposingText("f", 1);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         Editable urlText = getUrlBarText(urlBar);
-        assertEquals("chrome://f", urlText.toString());
-        assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
-        assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
+        Assert.assertEquals("chrome://f", urlText.toString());
+        Assert.assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
+        Assert.assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
 
         // Test with > 1 characters in composition.
 
@@ -688,12 +714,12 @@
                 urlBar.mInputConnection.setComposingText("fl", 1);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         urlText = getUrlBarText(urlBar);
-        assertEquals("chrome://fl", urlText.toString());
-        assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
-        assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
+        Assert.assertEquals("chrome://fl", urlText.toString());
+        Assert.assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 9);
+        Assert.assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
 
         // Test with non-matching composition.  Should just append to the URL text.
 
@@ -707,12 +733,12 @@
                 urlBar.mInputConnection.setComposingText("g", 1);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         urlText = getUrlBarText(urlBar);
-        assertEquals("chrome://fg", urlText.toString());
-        assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
-        assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
+        Assert.assertEquals("chrome://fg", urlText.toString());
+        Assert.assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
+        Assert.assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 11);
 
         // Test with composition text that matches the entire text w/o autocomplete.
 
@@ -726,12 +752,12 @@
                 urlBar.mInputConnection.setComposingText("chrome://f", 1);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         urlText = getUrlBarText(urlBar);
-        assertEquals("chrome://f", urlText.toString());
-        assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 0);
-        assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
+        Assert.assertEquals("chrome://f", urlText.toString());
+        Assert.assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 0);
+        Assert.assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 10);
 
         // Test with composition text longer than the URL text.  Shouldn't crash and should
         // just append text.
@@ -746,49 +772,52 @@
                 urlBar.mInputConnection.setComposingText("blahblahblah", 1);
             }
         });
-        assertFalse(state.hasAutocomplete);
+        Assert.assertFalse(state.hasAutocomplete);
 
         urlText = getUrlBarText(urlBar);
-        assertEquals("chrome://fblahblahblah", urlText.toString());
-        assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
-        assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 22);
+        Assert.assertEquals("chrome://fblahblahblah", urlText.toString());
+        Assert.assertEquals(BaseInputConnection.getComposingSpanStart(urlText), 10);
+        Assert.assertEquals(BaseInputConnection.getComposingSpanEnd(urlText), 22);
     }
 
     /**
      * Test to verify the omnibox can take focus during startup before native libraries have
      * loaded.
      */
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
-    public void testFocusingOnStartup() throws InterruptedException {
+    public void testFocusingOnStartup() {
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        prepareUrlIntent(intent, "about:blank");
-        startActivityCompletely(intent);
+        mActivityTestRule.prepareUrlIntent(intent, "about:blank");
+        mActivityTestRule.startActivityCompletely(intent);
 
         UrlBar urlBar = getUrlBar();
-        assertNotNull(urlBar);
+        Assert.assertNotNull(urlBar);
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
         OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true);
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testCopyHuge() throws InterruptedException {
-        startMainActivityWithURL(HUGE_URL);
+        mActivityTestRule.startMainActivityWithURL(HUGE_URL);
         OmniboxTestUtils.toggleUrlBarFocus(getUrlBar(), true);
-        assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.copy));
+        Assert.assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.copy));
     }
 
+    @Test
     @SmallTest
     @Feature({"Omnibox"})
     @RetryOnFailure
     public void testCutHuge() throws InterruptedException {
-        startMainActivityWithURL(HUGE_URL);
+        mActivityTestRule.startMainActivityWithURL(HUGE_URL);
         OmniboxTestUtils.toggleUrlBarFocus(getUrlBar(), true);
-        assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.cut));
+        Assert.assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.cut));
     }
 
     /**
@@ -797,26 +826,27 @@
      * or android.R.id.cut.
      */
     private String copyUrlToClipboard(final int action) {
-        ClipboardManager clipboardManager = (ClipboardManager)
-                getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
-
-        clipboardManager.setPrimaryClip(ClipData.newPlainText(null, ""));
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<String>() {
             @Override
-            public void run() {
-                assertTrue(getUrlBar().onTextContextMenuItem(action));
+            public String call() {
+                ClipboardManager clipboardManager =
+                        (ClipboardManager) mActivityTestRule.getActivity().getSystemService(
+                                Context.CLIPBOARD_SERVICE);
+
+                clipboardManager.setPrimaryClip(ClipData.newPlainText(null, ""));
+
+                Assert.assertTrue(getUrlBar().onTextContextMenuItem(action));
+                ClipData clip = clipboardManager.getPrimaryClip();
+                CharSequence text = (clip != null && clip.getItemCount() != 0)
+                        ? clip.getItemAt(0).getText()
+                        : null;
+                return text != null ? text.toString() : null;
             }
         });
-
-        ClipData clip = clipboardManager.getPrimaryClip();
-        CharSequence text = (clip != null && clip.getItemCount() != 0)
-                ? clip.getItemAt(0).getText() : null;
-        return text != null ? text.toString() : null;
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
+    @Before
+    public void setUp() throws InterruptedException {
         // Each test will start the activity.
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java
index c73f4ea4..7b15db7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java
@@ -6,42 +6,56 @@
 
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.policy.CombinedPolicyProvider;
 import org.chromium.policy.PolicyProvider;
 
 /** Instrumentation tests for {@link CombinedPolicyProvider} */
-public class CombinedPolicyProviderTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class CombinedPolicyProviderTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String DATA_URI = "data:text/plain;charset=utf-8;base64,dGVzdA==";
 
-    public CombinedPolicyProviderTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * Checks that the {@link CombinedPolicyProvider} properly notifies tabs when incognito mode is
      * disabled.
      */
-    @Feature({"Policy" })
+    @Test
+    @Feature({"Policy"})
     @SmallTest
     @RetryOnFailure
     public void testTerminateIncognitoSon() throws InterruptedException {
         final boolean incognitoMode = true;
 
-        TabModel incognitoTabModel = getActivity().getTabModelSelector().getModel(incognitoMode);
-        loadUrlInNewTab(DATA_URI, incognitoMode);
-        loadUrlInNewTab(DATA_URI, incognitoMode);
-        assertEquals(2, incognitoTabModel.getCount());
+        TabModel incognitoTabModel =
+                mActivityTestRule.getActivity().getTabModelSelector().getModel(incognitoMode);
+        mActivityTestRule.loadUrlInNewTab(DATA_URI, incognitoMode);
+        mActivityTestRule.loadUrlInNewTab(DATA_URI, incognitoMode);
+        Assert.assertEquals(2, incognitoTabModel.getCount());
 
         final CombinedPolicyProvider provider = CombinedPolicyProvider.get();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -56,6 +70,6 @@
             }
         });
 
-        assertEquals(0, incognitoTabModel.getCount());
+        Assert.assertEquals(0, incognitoTabModel.getCount());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesBasicTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesBasicTest.java
index 7265b49..3c851794 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesBasicTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesBasicTest.java
@@ -11,13 +11,23 @@
 import android.content.Context;
 import android.preference.CheckBoxPreference;
 import android.preference.PreferenceScreen;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.sync.ProfileSyncService;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.components.sync.AndroidSyncSettings;
 import org.chromium.components.sync.test.util.MockSyncContentResolverDelegate;
@@ -25,26 +35,27 @@
 /**
  * Integration tests for ClearBrowsingDataPreferencesBasic.
  */
-public class ClearBrowsingDataPreferencesBasicTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ClearBrowsingDataPreferencesBasicTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String GOOGLE_ACCOUNT = "Google Account";
     private static final String OTHER_ACTIVITY = "other activity";
     private static final String SIGNED_IN_DEVICES = "signed-in devices";
 
-    public ClearBrowsingDataPreferencesBasicTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws InterruptedException {
+        SigninTestUtil.setUpAuthForTest(InstrumentationRegistry.getInstrumentation());
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        SigninTestUtil.setUpAuthForTest(getInstrumentation());
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         ProfileSyncService.overrideForTests(null);
-        super.tearDown();
     }
 
     private static class StubProfileSyncService extends ProfileSyncService {
@@ -54,7 +65,7 @@
     }
 
     private void setSyncable(boolean syncable) {
-        Context context = getInstrumentation().getTargetContext();
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         MockSyncContentResolverDelegate delegate = new MockSyncContentResolverDelegate();
         delegate.setMasterSyncAutomatically(syncable);
         AndroidSyncSettings.overrideForTests(context, delegate);
@@ -80,12 +91,13 @@
     /**
      * Tests that for users who are not signed in, only the general information is shown.
      */
+    @Test
     @SmallTest
     public void testCheckBoxTextNonsigned() throws Exception {
         SigninTestUtil.resetSigninState();
 
-        final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferencesBasic.class.getName());
+        final Preferences preferences = mActivityTestRule.startPreferences(
+                ClearBrowsingDataPreferencesBasic.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -110,13 +122,14 @@
      * Tests that for users who are signed in but don't have sync activated, only information about
      * your "google account" which will stay signed in and "other activity" is shown.
      */
+    @Test
     @SmallTest
     public void testCheckBoxTextSigned() throws Exception {
         SigninTestUtil.addAndSignInTestAccount();
         setSyncable(false);
 
-        final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferencesBasic.class.getName());
+        final Preferences preferences = mActivityTestRule.startPreferences(
+                ClearBrowsingDataPreferencesBasic.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -141,13 +154,14 @@
      * Tests that users who are signed in, and have sync enabled see information about their
      * "google account", "other activity" and history on "signed in devices".
      */
+    @Test
     @SmallTest
     public void testCheckBoxTextSignedAndSynced() throws Exception {
         SigninTestUtil.addAndSignInTestAccount();
         setSyncable(true);
 
-        final Preferences preferences =
-                startPreferences(ClearBrowsingDataPreferencesBasic.class.getName());
+        final Preferences preferences = mActivityTestRule.startPreferences(
+                ClearBrowsingDataPreferencesBasic.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivityTest.java
index c8dd3a62..59bea96 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivityTest.java
@@ -7,18 +7,28 @@
 import android.annotation.TargetApi;
 import android.content.Intent;
 import android.os.Build;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v7.app.AlertDialog;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -26,42 +36,39 @@
 /**
  * Tests for ManageSpaceActivity.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @TargetApi(Build.VERSION_CODES.KITKAT)
-@CommandLineFlags.Add({"enable-site-engagement"})
 @MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT)
-public class ManageSpaceActivityTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({"enable-site-engagement", ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ManageSpaceActivityTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private EmbeddedTestServer mTestServer;
 
-    public ManageSpaceActivityTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        if (getName().equals("testClearUnimporantWithoutChromeStart")) {
-            return;
+    @Before
+    public void setUp() throws Exception {
+        if (!mActivityTestRule.getName().equals("testClearUnimporantWithoutChromeStart")) {
+            mActivityTestRule.startMainActivityOnBlankPage();
         }
-        startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTestServer.stopAndDestroyServer();
     }
 
     private ManageSpaceActivity startManageSpaceActivity() {
-        Intent intent =
-                new Intent(getInstrumentation().getTargetContext(), ManageSpaceActivity.class);
+        Intent intent = new Intent(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                ManageSpaceActivity.class);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        return (ManageSpaceActivity) getInstrumentation().startActivitySync(intent);
+        return (ManageSpaceActivity) InstrumentationRegistry.getInstrumentation().startActivitySync(
+                intent);
     }
 
     public void waitForClearButtonEnabled(final ManageSpaceActivity activity) {
@@ -100,12 +107,14 @@
         };
     }
 
+    @Test
     @SmallTest
     @RetryOnFailure
     public void testLaunchActivity() {
         startManageSpaceActivity();
     }
 
+    @Test
     @MediumTest
     @RetryOnFailure
     @Feature({"SiteEngagement"})
@@ -114,11 +123,13 @@
                 mTestServer.getURL("/chrome/test/data/android/storage_persistance.html");
         final String serverOrigin = mTestServer.getURL("/");
 
-        loadUrl(cookiesUrl + "#clear");
-        assertEquals("false", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
-        runJavaScriptCodeInCurrentTab("setStorage()");
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
-        loadUrl("about:blank");
+        mActivityTestRule.loadUrl(cookiesUrl + "#clear");
+        Assert.assertEquals(
+                "false", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setStorage()");
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl("about:blank");
 
         // Now we set the origin as important, and check that we don't clear it.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -139,10 +150,12 @@
         waitForClearButtonEnabled(manageSpaceActivity);
         manageSpaceActivity.finish();
 
-        loadUrl(cookiesUrl);
-        assertEquals("true", runJavaScriptCodeInCurrentTab("hasAllStorage()"));
+        mActivityTestRule.loadUrl(cookiesUrl);
+        Assert.assertEquals(
+                "true", mActivityTestRule.runJavaScriptCodeInCurrentTab("hasAllStorage()"));
     }
 
+    @Test
     @MediumTest
     @Feature({"SiteEngagement"})
     public void testClearUnimporantWithoutChromeStart() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
index 84b32d3..6d9b5484 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
@@ -6,13 +6,22 @@
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
 import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
 import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
@@ -20,7 +29,8 @@
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil;
 import org.chromium.content.common.ContentSwitches;
@@ -31,30 +41,27 @@
 /**
  * Tests for everything under Settings > Site Settings.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class SiteSettingsPreferencesTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SiteSettingsPreferencesTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private EmbeddedTestServer mTestServer;
 
-    public SiteSettingsPreferencesTest() {
-        super(ChromeActivity.class);
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
     }
 
     private void setAllowLocation(final boolean enabled) {
@@ -72,8 +79,8 @@
                                 SingleCategoryPreferences.READ_WRITE_TOGGLE_KEY);
 
                 websitePreferences.onPreferenceChange(location, enabled);
-                assertEquals("Location should be " + (enabled ? "allowed" : "blocked"), enabled,
-                        LocationSettings.getInstance().areAllLocationSettingsEnabled());
+                Assert.assertEquals("Location should be " + (enabled ? "allowed" : "blocked"),
+                        enabled, LocationSettings.getInstance().areAllLocationSettingsEnabled());
                 preferenceActivity.finish();
             }
         });
@@ -84,8 +91,9 @@
                 new Callable<InfoBarTestAnimationListener>() {
                     @Override
                     public InfoBarTestAnimationListener call() throws Exception {
-                        InfoBarContainer container =
-                                getActivity().getActivityTab().getInfoBarContainer();
+                        InfoBarContainer container = mActivityTestRule.getActivity()
+                                                             .getActivityTab()
+                                                             .getInfoBarContainer();
                         InfoBarTestAnimationListener listener =  new InfoBarTestAnimationListener();
                         container.addAnimationListener(listener);
                         return listener;
@@ -96,6 +104,7 @@
     /**
      * Sets Allow Location Enabled to be true and make sure it is set correctly.
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testSetAllowLocationEnabled() throws Exception {
@@ -103,54 +112,58 @@
         InfoBarTestAnimationListener listener = setInfoBarAnimationListener();
 
         // Launch a page that uses geolocation and make sure an infobar shows up.
-        loadUrl(mTestServer.getURL(
-                "/chrome/test/data/geolocation/geolocation_on_load.html"));
+        mActivityTestRule.loadUrl(
+                mTestServer.getURL("/chrome/test/data/geolocation/geolocation_on_load.html"));
         listener.addInfoBarAnimationFinished("InfoBar not added.");
 
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
     }
 
     /**
      * Sets Allow Location Enabled to be false and make sure it is set correctly.
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testSetAllowLocationNotEnabled() throws Exception {
         setAllowLocation(false);
 
         // Launch a page that uses geolocation.
-        loadUrl(mTestServer.getURL(
-                "/chrome/test/data/geolocation/geolocation_on_load.html"));
+        mActivityTestRule.loadUrl(
+                mTestServer.getURL("/chrome/test/data/geolocation/geolocation_on_load.html"));
 
         // No infobars are expected.
-        assertTrue(getInfoBars().isEmpty());
+        Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty());
     }
 
     private Preferences startSiteSettingsMenu(String category) {
         Bundle fragmentArgs = new Bundle();
         fragmentArgs.putString(SingleCategoryPreferences.EXTRA_CATEGORY, category);
         Intent intent = PreferencesLauncher.createIntentForSettingsPage(
-                getInstrumentation().getTargetContext(), SiteSettingsPreferences.class.getName());
+                InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                SiteSettingsPreferences.class.getName());
         intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
-        return (Preferences) getInstrumentation().startActivitySync(intent);
+        return (Preferences) InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
     }
 
     private Preferences startSiteSettingsCategory(String category) {
         Bundle fragmentArgs = new Bundle();
         fragmentArgs.putString(SingleCategoryPreferences.EXTRA_CATEGORY, category);
         Intent intent = PreferencesLauncher.createIntentForSettingsPage(
-                getInstrumentation().getTargetContext(), SingleCategoryPreferences.class.getName());
+                InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                SingleCategoryPreferences.class.getName());
         intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
-        return (Preferences) getInstrumentation().startActivitySync(intent);
+        return (Preferences) InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
     }
 
     private Preferences startSingleWebsitePreferences(Website site) {
         Bundle fragmentArgs = new Bundle();
         fragmentArgs.putSerializable(SingleWebsitePreferences.EXTRA_SITE, site);
         Intent intent = PreferencesLauncher.createIntentForSettingsPage(
-                getInstrumentation().getTargetContext(), SingleWebsitePreferences.class.getName());
+                InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                SingleWebsitePreferences.class.getName());
         intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
-        return (Preferences) getInstrumentation().startActivitySync(intent);
+        return (Preferences) InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
     }
 
     private void setCookiesEnabled(final Preferences preferenceActivity, final boolean enabled) {
@@ -166,11 +179,11 @@
                         (ChromeBaseCheckBoxPreference) websitePreferences.findPreference(
                                 SingleCategoryPreferences.THIRD_PARTY_COOKIES_TOGGLE_KEY);
 
-                assertEquals("Third-party cookie toggle should be "
-                        + (doesAcceptCookies() ? "enabled" : " disabled"),
+                Assert.assertEquals("Third-party cookie toggle should be "
+                                + (doesAcceptCookies() ? "enabled" : " disabled"),
                         doesAcceptCookies(), thirdPartyCookies.isEnabled());
                 websitePreferences.onPreferenceChange(cookies, enabled);
-                assertEquals("Cookies should be " + (enabled ? "allowed" : "blocked"),
+                Assert.assertEquals("Cookies should be " + (enabled ? "allowed" : "blocked"),
                         doesAcceptCookies(), enabled);
             }
 
@@ -192,7 +205,8 @@
                                 SingleCategoryPreferences.THIRD_PARTY_COOKIES_TOGGLE_KEY);
 
                 websitePreferences.onPreferenceChange(thirdPartyCookies, enabled);
-                assertEquals("Third-party cookies should be " + (enabled ? "allowed" : "blocked"),
+                Assert.assertEquals(
+                        "Third-party cookies should be " + (enabled ? "allowed" : "blocked"),
                         !PrefServiceBridge.getInstance().isBlockThirdPartyCookiesEnabled(),
                         enabled);
             }
@@ -212,8 +226,8 @@
                         websitePreferences.findPreference(
                                 SingleCategoryPreferences.READ_WRITE_TOGGLE_KEY);
                 websitePreferences.onPreferenceChange(popups, enabled);
-                assertEquals("Popups should be " + (enabled ? "allowed" : "blocked"), enabled,
-                        PrefServiceBridge.getInstance().popupsEnabled());
+                Assert.assertEquals("Popups should be " + (enabled ? "allowed" : "blocked"),
+                        enabled, PrefServiceBridge.getInstance().popupsEnabled());
             }
         });
         preferenceActivity.finish();
@@ -232,7 +246,7 @@
                         websitePreferences.findPreference(
                                 SingleCategoryPreferences.READ_WRITE_TOGGLE_KEY);
                 websitePreferences.onPreferenceChange(toggle, enabled);
-                assertEquals("Camera should be " + (enabled ? "allowed" : "blocked"),
+                Assert.assertEquals("Camera should be " + (enabled ? "allowed" : "blocked"),
                         enabled, PrefServiceBridge.getInstance().isCameraEnabled());
             }
         });
@@ -252,8 +266,8 @@
                         websitePreferences.findPreference(
                                 SingleCategoryPreferences.READ_WRITE_TOGGLE_KEY);
                 websitePreferences.onPreferenceChange(toggle, enabled);
-                assertEquals("Mic should be " + (enabled ? "allowed" : "blocked"),
-                        enabled, PrefServiceBridge.getInstance().isMicEnabled());
+                Assert.assertEquals("Mic should be " + (enabled ? "allowed" : "blocked"), enabled,
+                        PrefServiceBridge.getInstance().isMicEnabled());
             }
         });
         preferenceActivity.finish();
@@ -282,6 +296,7 @@
      * Tests that disabling cookies turns off the third-party cookie toggle.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testThirdPartyCookieToggleGetsDisabled() throws Exception {
@@ -297,6 +312,7 @@
     /**
      * Allows cookies to be set and ensures that they are.
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testCookiesNotBlocked() throws Exception {
@@ -308,19 +324,22 @@
         final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html");
 
         // Load the page and clear any set cookies.
-        loadUrl(url + "#clear");
-        assertEquals("\"\"", runJavaScriptCodeInCurrentTab("getCookie()"));
-        runJavaScriptCodeInCurrentTab("setCookie()");
-        assertEquals("\"Foo=Bar\"", runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.loadUrl(url + "#clear");
+        Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()");
+        Assert.assertEquals(
+                "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
 
         // Load the page again and ensure the cookie still is set.
-        loadUrl(url);
-        assertEquals("\"Foo=Bar\"", runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.loadUrl(url);
+        Assert.assertEquals(
+                "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
     }
 
     /**
      * Blocks cookies from being set and ensures that no cookies can be set.
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testCookiesBlocked() throws Exception {
@@ -332,52 +351,55 @@
         final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html");
 
         // Load the page and clear any set cookies.
-        loadUrl(url + "#clear");
-        assertEquals("\"\"", runJavaScriptCodeInCurrentTab("getCookie()"));
-        runJavaScriptCodeInCurrentTab("setCookie()");
-        assertEquals("\"\"", runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.loadUrl(url + "#clear");
+        Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()");
+        Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
 
         // Load the page again and ensure the cookie remains unset.
-        loadUrl(url);
-        assertEquals("\"\"", runJavaScriptCodeInCurrentTab("getCookie()"));
+        mActivityTestRule.loadUrl(url);
+        Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()"));
     }
 
     /**
      * Sets Allow Popups Enabled to be false and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testPopupsBlocked() throws Exception {
         setEnablePopups(false);
 
         // Test that the popup doesn't open.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html"));
+        mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html"));
 
-        getInstrumentation().waitForIdleSync();
-        assertEquals(1, getTabCount());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        Assert.assertEquals(1, getTabCount());
     }
 
     /**
      * Sets Allow Popups Enabled to be true and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testPopupsNotBlocked() throws Exception {
         setEnablePopups(true);
 
         // Test that a popup opens.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html"));
-        getInstrumentation().waitForIdleSync();
+        mActivityTestRule.loadUrl(mTestServer.getURL("/chrome/test/data/android/popup.html"));
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        assertEquals(2, getTabCount());
+        Assert.assertEquals(2, getTabCount());
     }
 
     /**
      * Test that showing the Site Settings menu doesn't crash (crbug.com/610576).
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testSiteSettingsMenu() throws Exception {
@@ -389,6 +411,7 @@
      * Test the Media Menu.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testMediaMenu() throws Exception {
@@ -402,15 +425,15 @@
 
                 SiteSettingsPreference allSites  = (SiteSettingsPreference)
                         siteSettings.findPreference(SiteSettingsPreferences.ALL_SITES_KEY);
-                assertEquals(null, allSites);
+                Assert.assertEquals(null, allSites);
 
                 SiteSettingsPreference autoplay  = (SiteSettingsPreference)
                         siteSettings.findPreference(SiteSettingsPreferences.AUTOPLAY_KEY);
-                assertFalse(autoplay == null);
+                Assert.assertFalse(autoplay == null);
 
                 SiteSettingsPreference protectedContent = (SiteSettingsPreference)
                         siteSettings.findPreference(SiteSettingsPreferences.PROTECTED_CONTENT_KEY);
-                assertFalse(protectedContent == null);
+                Assert.assertFalse(protectedContent == null);
 
                 preferenceActivity.finish();
             }
@@ -421,6 +444,7 @@
      * Tests Reset Site not crashing on host names (issue 600232).
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testResetCrash600232() throws Exception {
@@ -443,6 +467,7 @@
      * Sets Allow Camera Enabled to be false and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@@ -450,17 +475,19 @@
         setEnableCamera(false);
 
         // Test that the camera permission doesn't get requested.
-        loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
-        runJavaScriptCodeInCurrentTab("getUserMediaAndStop({video: true, audio: false});");
+        mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(
+                "getUserMediaAndStop({video: true, audio: false});");
 
         // No infobars are expected.
-        assertTrue(getInfoBars().isEmpty());
+        Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty());
     }
 
     /**
      * Sets Allow Mic Enabled to be false and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@@ -468,17 +495,19 @@
         setEnableMic(false);
 
         // Test that the microphone permission doesn't get requested.
-        loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
-        runJavaScriptCodeInCurrentTab("getUserMediaAndStop({video: false, audio: true});");
+        mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(
+                "getUserMediaAndStop({video: false, audio: true});");
 
         // No infobars are expected.
-        assertTrue(getInfoBars().isEmpty());
+        Assert.assertTrue(mActivityTestRule.getInfoBars().isEmpty());
     }
 
     /**
      * Sets Allow Camera Enabled to be true and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@@ -488,17 +517,19 @@
         InfoBarTestAnimationListener listener = setInfoBarAnimationListener();
 
         // Launch a page that uses camera and make sure an infobar shows up.
-        loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
-        runJavaScriptCodeInCurrentTab("getUserMediaAndStop({video: true, audio: false});");
+        mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(
+                "getUserMediaAndStop({video: true, audio: false});");
 
         listener.addInfoBarAnimationFinished("InfoBar not added.");
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
     }
 
     /**
      * Sets Allow Mic Enabled to be true and make sure it is set correctly.
      * @throws Exception
      */
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     @CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@@ -508,11 +539,12 @@
         InfoBarTestAnimationListener listener = setInfoBarAnimationListener();
 
         // Launch a page that uses the microphone and make sure an infobar shows up.
-        loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
-        runJavaScriptCodeInCurrentTab("getUserMediaAndStop({video: false, audio: true});");
+        mActivityTestRule.loadUrl(mTestServer.getURL("/content/test/data/media/getusermedia.html"));
+        mActivityTestRule.runJavaScriptCodeInCurrentTab(
+                "getUserMediaAndStop({video: false, audio: true});");
 
         listener.addInfoBarAnimationFinished("InfoBar not added.");
-        assertEquals("Wrong infobar count", 1, getInfoBars().size());
+        Assert.assertEquals("Wrong infobar count", 1, mActivityTestRule.getInfoBars().size());
     }
 
     /**
@@ -524,18 +556,21 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                assertEquals("Background Sync should be " + (enabled ? "enabled" : "disabled"),
+                Assert.assertEquals(
+                        "Background Sync should be " + (enabled ? "enabled" : "disabled"),
                         PrefServiceBridge.getInstance().isBackgroundSyncAllowed(), enabled);
             }
         });
     }
 
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testAllowBackgroundSync() {
         doTestBackgroundSyncPermission(true);
     }
 
+    @Test
     @SmallTest
     @Feature({"Preferences"})
     public void testBlockBackgroundSync() {
@@ -546,7 +581,7 @@
         return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return getActivity().getTabModelSelector().getTotalTabCount();
+                return mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount();
             }
         });
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java
index 141a15a..d1b719ac 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java
@@ -12,8 +12,15 @@
 import android.print.PrintAttributes;
 import android.print.PrintDocumentAdapter;
 import android.print.PrintDocumentInfo;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
@@ -22,8 +29,10 @@
 import org.chromium.base.test.util.TestFileUtil;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.content.common.ContentSwitches;
 import org.chromium.printing.PrintDocumentAdapterWrapper;
@@ -43,8 +52,14 @@
  * TODO(cimamoglu): Add a test with multiple, stacked onLayout/onWrite calls.
  * TODO(cimamoglu): Add a test which emulates Chromium failing to generate a PDF.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class PrintingControllerTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class PrintingControllerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEMP_FILE_NAME = "temp_print";
     private static final String TEMP_FILE_EXTENSION = ".pdf";
@@ -54,12 +69,8 @@
     private static final String PDF_PREAMBLE = "%PDF-1";
     private static final long TEST_TIMEOUT = 20000L;
 
-    public PrintingControllerTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
+    @Before
+    public void setUp() throws InterruptedException {
         // Do nothing.
     }
 
@@ -92,14 +103,15 @@
      * controller: onStart, onLayout, onWrite, onFinish.  Each one is called once, and in this
      * order, in the UI thread.
      */
+    @Test
     @TargetApi(Build.VERSION_CODES.KITKAT)
     @LargeTest
     @Feature({"Printing"})
     public void testNormalPrintingFlow() throws Throwable {
         if (!ApiCompatibilityUtils.isPrintingSupported()) return;
 
-        startMainActivityWithURL(URL);
-        final Tab currentTab = getActivity().getActivityTab();
+        mActivityTestRule.startMainActivityWithURL(URL);
+        final Tab currentTab = mActivityTestRule.getActivity().getActivityTab();
 
         final PrintingControllerImpl printingController = createControllerOnUiThread();
 
@@ -108,7 +120,8 @@
         callStartOnUiThread(printingController);
 
         // Create a temporary file to save the PDF.
-        final File cacheDir = getInstrumentation().getTargetContext().getCacheDir();
+        final File cacheDir =
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getCacheDir();
         final File tempFile = File.createTempFile(TEMP_FILE_NAME, TEMP_FILE_EXTENSION, cacheDir);
         final ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(tempFile,
                 (ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE));
@@ -140,12 +153,12 @@
         try {
             // This blocks until the PDF is generated.
             result.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
-            assertTrue(tempFile.length() > 0);
+            Assert.assertTrue(tempFile.length() > 0);
             in = new FileInputStream(tempFile);
             byte[] b = new byte[PDF_PREAMBLE.length()];
             in.read(b);
             String preamble = new String(b);
-            assertEquals(PDF_PREAMBLE, preamble);
+            Assert.assertEquals(PDF_PREAMBLE, preamble);
         } finally {
             callFinishOnUiThread(printingController);
             if (in != null) in.close();
@@ -162,6 +175,7 @@
      * @SmallTest
      * @Feature({"Printing"})
      */
+    @Test
     @CommandLineFlags.Add(ContentSwitches.DISABLE_POPUP_BLOCKING)
     @DisabledTest(message = "crbug.com/532652")
     public void testPrintClosedWindow() throws Throwable {
@@ -173,15 +187,16 @@
                 + "  setTimeout(()=>{w.print(); document.title='completed'}, 0);"
                 + "}</script></body></html>";
 
-        startMainActivityWithURL("data:text/html;charset=utf-8," + html);
+        mActivityTestRule.startMainActivityWithURL("data:text/html;charset=utf-8," + html);
 
-        Tab mTab = getActivity().getActivityTab();
-        assertEquals("title does not match initial title", "printwindowclose", mTab.getTitle());
+        Tab mTab = mActivityTestRule.getActivity().getActivityTab();
+        Assert.assertEquals(
+                "title does not match initial title", "printwindowclose", mTab.getTitle());
 
         TabTitleObserver mOnTitleUpdatedHelper = new TabTitleObserver(mTab, "completed");
-        runJavaScriptCodeInCurrentTab("printClosedWindow();");
+        mActivityTestRule.runJavaScriptCodeInCurrentTab("printClosedWindow();");
         mOnTitleUpdatedHelper.waitForTitleUpdate(5);
-        assertEquals("JS did not finish running", "completed", mTab.getTitle());
+        Assert.assertEquals("JS did not finish running", "completed", mTab.getTitle());
     }
 
     private PrintingControllerImpl createControllerOnUiThread() {
@@ -196,11 +211,11 @@
                         }
                     });
 
-            runTestOnUiThread(task);
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(task);
             PrintingControllerImpl result = task.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
             return result;
         } catch (Throwable e) {
-            fail("Error on creating PrintingControllerImpl on the UI thread: " + e);
+            Assert.fail("Error on creating PrintingControllerImpl on the UI thread: " + e);
         }
         return null;
     }
@@ -216,27 +231,27 @@
                 }
             };
 
-            runTestOnUiThread(new Runnable() {
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
                 @Override
                 public void run() {
                     controller.startPrint(new TabPrinter(tab), mockPrintManagerDelegate);
                 }
             });
         } catch (Throwable e) {
-            fail("Error on calling startPrint of PrintingControllerImpl " + e);
+            Assert.fail("Error on calling startPrint of PrintingControllerImpl " + e);
         }
     }
 
     private void callStartOnUiThread(final PrintingControllerImpl controller) {
         try {
-            runTestOnUiThread(new Runnable() {
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
                 @Override
                 public void run() {
                     controller.onStart();
                 }
             });
         } catch (Throwable e) {
-            fail("Error on calling onStart of PrintingControllerImpl " + e);
+            Assert.fail("Error on calling onStart of PrintingControllerImpl " + e);
         }
     }
 
@@ -246,7 +261,7 @@
             final PrintAttributes newAttributes,
             final PrintDocumentAdapterWrapper.LayoutResultCallbackWrapper layoutResultCallback) {
         try {
-            runTestOnUiThread(new Runnable() {
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
                 @Override
                 public void run() {
                     controller.onLayout(
@@ -258,7 +273,7 @@
                 }
             });
         } catch (Throwable e) {
-            fail("Error on calling onLayout of PrintingControllerImpl " + e);
+            Assert.fail("Error on calling onLayout of PrintingControllerImpl " + e);
         }
     }
 
@@ -280,26 +295,26 @@
                                 // Result is ready, signal to continue.
                                 result.run();
                             } catch (IOException ex) {
-                                fail("Failed file operation: " + ex.toString());
+                                Assert.fail("Failed file operation: " + ex.toString());
                             }
                         }
                     }
             );
         } catch (Throwable e) {
-            fail("Error on calling onWriteInternal of PrintingControllerImpl " + e);
+            Assert.fail("Error on calling onWriteInternal of PrintingControllerImpl " + e);
         }
     }
 
     private void callFinishOnUiThread(final PrintingControllerImpl controller) {
         try {
-            runTestOnUiThread(new Runnable() {
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
                 @Override
                 public void run() {
                     controller.onFinish();
                 }
             });
         } catch (Throwable e) {
-            fail("Error on calling onFinish of PrintingControllerImpl " + e);
+            Assert.fail("Error on calling onFinish of PrintingControllerImpl " + e);
         }
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java
index b73c777..9ebae05 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java
@@ -4,35 +4,45 @@
 
 package org.chromium.chrome.browser.services;
 
-import android.test.UiThreadTest;
+import android.support.test.annotation.UiThreadTest;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /**
  * Google Services Manager tests
  */
-public class GoogleServicesManagerIntegrationTest
-        extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public GoogleServicesManagerIntegrationTest() {
-        super(ChromeActivity.class);
-    }
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class GoogleServicesManagerIntegrationTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     /**
      * Test changing the state of auto login
      * @SmallTest
      * @Feature({"Sync", "Main"})
      */
+    @Test
     @DisabledTest(message = "crbug.com/413289")
     @UiThreadTest
     public void testSetAutologinState() {
         // TODO(acleung): Add back some sort of test for the GSM.
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/shape_detection/ShapeDetectionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/shape_detection/ShapeDetectionTest.java
index 3f64ccb..98836948 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/shape_detection/ShapeDetectionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/shape_detection/ShapeDetectionTest.java
@@ -5,15 +5,25 @@
 package org.chromium.chrome.browser.shape_detection;
 
 import android.os.StrictMode;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -26,34 +36,39 @@
  *  is based on android.media.FaceDetector and doesn't need special treatment,
  *  hence is tested via content_browsertests.
  */
-public class ShapeDetectionTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ShapeDetectionTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String BARCODE_TEST_EXPECTED_TAB_TITLE = "https://chromium.org";
     private static final String TEXT_TEST_EXPECTED_TAB_TITLE =
             "The quick brown fox jumped over the lazy dog. Helvetica Neue 36.";
     private StrictMode.ThreadPolicy mOldPolicy;
 
-    public ShapeDetectionTest() {
-        super(ChromeActivity.class);
-    }
-
     /**
      * Verifies that QR codes are detected correctly.
      */
+    @Test
     @CommandLineFlags.Add("enable-experimental-web-platform-features")
     @Feature({"ShapeDetection"})
     @LargeTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
     public void testBarcodeDetection() throws InterruptedException, TimeoutException {
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         try {
-            Tab tab = getActivity().getActivityTab();
+            Tab tab = mActivityTestRule.getActivity().getActivityTab();
             TabTitleObserver titleObserver =
                     new TabTitleObserver(tab, BARCODE_TEST_EXPECTED_TAB_TITLE);
-            loadUrl(testServer.getURL("/chrome/test/data/android/barcode_detection.html"));
+            mActivityTestRule.loadUrl(
+                    testServer.getURL("/chrome/test/data/android/barcode_detection.html"));
             titleObserver.waitForTitleUpdate(10);
 
-            assertEquals(BARCODE_TEST_EXPECTED_TAB_TITLE, tab.getTitle());
+            Assert.assertEquals(BARCODE_TEST_EXPECTED_TAB_TITLE, tab.getTitle());
         } finally {
             testServer.stopAndDestroyServer();
         }
@@ -62,21 +77,23 @@
     /**
      * Verifies that text is detected correctly.
      */
+    @Test
     @CommandLineFlags.Add("enable-experimental-web-platform-features")
     @Feature({"ShapeDetection"})
     @LargeTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
     public void testTextDetection() throws InterruptedException, TimeoutException {
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         try {
-            Tab tab = getActivity().getActivityTab();
+            Tab tab = mActivityTestRule.getActivity().getActivityTab();
             TabTitleObserver titleObserver =
                     new TabTitleObserver(tab, TEXT_TEST_EXPECTED_TAB_TITLE);
-            loadUrl(testServer.getURL("/chrome/test/data/android/text_detection.html"));
+            mActivityTestRule.loadUrl(
+                    testServer.getURL("/chrome/test/data/android/text_detection.html"));
             titleObserver.waitForTitleUpdate(10);
 
-            assertEquals(TEXT_TEST_EXPECTED_TAB_TITLE, tab.getTitle());
+            Assert.assertEquals(TEXT_TEST_EXPECTED_TAB_TITLE, tab.getTitle());
         } finally {
             testServer.stopAndDestroyServer();
         }
@@ -85,9 +102,9 @@
     /**
      * We need to allow a looser policy due to the Google Play Services internals.
      */
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
@@ -96,19 +113,13 @@
         });
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 StrictMode.setThreadPolicy(mOldPolicy);
             }
         });
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java
index b69e51ce5..209bb2ea 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderTest.java
@@ -10,14 +10,25 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.childaccounts.ChildAccountService;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.signin.SigninTestUtil;
 import org.chromium.components.webrestrictions.browser.WebRestrictionsContentProvider;
 
@@ -27,24 +38,36 @@
 /**
  * Instrumentation test for SupervisedUserContentProvider.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class SupervisedUserContentProviderTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SupervisedUserContentProviderTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String DEFAULT_ACCOUNT = "test@gmail.com";
     private static final String AUTHORITY_SUFFIX = ".SupervisedUserProvider";
     private ContentResolver mResolver;
     private String mAuthority;
     private Uri mUri;
 
-    public SupervisedUserContentProviderTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mResolver = getInstrumentation().getTargetContext().getContentResolver();
-        assertNotNull(mResolver);
-        mAuthority = getInstrumentation().getTargetContext().getPackageName() + AUTHORITY_SUFFIX;
+        SigninTestUtil.setUpAuthForTest(InstrumentationRegistry.getInstrumentation());
+
+        // In principle the SupervisedUserContentProvider should work whenever Chrome is installed
+        // (even if it isn't running), but to test it we need to set up a dummy child, and to do
+        // this within a test we need to start Chrome.
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mResolver = InstrumentationRegistry.getInstrumentation()
+                            .getTargetContext()
+                            .getContentResolver();
+        Assert.assertNotNull(mResolver);
+        mAuthority =
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName()
+                + AUTHORITY_SUFFIX;
         mUri = new Uri.Builder()
                        .scheme(ContentResolver.SCHEME_CONTENT)
                        .authority(mAuthority)
@@ -53,34 +76,25 @@
         SigninTestUtil.resetSigninState();
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         SigninTestUtil.resetSigninState();
         SigninTestUtil.tearDownAuthForTest();
-        super.tearDown();
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        SigninTestUtil.setUpAuthForTest(getInstrumentation());
-
-        // In principle the SupervisedUserContentProvider should work whenever Chrome is installed
-        // (even if it isn't running), but to test it we need to set up a dummy child, and to do
-        // this within a test we need to start Chrome.
-        startMainActivityOnBlankPage();
-    }
-
+    @Test
     @SmallTest
     public void testSupervisedUserDisabled() throws RemoteException, ExecutionException {
         ContentProviderClient client = mResolver.acquireContentProviderClient(mAuthority);
-        assertNotNull(client);
+        Assert.assertNotNull(client);
         Cursor cursor = client.query(mUri, null, "url = 'http://google.com'", null, null);
-        assertNull(cursor);
+        Assert.assertNull(cursor);
     }
 
+    @Test
     @SmallTest
     public void testNoSupervisedUser() throws RemoteException, ExecutionException {
-        assertFalse(ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
+        Assert.assertFalse(ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
 
             @Override
             public Boolean call() throws Exception {
@@ -90,21 +104,22 @@
 
         }));
         ContentProviderClient client = mResolver.acquireContentProviderClient(mAuthority);
-        assertNotNull(client);
+        Assert.assertNotNull(client);
         SupervisedUserContentProvider.enableContentProviderForTesting();
         Cursor cursor = client.query(mUri, null, "url = 'http://google.com'", null, null);
-        assertNotNull(cursor);
-        assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
+        Assert.assertNotNull(cursor);
+        Assert.assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
         cursor = client.query(mUri, null, "url = 'http://www.notgoogle.com'", null, null);
-        assertNotNull(cursor);
-        assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
+        Assert.assertNotNull(cursor);
+        Assert.assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
     }
 
+    @Test
     @SmallTest
     public void testWithSupervisedUser() throws RemoteException, ExecutionException {
         final Account account = SigninTestUtil.addAndSignInTestAccount();
-        assertNotNull(account);
-        assertTrue(ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
+        Assert.assertNotNull(account);
+        Assert.assertTrue(ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
 
             @Override
             public Boolean call() throws Exception {
@@ -114,12 +129,12 @@
 
         }));
         ContentProviderClient client = mResolver.acquireContentProviderClient(mAuthority);
-        assertNotNull(client);
+        Assert.assertNotNull(client);
         SupervisedUserContentProvider.enableContentProviderForTesting();
         // setFilter for testing sets a default filter that blocks by default.
         mResolver.call(mUri, "setFilterForTesting", null, null);
         Cursor cursor = client.query(mUri, null, "url = 'http://www.google.com'", null, null);
-        assertNotNull(cursor);
-        assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
+        Assert.assertNotNull(cursor);
+        Assert.assertEquals(WebRestrictionsContentProvider.BLOCKED, cursor.getInt(0));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
index e4ac29c6..c2887ed5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateTest.java
@@ -4,15 +4,26 @@
 
 package org.chromium.chrome.browser.tab;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationParams;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.navigation_interception.NavigationParams;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -27,8 +38,15 @@
 /**
  * Tests for InterceptNavigationDelegate
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class InterceptNavigationDelegateTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class InterceptNavigationDelegateTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String BASE_PAGE = "/chrome/test/data/navigation_interception/";
     private static final String NAVIGATION_FROM_TIMEOUT_PAGE =
             BASE_PAGE + "navigation_from_timer.html";
@@ -78,15 +96,6 @@
         }
     }
 
-    public InterceptNavigationDelegateTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
     private void waitTillExpectedCallsComplete(int count, long timeout) {
         CriteriaHelper.pollUiThread(
                 Criteria.equals(count, new Callable<Integer>() {
@@ -97,10 +106,10 @@
                 }), timeout, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mActivity = mActivityTestRule.getActivity();
         mInterceptNavigationDelegate = new TestInterceptNavigationDelegate();
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -109,95 +118,104 @@
                 tab.setInterceptNavigationDelegate(mInterceptNavigationDelegate);
             }
         });
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromTimer() throws InterruptedException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_TIMEOUT_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(NAVIGATION_FROM_TIMEOUT_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertFalse(mNavParamHistory.get(1).hasUserGesture);
-        assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromUserGesture() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertTrue(mNavParamHistory.get(1).hasUserGesture);
-        assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertTrue(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromXHRCallback() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertFalse(mNavParamHistory.get(1).hasUserGesture);
-        assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromXHRCallbackAndShortTimeout()
             throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_SHORT_TIMEOUT_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(
+                mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_SHORT_TIMEOUT_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertFalse(mNavParamHistory.get(1).hasUserGesture);
-        assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromXHRCallbackAndLongTimeout()
             throws InterruptedException, TimeoutException {
-        loadUrl(
+        mActivityTestRule.loadUrl(
                 mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_LONG_TIMEOUT_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(2, LONG_MAX_TIME_TO_WAIT_IN_MS);
-        assertFalse(mNavParamHistory.get(1).hasUserGesture);
-        assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @SmallTest
     public void testNavigationFromImageOnLoad() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_IMAGE_ONLOAD_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(NAVIGATION_FROM_IMAGE_ONLOAD_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(2, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertFalse(mNavParamHistory.get(1).hasUserGesture);
-        assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
+        Assert.assertFalse(mNavParamHistory.get(1).hasUserGesture);
+        Assert.assertTrue(mNavParamHistory.get(1).hasUserGestureCarryover);
     }
 
+    @Test
     @MediumTest
     public void testExternalAppIframeNavigation() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_IFRAME_PAGE));
-        assertEquals(1, mNavParamHistory.size());
+        mActivityTestRule.loadUrl(mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_IFRAME_PAGE));
+        Assert.assertEquals(1, mNavParamHistory.size());
 
         DOMUtils.clickNode(mActivity.getActivityTab().getContentViewCore(), "first");
         waitTillExpectedCallsComplete(3, DEFAULT_MAX_TIME_TO_WAIT_IN_MS);
-        assertEquals(3, mExternalNavParamHistory.size());
+        Assert.assertEquals(3, mExternalNavParamHistory.size());
 
-        assertTrue(mNavParamHistory.get(2).isExternalProtocol);
-        assertFalse(mNavParamHistory.get(2).isMainFrame);
-        assertTrue(mExternalNavParamHistory.get(2).getRedirectHandler().shouldStayInChrome(true));
+        Assert.assertTrue(mNavParamHistory.get(2).isExternalProtocol);
+        Assert.assertFalse(mNavParamHistory.get(2).isMainFrame);
+        Assert.assertTrue(
+                mExternalNavParamHistory.get(2).getRedirectHandler().shouldStayInChrome(true));
     }
 
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java
index 23ca61c..c085797 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/SadTabTest.java
@@ -7,53 +7,66 @@
 import android.support.test.filters.SmallTest;
 import android.widget.Button;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /**
  * Tests related to the sad tab logic.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class SadTabTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class SadTabTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
-    public SadTabTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * Verify that the sad tab is shown when the renderer crashes.
      */
+    @Test
     @SmallTest
     @Feature({"SadTab"})
     public void testSadTabShownWhenRendererProcessKilled() {
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
-        assertFalse(tab.isShowingSadTab());
+        Assert.assertFalse(tab.isShowingSadTab());
         simulateRendererKilled(tab, true);
-        assertTrue(tab.isShowingSadTab());
+        Assert.assertTrue(tab.isShowingSadTab());
     }
 
     /**
      * Verify that the sad tab is not shown when the renderer crashes in the background or the
      * renderer was killed by the OS out-of-memory killer.
      */
+    @Test
     @SmallTest
     @Feature({"SadTab"})
     public void testSadTabNotShownWhenRendererProcessKilledInBackround() {
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
-        assertFalse(tab.isShowingSadTab());
+        Assert.assertFalse(tab.isShowingSadTab());
         simulateRendererKilled(tab, false);
-        assertFalse(tab.isShowingSadTab());
+        Assert.assertFalse(tab.isShowingSadTab());
     }
 
     /**
@@ -63,32 +76,39 @@
      * @throws InterruptedException
      * @throws IllegalArgumentException
      */
+    @Test
     @SmallTest
     @Feature({"SadTab"})
     public void testSadTabPageButtonText() throws IllegalArgumentException, InterruptedException {
-        final Tab tab = getActivity().getActivityTab();
+        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
-        assertFalse(tab.isShowingSadTab());
+        Assert.assertFalse(tab.isShowingSadTab());
         simulateRendererKilled(tab, true);
-        assertTrue(tab.isShowingSadTab());
+        Assert.assertTrue(tab.isShowingSadTab());
         String actualText = getSadTabButton(tab).getText().toString();
-        assertEquals("Expected the sad tab button to have the reload label",
-                getActivity().getString(R.string.sad_tab_reload_label), actualText);
+        Assert.assertEquals("Expected the sad tab button to have the reload label",
+                mActivityTestRule.getActivity().getString(R.string.sad_tab_reload_label),
+                actualText);
 
         reloadSadTab(tab);
-        assertTrue(tab.isShowingSadTab());
+        Assert.assertTrue(tab.isShowingSadTab());
         actualText = getSadTabButton(tab).getText().toString();
-        assertEquals(
+        Assert.assertEquals(
                 "Expected the sad tab button to have the feedback label after the tab button "
-                + "crashes twice in a row.",
-                getActivity().getString(R.string.sad_tab_send_feedback_label), actualText);
-        loadUrl("about:blank");
-        assertFalse("Expected about:blank to destroy the sad tab however the sad tab is still in "
-                + "view", tab.isShowingSadTab());
+                        + "crashes twice in a row.",
+                mActivityTestRule.getActivity().getString(R.string.sad_tab_send_feedback_label),
+                actualText);
+        mActivityTestRule.loadUrl("about:blank");
+        Assert.assertFalse(
+                "Expected about:blank to destroy the sad tab however the sad tab is still in "
+                        + "view",
+                tab.isShowingSadTab());
         simulateRendererKilled(tab, true);
         actualText = getSadTabButton(tab).getText().toString();
-        assertEquals("Expected the sad tab button to have the reload label after a successful load",
-                getActivity().getString(R.string.sad_tab_reload_label), actualText);
+        Assert.assertEquals(
+                "Expected the sad tab button to have the reload label after a successful load",
+                mActivityTestRule.getActivity().getString(R.string.sad_tab_reload_label),
+                actualText);
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java
index ee4cbde8..f6eb88d2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabUmaTest.java
@@ -4,16 +4,27 @@
 
 package org.chromium.chrome.browser.tab;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MetricsUtils.HistogramDelta;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.net.test.EmbeddedTestServer;
 
@@ -23,48 +34,47 @@
 /**
  * Tests for Tab-related histogram collection.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class TabUmaTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class TabUmaTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TEST_PATH = "/chrome/test/data/android/about.html";
 
     private EmbeddedTestServer mTestServer;
     private String mTestUrl;
 
-    public TabUmaTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mTestUrl = mTestServer.getURL(TEST_PATH);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
      * Verify that Tab.StatusWhenSwitchedBackToForeground is correctly recording lazy loads.
      */
+    @Test
     @MediumTest
     @Feature({"Uma"})
     public void testTabStatusWhenSwitchedToLazyLoads() throws ExecutionException {
         final Tab tab = ThreadUtils.runOnUiThreadBlocking(new Callable<Tab>() {
             @Override
             public Tab call() {
-                Tab bgTab = Tab.createTabForLazyLoad(getActivity(), false,
-                        getActivity().getWindowAndroid(), TabLaunchType.FROM_LONGPRESS_BACKGROUND,
-                        Tab.INVALID_TAB_ID, new LoadUrlParams(mTestUrl));
+                Tab bgTab = Tab.createTabForLazyLoad(mActivityTestRule.getActivity(), false,
+                        mActivityTestRule.getActivity().getWindowAndroid(),
+                        TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.INVALID_TAB_ID,
+                        new LoadUrlParams(mTestUrl));
                 bgTab.initialize(null, null, new TabDelegateFactory(), true, false);
                 return bgTab;
             }
@@ -73,7 +83,7 @@
         String histogram = "Tab.StatusWhenSwitchedBackToForeground";
         HistogramDelta lazyLoadCount =
                 new HistogramDelta(histogram, TabUma.TAB_STATUS_LAZY_LOAD_FOR_BG_TAB);
-        assertEquals(0, lazyLoadCount.getDelta()); // Sanity check.
+        Assert.assertEquals(0, lazyLoadCount.getDelta()); // Sanity check.
 
         // Show the tab and verify that one sample was recorded in the lazy load bucket.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -82,7 +92,7 @@
                 tab.show(TabSelectionType.FROM_USER);
             }
         });
-        assertEquals(1, lazyLoadCount.getDelta());
+        Assert.assertEquals(1, lazyLoadCount.getDelta());
 
         // Show the tab again and verify that we didn't record another sample.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -91,12 +101,13 @@
                 tab.show(TabSelectionType.FROM_USER);
             }
         });
-        assertEquals(1, lazyLoadCount.getDelta());
+        Assert.assertEquals(1, lazyLoadCount.getDelta());
     }
 
     /**
      * Verify that Tab.BackgroundLoadStatus is correctly recorded.
      */
+    @Test
     @MediumTest
     @Feature({"Uma"})
     public void testTabBackgroundLoadStatus() throws ExecutionException {
@@ -107,34 +118,34 @@
                 new HistogramDelta(histogram, TabUma.TAB_BACKGROUND_LOAD_LOST);
         HistogramDelta skippedLoadCount =
                 new HistogramDelta(histogram, TabUma.TAB_BACKGROUND_LOAD_SKIPPED);
-        assertEquals(0, shownLoadCount.getDelta());
-        assertEquals(0, lostLoadCount.getDelta());
-        assertEquals(0, skippedLoadCount.getDelta());
+        Assert.assertEquals(0, shownLoadCount.getDelta());
+        Assert.assertEquals(0, lostLoadCount.getDelta());
+        Assert.assertEquals(0, skippedLoadCount.getDelta());
 
         // Test a live tab created in background and shown.
         final Tab liveBgTab = ThreadUtils.runOnUiThreadBlocking(new Callable<Tab>() {
             @Override
             public Tab call() {
-                Tab bgTab = Tab.createLiveTab(Tab.INVALID_TAB_ID, getActivity(), false,
-                        getActivity().getWindowAndroid(), TabLaunchType.FROM_LONGPRESS_BACKGROUND,
-                        Tab.INVALID_TAB_ID, true);
+                Tab bgTab = Tab.createLiveTab(Tab.INVALID_TAB_ID, mActivityTestRule.getActivity(),
+                        false, mActivityTestRule.getActivity().getWindowAndroid(),
+                        TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.INVALID_TAB_ID, true);
                 bgTab.initialize(null, null, new TabDelegateFactory(), true, false);
                 bgTab.loadUrl(new LoadUrlParams(mTestUrl));
                 bgTab.show(TabSelectionType.FROM_USER);
                 return bgTab;
             }
         });
-        assertEquals(1, shownLoadCount.getDelta());
-        assertEquals(0, lostLoadCount.getDelta());
-        assertEquals(0, skippedLoadCount.getDelta());
+        Assert.assertEquals(1, shownLoadCount.getDelta());
+        Assert.assertEquals(0, lostLoadCount.getDelta());
+        Assert.assertEquals(0, skippedLoadCount.getDelta());
 
         // Test a live tab killed in background before shown.
         final Tab killedBgTab = ThreadUtils.runOnUiThreadBlocking(new Callable<Tab>() {
             @Override
             public Tab call() {
-                Tab bgTab = Tab.createLiveTab(Tab.INVALID_TAB_ID, getActivity(), false,
-                        getActivity().getWindowAndroid(), TabLaunchType.FROM_LONGPRESS_BACKGROUND,
-                        Tab.INVALID_TAB_ID, true);
+                Tab bgTab = Tab.createLiveTab(Tab.INVALID_TAB_ID, mActivityTestRule.getActivity(),
+                        false, mActivityTestRule.getActivity().getWindowAndroid(),
+                        TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.INVALID_TAB_ID, true);
                 bgTab.initialize(null, null, new TabDelegateFactory(), true, false);
                 bgTab.loadUrl(new LoadUrlParams(mTestUrl));
                 // Simulate the renderer being killed by the OS.
@@ -143,25 +154,26 @@
                 return bgTab;
             }
         });
-        assertEquals(1, shownLoadCount.getDelta());
-        assertEquals(1, lostLoadCount.getDelta());
-        assertEquals(0, skippedLoadCount.getDelta());
+        Assert.assertEquals(1, shownLoadCount.getDelta());
+        Assert.assertEquals(1, lostLoadCount.getDelta());
+        Assert.assertEquals(0, skippedLoadCount.getDelta());
 
         // Test a tab created in background but not loaded eagerly.
         final Tab frozenBgTab = ThreadUtils.runOnUiThreadBlocking(new Callable<Tab>() {
             @Override
             public Tab call() {
-                Tab bgTab = Tab.createTabForLazyLoad(getActivity(), false,
-                        getActivity().getWindowAndroid(), TabLaunchType.FROM_LONGPRESS_BACKGROUND,
-                        Tab.INVALID_TAB_ID, new LoadUrlParams(mTestUrl));
+                Tab bgTab = Tab.createTabForLazyLoad(mActivityTestRule.getActivity(), false,
+                        mActivityTestRule.getActivity().getWindowAndroid(),
+                        TabLaunchType.FROM_LONGPRESS_BACKGROUND, Tab.INVALID_TAB_ID,
+                        new LoadUrlParams(mTestUrl));
                 bgTab.initialize(null, null, new TabDelegateFactory(), true, false);
                 bgTab.show(TabSelectionType.FROM_USER);
                 return bgTab;
             }
         });
-        assertEquals(1, shownLoadCount.getDelta());
-        assertEquals(1, lostLoadCount.getDelta());
-        assertEquals(1, skippedLoadCount.getDelta());
+        Assert.assertEquals(1, shownLoadCount.getDelta());
+        Assert.assertEquals(1, lostLoadCount.getDelta());
+        Assert.assertEquals(1, skippedLoadCount.getDelta());
 
         // Show every tab again and make sure we didn't record more samples - this metric should be
         // recorded only on first display.
@@ -173,8 +185,8 @@
                 frozenBgTab.show(TabSelectionType.FROM_USER);
             }
         });
-        assertEquals(1, shownLoadCount.getDelta());
-        assertEquals(1, lostLoadCount.getDelta());
-        assertEquals(1, skippedLoadCount.getDelta());
+        Assert.assertEquals(1, shownLoadCount.getDelta());
+        Assert.assertEquals(1, lostLoadCount.getDelta());
+        Assert.assertEquals(1, skippedLoadCount.getDelta());
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
index c1b7667..7f3eeaf98 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
@@ -10,21 +10,29 @@
 import android.support.test.filters.SmallTest;
 import android.text.TextUtils;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.ObserverList.RewindableIterator;
 import org.chromium.base.SysUtils;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
 import org.chromium.chrome.browser.tab.TabTestUtils;
 import org.chromium.chrome.browser.util.ColorUtils;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.DisableInTabbedMode;
 import org.chromium.content.browser.InterstitialPageDelegateAndroid;
@@ -36,12 +44,14 @@
 /**
  * Contains tests for the brand color feature.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class BrandColorTest extends ChromeActivityTestCaseBase<ChromeActivity> {
-
-    public BrandColorTest() {
-        super(ChromeActivity.class);
-    }
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class BrandColorTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String BRAND_COLOR_1 = "#482329";
     private static final String BRAND_COLOR_2 = "#505050";
@@ -65,11 +75,6 @@
                 + "</html>");
     }
 
-    @Override
-    public void startMainActivity() {
-        // Don't launch activity automatically.
-    }
-
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     private void checkForBrandColor(final int brandColor) {
         CriteriaHelper.pollUiThread(new Criteria(
@@ -97,24 +102,24 @@
                     Criteria.equals(expectedStatusBarColor, new Callable<Integer>() {
                         @Override
                         public Integer call() {
-                            return getActivity().getWindow().getStatusBarColor();
+                            return mActivityTestRule.getActivity().getWindow().getStatusBarColor();
                         }
                     }));
         }
     }
 
-    @Override
     protected void startMainActivityWithURL(String url) throws InterruptedException {
-        super.startMainActivityWithURL(url);
-        mToolbar = (ToolbarPhone) getActivity().findViewById(R.id.toolbar);
+        mActivityTestRule.startMainActivityWithURL(url);
+        mToolbar = (ToolbarPhone) mActivityTestRule.getActivity().findViewById(R.id.toolbar);
         mToolbarDataProvider = mToolbar.getToolbarDataProvider();
-        mDefaultColor = ApiCompatibilityUtils.getColor(getActivity().getResources(),
-                R.color.default_primary_color);
+        mDefaultColor = ApiCompatibilityUtils.getColor(
+                mActivityTestRule.getActivity().getResources(), R.color.default_primary_color);
     }
 
     /**
      * Test for having default primary color working correctly.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
@@ -126,6 +131,7 @@
     /**
      * Test for adding a brand color for a url.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
@@ -137,6 +143,7 @@
     /**
      * Test for immediately setting the brand color.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
@@ -147,10 +154,11 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().getToolbarManager().updatePrimaryColor(mDefaultColor, false);
+                mActivityTestRule.getActivity().getToolbarManager().updatePrimaryColor(
+                        mDefaultColor, false);
                 // Since the color should change instantly, there is no need to use the criteria
                 // helper.
-                assertEquals(mToolbarDataProvider.getPrimaryColor(),
+                Assert.assertEquals(mToolbarDataProvider.getPrimaryColor(),
                         mToolbar.getBackgroundDrawable().getColor());
             }
         });
@@ -159,6 +167,7 @@
     /**
      * Test to make sure onLoadStarted doesn't reset the brand color.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
@@ -167,7 +176,7 @@
         ThreadUtils.postOnUiThread(new Runnable() {
             @Override
             public void run() {
-                Tab tab = getActivity().getActivityTab();
+                Tab tab = mActivityTestRule.getActivity().getActivityTab();
                 RewindableIterator<TabObserver> observers = TabTestUtils.getTabObservers(tab);
                 while (observers.hasNext()) {
                     observers.next().onLoadStarted(tab, true);
@@ -180,13 +189,14 @@
     /**
      * Test for checking navigating to new brand color updates correctly.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
     public void testNavigatingToNewBrandColor() throws InterruptedException {
         startMainActivityWithURL(getUrlWithBrandColor(BRAND_COLOR_1));
         checkForBrandColor(Color.parseColor(BRAND_COLOR_1));
-        loadUrl(getUrlWithBrandColor(BRAND_COLOR_2));
+        mActivityTestRule.loadUrl(getUrlWithBrandColor(BRAND_COLOR_2));
         checkForBrandColor(Color.parseColor(BRAND_COLOR_2));
     }
 
@@ -194,27 +204,28 @@
      * Test for checking navigating to a brand color site from a site with no brand color and then
      * back again.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @Feature({"Omnibox"})
     public void testNavigatingToBrandColorAndBack() throws InterruptedException {
         startMainActivityWithURL("about:blank");
         checkForBrandColor(mDefaultColor);
-        loadUrl(getUrlWithBrandColor(BRAND_COLOR_1));
+        mActivityTestRule.loadUrl(getUrlWithBrandColor(BRAND_COLOR_1));
         checkForBrandColor(Color.parseColor(BRAND_COLOR_1));
-        loadUrl("about:blank");
+        mActivityTestRule.loadUrl("about:blank");
         checkForBrandColor(mDefaultColor);
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                getActivity().onBackPressed();
+                mActivityTestRule.getActivity().onBackPressed();
             }
         });
         checkForBrandColor(Color.parseColor(BRAND_COLOR_1));
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                getActivity().onBackPressed();
+                mActivityTestRule.getActivity().onBackPressed();
             }
         });
         checkForBrandColor(mDefaultColor);
@@ -225,6 +236,7 @@
      *
      * TODO(aurimas): investigate why this test is crasing in tabbed mode.
      */
+    @Test
     @SmallTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
     @DisableInTabbedMode
@@ -238,17 +250,19 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                getActivity().getActivityTab().getWebContents().showInterstitialPage(
-                        brandColorUrl, delegate.getNative());
+                mActivityTestRule.getActivity()
+                        .getActivityTab()
+                        .getWebContents()
+                        .showInterstitialPage(brandColorUrl, delegate.getNative());
             }
         });
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return getActivity().getActivityTab().isShowingInterstitialPage();
+                return mActivityTestRule.getActivity().getActivityTab().isShowingInterstitialPage();
             }
         });
         checkForBrandColor(ApiCompatibilityUtils.getColor(
-                getActivity().getResources(), R.color.default_primary_color));
+                mActivityTestRule.getActivity().getResources(), R.color.default_primary_color));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
index 42838fd..73edd89 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
@@ -4,18 +4,28 @@
 
 package org.chromium.chrome.browser.toolbar;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.omnibox.UrlBar;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.widget.findinpage.FindToolbar;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.MenuUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
@@ -27,21 +37,24 @@
 /**
  * Tests for toolbar manager behavior.
  */
-public class ToolbarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ToolbarTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String TEST_PAGE = "/chrome/test/data/android/test.html";
 
-    public ToolbarTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     private void findInPageFromMenu() {
-        MenuUtils.invokeCustomMenuActionSync(getInstrumentation(),
-                getActivity(), R.id.find_in_page_id);
+        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), R.id.find_in_page_id);
 
         waitForFindInPageVisibility(true);
     }
@@ -50,8 +63,9 @@
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                FindToolbar findToolbar = (FindToolbar) getActivity().findViewById(
-                        R.id.find_toolbar);
+                FindToolbar findToolbar =
+                        (FindToolbar) mActivityTestRule.getActivity().findViewById(
+                                R.id.find_toolbar);
 
                 boolean isVisible = findToolbar != null && findToolbar.isShown();
                 return (visible == isVisible) && !findToolbar.isAnimating();
@@ -70,18 +84,19 @@
         return isShowingError[0];
     }
 
+    @Test
     @MediumTest
     public void testNTPNavigatesToErrorPageOnDisconnectedNetwork() throws Exception {
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         String testUrl = testServer.getURL(TEST_PAGE);
 
-        Tab tab = getActivity().getActivityTab();
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
 
         // Load new tab page.
-        loadUrl(UrlConstants.NTP_URL);
-        assertEquals(UrlConstants.NTP_URL, tab.getUrl());
-        assertFalse(isErrorPage(tab));
+        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
+        Assert.assertEquals(UrlConstants.NTP_URL, tab.getUrl());
+        Assert.assertFalse(isErrorPage(tab));
 
         // Stop the server and also disconnect the network.
         testServer.stopAndDestroyServer();
@@ -92,18 +107,19 @@
             }
         });
 
-        loadUrl(testUrl);
-        assertEquals(testUrl, tab.getUrl());
-        assertTrue(isErrorPage(tab));
+        mActivityTestRule.loadUrl(testUrl);
+        Assert.assertEquals(testUrl, tab.getUrl());
+        Assert.assertTrue(isErrorPage(tab));
     }
 
+    @Test
     @MediumTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
     @Feature({"Omnibox"})
     public void testFindInPageDismissedOnOmniboxFocus() {
         findInPageFromMenu();
 
-        UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+        UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar);
         OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
         OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
index 1e0efa0..599c190 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
@@ -4,16 +4,26 @@
 
 package org.chromium.chrome.browser.translate;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.infobar.InfoBar;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
 import org.chromium.chrome.test.util.InfoBarUtil;
@@ -29,7 +39,13 @@
  * Note: these tests all currently fail because they depend on a newer version of Google Play
  * Services than is installed on the test devices. See http://crbug.com/514449
  */
-public class TranslateInfoBarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class TranslateInfoBarTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     private static final String TRANSLATE_PAGE = "/chrome/test/data/translate/fr_test.html";
     private static final String ENABLE_COMPACT_UI_FEATURE = "enable-features=TranslateCompactUI";
@@ -42,39 +58,31 @@
     private InfoBarTestAnimationListener mListener;
     private EmbeddedTestServer mTestServer;
 
-    public TranslateInfoBarTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInfoBarContainer = getActivity().getActivityTab().getInfoBarContainer();
+    @Before
+    public void setUp() throws Exception {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        mInfoBarContainer = mActivityTestRule.getActivity().getActivityTab().getInfoBarContainer();
         mListener =  new InfoBarTestAnimationListener();
         mInfoBarContainer.addAnimationListener(mListener);
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         mTestServer.stopAndDestroyServer();
-        super.tearDown();
     }
 
     /**
      * Test the new translate compact UI.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
     @CommandLineFlags.Add(ENABLE_COMPACT_UI_FEATURE)
     public void testTranslateCompactInfoBarAppears() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened.");
         InfoBar infoBar = mInfoBarContainer.getInfoBarsForTesting().get(0);
         TranslateUtil.assertCompactTranslateInfoBar(infoBar);
@@ -83,39 +91,42 @@
     /**
      * Test the translate language panel.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
     @CommandLineFlags.Add(DISABLE_COMPACT_UI_FEATURE)
     public void testTranslateLanguagePanel() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened.");
         InfoBar infoBar = mInfoBarContainer.getInfoBarsForTesting().get(0);
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBar));
-        assertTrue(InfoBarUtil.hasSecondaryButton(infoBar));
-        TranslateUtil.openLanguagePanel(this, infoBar);
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBar));
+        Assert.assertTrue(InfoBarUtil.hasSecondaryButton(infoBar));
+        TranslateUtil.openLanguagePanel(InstrumentationRegistry.getInstrumentation(),
+                mActivityTestRule.getActivity(), infoBar);
     }
 
     /**
      * Test the "never translate" panel.
      */
+    @Test
     @MediumTest
     @Feature({"Browser", "Main"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
     @CommandLineFlags.Add(DISABLE_COMPACT_UI_FEATURE)
     public void testTranslateNeverPanel() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened.");
         InfoBar infoBar = mInfoBarContainer.getInfoBarsForTesting().get(0);
 
-        assertTrue(InfoBarUtil.clickCloseButton(infoBar));
+        Assert.assertTrue(InfoBarUtil.clickCloseButton(infoBar));
         mListener.removeInfoBarAnimationFinished("Infobar not removed.");
 
         // Reload the page so the infobar shows again
-        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened");
         infoBar = mInfoBarContainer.getInfoBarsForTesting().get(0);
-        assertTrue(InfoBarUtil.clickCloseButton(infoBar));
+        Assert.assertTrue(InfoBarUtil.clickCloseButton(infoBar));
         mListener.swapInfoBarAnimationFinished("InfoBar not swapped");
 
         TranslateUtil.assertInfoBarText(infoBar, NEVER_TRANSLATE_MESSAGE);
@@ -127,14 +138,15 @@
      * @MediumTest
      * @Feature({"Browser", "Main"})
      */
+    @Test
     @DisabledTest(message = "crbug.com/514449")
     public void testTranslateTransitions() throws InterruptedException, TimeoutException {
-        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mActivityTestRule.loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not Added");
-        InfoBar infoBar = getInfoBars().get(0);
-        assertTrue(InfoBarUtil.hasPrimaryButton(infoBar));
-        assertTrue(InfoBarUtil.hasSecondaryButton(infoBar));
-        assertTrue(InfoBarUtil.clickPrimaryButton(infoBar));
+        InfoBar infoBar = mActivityTestRule.getInfoBars().get(0);
+        Assert.assertTrue(InfoBarUtil.hasPrimaryButton(infoBar));
+        Assert.assertTrue(InfoBarUtil.hasSecondaryButton(infoBar));
+        Assert.assertTrue(InfoBarUtil.clickPrimaryButton(infoBar));
         mListener.swapInfoBarAnimationFinished("BEFORE -> TRANSLATING transition not Swapped.");
         mListener.swapInfoBarAnimationFinished("TRANSLATING -> ERROR transition not Swapped.");
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java
index eaa34de..14f4434 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java
@@ -4,13 +4,23 @@
 
 package org.chromium.chrome.browser.video;
 
+import android.support.test.InstrumentationRegistry;
 import android.view.KeyEvent;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.KeyUtils;
@@ -20,7 +30,14 @@
 /**
  * Test suite for fullscreen video implementation.
  */
-public class FullscreenVideoTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class FullscreenVideoTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final int TEST_TIMEOUT = 3000;
     private boolean mIsTabFullscreen = false;
 
@@ -31,13 +48,9 @@
         }
     }
 
-    public FullscreenVideoTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
@@ -46,27 +59,29 @@
      *
      * @MediumTest
      */
+    @Test
     @FlakyTest(message = "crbug.com/458368")
     public void testExitFullscreenNotifiesTabObservers() throws InterruptedException {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
         try {
             String url = testServer.getURL(
                     "/chrome/test/data/android/media/video-fullscreen.html");
-            loadUrl(url);
-            Tab tab = getActivity().getActivityTab();
+            mActivityTestRule.loadUrl(url);
+            Tab tab = mActivityTestRule.getActivity().getActivityTab();
             FullscreenTabObserver observer = new FullscreenTabObserver();
             tab.addObserver(observer);
 
-            TestTouchUtils.singleClickView(getInstrumentation(), tab.getView(), 500, 500);
+            TestTouchUtils.singleClickView(
+                    InstrumentationRegistry.getInstrumentation(), tab.getView(), 500, 500);
             waitForVideoToEnterFullscreen();
             // Key events have to be dispached on UI thread.
-            KeyUtils.singleKeyEventActivity(
-                    getInstrumentation(), getActivity(), KeyEvent.KEYCODE_BACK);
+            KeyUtils.singleKeyEventActivity(InstrumentationRegistry.getInstrumentation(),
+                    mActivityTestRule.getActivity(), KeyEvent.KEYCODE_BACK);
 
             waitForTabToExitFullscreen();
-            assertEquals("URL mismatch after exiting fullscreen video",
-                    url, getActivity().getActivityTab().getUrl());
+            Assert.assertEquals("URL mismatch after exiting fullscreen video", url,
+                    mActivityTestRule.getActivity().getActivityTab().getUrl());
         } finally {
             testServer.stopAndDestroyServer();
         }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java
index 75169f3..1a0fee3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/video/VideoTest.java
@@ -4,14 +4,24 @@
 
 package org.chromium.chrome.browser.video;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.net.test.EmbeddedTestServer;
@@ -21,39 +31,43 @@
 /**
  *  Simple tests of html5 video.
  */
-public class VideoTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class VideoTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
-    public VideoTest() {
-        super(ChromeActivity.class);
-    }
-
+    @Test
     @DisableIf.Build(sdk_is_less_than = 19, message = "crbug.com/582067")
     @Feature({"Media", "Media-Video", "Main"})
     @LargeTest
     @RetryOnFailure
     public void testLoadMediaUrl() throws InterruptedException, TimeoutException {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
         try {
-            Tab tab = getActivity().getActivityTab();
+            Tab tab = mActivityTestRule.getActivity().getActivityTab();
             TabTitleObserver titleObserver = new TabTitleObserver(tab, "ready_to_play");
-            loadUrl(testServer.getURL("/chrome/test/data/android/media/video-play.html"));
+            mActivityTestRule.loadUrl(
+                    testServer.getURL("/chrome/test/data/android/media/video-play.html"));
             titleObserver.waitForTitleUpdate(5);
-            assertEquals("ready_to_play", tab.getTitle());
+            Assert.assertEquals("ready_to_play", tab.getTitle());
 
             titleObserver = new TabTitleObserver(tab, "ended");
             DOMUtils.clickNode(tab.getContentViewCore(), "button1");
             // Now the video will play for 5 secs.
             // Makes sure that the video ends and title was changed.
             titleObserver.waitForTitleUpdate(15);
-            assertEquals("ended", tab.getTitle());
+            Assert.assertEquals("ended", tab.getTitle());
         } finally {
             testServer.stopAndDestroyServer();
         }
     }
 
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenManagerTest.java
index 8678d77..d7a9d74 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenManagerTest.java
@@ -7,8 +7,15 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
@@ -17,10 +24,12 @@
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.TabLoadObserver;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.content.browser.test.util.Criteria;
@@ -33,8 +42,15 @@
 /**
  * Tests org.chromium.chrome.browser.webapps.AddToHomescreenManager and its C++ counterpart.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class AddToHomescreenManagerTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class AddToHomescreenManagerTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
+
     private static final String WEBAPP_ACTION_NAME = "WEBAPP_ACTION";
 
     private static final String WEBAPP_TITLE = "Webapp shortcut";
@@ -111,7 +127,7 @@
 
             @Override
             public void updateSplashScreenImage(String splashScreenImage) {
-                assertNull(mSplashImage);
+                Assert.assertNull(mSplashImage);
                 mSplashImage = splashScreenImage;
             }
         }
@@ -153,51 +169,46 @@
     private Tab mTab;
     private TestShortcutHelperDelegate mShortcutHelperDelegate;
 
-    public AddToHomescreenManagerTest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
+        mActivityTestRule.startMainActivityOnBlankPage();
         ChromeWebApkHost.initForTesting(false);
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
+        mTestServer = EmbeddedTestServer.createAndStartServer(
+                InstrumentationRegistry.getInstrumentation().getContext());
         mShortcutHelperDelegate = new TestShortcutHelperDelegate();
         ShortcutHelper.setDelegateForTests(mShortcutHelperDelegate);
-        mActivity = getActivity();
+        mActivity = mActivityTestRule.getActivity();
         mTab = mActivity.getActivityTab();
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcuts() throws Exception {
         // Add a webapp shortcut and make sure the intent's parameters make sense.
         loadUrl(WEBAPP_HTML, WEBAPP_TITLE);
         addShortcutToTab(mTab, "");
-        assertEquals(WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
 
         Intent launchIntent = mShortcutHelperDelegate.mRequestedShortcutIntent;
-        assertEquals(WEBAPP_HTML, launchIntent.getStringExtra(ShortcutHelper.EXTRA_URL));
-        assertEquals(WEBAPP_ACTION_NAME, launchIntent.getAction());
-        assertEquals(mActivity.getPackageName(), launchIntent.getPackage());
+        Assert.assertEquals(WEBAPP_HTML, launchIntent.getStringExtra(ShortcutHelper.EXTRA_URL));
+        Assert.assertEquals(WEBAPP_ACTION_NAME, launchIntent.getAction());
+        Assert.assertEquals(mActivity.getPackageName(), launchIntent.getPackage());
 
         // Add a second shortcut and make sure it matches the second webapp's parameters.
         mShortcutHelperDelegate.clearRequestedShortcutData();
         loadUrl(SECOND_WEBAPP_HTML, SECOND_WEBAPP_TITLE);
         addShortcutToTab(mTab, "");
-        assertEquals(SECOND_WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(SECOND_WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
 
         Intent newLaunchIntent = mShortcutHelperDelegate.mRequestedShortcutIntent;
-        assertEquals(SECOND_WEBAPP_HTML, newLaunchIntent.getStringExtra(ShortcutHelper.EXTRA_URL));
-        assertEquals(WEBAPP_ACTION_NAME, newLaunchIntent.getAction());
-        assertEquals(mActivity.getPackageName(), newLaunchIntent.getPackage());
+        Assert.assertEquals(
+                SECOND_WEBAPP_HTML, newLaunchIntent.getStringExtra(ShortcutHelper.EXTRA_URL));
+        Assert.assertEquals(WEBAPP_ACTION_NAME, newLaunchIntent.getAction());
+        Assert.assertEquals(mActivity.getPackageName(), newLaunchIntent.getPackage());
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddBookmarkShortcut() throws Exception {
@@ -205,40 +216,44 @@
         addShortcutToTab(mTab, "");
 
         // Make sure the intent's parameters make sense.
-        assertEquals(NORMAL_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(NORMAL_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
 
         Intent launchIntent = mShortcutHelperDelegate.mRequestedShortcutIntent;
-        assertEquals(mActivity.getPackageName(), launchIntent.getPackage());
-        assertEquals(Intent.ACTION_VIEW, launchIntent.getAction());
-        assertEquals(NORMAL_HTML, launchIntent.getDataString());
+        Assert.assertEquals(mActivity.getPackageName(), launchIntent.getPackage());
+        Assert.assertEquals(Intent.ACTION_VIEW, launchIntent.getAction());
+        Assert.assertEquals(NORMAL_HTML, launchIntent.getDataString());
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcutsWithoutTitleEdit() throws Exception {
         // Add a webapp shortcut using the page's title.
         loadUrl(WEBAPP_HTML, WEBAPP_TITLE);
         addShortcutToTab(mTab, "");
-        assertEquals(WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcutsWithTitleEdit() throws Exception {
         // Add a webapp shortcut with a custom title.
         loadUrl(WEBAPP_HTML, WEBAPP_TITLE);
         addShortcutToTab(mTab, EDITED_WEBAPP_TITLE);
-        assertEquals(EDITED_WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(EDITED_WEBAPP_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcutsWithApplicationName() throws Exception {
         loadUrl(META_APP_NAME_HTML, META_APP_NAME_PAGE_TITLE);
         addShortcutToTab(mTab, "");
-        assertEquals(META_APP_NAME_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
+        Assert.assertEquals(META_APP_NAME_TITLE, mShortcutHelperDelegate.mRequestedShortcutTitle);
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE)
@@ -248,6 +263,7 @@
         addShortcutToTab(spawnedPopup, "");
     }
 
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcutSplashScreenIcon() throws Exception {
@@ -272,8 +288,8 @@
                     R.dimen.webapp_splash_image_size_ideal);
             Bitmap splashImage =
                     ShortcutHelper.decodeBitmapFromString(dataStorageFactory.mSplashImage);
-            assertEquals(idealSize, splashImage.getWidth());
-            assertEquals(idealSize, splashImage.getHeight());
+            Assert.assertEquals(idealSize, splashImage.getWidth());
+            Assert.assertEquals(idealSize, splashImage.getHeight());
         } finally {
             mTestServer.stopAndDestroyServer();
         }
@@ -281,6 +297,7 @@
 
     /** Tests that the appinstalled event is fired when an app is installed.
      */
+    @Test
     @SmallTest
     @Feature("{Webapp}")
     public void testAddWebappShortcutAppInstalledEvent() throws Exception {
@@ -352,12 +369,15 @@
         CriteriaHelper.pollUiThread(Criteria.equals(2, new Callable<Integer>() {
             @Override
             public Integer call() {
-                return getActivity().getTabModelSelector().getModel(false).getCount();
+                return mActivityTestRule.getActivity()
+                        .getTabModelSelector()
+                        .getModel(false)
+                        .getCount();
             }
         }));
 
-        TabModel tabModel = getActivity().getTabModelSelector().getModel(false);
-        assertEquals(0, tabModel.indexOf(mTab));
-        return getActivity().getTabModelSelector().getModel(false).getTabAt(1);
+        TabModel tabModel = mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
+        Assert.assertEquals(0, tabModel.indexOf(mTab));
+        return mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getTabAt(1);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
index 27c7ac6..7bf8b32 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
@@ -6,15 +6,25 @@
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.view.View;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRestriction;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -32,35 +42,36 @@
 /**
  * Tests related to the ToolbarProgressBar.
  */
+@RunWith(ChromeJUnit4ClassRunner.class)
 @RetryOnFailure
-public class ToolbarProgressBarTest extends ChromeActivityTestCaseBase<ChromeTabbedActivity> {
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
+        ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG})
+public class ToolbarProgressBarTest {
+    @Rule
+    public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
+            new ChromeActivityTestRule<>(ChromeActivity.class);
 
     static final int TEST_WAIT_TIME_MS = 60000;
     private static final String TEST_PAGE = "/chrome/test/data/android/progressbar_test.html";
 
-    public ToolbarProgressBarTest() {
-        super(ChromeTabbedActivity.class);
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
+    @Before
+    public void setUp() throws InterruptedException {
+        mActivityTestRule.startMainActivityOnBlankPage();
     }
 
     /**
      * Test that the progress bar only traverses the page a single time per navigation.
      */
+    @Test
     @Feature({"Android-Toolbar"})
     @MediumTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
-    public void testToolbarTraversesScreenOnce()
-            throws InterruptedException, TimeoutException {
-
+    public void testToolbarTraversesScreenOnce() throws InterruptedException, TimeoutException {
         EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
-                getInstrumentation().getContext());
+                InstrumentationRegistry.getInstrumentation().getContext());
 
         final WebContents webContents =
-                getActivity().getActivityTab().getWebContents();
+                mActivityTestRule.getActivity().getActivityTab().getWebContents();
 
         TestWebContentsObserver observer = new TestWebContentsObserver(webContents);
         // Start and stop load events are carefully tracked; there should be two start-stop pairs
@@ -68,17 +79,19 @@
         OnPageStartedHelper startHelper = observer.getOnPageStartedHelper();
         OnPageFinishedHelper finishHelper = observer.getOnPageFinishedHelper();
 
-        ToolbarProgressBar progressBar =
-                getActivity().getToolbarManager().getToolbarLayout().getProgressBar();
+        ToolbarProgressBar progressBar = mActivityTestRule.getActivity()
+                                                 .getToolbarManager()
+                                                 .getToolbarLayout()
+                                                 .getProgressBar();
 
         // Reset progress bar start count in case anything else triggered it.
         progressBar.resetStartCountForTesting();
 
         // Ensure no load events have occured yet.
-        assertEquals(0, startHelper.getCallCount());
-        assertEquals(0, finishHelper.getCallCount());
+        Assert.assertEquals(0, startHelper.getCallCount());
+        Assert.assertEquals(0, finishHelper.getCallCount());
 
-        loadUrl(testServer.getURL(TEST_PAGE));
+        mActivityTestRule.loadUrl(testServer.getURL(TEST_PAGE));
 
         // Wait for the initial page to be loaded if it hasn't already.
         if (finishHelper.getCallCount() == 0) {
@@ -86,23 +99,23 @@
         }
 
         // Exactly one start load and one finish load event should have occured.
-        assertEquals(1, startHelper.getCallCount());
-        assertEquals(1, finishHelper.getCallCount());
+        Assert.assertEquals(1, startHelper.getCallCount());
+        Assert.assertEquals(1, finishHelper.getCallCount());
 
         // Load content in the iframe of the test page to trigger another load.
         JavaScriptUtils.executeJavaScript(webContents, "loadIframeInPage();");
 
         // A load start will be triggered.
         startHelper.waitForCallback(startHelper.getCallCount(), 1);
-        assertEquals(2, startHelper.getCallCount());
+        Assert.assertEquals(2, startHelper.getCallCount());
 
         // Wait for the iframe to finish loading.
         finishHelper.waitForCallback(finishHelper.getCallCount(), 1);
-        assertEquals(2, finishHelper.getCallCount());
+        Assert.assertEquals(2, finishHelper.getCallCount());
 
         // Though the page triggered two load events, the progress bar should have only appeared a
         // single time.
-        assertEquals(1, progressBar.getStartCountForTesting());
+        Assert.assertEquals(1, progressBar.getStartCountForTesting());
     }
 
     /**
@@ -110,6 +123,7 @@
      * results in a hidden progress bar.
      * @throws InterruptedException
      */
+    @Test
     @Feature({"Android-Toolbar"})
     @MediumTest
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE)
@@ -122,8 +136,10 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                progressBar.set(
-                        getActivity().getToolbarManager().getToolbarLayout().getProgressBar());
+                progressBar.set(mActivityTestRule.getActivity()
+                                        .getToolbarManager()
+                                        .getToolbarLayout()
+                                        .getProgressBar());
                 progressBar.get().setAlphaAnimationDuration(10);
                 progressBar.get().setHidingDelay(10);
                 progressBar.get().animate().setListener(new AnimatorListener() {
@@ -172,8 +188,8 @@
             while (!animationEnded.get() && System.currentTimeMillis() < deadline) {
                 onAnimationEnd.wait(deadline - System.currentTimeMillis());
             }
-            assertEquals(1.0f, progressBar.get().getAlpha());
-            assertEquals(View.VISIBLE, progressBar.get().getVisibility());
+            Assert.assertEquals(1.0f, progressBar.get().getAlpha(), 0);
+            Assert.assertEquals(View.VISIBLE, progressBar.get().getVisibility());
         }
 
         // Clear progress and check that the progress bar is hidden.
@@ -190,8 +206,8 @@
             while (!animationEnded.get() && System.currentTimeMillis() < deadline) {
                 onAnimationEnd.wait(deadline - System.currentTimeMillis());
             }
-            assertEquals(0.0f, progressBar.get().getAlpha());
-            assertNotSame(View.VISIBLE, progressBar.get().getVisibility());
+            Assert.assertEquals(0.0f, progressBar.get().getAlpha(), 0);
+            Assert.assertNotSame(View.VISIBLE, progressBar.get().getVisibility());
         }
     }
 }
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 86d7e63..29f329545 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -978,9 +978,6 @@
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_FOUND_PRINTER" desc="The printer-found message shown in the manually add printer dialog.">
       Printer found
     </message>
-    <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_MANUFACTURER_MODEL" desc="The message shown in the select manufacturer and model dialog.">
-      Could not detect your printer model. Select a manufacturer and model from the list.
-    </message>
     <message name="IDS_SETTINGS_PRINTING_CUPS_PRINTER_MANUFACTURER" desc="Label for the dropdown menu to select a manufacturer for the printer.">
       Manufacturer
     </message>
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index e8e64fa..13896fb0 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -2164,7 +2164,7 @@
   {
     content::WebContentsAddedObserver observer;
     ASSERT_TRUE(content::ExecuteScript(old_contents,
-                                       "window.name = 'test-name';\n"
+                                       "window.name = 'old-contents';\n"
                                        "chrome.windows.create({url: '" +
                                            extension_url.spec() + "'})"));
     new_contents = observer.GetWebContents();
@@ -2184,6 +2184,16 @@
       new_contents, "window.domAutomationController.send(!!window.opener)",
       &window_opener_cast_to_bool));
   EXPECT_FALSE(window_opener_cast_to_bool);
+
+  // Verify that |new_contents| can find |old_contents| using window.open/name.
+  std::string location_of_other_window;
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      new_contents,
+      "var w = window.open('', 'old-contents');\n"
+      "window.domAutomationController.send(w.location.href);",
+      &location_of_other_window));
+  EXPECT_EQ(old_contents->GetMainFrame()->GetLastCommittedURL().spec(),
+            location_of_other_window);
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/resources/print_preview/cloud_print_interface.js b/chrome/browser/resources/print_preview/cloud_print_interface.js
index cacf1db..864f493 100644
--- a/chrome/browser/resources/print_preview/cloud_print_interface.js
+++ b/chrome/browser/resources/print_preview/cloud_print_interface.js
@@ -2,9 +2,31 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+cr.exportPath('cloudprint');
+
+/**
+ * Event types dispatched by the cloudprint interface.
+ * @enum {string}
+ */
+cloudprint.CloudPrintInterfaceEventType = {
+  INVITES_DONE: 'cloudprint.CloudPrintInterface.INVITES_DONE',
+  INVITES_FAILED: 'cloudprint.CloudPrintInterface.INVITES_FAILED',
+  PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE',
+  PRINTER_FAILED: 'cloudprint.CloudPrintInterface.PRINTER_FAILED',
+  PROCESS_INVITE_DONE: 'cloudprint.CloudPrintInterface.PROCESS_INVITE_DONE',
+  PROCESS_INVITE_FAILED:
+      'cloudprint.CloudPrintInterface.PROCESS_INVITE_FAILED',
+  SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE',
+  SEARCH_FAILED: 'cloudprint.CloudPrintInterface.SEARCH_FAILED',
+  SUBMIT_DONE: 'cloudprint.CloudPrintInterface.SUBMIT_DONE',
+  SUBMIT_FAILED: 'cloudprint.CloudPrintInterface.SUBMIT_FAILED',
+};
+
 cr.define('cloudprint', function() {
   'use strict';
 
+  var CloudPrintInterfaceEventType = cloudprint.CloudPrintInterfaceEventType;
+
   /**
    * API to the Google Cloud Print service.
    * @param {string} baseUrl Base part of the Google Cloud Print service URL
@@ -67,14 +89,14 @@
 
     /**
      * Pending requests delayed until we get access token.
-     * @type {!Array<!CloudPrintRequest>}
+     * @type {!Array<!cloudprint.CloudPrintRequest>}
      * @private
      */
     this.requestQueue_ = [];
 
     /**
      * Outstanding cloud destination search requests.
-     * @type {!Array<!CloudPrintRequest>}
+     * @type {!Array<!cloudprint.CloudPrintRequest>}
      * @private
      */
     this.outstandingCloudSearchRequests_ = [];
@@ -87,25 +109,7 @@
     this.tracker_ = new EventTracker();
 
     this.addEventListeners_();
-  };
-
-  /**
-   * Event types dispatched by the interface.
-   * @enum {string}
-   */
-  CloudPrintInterface.EventType = {
-    INVITES_DONE: 'cloudprint.CloudPrintInterface.INVITES_DONE',
-    INVITES_FAILED: 'cloudprint.CloudPrintInterface.INVITES_FAILED',
-    PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE',
-    PRINTER_FAILED: 'cloudprint.CloudPrintInterface.PRINTER_FAILED',
-    PROCESS_INVITE_DONE: 'cloudprint.CloudPrintInterface.PROCESS_INVITE_DONE',
-    PROCESS_INVITE_FAILED:
-        'cloudprint.CloudPrintInterface.PROCESS_INVITE_FAILED',
-    SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE',
-    SEARCH_FAILED: 'cloudprint.CloudPrintInterface.SEARCH_FAILED',
-    SUBMIT_DONE: 'cloudprint.CloudPrintInterface.SUBMIT_DONE',
-    SUBMIT_FAILED: 'cloudprint.CloudPrintInterface.SUBMIT_FAILED',
-  };
+  }
 
   /**
    * Content type header value for a URL encoded HTTP request.
@@ -183,8 +187,8 @@
 
     /**
      * Sends Google Cloud Print search API request.
-     * @param {string=} opt_account Account the search is sent for. When
-     *      omitted, the search is done on behalf of the primary user.
+     * @param {?string=} opt_account Account the search is sent for. When
+     *      null or omitted, the search is done on behalf of the primary user.
      * @param {print_preview.DestinationOrigin=} opt_origin When specified,
      *     searches destinations for {@code opt_origin} only, otherwise starts
      *     searches for all origins.
@@ -262,8 +266,8 @@
       var params = [
         new HttpParam('printerid', invitation.destination.id),
         new HttpParam('email', invitation.scopeId),
-        new HttpParam('accept', accept),
-        new HttpParam('use_cdd', true),
+        new HttpParam('accept', accept ? 'true' : 'false'),
+        new HttpParam('use_cdd', 'true'),
       ];
       this.sendOrQueueRequest_(this.buildRequest_(
           'POST',
@@ -332,7 +336,7 @@
           'printer',
           params,
           origin,
-          account,
+          account || '',
           this.onPrinterDone_.bind(this, printerId)));
     },
 
@@ -357,9 +361,9 @@
      * @param {?string} account Account the request is sent for. Can be
      *     {@code null} or empty string if the request is not cookie bound or
      *     is sent on behalf of the primary user.
-     * @param {function(number, Object, !print_preview.DestinationOrigin)}
-     *     callback Callback to invoke when request completes.
-     * @return {!CloudPrintRequest} Partially prepared request.
+     * @param {function(!cloudprint.CloudPrintRequest)} callback Callback to
+     *     invoke when request completes.
+     * @return {!cloudprint.CloudPrintRequest} Partially prepared request.
      * @private
      */
     buildRequest_: function(method, action, params, origin, account, callback) {
@@ -411,13 +415,14 @@
         xhr.setRequestHeader(header, headers[header]);
       }
 
-      return new CloudPrintRequest(xhr, body, origin, account, callback);
+      return new cloudprint.CloudPrintRequest(xhr, body, origin, account,
+                                              callback);
     },
 
     /**
      * Sends a request to the Google Cloud Print API or queues if it needs to
      *     wait OAuth2 access token.
-     * @param {!CloudPrintRequest} request Request to send or queue.
+     * @param {!cloudprint.CloudPrintRequest} request Request to send or queue.
      * @private
      */
     sendOrQueueRequest_: function(request) {
@@ -431,7 +436,7 @@
 
     /**
      * Sends a request to the Google Cloud Print API.
-     * @param {!CloudPrintRequest} request Request to send.
+     * @param {!cloudprint.CloudPrintRequest} request Request to send.
      * @private
      */
     sendRequest_: function(request) {
@@ -442,8 +447,10 @@
 
     /**
      * Creates a Google Cloud Print interface error that is ready to dispatch.
-     * @param {!CloudPrintInterface.EventType} type Type of the error.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintInterfaceEventType} type Type of the
+     *     error.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @return {!Event} Google Cloud Print interface error event.
      * @private
      */
@@ -463,7 +470,8 @@
 
     /**
      * Updates user info and session index from the {@code request} response.
-     * @param {!CloudPrintRequest} request Request to extract user info from.
+     * @param {!cloudprint.CloudPrintRequest} request Request to extract user
+     *     info from.
      * @private
      */
     setUsers_: function(request) {
@@ -523,13 +531,14 @@
     /**
      * Called when the ready-state of a XML http request changes.
      * Calls the successCallback with the result or dispatches an ERROR event.
-     * @param {!CloudPrintRequest} request Request that was changed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that was changed.
      * @private
      */
     onReadyStateChange_: function(request) {
       if (request.xhr.readyState == 4) {
         if (request.xhr.status == 200) {
-          request.result = JSON.parse(request.xhr.responseText);
+          request.result = /** @type {Object} */ (
+              JSON.parse(request.xhr.responseText));
           if (request.origin == print_preview.DestinationOrigin.COOKIES &&
               request.result['success']) {
             this.xsrfTokens_[request.result['request']['user']] =
@@ -545,7 +554,8 @@
      * Called when the search request completes.
      * @param {boolean} isRecent Whether the search request was for recent
      *     destinations.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @private
      */
     onSearchDone_: function(isRecent, request) {
@@ -580,13 +590,13 @@
         // Extract and store users.
         this.setUsers_(request);
         // Dispatch SEARCH_DONE event.
-        event = new Event(CloudPrintInterface.EventType.SEARCH_DONE);
+        event = new Event(CloudPrintInterfaceEventType.SEARCH_DONE);
         event.origin = request.origin;
         event.printers = printerList;
         event.isRecent = isRecent;
       } else {
         event = this.createErrorEvent_(
-            CloudPrintInterface.EventType.SEARCH_FAILED,
+            CloudPrintInterfaceEventType.SEARCH_FAILED,
             request);
       }
       event.user = activeUser;
@@ -596,7 +606,8 @@
 
     /**
      * Called when invitations search request completes.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @private
      */
     onInvitesDone_: function(request) {
@@ -618,11 +629,11 @@
           }
         });
         // Dispatch INVITES_DONE event.
-        event = new Event(CloudPrintInterface.EventType.INVITES_DONE);
+        event = new Event(CloudPrintInterfaceEventType.INVITES_DONE);
         event.invitations = invitationList;
       } else {
         event = this.createErrorEvent_(
-            CloudPrintInterface.EventType.INVITES_FAILED, request);
+            CloudPrintInterfaceEventType.INVITES_FAILED, request);
       }
       event.user = activeUser;
       this.dispatchEvent(event);
@@ -632,7 +643,8 @@
      * Called when invitation processing request completes.
      * @param {!print_preview.Invitation} invitation Processed invitation.
      * @param {boolean} accept Whether this invitation was accepted or rejected.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @private
      */
     onProcessInviteDone_: function(invitation, accept, request) {
@@ -642,7 +654,7 @@
            request.result['request'] &&
            request.result['request']['user']) || '';
       if (request.xhr.status == 200 && request.result['success']) {
-        event = new Event(CloudPrintInterface.EventType.PROCESS_INVITE_DONE);
+        event = new Event(CloudPrintInterfaceEventType.PROCESS_INVITE_DONE);
         if (accept) {
           try {
             event.printer = cloudprint.CloudDestinationParser.parse(
@@ -653,7 +665,7 @@
         }
       } else {
         event = this.createErrorEvent_(
-            CloudPrintInterface.EventType.PROCESS_INVITE_FAILED, request);
+            CloudPrintInterfaceEventType.PROCESS_INVITE_FAILED, request);
       }
       event.invitation = invitation;
       event.accept = accept;
@@ -663,18 +675,19 @@
 
     /**
      * Called when the submit request completes.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @private
      */
     onSubmitDone_: function(request) {
       if (request.xhr.status == 200 && request.result['success']) {
         var submitDoneEvent = new Event(
-            CloudPrintInterface.EventType.SUBMIT_DONE);
+            CloudPrintInterfaceEventType.SUBMIT_DONE);
         submitDoneEvent.jobId = request.result['job']['id'];
         this.dispatchEvent(submitDoneEvent);
       } else {
         var errorEvent = this.createErrorEvent_(
-            CloudPrintInterface.EventType.SUBMIT_FAILED, request);
+            CloudPrintInterfaceEventType.SUBMIT_FAILED, request);
         this.dispatchEvent(errorEvent);
       }
     },
@@ -682,7 +695,8 @@
     /**
      * Called when the printer request completes.
      * @param {string} destinationId ID of the destination that was looked up.
-     * @param {!CloudPrintRequest} request Request that has been completed.
+     * @param {!cloudprint.CloudPrintRequest} request Request that has been
+     *     completed.
      * @private
      */
     onPrinterDone_: function(destinationId, request) {
@@ -725,12 +739,12 @@
           return;
         }
         var printerDoneEvent =
-            new Event(CloudPrintInterface.EventType.PRINTER_DONE);
+            new Event(CloudPrintInterfaceEventType.PRINTER_DONE);
         printerDoneEvent.printer = printer;
         this.dispatchEvent(printerDoneEvent);
       } else {
         var errorEvent = this.createErrorEvent_(
-            CloudPrintInterface.EventType.PRINTER_FAILED, request);
+            CloudPrintInterfaceEventType.PRINTER_FAILED, request);
         errorEvent.destinationId = destinationId;
         errorEvent.destinationOrigin = request.origin;
         this.dispatchEvent(errorEvent);
@@ -746,8 +760,8 @@
    * @param {?string} account Account the request is sent for. Can be
    *     {@code null} or empty string if the request is not cookie bound or
    *     is sent on behalf of the primary user.
-   * @param {function(!CloudPrintRequest)} callback Callback to invoke when
-   *     request completes.
+   * @param {function(!cloudprint.CloudPrintRequest)} callback Callback to
+   *     invoke when request completes.
    * @constructor
    */
   function CloudPrintRequest(xhr, body, origin, account, callback) {
@@ -777,7 +791,7 @@
 
     /**
      * Callback to invoke when request completes.
-     * @type {function(!CloudPrintRequest)}
+     * @type {function(!cloudprint.CloudPrintRequest)}
      */
     this.callback = callback;
 
@@ -786,7 +800,7 @@
      * @type {Object} JSON response.
      */
     this.result = null;
-  };
+  }
 
   /**
    * Data structure that represents an HTTP parameter.
@@ -806,10 +820,11 @@
      * @type {string}
      */
     this.value = value;
-  };
+  }
 
   // Export
   return {
-    CloudPrintInterface: CloudPrintInterface
+    CloudPrintInterface: CloudPrintInterface,
+    CloudPrintRequest: CloudPrintRequest
   };
 });
diff --git a/chrome/browser/resources/print_preview/common/overlay.js b/chrome/browser/resources/print_preview/common/overlay.js
index fc2f1b86..9ff7f753 100644
--- a/chrome/browser/resources/print_preview/common/overlay.js
+++ b/chrome/browser/resources/print_preview/common/overlay.js
@@ -12,7 +12,7 @@
    */
   function Overlay() {
     print_preview.Component.call(this);
-  };
+  }
 
   Overlay.prototype = {
     __proto__: print_preview.Component.prototype,
diff --git a/chrome/browser/resources/print_preview/common/search_box.js b/chrome/browser/resources/print_preview/common/search_box.js
index 836bddb..c94fd09f 100644
--- a/chrome/browser/resources/print_preview/common/search_box.js
+++ b/chrome/browser/resources/print_preview/common/search_box.js
@@ -31,7 +31,7 @@
      * @private {HTMLInputElement}
      */
     this.input_ = null;
-  };
+  }
 
   /**
    * Enumeration of event types dispatched from the search box.
diff --git a/chrome/browser/resources/print_preview/component.js b/chrome/browser/resources/print_preview/component.js
index 0b53d1e..5431b74 100644
--- a/chrome/browser/resources/print_preview/component.js
+++ b/chrome/browser/resources/print_preview/component.js
@@ -35,7 +35,7 @@
      * @private
      */
     this.children_ = [];
-  };
+  }
 
   Component.prototype = {
     __proto__: cr.EventTarget.prototype,
@@ -165,7 +165,8 @@
      * @return {!HTMLElement} Element selected by the given query.
      */
     getChildElement: function(query) {
-      return assert(this.element_.querySelector(query));
+      return /** @type {!HTMLElement} */ (
+          assert(this.element_.querySelector(query)));
     },
 
     /**
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js
index 05c60f87..bc55356e 100644
--- a/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -913,23 +913,23 @@
       this.cloudPrintInterface_ = cloudPrintInterface;
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.SEARCH_DONE,
+          cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE,
           this.onCloudPrintSearchDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.SEARCH_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.SEARCH_FAILED,
           this.onCloudPrintSearchDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PRINTER_DONE,
+          cloudprint.CloudPrintInterfaceEventType.PRINTER_DONE,
           this.onCloudPrintPrinterDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PRINTER_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.PRINTER_FAILED,
           this.onCloudPrintPrinterFailed_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PROCESS_INVITE_DONE,
+          cloudprint.CloudPrintInterfaceEventType.PROCESS_INVITE_DONE,
           this.onCloudPrintProcessInviteDone_.bind(this));
     },
 
@@ -1128,7 +1128,7 @@
         if (origins.length == 0 ||
             (opt_origin && origins.indexOf(opt_origin) < 0)) {
           this.cloudPrintInterface_.search(
-              this.userInfo_.activeUser || '', opt_origin);
+              this.userInfo_.activeUser, opt_origin);
           cr.dispatchSimpleEvent(
               this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED);
         }
diff --git a/chrome/browser/resources/print_preview/data/invitation_store.js b/chrome/browser/resources/print_preview/data/invitation_store.js
index bfc1265..9524ca2 100644
--- a/chrome/browser/resources/print_preview/data/invitation_store.js
+++ b/chrome/browser/resources/print_preview/data/invitation_store.js
@@ -105,19 +105,19 @@
       this.cloudPrintInterface_ = cloudPrintInterface;
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.INVITES_DONE,
+          cloudprint.CloudPrintInterfaceEventType.INVITES_DONE,
           this.onCloudPrintInvitesDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.INVITES_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.INVITES_FAILED,
           this.onCloudPrintInvitesDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PROCESS_INVITE_DONE,
+          cloudprint.CloudPrintInterfaceEventType.PROCESS_INVITE_DONE,
           this.onCloudPrintProcessInviteDone_.bind(this));
       this.tracker_.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PROCESS_INVITE_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.PROCESS_INVITE_FAILED,
           this.onCloudPrintProcessInviteFailed_.bind(this));
     },
 
diff --git a/chrome/browser/resources/print_preview/metrics.js b/chrome/browser/resources/print_preview/metrics.js
index a37a94cd..f301ef0f 100644
--- a/chrome/browser/resources/print_preview/metrics.js
+++ b/chrome/browser/resources/print_preview/metrics.js
@@ -9,7 +9,7 @@
    * Object used to measure usage statistics.
    * @constructor
    */
-  function Metrics() {};
+  function Metrics() {}
 
   /**
    * Enumeration of buckets that a user can enter while using the destination
@@ -105,7 +105,7 @@
 
     /** @private {number} */
     this.maxBucket_ = maxBucket;
-  };
+  }
 
   MetricsContext.prototype = {
     /**
@@ -131,7 +131,7 @@
         this,
         'PrintPreview.DestinationAction',
         Metrics.DestinationSearchBucket.DESTINATION_SEARCH_MAX_BUCKET);
-  };
+  }
 
   DestinationSearchMetricsContext.prototype = {
     __proto__: MetricsContext.prototype
@@ -146,7 +146,7 @@
     MetricsContext.call(this,
                         'PrintPreview.GcpPromo',
                         Metrics.GcpPromoBucket.GCP_PROMO_MAX_BUCKET);
-  };
+  }
 
   GcpPromoMetricsContext.prototype = {
     __proto__: MetricsContext.prototype
@@ -162,7 +162,7 @@
         this,
         'PrintPreview.PrintSettingsUi',
         Metrics.PrintSettingsUiBucket.PRINT_SETTINGS_UI_MAX_BUCKET);
-  };
+  }
 
   PrintSettingsUiMetricsContext.prototype = {
     __proto__: MetricsContext.prototype
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js
index 6e8a86c..e422037 100644
--- a/chrome/browser/resources/print_preview/native_layer.js
+++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -79,7 +79,7 @@
         this.onProvisionalDestinationResolved_.bind(this);
     global.failedToResolveProvisionalPrinter =
         this.failedToResolveProvisionalDestination_.bind(this);
-  };
+  }
 
   /**
    * Event types dispatched from the Chromium native layer.
@@ -304,9 +304,9 @@
         'collate': true,
         'copies': 1,
         'deviceName': destination.id,
-        'dpiHorizontal': "horizontal_dpi" in printTicketStore.dpi.getValue() ?
+        'dpiHorizontal': 'horizontal_dpi' in printTicketStore.dpi.getValue() ?
            printTicketStore.dpi.getValue().horizontal_dpi : 0,
-        'dpiVertical': "vertical_dpi" in printTicketStore.dpi.getValue() ?
+        'dpiVertical': 'vertical_dpi' in printTicketStore.dpi.getValue() ?
            printTicketStore.dpi.getValue().vertical_dpi : 0,
         'duplex': printTicketStore.duplex.getValue() ?
             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
@@ -388,9 +388,9 @@
         'printWithExtension': destination.isExtension,
         'rasterizePDF': printTicketStore.rasterize.getValue(),
         'scaleFactor': printTicketStore.scaling.getValueAsNumber(),
-        'dpiHorizontal': "horizontal_dpi" in printTicketStore.dpi.getValue() ?
+        'dpiHorizontal': 'horizontal_dpi' in printTicketStore.dpi.getValue() ?
            printTicketStore.dpi.getValue().horizontal_dpi : 0,
-        'dpiVertical': "vertical_dpi" in printTicketStore.dpi.getValue() ?
+        'dpiVertical': 'vertical_dpi' in printTicketStore.dpi.getValue() ?
            printTicketStore.dpi.getValue().vertical_dpi : 0,
         'deviceName': destination.id,
         'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
@@ -953,89 +953,77 @@
 
     /**
      * Whether the print preview should be in auto-print mode.
-     * @type {boolean}
-     * @private
+     * @private {boolean}
      */
     this.isInKioskAutoPrintMode_ = isInKioskAutoPrintMode;
 
     /**
      * Whether the print preview should switch to App Kiosk mode.
-     * @type {boolean}
-     * @private
+     * @private {boolean}
      */
     this.isInAppKioskMode_ = isInAppKioskMode;
 
     /**
      * Character delimeter of thousands digits.
-     * @type {string}
-     * @private
+     * @private {string}
      */
     this.thousandsDelimeter_ = thousandsDelimeter;
 
     /**
      * Character delimeter of the decimal point.
-     * @type {string}
-     * @private
+     * @private {string}
      */
     this.decimalDelimeter_ = decimalDelimeter;
 
     /**
      * Unit type of local machine's measurement system.
-     * @type {print_preview.MeasurementSystemUnitType}
-     * @private
+     * @private {print_preview.MeasurementSystemUnitType}
      */
     this.unitType_ = unitType;
 
     /**
      * Whether the document to print is modifiable.
-     * @type {boolean}
-     * @private
+     * @private {boolean}
      */
     this.isDocumentModifiable_ = isDocumentModifiable;
 
     /**
      * Title of the document.
-     * @type {string}
-     * @private
+     * @private {string}
      */
     this.documentTitle_ = documentTitle;
 
     /**
      * Whether the document has selection.
-     * @type {string}
-     * @private
+     * @private {boolean}
      */
     this.documentHasSelection_ = documentHasSelection;
 
     /**
      * Whether selection only should be printed.
-     * @type {string}
-     * @private
+     * @private {boolean}
      */
     this.selectionOnly_ = selectionOnly;
 
     /**
      * ID of the system default destination.
-     * @type {?string}
-     * @private
+     * @private {?string}
      */
     this.systemDefaultDestinationId_ = systemDefaultDestinationId;
 
     /**
      * Serialized app state.
-     * @type {?string}
-     * @private
+     * @private {?string}
      */
     this.serializedAppStateStr_ = serializedAppStateStr;
 
     /**
      * Serialized default destination selection rules.
-     * @type {?string}
-     * @private
+     * @private {?string}
      */
     this.serializedDefaultDestinationSelectionRulesStr_ =
         serializedDefaultDestinationSelectionRulesStr;
-  };
+  }
 
   NativeInitialSettings.prototype = {
     /**
diff --git a/chrome/browser/resources/print_preview/preview_generator.js b/chrome/browser/resources/print_preview/preview_generator.js
index 38575d8..d7396a1 100644
--- a/chrome/browser/resources/print_preview/preview_generator.js
+++ b/chrome/browser/resources/print_preview/preview_generator.js
@@ -144,7 +144,7 @@
     this.tracker_ = new EventTracker();
 
     this.addEventListeners_();
-  };
+  }
 
   /**
    * Event types dispatched by the preview generator.
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.js b/chrome/browser/resources/print_preview/previewarea/preview_area.js
index a8f754e..d7f861ee 100644
--- a/chrome/browser/resources/print_preview/previewarea/preview_area.js
+++ b/chrome/browser/resources/print_preview/previewarea/preview_area.js
@@ -293,8 +293,8 @@
     /**
      * Set a callback that gets called when a key event is received that
      * originates in the plugin.
-     * @param {function(Event)} callback The callback to be called with a key
-     *     event.
+     * @param {function(KeyboardEvent)} callback The callback to be called with
+     *     a key event.
      */
     setPluginKeyEventCallback: function(callback) {
       this.keyEventCallback_ = callback;
diff --git a/chrome/browser/resources/print_preview/print_header.js b/chrome/browser/resources/print_preview/print_header.js
index 8314a11..630c5e19 100644
--- a/chrome/browser/resources/print_preview/print_header.js
+++ b/chrome/browser/resources/print_preview/print_header.js
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// <include src="../../../../ui/webui/resources/js/cr/ui/node_utils.js">
+
 cr.define('print_preview', function() {
   'use strict';
 
@@ -45,7 +47,7 @@
      * @private
      */
     this.isPrintButtonEnabled_ = true;
-  };
+  }
 
   /**
    * Event types dispatched by the print header.
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index fe4a016..03ce8f7 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -6,10 +6,32 @@
 
 // <include src="component.js">
 // <include src="print_preview_focus_manager.js">
+//
+
+cr.exportPath('print_preview');
+
+/**
+ * States of the print preview.
+ * @enum {string}
+ * @private
+ */
+print_preview.PrintPreviewUiState_ = {
+  INITIALIZING: 'initializing',
+  READY: 'ready',
+  OPENING_PDF_PREVIEW: 'opening-pdf-preview',
+  OPENING_NATIVE_PRINT_DIALOG: 'opening-native-print-dialog',
+  PRINTING: 'printing',
+  FILE_SELECTION: 'file-selection',
+  CLOSING: 'closing',
+  ERROR: 'error'
+};
+
 
 cr.define('print_preview', function() {
   'use strict';
 
+  var PrintPreviewUiState_ = print_preview.PrintPreviewUiState_;
+
   /**
    * Container class for Chromium's print preview.
    * @constructor
@@ -270,10 +292,10 @@
 
     /**
      * State of the print preview UI.
-     * @type {print_preview.PrintPreview.UiState_}
+     * @type {print_preview.PrintPreviewUiState_}
      * @private
      */
-    this.uiState_ = PrintPreview.UiState_.INITIALIZING;
+    this.uiState_ = PrintPreviewUiState_.INITIALIZING;
 
     /**
      * Whether document preview generation is in progress.
@@ -288,23 +310,7 @@
      * @private
      */
     this.showSystemDialogBeforeNextPrint_ = false;
-  };
-
-  /**
-   * States of the print preview.
-   * @enum {string}
-   * @private
-   */
-  PrintPreview.UiState_ = {
-    INITIALIZING: 'initializing',
-    READY: 'ready',
-    OPENING_PDF_PREVIEW: 'opening-pdf-preview',
-    OPENING_NATIVE_PRINT_DIALOG: 'opening-native-print-dialog',
-    PRINTING: 'printing',
-    FILE_SELECTION: 'file-selection',
-    CLOSING: 'closing',
-    ERROR: 'error'
-  };
+  }
 
   /**
    * What can happen when print preview tries to print.
@@ -377,13 +383,13 @@
 
       if ($('system-dialog-link')) {
         this.tracker.add(
-            $('system-dialog-link'),
+            getRequiredElement('system-dialog-link'),
             'click',
             this.openSystemPrintDialog_.bind(this));
       }
       if ($('open-pdf-in-preview-link')) {
         this.tracker.add(
-            $('open-pdf-in-preview-link'),
+            getRequiredElement('open-pdf-in-preview-link'),
             'click',
             this.onOpenPdfInPreviewLinkClick_.bind(this));
       }
@@ -529,16 +535,16 @@
      * @private
      */
     printDocumentOrOpenPdfPreview_: function(isPdfPreview) {
-      assert(this.uiState_ == PrintPreview.UiState_.READY,
+      assert(this.uiState_ == PrintPreviewUiState_.READY,
              'Print document request received when not in ready state: ' +
                  this.uiState_);
       if (isPdfPreview) {
-        this.uiState_ = PrintPreview.UiState_.OPENING_PDF_PREVIEW;
+        this.uiState_ = PrintPreviewUiState_.OPENING_PDF_PREVIEW;
       } else if (this.destinationStore_.selectedDestination.id ==
           print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {
-        this.uiState_ = PrintPreview.UiState_.FILE_SELECTION;
+        this.uiState_ = PrintPreviewUiState_.FILE_SELECTION;
       } else {
-        this.uiState_ = PrintPreview.UiState_.PRINTING;
+        this.uiState_ = PrintPreviewUiState_.PRINTING;
       }
       this.setIsEnabled_(false);
       this.printHeader_.isCancelButtonEnabled = true;
@@ -551,7 +557,7 @@
              !this.destinationStore_.selectedDestination.isExtension &&
              this.destinationStore_.selectedDestination.id !=
                  print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) ||
-             this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW) {
+             this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW) {
           // Hide the dialog for now. The actual print command will be issued
           // when the preview generation is done.
           this.nativeLayer_.startHideDialog();
@@ -566,9 +572,9 @@
      */
     printIfReady_: function() {
       var okToPrint =
-          (this.uiState_ == PrintPreview.UiState_.PRINTING ||
-           this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW ||
-           this.uiState_ == PrintPreview.UiState_.FILE_SELECTION ||
+          (this.uiState_ == PrintPreviewUiState_.PRINTING ||
+           this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW ||
+           this.uiState_ == PrintPreviewUiState_.FILE_SELECTION ||
            this.isInKioskAutoPrintMode_) &&
           this.destinationStore_.selectedDestination &&
           this.destinationStore_.selectedDestination.capabilities;
@@ -589,11 +595,11 @@
                     PRINT_WITH_SETTINGS_COLLAPSED);
       }
       this.nativeLayer_.startPrint(
-          this.destinationStore_.selectedDestination,
+          assert(this.destinationStore_.selectedDestination),
           this.printTicketStore_,
           this.cloudPrintInterface_,
           this.documentInfo_,
-          this.uiState_ == PrintPreview.UiState_.OPENING_PDF_PREVIEW,
+          this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW,
           this.showSystemDialogBeforeNextPrint_);
       this.showSystemDialogBeforeNextPrint_ = false;
       return PrintPreview.PrintAttemptResult_.PRINTED;
@@ -605,7 +611,7 @@
      */
     close_: function() {
       this.exitDocument();
-      this.uiState_ = PrintPreview.UiState_.CLOSING;
+      this.uiState_ = PrintPreviewUiState_.CLOSING;
       this.nativeLayer_.startCloseDialog();
     },
 
@@ -625,7 +631,7 @@
       }
       setIsVisible(getRequiredElement('system-dialog-throbber'), true);
       this.setIsEnabled_(false);
-      this.uiState_ = PrintPreview.UiState_.OPENING_NATIVE_PRINT_DIALOG;
+      this.uiState_ = PrintPreviewUiState_.OPENING_NATIVE_PRINT_DIALOG;
       this.nativeLayer_.startShowSystemDialog();
     },
 
@@ -638,10 +644,10 @@
      * @private
      */
     onInitialSettingsSet_: function(event) {
-      assert(this.uiState_ == PrintPreview.UiState_.INITIALIZING,
+      assert(this.uiState_ == PrintPreviewUiState_.INITIALIZING,
              'Updating initial settings when not in initializing state: ' +
                  this.uiState_);
-      this.uiState_ = PrintPreview.UiState_.READY;
+      this.uiState_ = PrintPreviewUiState_.READY;
 
       var settings = event.initialSettings;
       this.isInKioskAutoPrintMode_ = settings.isInKioskAutoPrintMode;
@@ -667,7 +673,7 @@
       $('document-title').innerText = settings.documentTitle;
       this.hideSystemDialogLink_ = settings.isInAppKioskMode;
       if ($('system-dialog-link')) {
-        setIsVisible($('system-dialog-link'),
+        setIsVisible(getRequiredElement('system-dialog-link'),
                      this.shouldShowSystemDialogLink_());
       }
     },
@@ -687,19 +693,19 @@
           event.appKioskMode);
       this.tracker.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.SUBMIT_DONE,
+          cloudprint.CloudPrintInterfaceEventType.SUBMIT_DONE,
           this.onCloudPrintSubmitDone_.bind(this));
       this.tracker.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.SEARCH_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.SEARCH_FAILED,
           this.onCloudPrintError_.bind(this));
       this.tracker.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.SUBMIT_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.SUBMIT_FAILED,
           this.onCloudPrintError_.bind(this));
       this.tracker.add(
           this.cloudPrintInterface_,
-          cloudprint.CloudPrintInterface.EventType.PRINTER_FAILED,
+          cloudprint.CloudPrintInterfaceEventType.PRINTER_FAILED,
           this.onCloudPrintError_.bind(this));
 
       this.destinationStore_.setCloudPrintInterface(this.cloudPrintInterface_);
@@ -716,11 +722,12 @@
      * @private
      */
     onPrintToCloud_: function(event) {
-      assert(this.uiState_ == PrintPreview.UiState_.PRINTING,
+      assert(this.uiState_ == PrintPreviewUiState_.PRINTING,
              'Document ready to be sent to the cloud when not in printing ' +
                  'state: ' + this.uiState_);
       assert(this.cloudPrintInterface_ != null,
              'Google Cloud Print is not enabled');
+      assert(this.destinationStore_.selectedDestination != null);
       this.cloudPrintInterface_.submit(
           this.destinationStore_.selectedDestination,
           this.printTicketStore_,
@@ -734,11 +741,11 @@
      * @private
      */
     onFileSelectionCancel_: function() {
-      assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION,
+      assert(this.uiState_ == PrintPreviewUiState_.FILE_SELECTION,
              'File selection cancelled when not in file-selection state: ' +
                  this.uiState_);
       this.setIsEnabled_(true);
-      this.uiState_ = PrintPreview.UiState_.READY;
+      this.uiState_ = PrintPreviewUiState_.READY;
     },
 
     /**
@@ -746,12 +753,12 @@
      * @private
      */
     onFileSelectionComplete_: function() {
-      assert(this.uiState_ == PrintPreview.UiState_.FILE_SELECTION,
+      assert(this.uiState_ == PrintPreviewUiState_.FILE_SELECTION,
              'File selection completed when not in file-selection state: ' +
                  this.uiState_);
       this.previewArea_.showCustomMessage(
           loadTimeData.getString('printingToPDFInProgress'));
-      this.uiState_ = PrintPreview.UiState_.PRINTING;
+      this.uiState_ = PrintPreviewUiState_.PRINTING;
     },
 
     /**
@@ -760,7 +767,7 @@
      * @private
      */
     onCloudPrintSubmitDone_: function(event) {
-      assert(this.uiState_ == PrintPreview.UiState_.PRINTING,
+      assert(this.uiState_ == PrintPreviewUiState_.PRINTING,
              'Submited job to Google Cloud Print but not in printing state ' +
                  this.uiState_);
       this.close_();
@@ -817,7 +824,7 @@
     onPreviewGenerationFail_: function() {
       this.isPreviewGenerationInProgress_ = false;
       this.printHeader_.isPrintButtonEnabled = false;
-      if (this.uiState_ == PrintPreview.UiState_.PRINTING)
+      if (this.uiState_ == PrintPreviewUiState_.PRINTING)
         this.nativeLayer_.startCancelPendingPrint();
     },
 
@@ -829,7 +836,7 @@
     onOpenPdfInPreviewLinkClick_: function() {
       if ($('open-pdf-in-preview-link').classList.contains('disabled'))
         return;
-      assert(this.uiState_ == PrintPreview.UiState_.READY,
+      assert(this.uiState_ == PrintPreviewUiState_.READY,
              'Trying to open pdf in preview when not in ready state: ' +
                  this.uiState_);
       setIsVisible(getRequiredElement('open-preview-app-throbber'), true);
@@ -844,7 +851,7 @@
      * @private
      */
     onPrintButtonClick_: function() {
-      assert(this.uiState_ == PrintPreview.UiState_.READY,
+      assert(this.uiState_ == PrintPreviewUiState_.READY,
              'Trying to print when not in ready state: ' + this.uiState_);
       this.printDocumentOrOpenPdfPreview_(false /*isPdfPreview*/);
     },
@@ -911,7 +918,7 @@
           this.destinationStore_.selectedDestination &&
           this.printTicketStore_.isTicketValid() &&
           this.printHeader_.isPrintButtonEnabled) {
-        assert(this.uiState_ == PrintPreview.UiState_.READY,
+        assert(this.uiState_ == PrintPreviewUiState_.READY,
             'Trying to print when not in ready state: ' + this.uiState_);
         var activeElementTag = document.activeElement.tagName.toUpperCase();
         if (activeElementTag != 'BUTTON' && activeElementTag != 'SELECT' &&
@@ -931,7 +938,7 @@
      * @private
      */
     onSettingsInvalid_: function() {
-      this.uiState_ = PrintPreview.UiState_.ERROR;
+      this.uiState_ = PrintPreviewUiState_.ERROR;
       this.isPreviewGenerationInProgress_ = false;
       this.printHeader_.isPrintButtonEnabled = false;
       this.previewArea_.cancelTimeout();
@@ -1196,13 +1203,13 @@
      */
     onDestinationSelect_: function() {
       if ($('system-dialog-link')) {
-        setIsVisible($('system-dialog-link'),
+        setIsVisible(getRequiredElement('system-dialog-link'),
                      this.shouldShowSystemDialogLink_());
       }
       // Reset if we had a bad settings fetch since the user selected a new
       // printer.
-      if (this.uiState_ == PrintPreview.UiState_.ERROR)
-        this.uiState_ = PrintPreview.UiState_.READY;
+      if (this.uiState_ == PrintPreviewUiState_.ERROR)
+        this.uiState_ = PrintPreviewUiState_.READY;
       if (this.destinationStore_.selectedDestination &&
           this.isInKioskAutoPrintMode_) {
         this.onPrintButtonClick_();
diff --git a/chrome/browser/resources/print_preview/print_preview_animations.js b/chrome/browser/resources/print_preview/print_preview_animations.js
index 5b7ad05..d931694 100644
--- a/chrome/browser/resources/print_preview/print_preview_animations.js
+++ b/chrome/browser/resources/print_preview/print_preview_animations.js
@@ -73,6 +73,7 @@
   el.style.height = 'auto';
   var height = el.offsetHeight;
   el.style.height = height + 'px';
+  /** @suppress {suspiciousCode} */
   el.offsetHeight;  // Should force an update of the computed style.
   animationEventTracker.add(
       el, 'transitionend', onFadeOutTransitionEnd.bind(el), false);
@@ -129,14 +130,16 @@
   // To make the option visible during the first fade in.
   el.hidden = false;
 
-  var leftColumn = el.querySelector('.left-column');
+  var leftColumn = assertInstanceof(el.querySelector('.left-column'),
+                                    HTMLElement);
   wrapContentsInDiv(leftColumn, ['invisible']);
-  var rightColumn = el.querySelector('.right-column');
+  var rightColumn = assertInstanceof(el.querySelector('.right-column'),
+                                     HTMLElement);
   wrapContentsInDiv(rightColumn, ['invisible']);
 
   var toAnimate = el.querySelectorAll('.collapsible');
   for (var i = 0; i < toAnimate.length; i++)
-    fadeInElement(toAnimate[i], opt_justShow);
+    fadeInElement(assertInstanceof(toAnimate[i], HTMLElement), opt_justShow);
   el.classList.add('visible');
 }
 
@@ -150,10 +153,13 @@
   if (!el.classList.contains('visible'))
     return;
 
-  var leftColumn = el.querySelector('.left-column');
+  var leftColumn = assertInstanceof(el.querySelector('.left-column'),
+                                    HTMLElement);
   wrapContentsInDiv(leftColumn, ['visible']);
-  var rightColumn = el.querySelector('.right-column');
-  wrapContentsInDiv(rightColumn, ['visible']);
+  var rightColumn = assertInstanceof(el.querySelector('.right-column'),
+                                     HTMLElement);
+  if (rightColumn)
+    wrapContentsInDiv(rightColumn, ['visible']);
 
   var toAnimate = el.querySelectorAll('.collapsible');
   for (var i = 0; i < toAnimate.length; i++) {
@@ -162,7 +168,7 @@
       toAnimate[i].classList.add('closing');
       toAnimate[i].classList.remove('visible');
     } else {
-      fadeOutElement(toAnimate[i]);
+      fadeOutElement(assertInstanceof(toAnimate[i], HTMLElement));
     }
   }
   el.classList.remove('visible');
@@ -172,8 +178,8 @@
  * Wraps the contents of |el| in a div element and attaches css classes
  * |classes| in the new div, only if has not been already done. It is necessary
  * for animating the height of table cells.
- * @param {HTMLElement} el The element to be processed.
- * @param {array} classes The css classes to add.
+ * @param {!HTMLElement} el The element to be processed.
+ * @param {!Array} classes The css classes to add.
  */
 function wrapContentsInDiv(el, classes) {
   var div = el.querySelector('div');
diff --git a/chrome/browser/resources/print_preview/print_preview_focus_manager.js b/chrome/browser/resources/print_preview/print_preview_focus_manager.js
index b5d74ef..921b53a 100644
--- a/chrome/browser/resources/print_preview/print_preview_focus_manager.js
+++ b/chrome/browser/resources/print_preview/print_preview_focus_manager.js
@@ -12,7 +12,7 @@
    * @extends {cr.ui.FocusManager}
    */
   function PrintPreviewFocusManager() {
-  };
+  }
 
   cr.addSingletonGetter(PrintPreviewFocusManager);
 
diff --git a/chrome/browser/resources/print_preview/print_preview_utils.js b/chrome/browser/resources/print_preview/print_preview_utils.js
index 4c059bb..56e2813 100644
--- a/chrome/browser/resources/print_preview/print_preview_utils.js
+++ b/chrome/browser/resources/print_preview/print_preview_utils.js
@@ -216,8 +216,8 @@
 }
 
 /**
- * @param {!goog.array.ArrayLike<!{locale: string, value: string}>}
- *     localizedStrings An array of strings with corresponding locales.
+ * @param {!Array<!{locale: string, value: string}>} localizedStrings An array
+ *     of strings with corresponding locales.
  * @param {string} locale Locale to look the string up for.
  * @return {string} A string for the requested {@code locale}. An empty string
  *     if there's no string for the specified locale found.
@@ -232,8 +232,8 @@
 }
 
 /**
- * @param {!goog.array.ArrayLike<!{locale: string, value: string}>}
- *     localizedStrings An array of strings with corresponding locales.
+ * @param {!Array<!{locale: string, value: string}>} localizedStrings An array
+ *     of strings with corresponding locales.
  * @return {string} A string for the current locale. An empty string if there's
  *     no string for the current locale found.
  */
diff --git a/chrome/browser/resources/settings/controls/controlled_button.html b/chrome/browser/resources/settings/controls/controlled_button.html
index ddad0bd..df305d10 100644
--- a/chrome/browser/resources/settings/controls/controlled_button.html
+++ b/chrome/browser/resources/settings/controls/controlled_button.html
@@ -29,11 +29,15 @@
       }
 
       :host(:not([end-justified])) cr-policy-pref-indicator {
-        -webkit-margin-start: var(--justify-margin);
+        -webkit-margin-end: calc(
+            var(--cr-control-spacing) - var(--justify-margin));
+        -webkit-margin-start: var(--cr-control-spacing);
       }
 
       :host([end-justified]) cr-policy-pref-indicator {
-        -webkit-margin-end: var(--justify-margin);
+        -webkit-margin-end: var(--cr-control-spacing);
+        -webkit-margin-start: calc(
+            var(--cr-control-spacing) - var(--justify-margin));
         order: -1;
       }
     </style>
diff --git a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
index 867ac2c9..e3b615e 100644
--- a/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
+++ b/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
@@ -275,9 +275,6 @@
     <add-printer-dialog>
       <div class="dialog-title">$i18n{addPrintersManuallyTitle}</div>
       <div class="dialog-body">
-        <div class="settings-box first">
-          $i18n{selectManufacturerModelMessage}
-        </div>
         <div class="settings-box two-line">
           <div class="start">
             <div class="label">$i18n{printerManufacturer}</div>
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 87902bb..fe4c694 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -296,7 +296,7 @@
   // updating the text in the omnibox but this alert and GetAccessibleNodeData
   // below make the answer contents accessible.
   if (match_.answer)
-    NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+    NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
 }
 
 gfx::Size OmniboxResultView::GetPreferredSize() const {
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 7cd352b..f962577 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1449,8 +1449,6 @@
     {"searchingPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SEARCHING_PRINTER},
     {"printerNotFound", IDS_SETTINGS_PRINTING_CUPS_PRINTER_NOT_FOUND_PRINTER},
     {"printerFound", IDS_SETTINGS_PRINTING_CUPS_PRINTER_FOUND_PRINTER},
-    {"selectManufacturerModelMessage",
-     IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_MANUFACTURER_MODEL},
     {"printerManufacturer", IDS_SETTINGS_PRINTING_CUPS_PRINTER_MANUFACTURER},
     {"selectDriver", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_DRIVER},
     {"selectDriverButtonText",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
index 7dff367..e64931ca 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
@@ -4,13 +4,14 @@
 
 package org.chromium.chrome.test.util;
 
-import android.test.ActivityInstrumentationTestCase2;
+import android.app.Activity;
+import android.app.Instrumentation;
 import android.text.SpannableString;
 import android.text.style.ClickableSpan;
 import android.view.View;
 import android.widget.TextView;
 
-import junit.framework.Assert;
+import org.junit.Assert;
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.infobar.InfoBar;
@@ -25,11 +26,9 @@
 public class TranslateUtil {
     /**
      * Finds the first clickable span inside a TextView and clicks it.
-     *
-     * @return True if the panel is opened.
      */
-    public static void openLanguagePanel(ActivityInstrumentationTestCase2<?> test,
-            InfoBar infoBar) {
+    public static void openLanguagePanel(
+            Instrumentation instrumentation, Activity activity, InfoBar infoBar) {
         View view = infoBar.getView().findViewById(R.id.infobar_message);
         Assert.assertNotNull(view);
 
@@ -52,10 +51,9 @@
         float xPos = text.getPaddingLeft() + (sizePerChar * x);
         float yPos = text.getHeight() / (float) 2;
 
-        TestTouchUtils.singleClickView(test.getInstrumentation(), text, (int) xPos, (int) yPos);
+        TestTouchUtils.singleClickView(instrumentation, text, (int) xPos, (int) yPos);
 
-        assertInfoBarText(infoBar, test.getActivity().getString(
-                R.string.translate_infobar_change_languages));
+        assertInfoBarText(infoBar, activity.getString(R.string.translate_infobar_change_languages));
     }
 
     public static void assertInfoBarText(InfoBar infoBar, String expectedText) {
diff --git a/chrome/test/data/webui/print_preview.js b/chrome/test/data/webui/print_preview.js
index 81e518968..68d90b86 100644
--- a/chrome/test/data/webui/print_preview.js
+++ b/chrome/test/data/webui/print_preview.js
@@ -116,9 +116,9 @@
         __proto__: cr.EventTarget.prototype,
         search: function(isRecent) {}
       };
-      var oldCpInterfaceEventType = cloudprint.CloudPrintInterface.EventType;
+      var oldCpInterfaceEventType = cloudprint.CloudPrintInterfaceEventType;
       cloudprint.CloudPrintInterface = CloudPrintInterfaceStub;
-      cloudprint.CloudPrintInterface.EventType = oldCpInterfaceEventType;
+      cloudprint.CloudPrintInterfaceEventType = oldCpInterfaceEventType;
 
       print_preview.PreviewArea.prototype.checkPluginCompatibility_ =
           function() {
@@ -325,7 +325,7 @@
   this.nativeLayer_.dispatchEvent(cloudPrintEnableEvent);
 
   var searchDoneEvent =
-      new Event(cloudprint.CloudPrintInterface.EventType.SEARCH_DONE);
+      new Event(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE);
   searchDoneEvent.printers = [];
   searchDoneEvent.isRecent = true;
   searchDoneEvent.email = 'foo@chromium.org';
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 6a0becb..ba29a636 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1321,15 +1321,22 @@
   const base::TimeDelta fifteen_minutes = base::TimeDelta::FromMinutes(15);
   int upload_decision_metrics = 0;
   bool has_profile = false;
+  bool has_modified_profile = false;
 
-  // First, collect all of the addresses used recently.
+  // First, collect all of the addresses used or modified recently.
   for (AutofillProfile* profile : personal_data_->GetProfiles()) {
     has_profile = true;
-    if ((now - profile->use_date()) < fifteen_minutes ||
-        (now - profile->modification_date()) < fifteen_minutes) {
+    if ((now - profile->modification_date()) < fifteen_minutes) {
+      has_modified_profile = true;
+      candidate_profiles.push_back(*profile);
+    } else if ((now - profile->use_date()) < fifteen_minutes) {
       candidate_profiles.push_back(*profile);
     }
   }
+
+  AutofillMetrics::LogHasModifiedProfileOnCreditCardFormSubmission(
+      has_modified_profile);
+
   if (candidate_profiles.empty()) {
     upload_decision_metrics |=
         has_profile
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 4b3a699..be3d39fd 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -4677,6 +4677,9 @@
                                  AutofillMetrics::UPLOAD_OFFERED);
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+  // Verify the histogram entry for recent profile modification.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.HasModifiedProfile.CreditCardFormSubmission", true, 1);
 }
 
 TEST_F(AutofillManagerTest, UploadCreditCardAndSaveCopy) {
@@ -5201,6 +5204,9 @@
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(
       AutofillMetrics::UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS);
+  // Verify the histogram entry for recent profile modification.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.HasModifiedProfile.CreditCardFormSubmission", false, 1);
 }
 
 TEST_F(AutofillManagerTest,
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index 3134024..b2a6e3a8c 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -619,6 +619,13 @@
 }
 
 // static
+void AutofillMetrics::LogHasModifiedProfileOnCreditCardFormSubmission(
+    bool has_modified_profile) {
+  UMA_HISTOGRAM_BOOLEAN("Autofill.HasModifiedProfile.CreditCardFormSubmission",
+                        has_modified_profile);
+}
+
+// static
 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) {
   UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
 }
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index f3ff719..32b1148 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -754,6 +754,11 @@
   static void LogNumberOfProfilesAtAutofillableFormSubmission(
       size_t num_profiles);
 
+  // Log whether user modified an address profile shortly before submitting
+  // credit card form.
+  static void LogHasModifiedProfileOnCreditCardFormSubmission(
+      bool has_modified_profile);
+
   // Log the number of Autofill suggestions presented to the user when filling a
   // form.
   static void LogAddressSuggestionsCount(size_t num_suggestions);
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc
index 655739c..8adab71 100644
--- a/components/cdm/browser/cdm_message_filter_android.cc
+++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -51,8 +51,8 @@
 };
 
 const CodecInfo<media::AudioCodec> kAudioCodecsToQuery[] = {
+    // Vorbis is not supported. See http://crbug.com/710924 for details.
     {media::EME_CODEC_WEBM_OPUS, media::kCodecOpus, "video/webm"},
-    {media::EME_CODEC_WEBM_VORBIS, media::kCodecVorbis, "video/webm"},
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
     {media::EME_CODEC_MP4_AAC, media::kCodecAAC, "video/mp4"},
 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc
index e2e0d2b..d5386a1 100644
--- a/components/favicon/core/favicon_handler.cc
+++ b/components/favicon/core/favicon_handler.cc
@@ -220,7 +220,8 @@
 }
 
 void FaviconHandler::FetchFavicon(const GURL& url) {
-  cancelable_task_tracker_.TryCancelAll();
+  cancelable_task_tracker_for_page_url_.TryCancelAll();
+  cancelable_task_tracker_for_candidates_.TryCancelAll();
 
   url_ = url;
 
@@ -242,7 +243,7 @@
       url_, icon_types_, preferred_icon_size(),
       base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService,
                  base::Unretained(this)),
-      &cancelable_task_tracker_);
+      &cancelable_task_tracker_for_page_url_);
 }
 
 bool FaviconHandler::UpdateFaviconCandidate(
@@ -282,8 +283,7 @@
 void FaviconHandler::NotifyFaviconUpdated(
     const std::vector<favicon_base::FaviconRawBitmapResult>&
         favicon_bitmap_results) {
-  if (favicon_bitmap_results.empty())
-    return;
+  DCHECK(!favicon_bitmap_results.empty());
 
   gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
       favicon_bitmap_results,
@@ -339,6 +339,7 @@
     return;
   }
 
+  cancelable_task_tracker_for_candidates_.TryCancelAll();
   download_request_.Cancel();
   candidates_ = std::move(sorted_candidates);
   num_download_requests_ = 0;
@@ -456,7 +457,8 @@
 
 bool FaviconHandler::HasPendingTasksForTest() {
   return !download_request_.IsCancelled() ||
-         cancelable_task_tracker_.HasTrackedTasks();
+         cancelable_task_tracker_for_page_url_.HasTrackedTasks() ||
+         cancelable_task_tracker_for_candidates_.HasTrackedTasks();
 }
 
 bool FaviconHandler::ShouldSaveFavicon() {
@@ -509,7 +511,7 @@
       service_->GetFavicon(
           icon_url, icon_type, preferred_icon_size(),
           base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
-          &cancelable_task_tracker_);
+          &cancelable_task_tracker_for_candidates_);
     } else {
       // Ask the history service for the icon. This does two things:
       // 1. Attempts to fetch the favicon data from the database.
@@ -519,14 +521,13 @@
       service_->UpdateFaviconMappingsAndFetch(
           url_, icon_url, icon_type, preferred_icon_size(),
           base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
-          &cancelable_task_tracker_);
+          &cancelable_task_tracker_for_candidates_);
     }
   }
 }
 
 void FaviconHandler::OnFaviconData(const std::vector<
     favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) {
-  bool has_results = !favicon_bitmap_results.empty();
   bool has_valid_result = HasValidResult(favicon_bitmap_results);
   bool has_expired_or_incomplete_result =
       !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(),
@@ -540,14 +541,6 @@
     NotifyFaviconUpdated(favicon_bitmap_results);
   }
 
-  if (!current_candidate() ||
-      (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url,
-                                           current_candidate()->icon_type,
-                                           favicon_bitmap_results))) {
-    // The icon URLs have been updated since the favicon data was requested.
-    return;
-  }
-
   if (has_expired_or_incomplete_result) {
     ScheduleDownload(current_candidate()->icon_url,
                      current_candidate()->icon_type);
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h
index 30c0b1df..b49f4e5 100644
--- a/components/favicon/core/favicon_handler.h
+++ b/components/favicon/core/favicon_handler.h
@@ -255,10 +255,15 @@
     return download_largest_icon_ ? 0 : gfx::kFaviconSize;
   }
 
-  // Used for FaviconService requests.
-  base::CancelableTaskTracker cancelable_task_tracker_;
+  // Used for the GetFaviconForPageURL() request looking up the page URL,
+  // triggered in FetchFavicon().
+  base::CancelableTaskTracker cancelable_task_tracker_for_page_url_;
 
-  FaviconDriverObserver::NotificationIconType handler_type_;
+  // Used for various FaviconService methods triggered while processing
+  // candidates.
+  base::CancelableTaskTracker cancelable_task_tracker_for_candidates_;
+
+  const FaviconDriverObserver::NotificationIconType handler_type_;
 
   // URL of the page we're requesting the favicon for.
   GURL url_;
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc
index 584484a6..5f8f4913 100644
--- a/components/favicon/core/favicon_handler_unittest.cc
+++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -721,6 +721,43 @@
   EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL3));
 }
 
+// Test that sending an icon URL update different to the previous icon URL
+// update during a database lookup ignores the first icon URL and processes the
+// second.
+TEST_F(FaviconHandlerTest, UpdateDuringDatabaseLookup) {
+  const GURL kIconURL1 = kIconURL16x16;
+  const GURL kIconURL2 = kIconURL64x64;
+
+  // Defer the lookup completion such that RunUntilIdle() doesn't complete the
+  // lookup.
+  favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL1);
+
+  delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
+  delegate_.fake_downloader().Add(kIconURL2, IntVector{64});
+
+  std::unique_ptr<FaviconHandler> handler =
+      RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL1});
+
+  ASSERT_TRUE(VerifyAndClearExpectations());
+  ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+  // SetFavicons() and OnFaviconUpdated() should be called for the new icon URL
+  // and not |kIconURL1|.
+  EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL2, _, _));
+  EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
+
+  handler->OnUpdateFaviconURL(kPageURL,
+                              {FaviconURL(kIconURL2, FAVICON, kEmptySizes)});
+
+  // Finalizes the DB lookup, which should be thrown away as the favicon URLs
+  // were updated.
+  EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL2));
+  EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL2));
+}
+
 // Test that sending an icon URL update identical to the previous icon URL
 // update during image download is a no-op.
 TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileDownloadingShouldBeNoop) {
diff --git a/components/feature_engagement_tracker/internal/feature_config_storage_validator.h b/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
index e3358cf..d0ba4241 100644
--- a/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
+++ b/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
@@ -18,13 +18,13 @@
 struct EventConfig;
 struct FeatureConfig;
 
-// A StorageValidator that uses the FeatureConfiguration from
+// A StorageValidator that uses the FeatureConfig as the source of truth.
 class FeatureConfigStorageValidator : public StorageValidator {
  public:
   FeatureConfigStorageValidator();
   ~FeatureConfigStorageValidator() override;
 
-  // ConditionValidator implementation.
+  // StorageValidator implementation.
   bool ShouldStore(const std::string& event_name) override;
   bool ShouldKeep(const std::string& event_name,
                   uint32_t event_day,
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc
index d54b679..61fa25af 100644
--- a/components/url_formatter/url_formatter.cc
+++ b/components/url_formatter/url_formatter.cc
@@ -523,6 +523,17 @@
   allowed_set.remove(0x2010u);  // Hyphen
   allowed_set.remove(0x2027u);  // Hyphenation Point
 
+#if defined(OS_MACOSX)
+  // The following characters are reported as present in the default macOS
+  // system UI font, but they render as blank. Remove them from the allowed
+  // set to prevent spoofing.
+  // Tibetan characters used for transliteration of ancient texts:
+  allowed_set.remove(0x0F8Cu);
+  allowed_set.remove(0x0F8Du);
+  allowed_set.remove(0x0F8Eu);
+  allowed_set.remove(0x0F8Fu);
+#endif
+
   uspoof_setAllowedUnicodeSet(checker_, &allowed_set, status);
 }
 
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc
index a59b4b6..4b114f0 100644
--- a/components/url_formatter/url_formatter_unittest.cc
+++ b/components/url_formatter/url_formatter_unittest.cc
@@ -355,6 +355,10 @@
   {"xn--ab-yod.com", L"a\x05f4" L"b.com", false},
   // Hebrew Gershayim with Arabic is disallowed.
   {"xn--5eb7h.eg", L"\x0628\x05f4.eg", false},
+#if defined(OS_MACOSX)
+  // Tibetan transliteration characters are disallowed on Mac.
+  {"xn--com-luma.test.pl", L"\u0f8c.test.pl", false},
+#endif
 
   // Hyphens (http://unicode.org/cldr/utility/confusables.jsp?a=-)
   // Hyphen-Minus (the only hyphen allowed)
diff --git a/components/webdata/common/web_data_request_manager.cc b/components/webdata/common/web_data_request_manager.cc
index ec272c0..c52cfd82 100644
--- a/components/webdata/common/web_data_request_manager.cc
+++ b/components/webdata/common/web_data_request_manager.cc
@@ -117,15 +117,15 @@
 void WebDataRequestManager::RequestCompletedOnThread(
     std::unique_ptr<WebDataRequest> request,
     std::unique_ptr<WDTypedResult> result) {
-  // Manipulate the pending_requests_ collection while holding the lock.
+  // Check whether the request is active. It might have been cancelled in
+  // another thread before this completion handler was invoked. This means the
+  // request initiator is no longer interested in the result.
+  if (!request->IsActive())
+    return;
+
+  // Stop tracking the request. The request is already finished, so "stop
+  // tracking" is the same as post-facto cancellation.
   {
-    base::AutoLock l(pending_lock_);
-
-    // Check whether the request is active. It might have been cancelled in
-    // another thread before the lock was acquired.
-    if (!request->IsActive())
-      return;
-
     // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
     // is fixed.
     tracked_objects::ScopedTracker tracking_profile(
@@ -133,20 +133,10 @@
             "422460 "
             "WebDataRequestManager::RequestCompletedOnThread::UpdateMap"));
 
-    // Remove the request object from the pending_requests_ map. Note that this
-    // method has ownership of the object (it was passed by unique_ptr).
-    auto i = pending_requests_.find(request->GetHandle());
-    DCHECK(i != pending_requests_.end());
-    pending_requests_.erase(i);
-
-    // The request is no longer active.
-    request->MarkAsInactive();
+    CancelRequest(request->GetHandle());
   }
 
   // Notify the consumer if needed.
-  //
-  // NOTE: The pending_lock_ is no longer held here. It's up to the consumer to
-  // be appropriately thread safe.
   WebDataServiceConsumer* const consumer = request->GetConsumer();
   if (consumer) {
     // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 0d2e031..3ac1e6c 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -17,6 +17,7 @@
 #include "content/browser/android/content_view_core_impl.h"
 #include "content/browser/android/content_view_render_view.h"
 #include "content/browser/android/content_view_statics.h"
+#include "content/browser/android/context_selection_client.h"
 #include "content/browser/android/date_time_chooser_android.h"
 #include "content/browser/android/dialog_overlay_impl.h"
 #include "content/browser/android/gpu_process_callback.h"
@@ -43,6 +44,7 @@
     {"ChildProcessLauncher", content::RegisterChildProcessLauncher},
     {"ContentFeatureList", content::android::RegisterContentFeatureListJni},
     {"ContentVideoView", content::ContentVideoView::RegisterContentVideoView},
+    {"ContextSelectionClient", content::RegisterContextSelectionClient},
     {"GpuProcessCallback", content::RegisterGpuProcessCallback},
     {"MemoryMonitorAndroid", content::MemoryMonitorAndroid::Register},
     {"BackgroundSyncNetworkObserverAndroid",
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn
index 96e279f..c9b44c0 100644
--- a/ios/chrome/browser/ui/payments/BUILD.gn
+++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -27,6 +27,8 @@
     "payment_request_error_coordinator.mm",
     "payment_request_manager.h",
     "payment_request_manager.mm",
+    "payment_request_mediator.h",
+    "payment_request_mediator.mm",
     "payment_request_view_controller.h",
     "payment_request_view_controller.mm",
     "payment_request_view_controller_actions.h",
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.h b/ios/chrome/browser/ui/payments/payment_request_coordinator.h
index 938259a2..e0750cc3 100644
--- a/ios/chrome/browser/ui/payments/payment_request_coordinator.h
+++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.h
@@ -34,7 +34,6 @@
 namespace web {
 class PaymentDetails;
 class PaymentShippingOption;
-class PaymentResponse;
 }  // namespace web
 
 @class PaymentRequestCoordinator;
@@ -51,9 +50,11 @@
 - (void)paymentRequestCoordinatorDidSelectSettings:
     (PaymentRequestCoordinator*)coordinator;
 
-// Notifies the delegate that the user has confirmed the payment request.
+// Notifies the delegate that the user has completed the payment request.
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
-    didConfirmWithPaymentResponse:(web::PaymentResponse)paymentResponse;
+        didCompletePaymentRequest:(PaymentRequest*)paymentRequest
+                             card:(const autofill::CreditCard&)card
+                 verificationCode:(const base::string16&)verificationCode;
 
 // Notifies the delegate that the user has selected a shipping address.
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
@@ -115,7 +116,8 @@
 // |paymentRequest|, because CVC unmasking process may update the credit card
 // number and expiration date.
 - (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card
-                                      CVC:(const base::string16&)cvc;
+                         verificationCode:
+                             (const base::string16&)verificationCode;
 
 @end
 
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
index c43545a..395445d 100644
--- a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
@@ -21,14 +21,13 @@
 #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h"
 #include "components/payments/core/payment_address.h"
 #include "components/payments/core/payment_request_data_util.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/payments/payment_request.h"
 #include "ios/chrome/browser/payments/payment_request_util.h"
-#include "ios/chrome/browser/signin/signin_manager_factory.h"
 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h"
+#include "ios/chrome/browser/ui/payments/payment_request_mediator.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -44,9 +43,8 @@
 class PRCardUnmaskPromptViewBridge
     : public autofill::CardUnmaskPromptViewBridge {
  public:
-  explicit PRCardUnmaskPromptViewBridge(
-      autofill::CardUnmaskPromptController* controller,
-      UIViewController* base_view_controller)
+  PRCardUnmaskPromptViewBridge(autofill::CardUnmaskPromptController* controller,
+                               UIViewController* base_view_controller)
       : autofill::CardUnmaskPromptViewBridge(controller),
         base_view_controller_(base_view_controller) {}
 
@@ -73,9 +71,9 @@
       public autofill::payments::FullCardRequest::UIDelegate,
       public base::SupportsWeakPtr<FullCardRequester> {
  public:
-  explicit FullCardRequester(PaymentRequestCoordinator* owner,
-                             UIViewController* base_view_controller,
-                             ios::ChromeBrowserState* browser_state)
+  FullCardRequester(PaymentRequestCoordinator* owner,
+                    UIViewController* base_view_controller,
+                    ios::ChromeBrowserState* browser_state)
       : owner_(owner),
         base_view_controller_(base_view_controller),
         unmask_controller_(browser_state->GetPrefs(),
@@ -91,9 +89,11 @@
   }
 
   // payments::FullCardRequest::ResultDelegate:
-  void OnFullCardRequestSucceeded(const autofill::CreditCard& card,
-                                  const base::string16& cvc) override {
-    [owner_ fullCardRequestDidSucceedWithCard:card CVC:cvc];
+  void OnFullCardRequestSucceeded(
+      const autofill::CreditCard& card,
+      const base::string16& verificationCode) override {
+    [owner_ fullCardRequestDidSucceedWithCard:card
+                             verificationCode:verificationCode];
   }
 
   // payments::FullCardRequest::ResultDelegate:
@@ -139,6 +139,8 @@
   ShippingOptionSelectionCoordinator* _shippingOptionSelectionCoordinator;
   PaymentMethodSelectionCoordinator* _methodSelectionCoordinator;
 
+  PaymentRequestMediator* _mediator;
+
   // Receiver of the full credit card details. Also displays the unmask prompt
   // UI.
   std::unique_ptr<FullCardRequester> _fullCardRequester;
@@ -156,20 +158,16 @@
 @synthesize delegate = _delegate;
 
 - (void)start {
+  _mediator =
+      [[PaymentRequestMediator alloc] initWithBrowserState:_browserState];
+
   _viewController = [[PaymentRequestViewController alloc]
       initWithPaymentRequest:_paymentRequest];
   [_viewController setPageFavicon:_pageFavicon];
   [_viewController setPageTitle:_pageTitle];
   [_viewController setPageHost:_pageHost];
   [_viewController setDelegate:self];
-  DCHECK(_browserState);
-  const SigninManager* signinManager =
-      ios::SigninManagerFactory::GetForBrowserStateIfExists(_browserState);
-  if (signinManager && signinManager->IsAuthenticated()) {
-    NSString* accountName = base::SysUTF8ToNSString(
-        signinManager->GetAuthenticatedAccountInfo().email);
-    [_viewController setAuthenticatedAccountName:accountName];
-  }
+  [_viewController setDataSource:_mediator];
   [_viewController loadModel];
 
   _navigationController = [[UINavigationController alloc]
@@ -212,93 +210,17 @@
 }
 
 - (void)fullCardRequestDidSucceedWithCard:(const autofill::CreditCard&)card
-                                      CVC:(const base::string16&)cvc {
-  web::PaymentResponse paymentResponse;
-
-  // If the merchant specified the card network as part of the "basic-card"
-  // payment method, return "basic-card" as the method_name. Otherwise, return
-  // the name of the network directly.
-  std::string issuer_network =
-      autofill::data_util::GetPaymentRequestData(card.network())
-          .basic_card_issuer_network;
-  paymentResponse.method_name =
-      _paymentRequest->basic_card_specified_networks().find(issuer_network) !=
-              _paymentRequest->basic_card_specified_networks().end()
-          ? base::ASCIIToUTF16("basic-card")
-          : base::ASCIIToUTF16(issuer_network);
-
-  // Get the billing address
-  autofill::AutofillProfile billingAddress;
-
-  // TODO(crbug.com/714768): Make sure the billing address is set and valid
-  // before getting here. Once the bug is addressed, there will be no need to
-  // copy the address, *billing_address_ptr can be used to get the basic card
-  // response.
-  if (!card.billing_address_id().empty()) {
-    autofill::AutofillProfile* billingAddressPtr =
-        autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
-            card.billing_address_id(), _paymentRequest->billing_profiles());
-    if (billingAddressPtr)
-      billingAddress = *billingAddressPtr;
-  }
-
-  paymentResponse.details = GetBasicCardResponseFromAutofillCreditCard(
-      card, cvc, billingAddress,
-      GetApplicationContext()->GetApplicationLocale());
-
-  if (_paymentRequest->request_shipping()) {
-    autofill::AutofillProfile* shippingAddress =
-        _paymentRequest->selected_shipping_profile();
-    // TODO(crbug.com/602666): User should get here only if they have selected
-    // a shipping address.
-    DCHECK(shippingAddress);
-    paymentResponse.shipping_address = GetPaymentAddressFromAutofillProfile(
-        *shippingAddress, GetApplicationContext()->GetApplicationLocale());
-
-    web::PaymentShippingOption* shippingOption =
-        _paymentRequest->selected_shipping_option();
-    DCHECK(shippingOption);
-    paymentResponse.shipping_option = shippingOption->id;
-  }
-
-  if (_paymentRequest->request_payer_name()) {
-    autofill::AutofillProfile* contactInfo =
-        _paymentRequest->selected_contact_profile();
-    // TODO(crbug.com/602666): User should get here only if they have selected
-    // a contact info.
-    DCHECK(contactInfo);
-    paymentResponse.payer_name =
-        contactInfo->GetInfo(autofill::AutofillType(autofill::NAME_FULL),
-                             GetApplicationContext()->GetApplicationLocale());
-  }
-
-  if (_paymentRequest->request_payer_email()) {
-    autofill::AutofillProfile* contactInfo =
-        _paymentRequest->selected_contact_profile();
-    // TODO(crbug.com/602666): User should get here only if they have selected
-    // a contact info.
-    DCHECK(contactInfo);
-    paymentResponse.payer_email =
-        contactInfo->GetRawInfo(autofill::EMAIL_ADDRESS);
-  }
-
-  if (_paymentRequest->request_payer_phone()) {
-    autofill::AutofillProfile* contactInfo =
-        _paymentRequest->selected_contact_profile();
-    // TODO(crbug.com/602666): User should get here only if they have selected
-    // a contact info.
-    DCHECK(contactInfo);
-    paymentResponse.payer_phone =
-        contactInfo->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER);
-  }
-
+                         verificationCode:
+                             (const base::string16&)verificationCode {
   _viewController.view.userInteractionEnabled = NO;
   [_viewController setPending:YES];
   [_viewController loadModel];
   [[_viewController collectionView] reloadData];
 
   [_delegate paymentRequestCoordinator:self
-         didConfirmWithPaymentResponse:paymentResponse];
+             didCompletePaymentRequest:_paymentRequest
+                                  card:card
+                      verificationCode:verificationCode];
 }
 
 - (void)updatePaymentDetails:(web::PaymentDetails)paymentDetails {
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm
index f107112..f053f263 100644
--- a/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_coordinator_unittest.mm
@@ -37,8 +37,10 @@
 @implementation PaymentRequestCoordinatorDelegateMock
 
 typedef void (^mock_coordinator_cancel)(PaymentRequestCoordinator*);
-typedef void (^mock_coordinator_confirm)(PaymentRequestCoordinator*,
-                                         web::PaymentResponse);
+typedef void (^mock_coordinator_complete)(PaymentRequestCoordinator*,
+                                          PaymentRequest*,
+                                          const autofill::CreditCard&,
+                                          const base::string16&);
 typedef void (^mock_coordinator_select_shipping_address)(
     PaymentRequestCoordinator*,
     payments::PaymentAddress);
@@ -53,9 +55,11 @@
 }
 
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
-    didConfirmWithPaymentResponse:(web::PaymentResponse)paymentResponse {
-  return static_cast<mock_coordinator_confirm>([self blockForSelector:_cmd])(
-      coordinator, paymentResponse);
+        didCompletePaymentRequest:(PaymentRequest*)paymentRequest
+                             card:(const autofill::CreditCard&)card
+                 verificationCode:(const base::string16&)verificationCode {
+  return static_cast<mock_coordinator_complete>([self blockForSelector:_cmd])(
+      coordinator, paymentRequest, card, verificationCode);
 }
 
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
@@ -147,28 +151,22 @@
       mockForProtocol:@protocol(PaymentMethodSelectionCoordinatorDelegate)];
   id delegate_mock([[PaymentRequestCoordinatorDelegateMock alloc]
       initWithRepresentedObject:delegate]);
-  SEL selector =
-      @selector(paymentRequestCoordinator:didConfirmWithPaymentResponse:);
+  SEL selector = @selector(paymentRequestCoordinator:didCompletePaymentRequest:
+                           card:verificationCode:);
   [delegate_mock onSelector:selector
        callBlockExpectation:^(PaymentRequestCoordinator* callerCoordinator,
-                              web::PaymentResponse paymentResponse) {
-         EXPECT_EQ(base::ASCIIToUTF16("4111111111111111"),
-                   paymentResponse.details.card_number);
-         EXPECT_EQ(base::ASCIIToUTF16("Test User"),
-                   paymentResponse.details.cardholder_name);
-         EXPECT_EQ(base::ASCIIToUTF16("11"),
-                   paymentResponse.details.expiry_month);
-         EXPECT_EQ(base::ASCIIToUTF16("2022"),
-                   paymentResponse.details.expiry_year);
-         EXPECT_EQ(base::ASCIIToUTF16("123"),
-                   paymentResponse.details.card_security_code);
+                              PaymentRequest* paymentRequest,
+                              const autofill::CreditCard& card,
+                              const base::string16& verificationCode) {
+         EXPECT_EQ(credit_card_, card);
+         EXPECT_EQ(base::ASCIIToUTF16("123"), verificationCode);
          EXPECT_EQ(coordinator, callerCoordinator);
        }];
   [coordinator setDelegate:delegate_mock];
 
   // Call the card unmasking delegate method.
   [coordinator fullCardRequestDidSucceedWithCard:credit_card_
-                                             CVC:base::ASCIIToUTF16("123")];
+                                verificationCode:base::ASCIIToUTF16("123")];
 }
 
 // Tests that calling the ShippingAddressSelectionCoordinator delegate method
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm
index 68f25f1..79398b3e 100644
--- a/ios/chrome/browser/ui/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -9,12 +9,18 @@
 #import "base/mac/bind_objc_block.h"
 #include "base/mac/foundation_util.h"
 #include "base/memory/ptr_util.h"
+#include "base/strings/string16.h"
 #include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
 #import "base/values.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_manager.h"
+#include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/ios/browser/autofill_driver_ios.h"
 #include "components/payments/core/payment_address.h"
+#include "components/payments/core/payment_request_data_util.h"
+#include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/payments/payment_request.h"
@@ -560,7 +566,90 @@
 }
 
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
-    didConfirmWithPaymentResponse:(web::PaymentResponse)paymentResponse {
+        didCompletePaymentRequest:(PaymentRequest*)paymentRequest
+                             card:(const autofill::CreditCard&)card
+                 verificationCode:(const base::string16&)verificationCode {
+  web::PaymentResponse paymentResponse;
+
+  // If the merchant specified the card network as part of the "basic-card"
+  // payment method, return "basic-card" as the method_name. Otherwise, return
+  // the name of the network directly.
+  std::string issuer_network =
+      autofill::data_util::GetPaymentRequestData(card.network())
+          .basic_card_issuer_network;
+  paymentResponse.method_name =
+      paymentRequest->basic_card_specified_networks().find(issuer_network) !=
+              paymentRequest->basic_card_specified_networks().end()
+          ? base::ASCIIToUTF16("basic-card")
+          : base::ASCIIToUTF16(issuer_network);
+
+  // Get the billing address
+  autofill::AutofillProfile billingAddress;
+
+  // TODO(crbug.com/714768): Make sure the billing address is set and valid
+  // before getting here. Once the bug is addressed, there will be no need to
+  // copy the address, *billing_address_ptr can be used to get the basic card
+  // response.
+  if (!card.billing_address_id().empty()) {
+    autofill::AutofillProfile* billingAddressPtr =
+        autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
+            card.billing_address_id(), paymentRequest->billing_profiles());
+    if (billingAddressPtr)
+      billingAddress = *billingAddressPtr;
+  }
+
+  paymentResponse.details =
+      payments::data_util::GetBasicCardResponseFromAutofillCreditCard(
+          card, verificationCode, billingAddress,
+          GetApplicationContext()->GetApplicationLocale());
+
+  if (paymentRequest->request_shipping()) {
+    autofill::AutofillProfile* shippingAddress =
+        paymentRequest->selected_shipping_profile();
+    // TODO(crbug.com/602666): User should get here only if they have selected
+    // a shipping address.
+    DCHECK(shippingAddress);
+    paymentResponse.shipping_address =
+        payments::data_util::GetPaymentAddressFromAutofillProfile(
+            *shippingAddress, GetApplicationContext()->GetApplicationLocale());
+
+    web::PaymentShippingOption* shippingOption =
+        paymentRequest->selected_shipping_option();
+    DCHECK(shippingOption);
+    paymentResponse.shipping_option = shippingOption->id;
+  }
+
+  if (paymentRequest->request_payer_name()) {
+    autofill::AutofillProfile* contactInfo =
+        paymentRequest->selected_contact_profile();
+    // TODO(crbug.com/602666): User should get here only if they have selected
+    // a contact info.
+    DCHECK(contactInfo);
+    paymentResponse.payer_name =
+        contactInfo->GetInfo(autofill::AutofillType(autofill::NAME_FULL),
+                             GetApplicationContext()->GetApplicationLocale());
+  }
+
+  if (paymentRequest->request_payer_email()) {
+    autofill::AutofillProfile* contactInfo =
+        paymentRequest->selected_contact_profile();
+    // TODO(crbug.com/602666): User should get here only if they have selected
+    // a contact info.
+    DCHECK(contactInfo);
+    paymentResponse.payer_email =
+        contactInfo->GetRawInfo(autofill::EMAIL_ADDRESS);
+  }
+
+  if (paymentRequest->request_payer_phone()) {
+    autofill::AutofillProfile* contactInfo =
+        paymentRequest->selected_contact_profile();
+    // TODO(crbug.com/602666): User should get here only if they have selected
+    // a contact info.
+    DCHECK(contactInfo);
+    paymentResponse.payer_phone =
+        contactInfo->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER);
+  }
+
   [_paymentRequestJsManager
       resolveRequestPromiseWithPaymentResponse:paymentResponse
                              completionHandler:nil];
diff --git a/ios/chrome/browser/ui/payments/payment_request_mediator.h b/ios/chrome/browser/ui/payments/payment_request_mediator.h
new file mode 100644
index 0000000..7835b29
--- /dev/null
+++ b/ios/chrome/browser/ui/payments/payment_request_mediator.h
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_MEDIATOR_H_
+
+#include "ios/chrome/browser/ui/payments/payment_request_view_controller.h"
+
+namespace ios {
+class ChromeBrowserState;
+}  // namespace ios
+
+// A mediator object that provides data for a PaymentRequestViewController.
+@interface PaymentRequestMediator
+    : NSObject<PaymentRequestViewControllerDataSource>
+
+- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_MEDIATOR_H
diff --git a/ios/chrome/browser/ui/payments/payment_request_mediator.mm b/ios/chrome/browser/ui/payments/payment_request_mediator.mm
new file mode 100644
index 0000000..ce5c2d6f
--- /dev/null
+++ b/ios/chrome/browser/ui/payments/payment_request_mediator.mm
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/ui/payments/payment_request_mediator.h"
+
+#include "base/strings/sys_string_conversions.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "ios/chrome/browser/signin/signin_manager_factory.h"
+
+@implementation PaymentRequestMediator {
+  ios::ChromeBrowserState* _browserState;
+}
+
+- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState {
+  DCHECK(browserState);
+  self = [super init];
+  if (self) {
+    _browserState = browserState;
+  }
+  return self;
+}
+
+- (NSString*)authenticatedAccountName {
+  const SigninManager* signinManager =
+      ios::SigninManagerFactory::GetForBrowserStateIfExists(_browserState);
+  if (signinManager && signinManager->IsAuthenticated()) {
+    return base::SysUTF8ToNSString(
+        signinManager->GetAuthenticatedAccountInfo().email);
+  }
+  return nil;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller.h b/ios/chrome/browser/ui/payments/payment_request_view_controller.h
index 8059894..dcfad982 100644
--- a/ios/chrome/browser/ui/payments/payment_request_view_controller.h
+++ b/ios/chrome/browser/ui/payments/payment_request_view_controller.h
@@ -17,6 +17,15 @@
 
 @class PaymentRequestViewController;
 
+// Data source protocol for PaymentRequestViewController.
+@protocol PaymentRequestViewControllerDataSource<NSObject>
+
+// Returns the authenticated account name, if a user is authenticated.
+// Otherwise, returns nil.
+- (NSString*)authenticatedAccountName;
+
+@end
+
 // Delegate protocol for PaymentRequestViewController.
 @protocol PaymentRequestViewControllerDelegate<NSObject>
 
@@ -73,10 +82,10 @@
 
 // Whether the data source should be shown (usually until the first payment
 // has been completed) or not.
-@property(nonatomic, assign) BOOL showDataSource;
+@property(nonatomic, assign) BOOL showPaymentDataSource;
 
-// If the user is signed in, the name of the authenticated account.
-@property(nonatomic, copy) NSString* authenticatedAccountName;
+@property(nonatomic, weak) id<PaymentRequestViewControllerDataSource>
+    dataSource;
 
 // Updates the payment summary section UI. If |totalValueChanged| is YES,
 // adds a label to the total amount item indicating that the total amount was
diff --git a/ios/chrome/browser/ui/payments/payment_request_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
index 032aa18..1c825fbc 100644
--- a/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_view_controller.mm
@@ -127,8 +127,8 @@
 @synthesize pageHost = _pageHost;
 @synthesize pending = _pending;
 @synthesize delegate = _delegate;
-@synthesize showDataSource = _showDataSource;
-@synthesize authenticatedAccountName = _authenticatedAccountName;
+@synthesize showPaymentDataSource = _showPaymentDataSource;
+@synthesize dataSource = _dataSource;
 
 - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest {
   DCHECK(paymentRequest);
@@ -186,7 +186,7 @@
     _paymentRequest = paymentRequest;
 
     // By default, data source is shown.
-    _showDataSource = TRUE;
+    _showPaymentDataSource = TRUE;
   }
   return self;
 }
@@ -373,14 +373,14 @@
   [model addSectionWithIdentifier:SectionIdentifierFooter];
   CollectionViewFooterItem* footer =
       [[CollectionViewFooterItem alloc] initWithType:ItemTypeFooterText];
-  if (!_showDataSource) {
+  if (!_showPaymentDataSource) {
     footer.text =
         l10n_util::GetNSString(IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS);
-  } else if ([_authenticatedAccountName length]) {
+  } else if ([[_dataSource authenticatedAccountName] length]) {
     const std::string unformattedString = l10n_util::GetStringUTF8(
         IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN);
     const std::string accountName =
-        base::SysNSStringToUTF8(_authenticatedAccountName);
+        base::SysNSStringToUTF8([_dataSource authenticatedAccountName]);
     const std::string formattedString =
         base::StringPrintf(unformattedString.c_str(), accountName.c_str());
     footer.text = base::SysUTF8ToNSString(formattedString);
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index bd47e3ce9..85ca185 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -797,6 +797,15 @@
 
 // static
 NetworkChangeNotifier::ConnectionType
+NetworkChangeNotifier::ConnectionTypeFromInterfaces() {
+  NetworkInterfaceList interfaces;
+  if (!GetNetworkList(&interfaces, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES))
+    return CONNECTION_UNKNOWN;
+  return ConnectionTypeFromInterfaceList(interfaces);
+}
+
+// static
+NetworkChangeNotifier::ConnectionType
 NetworkChangeNotifier::ConnectionTypeFromInterfaceList(
     const NetworkInterfaceList& interfaces) {
   bool first = true;
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h
index a758cc3a..6678979 100644
--- a/net/base/network_change_notifier.h
+++ b/net/base/network_change_notifier.h
@@ -538,6 +538,10 @@
   // observers.
   static void SetInitialDnsConfig(const DnsConfig& config);
 
+  // Infer connection type from |GetNetworkList|. If all network interfaces
+  // have the same type, return it, otherwise return CONNECTION_UNKNOWN.
+  static ConnectionType ConnectionTypeFromInterfaces();
+
  private:
   friend class HostResolverImplDnsTest;
   friend class NetworkChangeNotifierAndroidTest;
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc
index 06261fc..42727f4 100644
--- a/net/base/network_change_notifier_win.cc
+++ b/net/base/network_change_notifier_win.cc
@@ -200,8 +200,8 @@
       << "WSALookupServiceEnd() failed with: " << result;
 
   // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN.
-  return found_connection ? NetworkChangeNotifier::CONNECTION_UNKNOWN :
-                            NetworkChangeNotifier::CONNECTION_NONE;
+  return found_connection ? ConnectionTypeFromInterfaces()
+                          : NetworkChangeNotifier::CONNECTION_NONE;
 }
 
 NetworkChangeNotifier::ConnectionType
diff --git a/net/http/http_auth_handler_ntlm_portable.cc b/net/http/http_auth_handler_ntlm_portable.cc
index 487e89cc..4c64597 100644
--- a/net/http/http_auth_handler_ntlm_portable.cc
+++ b/net/http/http_auth_handler_ntlm_portable.cc
@@ -72,15 +72,15 @@
 
 #if defined(ARCH_CPU_LITTLE_ENDIAN)
 #define IS_LITTLE_ENDIAN 1
-#undef  IS_BIG_ENDIAN
+#undef IS_BIG_ENDIAN
 #elif defined(ARCH_CPU_BIG_ENDIAN)
 #define IS_BIG_ENDIAN 1
-#undef  IS_LITTLE_ENDIAN
+#undef IS_LITTLE_ENDIAN
 #else
 #error "Unknown endianness"
 #endif
 
-#define NTLM_LOG(x) ((void) 0)
+#define NTLM_LOG(x) ((void)0)
 
 //-----------------------------------------------------------------------------
 // This file contains a cross-platform NTLM authentication implementation. It
@@ -88,54 +88,53 @@
 //-----------------------------------------------------------------------------
 
 enum {
-  NTLM_NegotiateUnicode             = 0x00000001,
-  NTLM_NegotiateOEM                 = 0x00000002,
-  NTLM_RequestTarget                = 0x00000004,
-  NTLM_Unknown1                     = 0x00000008,
-  NTLM_NegotiateSign                = 0x00000010,
-  NTLM_NegotiateSeal                = 0x00000020,
-  NTLM_NegotiateDatagramStyle       = 0x00000040,
-  NTLM_NegotiateLanManagerKey       = 0x00000080,
-  NTLM_NegotiateNetware             = 0x00000100,
-  NTLM_NegotiateNTLMKey             = 0x00000200,
-  NTLM_Unknown2                     = 0x00000400,
-  NTLM_Unknown3                     = 0x00000800,
-  NTLM_NegotiateDomainSupplied      = 0x00001000,
+  NTLM_NegotiateUnicode = 0x00000001,
+  NTLM_NegotiateOEM = 0x00000002,
+  NTLM_RequestTarget = 0x00000004,
+  NTLM_Unknown1 = 0x00000008,
+  NTLM_NegotiateSign = 0x00000010,
+  NTLM_NegotiateSeal = 0x00000020,
+  NTLM_NegotiateDatagramStyle = 0x00000040,
+  NTLM_NegotiateLanManagerKey = 0x00000080,
+  NTLM_NegotiateNetware = 0x00000100,
+  NTLM_NegotiateNTLMKey = 0x00000200,
+  NTLM_Unknown2 = 0x00000400,
+  NTLM_Unknown3 = 0x00000800,
+  NTLM_NegotiateDomainSupplied = 0x00001000,
   NTLM_NegotiateWorkstationSupplied = 0x00002000,
-  NTLM_NegotiateLocalCall           = 0x00004000,
-  NTLM_NegotiateAlwaysSign          = 0x00008000,
-  NTLM_TargetTypeDomain             = 0x00010000,
-  NTLM_TargetTypeServer             = 0x00020000,
-  NTLM_TargetTypeShare              = 0x00040000,
-  NTLM_NegotiateNTLM2Key            = 0x00080000,
-  NTLM_RequestInitResponse          = 0x00100000,
-  NTLM_RequestAcceptResponse        = 0x00200000,
-  NTLM_RequestNonNTSessionKey       = 0x00400000,
-  NTLM_NegotiateTargetInfo          = 0x00800000,
-  NTLM_Unknown4                     = 0x01000000,
-  NTLM_Unknown5                     = 0x02000000,
-  NTLM_Unknown6                     = 0x04000000,
-  NTLM_Unknown7                     = 0x08000000,
-  NTLM_Unknown8                     = 0x10000000,
-  NTLM_Negotiate128                 = 0x20000000,
-  NTLM_NegotiateKeyExchange         = 0x40000000,
-  NTLM_Negotiate56                  = 0x80000000
+  NTLM_NegotiateLocalCall = 0x00004000,
+  NTLM_NegotiateAlwaysSign = 0x00008000,
+  NTLM_TargetTypeDomain = 0x00010000,
+  NTLM_TargetTypeServer = 0x00020000,
+  NTLM_TargetTypeShare = 0x00040000,
+  NTLM_NegotiateNTLM2Key = 0x00080000,
+  NTLM_RequestInitResponse = 0x00100000,
+  NTLM_RequestAcceptResponse = 0x00200000,
+  NTLM_RequestNonNTSessionKey = 0x00400000,
+  NTLM_NegotiateTargetInfo = 0x00800000,
+  NTLM_Unknown4 = 0x01000000,
+  NTLM_Unknown5 = 0x02000000,
+  NTLM_Unknown6 = 0x04000000,
+  NTLM_Unknown7 = 0x08000000,
+  NTLM_Unknown8 = 0x10000000,
+  NTLM_Negotiate128 = 0x20000000,
+  NTLM_NegotiateKeyExchange = 0x40000000,
+  NTLM_Negotiate56 = 0x80000000
 };
 
 // We send these flags with our type 1 message.
 enum {
-  NTLM_TYPE1_FLAGS = (NTLM_NegotiateUnicode |
-                      NTLM_NegotiateOEM |
-                      NTLM_RequestTarget |
-                      NTLM_NegotiateNTLMKey |
-                      NTLM_NegotiateAlwaysSign |
-                      NTLM_NegotiateNTLM2Key)
+  NTLM_TYPE1_FLAGS =
+      (NTLM_NegotiateUnicode | NTLM_NegotiateOEM | NTLM_RequestTarget |
+       NTLM_NegotiateNTLMKey |
+       NTLM_NegotiateAlwaysSign |
+       NTLM_NegotiateNTLM2Key)
 };
 
 static const char NTLM_SIGNATURE[] = "NTLMSSP";
-static const char NTLM_TYPE1_MARKER[] = { 0x01, 0x00, 0x00, 0x00 };
-static const char NTLM_TYPE2_MARKER[] = { 0x02, 0x00, 0x00, 0x00 };
-static const char NTLM_TYPE3_MARKER[] = { 0x03, 0x00, 0x00, 0x00 };
+static const char NTLM_TYPE1_MARKER[] = {0x01, 0x00, 0x00, 0x00};
+static const char NTLM_TYPE2_MARKER[] = {0x02, 0x00, 0x00, 0x00};
+static const char NTLM_TYPE3_MARKER[] = {0x03, 0x00, 0x00, 0x00};
 
 enum {
   NTLM_TYPE1_HEADER_LEN = 32,
@@ -167,15 +166,15 @@
 
 //-----------------------------------------------------------------------------
 
-#define LogFlags(x) ((void) 0)
-#define LogBuf(a, b, c) ((void) 0)
-#define LogToken(a, b, c) ((void) 0)
+#define LogFlags(x) ((void)0)
+#define LogBuf(a, b, c) ((void)0)
+#define LogToken(a, b, c) ((void)0)
 
 //-----------------------------------------------------------------------------
 
 // Byte order swapping.
-#define SWAP16(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
-#define SWAP32(x) ((SWAP16((x) & 0xffff) << 16) | (SWAP16((x) >> 16)))
+#define SWAP16(x) ((((x)&0xff) << 8) | (((x) >> 8) & 0xff))
+#define SWAP32(x) ((SWAP16((x)&0xffff) << 16) | (SWAP16((x) >> 16)))
 
 static void* WriteBytes(void* buf, const void* data, uint32_t data_len) {
   memcpy(buf, data, data_len);
@@ -317,8 +316,8 @@
   memcpy(keybytes, hash, 16);
   ZapBuf(keybytes + 16, 5);
 
-  DESMakeKey(keybytes     , k1);
-  DESMakeKey(keybytes +  7, k2);
+  DESMakeKey(keybytes, k1);
+  DESMakeKey(keybytes + 7, k2);
   DESMakeKey(keybytes + 14, k3);
 
   DESEncrypt(k1, challenge, response);
@@ -370,10 +369,10 @@
 }
 
 struct Type2Msg {
-  uint32_t flags;            // NTLM_Xxx bitwise combination
-  uint8_t challenge[8];      // 8 byte challenge
-  const void* target;        // target string (type depends on flags)
-  uint32_t target_len;       // target length in bytes
+  uint32_t flags;        // NTLM_Xxx bitwise combination
+  uint8_t challenge[8];  // 8 byte challenge
+  const void* target;    // target string (type depends on flags)
+  uint32_t target_len;   // target length in bytes
 };
 
 // Returns OK or a network error code.
@@ -406,7 +405,7 @@
 
   // read target name security buffer
   uint32_t target_len = ReadUint16(cursor);
-  ReadUint16(cursor);  // discard next 16-bit value
+  ReadUint16(cursor);                    // discard next 16-bit value
   uint32_t offset = ReadUint32(cursor);  // get offset from in_buf
   msg->target_len = 0;
   msg->target = NULL;
@@ -462,7 +461,7 @@
 
   bool unicode = (msg.flags & NTLM_NegotiateUnicode) != 0;
 
-  // Temporary buffers for unicode strings
+// Temporary buffers for unicode strings
 #ifdef IS_BIG_ENDIAN
   base::string16 ucs_domain_buf, ucs_user_buf;
 #endif
@@ -485,8 +484,7 @@
     domain_ptr = ucs_domain_buf.data();
     domain_len = ucs_domain_buf.length() * 2;
     WriteUnicodeLE(const_cast<void*>(domain_ptr),
-                   (const base::char16*) domain_ptr,
-                   ucs_domain_buf.length());
+                   (const base::char16*)domain_ptr, ucs_domain_buf.length());
 #else
     domain_ptr = domain.data();
     domain_len = domain.length() * 2;
@@ -505,7 +503,7 @@
     ucs_user_buf = username;
     user_ptr = ucs_user_buf.data();
     user_len = ucs_user_buf.length() * 2;
-    WriteUnicodeLE(const_cast<void*>(user_ptr), (const base::char16*) user_ptr,
+    WriteUnicodeLE(const_cast<void*>(user_ptr), (const base::char16*)user_ptr,
                    ucs_user_buf.length());
 #else
     user_ptr = username.data();
@@ -526,7 +524,7 @@
     host_ptr = ucs_host_buf.data();
     host_len = ucs_host_buf.length() * 2;
 #ifdef IS_BIG_ENDIAN
-    WriteUnicodeLE(const_cast<void*>(host_ptr), (const base::char16*) host_ptr,
+    WriteUnicodeLE(const_cast<void*>(host_ptr), (const base::char16*)host_ptr,
                    ucs_host_buf.length());
 #endif
   } else {
@@ -630,14 +628,13 @@
 
 // static
 HttpAuthHandlerNTLM::GenerateRandomProc
-HttpAuthHandlerNTLM::generate_random_proc_ = GenerateRandom;
+    HttpAuthHandlerNTLM::generate_random_proc_ = GenerateRandom;
 
 // static
-HttpAuthHandlerNTLM::HostNameProc
-HttpAuthHandlerNTLM::get_host_name_proc_ = GetHostName;
+HttpAuthHandlerNTLM::HostNameProc HttpAuthHandlerNTLM::get_host_name_proc_ =
+    GetHostName;
 
-HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() {
-}
+HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() {}
 
 bool HttpAuthHandlerNTLM::NeedsIdentity() {
   // This gets called for each round-trip.  Only require identity on
@@ -662,8 +659,7 @@
 
 // static
 HttpAuthHandlerNTLM::GenerateRandomProc
-HttpAuthHandlerNTLM::SetGenerateRandomProc(
-    GenerateRandomProc proc) {
+HttpAuthHandlerNTLM::SetGenerateRandomProc(GenerateRandomProc proc) {
   GenerateRandomProc old_proc = generate_random_proc_;
   generate_random_proc_ = proc;
   return old_proc;
@@ -677,11 +673,9 @@
   return old_proc;
 }
 
-HttpAuthHandlerNTLM::Factory::Factory() {
-}
+HttpAuthHandlerNTLM::Factory::Factory() {}
 
-HttpAuthHandlerNTLM::Factory::~Factory() {
-}
+HttpAuthHandlerNTLM::Factory::~Factory() {}
 
 int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
                                       uint32_t in_token_len,
@@ -697,10 +691,9 @@
       return ERR_UNEXPECTED;
     uint8_t rand_buf[8];
     generate_random_proc_(rand_buf, 8);
-    rv = GenerateType3Msg(domain_,
-                          credentials_.username(), credentials_.password(),
-                          hostname, rand_buf,
-                          in_token, in_token_len, out_token, out_token_len);
+    rv = GenerateType3Msg(domain_, credentials_.username(),
+                          credentials_.password(), hostname, rand_buf, in_token,
+                          in_token_len, out_token, out_token_len);
   } else {
     rv = GenerateType1Msg(out_token, out_token_len);
   }
diff --git a/remoting/client/ios/app/client_connection_view_controller.h b/remoting/client/ios/app/client_connection_view_controller.h
index 29f5e1f..7ae3939 100644
--- a/remoting/client/ios/app/client_connection_view_controller.h
+++ b/remoting/client/ios/app/client_connection_view_controller.h
@@ -12,6 +12,7 @@
   ClientViewConnecting,
   ClientViewPinPrompt,
   ClientViewConnected,
+  ClientViewClosed,
 };
 
 // The host connection view controller delegate provides feedback for state
diff --git a/remoting/client/ios/app/client_connection_view_controller.mm b/remoting/client/ios/app/client_connection_view_controller.mm
index 34c0483..53bfc60 100644
--- a/remoting/client/ios/app/client_connection_view_controller.mm
+++ b/remoting/client/ios/app/client_connection_view_controller.mm
@@ -218,6 +218,9 @@
     case ClientViewConnected:
       [self showConnectedState];
       break;
+    case ClientViewClosed:
+      [self dismissViewControllerAnimated:YES completion:nil];
+      break;
   }
 }
 
@@ -304,9 +307,10 @@
       state = ClientViewConnected;
       break;
     case SessionFailed:
-    // TODO(nicholss): Implement.
+    // TODO(nicholss): Implement an error screen.
     case SessionClosed:
-    // TODO(nicholss): Implement.
+      state = ClientViewClosed;
+      break;
     default:
       LOG(ERROR) << "Unknown State for Session, " << sessionDetails.state;
       return;
diff --git a/remoting/client/ios/app/host_view_controller.mm b/remoting/client/ios/app/host_view_controller.mm
index 24a3514..5612581 100644
--- a/remoting/client/ios/app/host_view_controller.mm
+++ b/remoting/client/ios/app/host_view_controller.mm
@@ -111,6 +111,7 @@
   // TODO(nicholss): The FAB is being used to close the window at the moment
   // just as a demo  as the integration continues. This will not be the case
   // in the final app.
+  [_client disconnectFromHost];
   [self dismissViewControllerAnimated:YES completion:nil];
 }
 
diff --git a/remoting/client/ios/session/remoting_client.h b/remoting/client/ios/session/remoting_client.h
index d1ea4377..09a3a7b 100644
--- a/remoting/client/ios/session/remoting_client.h
+++ b/remoting/client/ios/session/remoting_client.h
@@ -46,6 +46,9 @@
              username:(NSString*)username
           accessToken:(NSString*)accessToken;
 
+// Disconnect the current host connection.
+- (void)disconnectFromHost;
+
 // Mirrors the native client session delegate interface:
 
 - (void)onConnectionState:(remoting::protocol::ConnectionToHost::State)state
diff --git a/remoting/client/ios/session/remoting_client.mm b/remoting/client/ios/session/remoting_client.mm
index da636ce..3338641 100644
--- a/remoting/client/ios/session/remoting_client.mm
+++ b/remoting/client/ios/session/remoting_client.mm
@@ -129,6 +129,13 @@
       _session.get()));
 }
 
+- (void)disconnectFromHost {
+  if (_session) {
+    _session->Disconnect();
+  }
+  // TODO(nicholss): Do we need to cleanup more?
+}
+
 #pragma mark - Eventing
 
 - (void)hostSessionPinProvided:(NSNotification*)notification {
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 620454d..2164cf72 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -18002,7 +18002,7 @@
 crbug.com/591099 http/tests/serviceworker/chromium/sandboxed-iframe-fetch-event.html [ Crash ]
 crbug.com/591099 http/tests/serviceworker/chromium/service-worker-gc.html [ Failure ]
 crbug.com/591099 http/tests/serviceworker/chromium/window-close-during-registration.html [ Failure ]
-crbug.com/591099 http/tests/serviceworker/fetch-request-xhr.html [ Failure Pass ]
+crbug.com/591099 http/tests/serviceworker/chromium.fetch-request-xhr.html [ Failure Pass ]
 crbug.com/591099 http/tests/serviceworker/indexeddb.html [ Pass Timeout ]
 crbug.com/591099 http/tests/serviceworker/navigation-preload/chromium/navigation-preload-resource-timing.html [ Failure Pass ]
 crbug.com/591099 http/tests/serviceworker/navigation-redirect.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index e34473f..50036e15 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2935,9 +2935,9 @@
 crbug.com/658997 external/wpt/service-workers/service-worker/fetch-csp.https.html [ Pass Timeout ]
 crbug.com/658997 external/wpt/service-workers/service-worker/fetch-event-async-respond-with.https.html [ Pass Timeout ]
 crbug.com/658997 external/wpt/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html [ Pass Timeout ]
-crbug.com/658997 external/wpt/service-workers/service-worker/fetch-request-css-base-url.https.html [ Skip ]
-crbug.com/658997 external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Skip ]
-crbug.com/658997 external/wpt/service-workers/service-worker/fetch-response-xhr.https.html [ Skip ]
+crbug.com/658997 external/wpt/service-workers/service-worker/fetch-request-css-base-url.https.html [ Pass Timeout ]
+crbug.com/658997 external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure Timeout ]
+crbug.com/658997 external/wpt/service-workers/service-worker/fetch-response-xhr.https.html [ Pass Timeout ]
 crbug.com/658997 external/wpt/service-workers/service-worker/getregistrations.https.html [ Pass Timeout ]
 crbug.com/658997 external/wpt/service-workers/service-worker/invalid-blobtype.https.html [ Skip ]
 crbug.com/658997 external/wpt/service-workers/service-worker/invalid-header.https.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html
index 87af410..3f24946 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html
@@ -3,7 +3,7 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/common/get-host-info.sub.js"></script>
-<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script src="resources/test-helpers.sub.js"></script>
 <script>
 async_test(function(t) {
     var SCOPE = 'resources/fetch-request-xhr-iframe.https.html';
@@ -15,13 +15,17 @@
         })
       .then(function() { return with_iframe(SCOPE); })
       .then(function(frame) {
+          t.add_cleanup(function() { frame.remove(); });
           var channel = new MessageChannel();
           channel.port1.onmessage = t.step_func(function(e) {
               if (e.data.results === 'finish') {
-                frame.remove();
                 service_worker_unregister_and_done(t, SCOPE);
               } else if (e.data.results == 'equals') {
                 assert_equals(e.data.got, e.data.expected);
+              } else if (e.data.results == 'array_equals') {
+                assert_array_equals(e.data.got, e.data.expected, e.data.msg);
+              } else if (e.data.results == 'failure') {
+                throw e.data.error;
               }
             });
           frame.contentWindow.postMessage({},
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-response-xhr.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-response-xhr.https.html
index 24eb44e2..74173e8b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-response-xhr.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-response-xhr.https.html
@@ -3,7 +3,7 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/common/get-host-info.sub.js"></script>
-<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script src="resources/test-helpers.sub.js"></script>
 <script>
 async_test(function(t) {
     var SCOPE = 'resources/fetch-response-xhr-iframe.https.html';
@@ -13,7 +13,7 @@
     window.addEventListener('message', t.step_func(on_message), false);
     function on_message(e) {
       assert_equals(e.data.results, 'foo, bar');
-      t.done();
+      e.source.postMessage('ACK', host_info['HTTPS_ORIGIN']);
     }
 
     service_worker_unregister_and_register(t, SCRIPT, SCOPE)
@@ -22,13 +22,19 @@
         })
       .then(function() { return with_iframe(SCOPE); })
       .then(function(frame) {
-          var channel = new MessageChannel();
-          channel.port1.onmessage = t.step_func(function(e) {
-              assert_equals(e.data.results, 'finish');
+          var channel;
+
+          t.add_cleanup(function() {
               frame.remove();
               service_worker_unregister_and_done(t, SCOPE);
             });
-          frame.contentWindow.postMessage({},
+
+          channel = new MessageChannel();
+          channel.port1.onmessage = t.step_func(function(e) {
+              assert_equals(e.data.results, 'finish');
+              t.done();
+            });
+          frame.contentWindow.postMessage('START',
                                           host_info['HTTPS_ORIGIN'],
                                           [channel.port2]);
         })
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
index ef2f925a..8afa237d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
@@ -8,6 +8,10 @@
   port.postMessage({results: 'equals', got: a, expected: b});
 }
 
+function assert_array_equals(a, b, msg) {
+  port.postMessage({results: 'array_equals', got: a, expected: b, msg: msg});
+}
+
 function get_boundary(headers) {
   var reg = new RegExp('multipart\/form-data; boundary=(.*)');
   for (var i = 0; i < headers.length; ++i) {
@@ -59,6 +63,70 @@
     });
 }
 
+function get_sorted_header_name_list(headers) {
+  var header_names = [];
+  var idx, name;
+
+  for (idx = 0; idx < headers.length; ++idx) {
+    name = headers[idx][0];
+    // The `Accept-Language` header is optional; its presence should not
+    // influence test results.
+    //
+    // > 4. If request’s header list does not contain `Accept-Language`, user
+    // >    agents should append `Accept-Language`/an appropriate value to
+    // >    request's header list.
+    //
+    // https://fetch.spec.whatwg.org/#fetching
+    if (name === 'accept-language') {
+      continue;
+    }
+
+    header_names.push(name);
+  }
+  header_names.sort();
+  return header_names;
+}
+
+function get_header_test() {
+  return xhr_send(host_info['HTTPS_ORIGIN'], 'GET', '', false)
+    .then(function(response) {
+        assert_array_equals(
+          get_sorted_header_name_list(response.headers),
+          ["accept"],
+          'event.request has the expected headers for same-origin GET.');
+      });
+}
+
+function post_header_test() {
+  return xhr_send(host_info['HTTPS_ORIGIN'], 'POST', '', false)
+    .then(function(response) {
+        assert_array_equals(
+          get_sorted_header_name_list(response.headers),
+          ["accept", "content-type"],
+          'event.request has the expected headers for same-origin POST.');
+      });
+}
+
+function cross_origin_get_header_test() {
+  return xhr_send(host_info['HTTPS_REMOTE_ORIGIN'], 'GET', '', false)
+    .then(function(response) {
+        assert_array_equals(
+          get_sorted_header_name_list(response.headers),
+          ["accept"],
+          'event.request has the expected headers for cross-origin GET.');
+      });
+}
+
+function cross_origin_post_header_test() {
+  return xhr_send(host_info['HTTPS_REMOTE_ORIGIN'], 'POST', '', false)
+    .then(function(response) {
+        assert_array_equals(
+          get_sorted_header_name_list(response.headers),
+          ["accept", "content-type"],
+          'event.request has the expected headers for cross-origin POST.');
+      });
+}
+
 function string_test() {
   return xhr_send(host_info['HTTPS_ORIGIN'], 'POST', 'test string', false)
     .then(function(response) {
@@ -166,7 +234,11 @@
 
 window.addEventListener('message', function(evt) {
     port = evt.ports[0];
-    string_test()
+    get_header_test()
+      .then(post_header_test)
+      .then(cross_origin_get_header_test)
+      .then(cross_origin_post_header_test)
+      .then(string_test)
       .then(blob_test)
       .then(custom_method_test)
       .then(options_method_test)
@@ -174,6 +246,9 @@
       .then(mode_credentials_test)
       .then(data_url_test)
       .then(function() { port.postMessage({results: 'finish'}); })
-      .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+      .catch(function(reason) {
+          var error = String(reason.message || reason);
+          port.postMessage({results: 'failure', error: error});
+        });
   });
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
index 08b887b7..1414596 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
@@ -23,11 +23,29 @@
   .then(function(xhr) {
       window.parent.postMessage({results: xhr.getResponseHeader('foo')},
                                 host_info['HTTPS_ORIGIN']);
+
+      return new Promise(function(resolve) {
+          window.addEventListener('message', function handle(evt) {
+              if (event.data !== 'ACK') {
+                return;
+              }
+
+              window.removeEventListener('message', handle);
+              resolve();
+            });
+        });
     });
 }
 
 window.addEventListener('message', function(evt) {
-    var port = evt.ports[0];
+    var port;
+
+    if (event.data !== 'START') {
+      return;
+    }
+
+    port = evt.ports[0];
+
     coalesce_headers_test()
       .then(function() { port.postMessage({results: 'finish'}); })
       .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-base-url.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-css-base-url.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-base-url.html
rename to third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-css-base-url.html
index 3654d6d5..a3b71c4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-base-url.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-css-base-url.html
@@ -1,4 +1,9 @@
 <!DOCTYPE html>
+<!-- This test is prefixed with `chromium.` because the equivalent version
+  available in Web Platform Tests is known to cause timeout errors in the
+  Chromium automated build system. This version should be maintained only to
+  preserve test coverage until the corresponding version in Web Platform Tests
+  can be made to pass consistently. See https://crbug.com/658997 -->
 <title>Service Worker: CSS's base URL must be the request URL even when fetched from other URL</title>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-xhr.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-xhr.html
similarity index 70%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-xhr.html
rename to third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-xhr.html
index 85dbe4c..133e7b4a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-xhr.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-xhr.html
@@ -1,4 +1,14 @@
 <!DOCTYPE html>
+<!-- This test is prefixed with `chromium.` because the equivalent version
+  available in Web Platform Tests is known to cause timeout errors in the
+  Chromium automated build system. See https://crbug.com/658997
+
+  Furthermore, the upstream version is more strict, and Chromium currently
+  fails it. See https://crbug.com/595993
+
+  This version should be maintained only to preserve test coverage until the
+  corresponding version in Web Platform Tests can be made to pass consistently.
+  -->
 <title>Service Worker: the body of FetchEvent using XMLHttpRequest</title>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
@@ -15,10 +25,10 @@
         })
       .then(function() { return with_iframe(SCOPE); })
       .then(function(frame) {
+          t.add_cleanup(function() { frame.remove(); });
           var channel = new MessageChannel();
           channel.port1.onmessage = t.step_func(function(e) {
               assert_equals(e.data.results, 'finish');
-              frame.remove();
               service_worker_unregister_and_done(t, SCOPE);
             });
           frame.contentWindow.postMessage({},
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-response-xhr.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-response-xhr.html
similarity index 74%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-response-xhr.html
rename to third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-response-xhr.html
index 76e5246..2d6df81 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-response-xhr.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-response-xhr.html
@@ -1,4 +1,9 @@
 <!DOCTYPE html>
+<!-- This test is prefixed with `chromium.` because the equivalent version
+  available in Web Platform Tests is known to cause timeout errors in the
+  Chromium automated build system. This version should be maintained only to
+  preserve test coverage until the corresponding version in Web Platform Tests
+  can be made to pass consistently. See https://crbug.com/658997 -->
 <title>Service Worker: the response of FetchEvent using XMLHttpRequest</title>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
@@ -15,11 +20,14 @@
         })
       .then(function() { return with_iframe(SCOPE); })
       .then(function(frame) {
+          t.add_cleanup(function() {
+              frame.remove();
+              service_worker_unregister_and_done(t, SCOPE);
+            });
           var channel = new MessageChannel();
           channel.port1.onmessage = t.step_func(function(e) {
               assert_equals(e.data.results, 'finish');
-              frame.remove();
-              service_worker_unregister_and_done(t, SCOPE);
+              t.done();
             });
           frame.contentWindow.postMessage({},
                                           host_info['HTTP_ORIGIN'],
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html
index 609ac6e4..738a537 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-xhr-iframe.html
@@ -67,6 +67,8 @@
 function get_header_test() {
   return xhr_send(host_info['HTTP_ORIGIN'], 'GET', '', false)
     .then(function(response) {
+        // This assertion is invalid because the User-Agent header should not
+        // be present.
         assert_array_equals(
           get_sorted_header_name_list(response.headers),
           ["accept", "user-agent"],
@@ -75,7 +77,7 @@
 }
 
 // TODO(tyoshino): Fix the stack not to include the Origin header as specified
-// in the spec.
+// in the spec. Likewise, the User-Agent header should not be present.
 function post_header_test() {
   return xhr_send(host_info['HTTP_ORIGIN'], 'POST', '', false)
     .then(function(response) {
@@ -89,6 +91,8 @@
 function cross_origin_get_header_test() {
   return xhr_send(host_info['HTTP_REMOTE_ORIGIN'], 'GET', '', false)
     .then(function(response) {
+        // This assertion is invalid because the User-Agent header should not
+        // be present.
         assert_array_equals(
           get_sorted_header_name_list(response.headers),
           ["accept", "user-agent"],
@@ -97,7 +101,7 @@
 }
 
 // TODO(tyoshino): Fix the stack not to include the Origin header as specified
-// in the spec.
+// in the spec. Likewise, the User-Agent header should not be present.
 function cross_origin_post_header_test() {
   return xhr_send(host_info['HTTP_REMOTE_ORIGIN'], 'POST', '', false)
     .then(function(response) {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index cbd9264a..e22c633c 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -264,20 +264,6 @@
   return clip_rect;
 }
 
-#ifdef CHECK_CLIP_RECTS
-#define CHECK_RECTS_EQ(expected, actual)                                \
-  do {                                                                  \
-    bool matches =                                                      \
-        (expected.isEmpty() && actual.isEmpty()) || expected == actual; \
-    if (!matches) {                                                     \
-      LOG(ERROR) << "Rects don't match for m_layer="                    \
-                 << m_layer.layoutObject()->debugName()                 \
-                 << " expected=" << expected.toString()                 \
-                 << " actual=" << actual.toString();                    \
-    }                                                                   \
-  } while (false);
-#endif
-
 void PaintLayerClipper::CalculateRectsWithGeometryMapper(
     const ClipRectsContext& context,
     const LayoutRect& paint_dirty_rect,
@@ -319,17 +305,6 @@
         foreground_rect.SetHasRadius(true);
     }
   }
-
-#ifdef CHECK_CLIP_RECTS
-  ClipRect testBackgroundRect, testForegroundRect;
-  LayoutRect testLayerBounds;
-  PaintLayerClipper(m_layer, nullptr)
-      .calculateRects(context, paintDirtyRect, testLayerBounds,
-                      testBackgroundRect, testForegroundRect, offsetFromRoot);
-  CHECK_RECTS_EQ(testBackgroundRect, backgroundRect);
-  CHECK_RECTS_EQ(testForegroundRect, foregroundRect);
-  CHECK_RECTS_EQ(testLayerBounds, layerBounds);
-#endif
 }
 
 void PaintLayerClipper::CalculateRects(
@@ -564,11 +539,6 @@
     }
 
     CalculateBackgroundClipRectWithGeometryMapper(context, output);
-#ifdef CHECK_CLIP_RECTS
-    ClipRect testBackgroundClipRect =
-        PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context);
-    CHECK_RECTS_EQ(testBackgroundClipRect, output);
-#endif
     return;
   }
   DCHECK(layer_.Parent());
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
index 8fd0e51..f1c33dd 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
@@ -91,6 +91,8 @@
 
 PaintLayerCompositor* PaintLayerStackingNode::Compositor() const {
   DCHECK(GetLayoutObject().View());
+  if (!GetLayoutObject().View())
+    return nullptr;
   return GetLayoutObject().View()->Compositor();
 }
 
@@ -110,7 +112,7 @@
     neg_z_order_list_->clear();
   z_order_lists_dirty_ = true;
 
-  if (!GetLayoutObject().DocumentBeingDestroyed())
+  if (!GetLayoutObject().DocumentBeingDestroyed() && Compositor())
     Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
 }
 
@@ -251,7 +253,8 @@
 
   if (is_stacked_ != should_be_stacked) {
     is_stacked_ = should_be_stacked;
-    if (!GetLayoutObject().DocumentBeingDestroyed() && !Layer()->IsRootLayer())
+    if (!GetLayoutObject().DocumentBeingDestroyed() &&
+        !Layer()->IsRootLayer() && Compositor())
       Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
   }
 }
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.h b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
index 44c818af..fe41a7bc 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.h
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.h
@@ -16,7 +16,7 @@
 
 namespace blink {
 
-class NullExecutionContext final
+class NullExecutionContext
     : public GarbageCollectedFinalized<NullExecutionContext>,
       public SecurityContext,
       public ExecutionContext {
@@ -57,7 +57,7 @@
   using SecurityContext::GetSecurityOrigin;
   using SecurityContext::GetContentSecurityPolicy;
 
-  DEFINE_INLINE_TRACE() {
+  DEFINE_INLINE_VIRTUAL_TRACE() {
     visitor->Trace(queue_);
     SecurityContext::Trace(visitor);
     ExecutionContext::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationDataTest.cpp b/third_party/WebKit/Source/modules/notifications/NotificationDataTest.cpp
index b726b05..839c2dd 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationDataTest.cpp
+++ b/third_party/WebKit/Source/modules/notifications/NotificationDataTest.cpp
@@ -8,6 +8,7 @@
 #include "core/testing/NullExecutionContext.h"
 #include "modules/notifications/Notification.h"
 #include "modules/notifications/NotificationOptions.h"
+#include "platform/weborigin/KURL.h"
 #include "platform/wtf/CurrentTime.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/Vector.h"
@@ -16,6 +17,7 @@
 namespace blink {
 namespace {
 
+const char kBaseUrl[] = "https://example.com/directory/";
 const char kNotificationTitle[] = "My Notification";
 
 const char kNotificationDir[] = "rtl";
@@ -24,9 +26,9 @@
 const char kNotificationTag[] = "my_tag";
 const char kNotificationEmptyTag[] = "";
 const char kNotificationImage[] = "https://example.com/image.jpg";
-const char kNotificationIcon[] = "https://example.com/icon.png";
+const char kNotificationIcon[] = "/icon.png";
 const char kNotificationIconInvalid[] = "https://invalid:icon:url";
-const char kNotificationBadge[] = "https://example.com/badge.png";
+const char kNotificationBadge[] = "badge.png";
 const unsigned kNotificationVibration[] = {42, 10, 20, 30, 40};
 const unsigned long long kNotificationTimestamp = 621046800ull;
 const bool kNotificationRenotify = true;
@@ -44,9 +46,29 @@
 const unsigned kNotificationVibrationUnnormalized[] = {10, 1000000, 50, 42};
 const int kNotificationVibrationNormalized[] = {10, 10000, 50};
 
+// Execution context that implements the VirtualCompleteURL method to complete
+// URLs that are assumed to be relative against a given base URL.
+class CompleteUrlExecutionContext final : public NullExecutionContext {
+ public:
+  explicit CompleteUrlExecutionContext(const String& base)
+      : base_(kParsedURLString, base) {}
+
+ protected:
+  ~CompleteUrlExecutionContext() final = default;
+
+  KURL VirtualCompleteURL(const String& url) const override {
+    return KURL(base_, url);
+  }
+
+ private:
+  KURL base_;
+};
+
 class NotificationDataTest : public ::testing::Test {
  public:
-  void SetUp() override { execution_context_ = new NullExecutionContext(); }
+  void SetUp() override {
+    execution_context_ = new CompleteUrlExecutionContext(kBaseUrl);
+  }
 
   ExecutionContext* GetExecutionContext() { return execution_context_.Get(); }
 
@@ -104,8 +126,12 @@
   EXPECT_EQ(kNotificationBody, notification_data.body);
   EXPECT_EQ(kNotificationTag, notification_data.tag);
 
-  // TODO(peter): Test the various icon properties when
-  // ExecutionContext::completeURL() works in this test.
+  KURL base(kParsedURLString, kBaseUrl);
+
+  // URLs should be resolved against the base URL of the execution context.
+  EXPECT_EQ(WebURL(KURL(base, kNotificationImage)), notification_data.image);
+  EXPECT_EQ(WebURL(KURL(base, kNotificationIcon)), notification_data.icon);
+  EXPECT_EQ(WebURL(KURL(base, kNotificationBadge)), notification_data.badge);
 
   ASSERT_EQ(vibration_pattern.size(), notification_data.vibrate.size());
   for (size_t i = 0; i < vibration_pattern.size(); ++i)
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.h b/third_party/WebKit/Source/modules/webaudio/PannerNode.h
index 6297df78..f9ca870 100644
--- a/third_party/WebKit/Source/modules/webaudio/PannerNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.h
@@ -32,7 +32,7 @@
 #include "modules/webaudio/AudioParam.h"
 #include "platform/audio/AudioBus.h"
 #include "platform/audio/Cone.h"
-#include "platform/audio/Distance.h"
+#include "platform/audio/DistanceEffect.h"
 #include "platform/audio/Panner.h"
 #include "platform/geometry/FloatPoint3D.h"
 #include "platform/wtf/HashMap.h"
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 8d3fd21..12a4ef67 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -414,8 +414,8 @@
     "audio/DenormalDisabler.h",
     "audio/DirectConvolver.cpp",
     "audio/DirectConvolver.h",
-    "audio/Distance.cpp",
-    "audio/Distance.h",
+    "audio/DistanceEffect.cpp",
+    "audio/DistanceEffect.h",
     "audio/DownSampler.cpp",
     "audio/DownSampler.h",
     "audio/DynamicsCompressor.cpp",
diff --git a/third_party/WebKit/Source/platform/audio/Distance.cpp b/third_party/WebKit/Source/platform/audio/DistanceEffect.cpp
similarity index 98%
rename from third_party/WebKit/Source/platform/audio/Distance.cpp
rename to third_party/WebKit/Source/platform/audio/DistanceEffect.cpp
index 1984eb7..1e01ca7 100644
--- a/third_party/WebKit/Source/platform/audio/Distance.cpp
+++ b/third_party/WebKit/Source/platform/audio/DistanceEffect.cpp
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "platform/audio/Distance.h"
+#include "platform/audio/DistanceEffect.h"
 
 #include <math.h>
 #include <algorithm>
diff --git a/third_party/WebKit/Source/platform/audio/Distance.h b/third_party/WebKit/Source/platform/audio/DistanceEffect.h
similarity index 96%
rename from third_party/WebKit/Source/platform/audio/Distance.h
rename to third_party/WebKit/Source/platform/audio/DistanceEffect.h
index 362ba14..51cab188 100644
--- a/third_party/WebKit/Source/platform/audio/Distance.h
+++ b/third_party/WebKit/Source/platform/audio/DistanceEffect.h
@@ -26,8 +26,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef Distance_h
-#define Distance_h
+#ifndef DistanceEffect_h
+#define DistanceEffect_h
 
 #include "platform/PlatformExport.h"
 #include "platform/wtf/Allocator.h"
@@ -78,4 +78,4 @@
 
 }  // namespace blink
 
-#endif  // Distance_h
+#endif  // DistanceEffect_h
diff --git a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
index 76098457..94c376d 100644
--- a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
@@ -20,14 +20,6 @@
 ImagePattern::ImagePattern(PassRefPtr<Image> image, RepeatMode repeat_mode)
     : Pattern(repeat_mode), tile_image_(image->ImageForCurrentFrame()) {
   previous_local_matrix_.setIdentity();
-  if (tile_image_) {
-    // TODO(fmalita): mechanism to extract the actual SkImageInfo from an
-    // SkImage?
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(
-        tile_image_->width() + (IsRepeatX() ? 0 : 2),
-        tile_image_->height() + (IsRepeatY() ? 0 : 2));
-    AdjustExternalMemoryAllocated(info.getSafeSize(info.minRowBytes()));
-  }
 }
 
 bool ImagePattern::IsLocalMatrixChanged(const SkMatrix& local_matrix) const {
diff --git a/third_party/WebKit/Source/platform/graphics/Pattern.cpp b/third_party/WebKit/Source/platform/graphics/Pattern.cpp
index 6da154d..c169fbc 100644
--- a/third_party/WebKit/Source/platform/graphics/Pattern.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Pattern.cpp
@@ -27,8 +27,6 @@
 
 #include "platform/graphics/Pattern.h"
 
-#include <v8.h>
-
 #include "platform/graphics/ImagePattern.h"
 #include "platform/graphics/PaintRecordPattern.h"
 #include "platform/graphics/paint/PaintFlags.h"
@@ -49,13 +47,9 @@
   return PaintRecordPattern::Create(std::move(record), repeat_mode);
 }
 
-Pattern::Pattern(RepeatMode repeat_mode, int64_t external_memory_allocated)
-    : repeat_mode_(repeat_mode), external_memory_allocated_(0) {
-  AdjustExternalMemoryAllocated(external_memory_allocated);
-}
+Pattern::Pattern(RepeatMode repeat_mode) : repeat_mode_(repeat_mode) {}
 
 Pattern::~Pattern() {
-  AdjustExternalMemoryAllocated(-external_memory_allocated_);
 }
 
 void Pattern::ApplyToFlags(PaintFlags& flags, const SkMatrix& local_matrix) {
@@ -69,12 +63,4 @@
   return local_matrix != cached_shader_->getLocalMatrix();
 }
 
-void Pattern::AdjustExternalMemoryAllocated(int64_t delta) {
-  delta = std::max(-external_memory_allocated_, delta);
-
-  v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta);
-
-  external_memory_allocated_ += delta;
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/Pattern.h b/third_party/WebKit/Source/platform/graphics/Pattern.h
index bce9d10..3784107 100644
--- a/third_party/WebKit/Source/platform/graphics/Pattern.h
+++ b/third_party/WebKit/Source/platform/graphics/Pattern.h
@@ -74,15 +74,10 @@
   virtual sk_sp<PaintShader> CreateShader(const SkMatrix&) = 0;
   virtual bool IsLocalMatrixChanged(const SkMatrix&) const;
 
-  void AdjustExternalMemoryAllocated(int64_t delta);
-
   RepeatMode repeat_mode_;
 
-  Pattern(RepeatMode, int64_t external_memory_allocated = 0);
+  Pattern(RepeatMode);
   mutable sk_sp<PaintShader> cached_shader_;
-
- private:
-  int64_t external_memory_allocated_;
 };
 
 }  // namespace blink
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c309a7f..c2a5e7f 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -3815,6 +3815,17 @@
   <summary>The autofill state related to a submitted form.</summary>
 </histogram>
 
+<histogram name="Autofill.HasModifiedProfile.CreditCardFormSubmission"
+    enum="Boolean">
+  <owner>csashi@google.com</owner>
+  <owner>jsaul@google.com</owner>
+  <owner>sebsg@chromium.org</owner>
+  <summary>
+    Whether user modified an address profile shortly before submitting a credit
+    card form.
+  </summary>
+</histogram>
+
 <histogram name="Autofill.IcuCollatorCreationSuccess" enum="BooleanSuccess">
   <owner>mathp@chromium.org</owner>
   <summary>
diff --git a/ui/gfx/win/direct_manipulation.cc b/ui/gfx/win/direct_manipulation.cc
index c6572f9..7f6a094 100644
--- a/ui/gfx/win/direct_manipulation.cc
+++ b/ui/gfx/win/direct_manipulation.cc
@@ -12,12 +12,11 @@
 // static
 std::unique_ptr<DirectManipulationHelper>
 DirectManipulationHelper::CreateInstance() {
-  std::unique_ptr<DirectManipulationHelper> instance;
-
-  if (base::win::GetVersion() >= base::win::VERSION_WIN10)
-    instance.reset(new DirectManipulationHelper);
-
-  return instance;
+  // TODO(dtapuska): Do not create a DirectManipulationHelper on any windows
+  // versions as it only causes issues. High Precision Touchpad events seem to
+  // always be sent to apps with recent Windows 10 versions. This class should
+  // eventually be removed. See crbug.com/647038.
+  return nullptr;
 }
 
 DirectManipulationHelper::DirectManipulationHelper() {}
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
index 0b6fa0f..a724541 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
@@ -125,7 +125,7 @@
 
       :host([narrow][showing-search]) #icon,
       :host([narrow][showing-search]) paper-spinner-lite {
-        -webkit-margin-start: var(--cr-control-spacing);
+        -webkit-margin-start: 18px;  /* Line up with Menu icon. */
       }
     </style>
     <template is="dom-if" id="spinnerTemplate">
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html
index bd7de80..fae5e91 100644
--- a/ui/webui/resources/cr_elements/shared_vars_css.html
+++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -8,7 +8,8 @@
       cursor: pointer;
     };
 
-    --cr-control-spacing: 18px;
+    /* Spacing between policy (controlledBy) indicator and control. */
+    --cr-control-spacing: 24px;
 
     --cr-focused-item-color: var(--google-grey-300);