diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 0032699..02e655cd 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2952,6 +2952,8 @@
         "views/location_bar/bubble_icon_view.h",
         "views/location_bar/content_setting_image_view.cc",
         "views/location_bar/content_setting_image_view.h",
+        "views/location_bar/find_bar_icon.cc",
+        "views/location_bar/find_bar_icon.h",
         "views/location_bar/icon_label_bubble_view.cc",
         "views/location_bar/icon_label_bubble_view.h",
         "views/location_bar/keyword_hint_view.cc",
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
index ee582f8..ae49cad 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
@@ -502,6 +502,10 @@
   // If the find bar is not visible, make it actually hidden, so it'll no longer
   // respond to key events.
   [[self view] setHidden:![self isFindBarVisible]];
+  // Notify the FindBarController that the visibility animation has completed in
+  // order to show or hide a decoration in the location bar.
+  if (findBarBridge_)
+    findBarBridge_->GetFindBarController()->FindBarVisibilityChanged();
 }
 
 - (gfx::Point)findBarWindowPosition {
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
index 326f4a32..2c69f1fa 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -75,6 +75,7 @@
   void UpdateContentSettingsIcons() override;
   void UpdateManagePasswordsIconAndBubble() override;
   void UpdateSaveCreditCardIcon() override;
+  void UpdateFindBarIconVisibility() override;
   void UpdateBookmarkStarVisibility() override;
   void UpdateZoomViewVisibility() override;
   void UpdateLocationBarVisibility(bool visible, bool animate) override;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
index 08e9f15..43564a6 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -198,6 +198,11 @@
   OnDecorationsChanged();
 }
 
+void LocationBarViewMac::UpdateFindBarIconVisibility() {
+  // TODO(crbug/651643): Implement for mac.
+  NOTIMPLEMENTED();
+}
+
 void LocationBarViewMac::UpdateBookmarkStarVisibility() {
   star_decoration_->SetVisible(IsStarEnabled());
 }
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc
index cfacd76..4a48552 100644
--- a/chrome/browser/ui/find_bar/find_bar_controller.cc
+++ b/chrome/browser/ui/find_bar/find_bar_controller.cc
@@ -12,10 +12,14 @@
 #include "build/build_config.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_state.h"
 #include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
+#include "chrome/browser/ui/location_bar/location_bar.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_details.h"
@@ -81,6 +85,15 @@
   }
 }
 
+void FindBarController::FindBarVisibilityChanged() {
+  if (web_contents_) {
+    chrome::FindBrowserWithWebContents(web_contents_)
+        ->window()
+        ->GetLocationBar()
+        ->UpdateFindBarIconVisibility();
+  }
+}
+
 void FindBarController::ChangeWebContents(WebContents* contents) {
   if (web_contents_) {
     registrar_.RemoveAll();
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.h b/chrome/browser/ui/find_bar/find_bar_controller.h
index e912a06..ed909f5 100644
--- a/chrome/browser/ui/find_bar/find_bar_controller.h
+++ b/chrome/browser/ui/find_bar/find_bar_controller.h
@@ -54,6 +54,9 @@
   void EndFindSession(SelectionAction selection_action,
                       ResultAction results_action);
 
+  // The visibility of the find bar view changed.
+  void FindBarVisibilityChanged();
+
   // Accessor for the attached WebContents.
   content::WebContents* web_contents() const { return web_contents_; }
 
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h
index 24cd148..6527807 100644
--- a/chrome/browser/ui/location_bar/location_bar.h
+++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -52,6 +52,9 @@
   // Updates the visibility and toggled state of the save credit card icon.
   virtual void UpdateSaveCreditCardIcon() = 0;
 
+  // Updates the visibility of the find bar image icon.
+  virtual void UpdateFindBarIconVisibility() = 0;
+
   // Updates the visibility of the bookmark star.
   virtual void UpdateBookmarkStarVisibility() = 0;
 
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index 311921d..0951d5ed 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -12,11 +12,14 @@
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/find_bar_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
+#include "ui/views/border.h"
 #include "ui/views/focus/external_focus_tracker.h"
 #include "ui/views/widget/root_view.h"
 #include "ui/views/widget/widget.h"
@@ -262,6 +265,10 @@
   if (widget_bounds.IsEmpty())
     return gfx::Rect();
 
+  gfx::Insets insets =
+      view()->border()->GetInsets() -
+      gfx::Insets(0, BackgroundWith1PxBorder::kLocationBarBorderThicknessDip);
+
   // Ask the view how large an area it needs to draw on.
   gfx::Size prefsize = view()->GetPreferredSize();
 
@@ -274,12 +281,13 @@
     return gfx::Rect();
 
   // Place the view in the top right corner of the widget boundaries (top left
-  // for RTL languages).
+  // for RTL languages). Adjust for the view insets to ensure the border lines
+  // up with the location bar.
   gfx::Rect view_location;
-  int x = widget_bounds.x();
+  int x = widget_bounds.x() - insets.left();
   if (!base::i18n::IsRTL())
-    x += widget_bounds.width() - prefsize.width();
-  int y = widget_bounds.y();
+    x += widget_bounds.width() - prefsize.width() + insets.width();
+  int y = widget_bounds.y() - insets.top();
   view_location.SetRect(x, y, prefsize.width(), prefsize.height());
 
   // When we get Find results back, we specify a selection rect, which we
@@ -344,6 +352,8 @@
     visible_bounds = host()->GetWindowBoundsInScreen();
   browser_view()->immersive_mode_controller()->OnFindBarVisibleBoundsChanged(
       visible_bounds);
+
+  find_bar_controller_->FindBarVisibilityChanged();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index 2236892..482af60 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -15,12 +15,15 @@
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/download/download_shelf_view.h"
 #include "chrome/browser/ui/views/exclusive_access_bubble_views.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
 #include "chrome/browser/ui/views/frame/contents_layout_manager.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "ui/base/hit_test.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -201,48 +204,55 @@
 }
 
 gfx::Rect BrowserViewLayout::GetFindBarBoundingBox() const {
-  // This function returns the area the Find Bar can be laid out within. This
-  // basically implies the "user-perceived content area" of the browser
-  // window excluding the vertical scrollbar. The "user-perceived content area"
-  // excludes the detached bookmark bar (in the New Tab case) and any infobars
-  // since they are not _visually_ connected to the Toolbar.
+  // This function returns the area the Find Bar can be laid out within. When
+  // the location bar/OmniBox is visible, the bounding box is the area extending
+  // from the bottom edge of the location bar/OmniBox to the bottom of the
+  // "user-perceived content area" of the browser window. The width matches the
+  // width of the location bar/OmniBox. If the location bar/OmniBox is not
+  // visible, the returned area is the full "user-perceived content area",
+  // excluding any vertical scrollbar.
+  // The "user-perceived content area" excludes the detached bookmark bar (in
+  // the New Tab case) and any infobars since they are not _visually_ connected
+  // to the Toolbar.
 
-  // First determine the bounding box of the content area in Widget
-  // coordinates.
-  gfx::Rect bounding_box = contents_container_->ConvertRectToWidget(
-      contents_container_->GetLocalBounds());
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
+  LocationBarView* location_bar_view = browser_view->GetLocationBarView();
 
-  gfx::Rect top_container_bounds = top_container_->ConvertRectToWidget(
-      top_container_->GetLocalBounds());
+  // Check for the presence of a visible OmniBox/location bar.
+  const bool has_location_bar =
+      browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR) &&
+      location_bar_view && location_bar_view->visible() &&
+      (!immersive_mode_controller_->IsEnabled() ||
+       immersive_mode_controller_->IsRevealed());
 
-  int find_bar_y = 0;
-  if (immersive_mode_controller_->IsEnabled() &&
-      !immersive_mode_controller_->IsRevealed()) {
-    // Position the find bar exactly below the top container. In immersive
-    // fullscreen, when the top-of-window views are not revealed, only the
-    // miniature immersive style tab strip is visible. Do not overlap the
-    // find bar and the tab strip.
-    find_bar_y = top_container_bounds.bottom();
-  } else {
-    // Overlap the find bar atop |top_container_|.
-    const int kTopOverlap = 6;
-    find_bar_y = top_container_bounds.bottom() - kTopOverlap;
+  gfx::Rect bounding_box;
+  // If the OmniBox/location bar is visible, anchor the find bar bounding box
+  // to its bottom edge.
+  if (has_location_bar) {
+    // The bounding box should be the area right below the OmniBox/location bar.
+    bounding_box = location_bar_view->ConvertRectToWidget(
+        location_bar_view->GetLocalBounds());
+    bounding_box.Inset(0, location_bar_view->height(), 0,
+                       -contents_container_->height());
+    return bounding_box;
   }
 
-  // Grow the height of |bounding_box| by the height of any elements between
-  // the top container and |contents_container_| such as the detached bookmark
-  // bar and any infobars.
-  int height_delta = bounding_box.y() - find_bar_y;
-  bounding_box.set_y(find_bar_y);
-  bounding_box.set_height(std::max(0, bounding_box.height() + height_delta));
-
-  // Finally decrease the width of the bounding box by the width of
-  // the vertical scroll bar.
-  int scrollbar_width = gfx::scrollbar_size();
-  bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width));
+  // Otherwise, use the contents container minus any infobars and detached
+  // bookmark bar from the top and a scrollbar width from the appropriate edge.
+  bounding_box = contents_container_->ConvertRectToWidget(
+      contents_container_->GetLocalBounds());
+  // Under ChromeOS, the top_container_ may include the title bar for hosted
+  // apps. Just make sure something of consequence is visible before it's height
+  // is used.
+  const int top_container_height = (browser_view->tabstrip()->visible() ||
+                                    browser_view->toolbar()->visible() ||
+                                    browser_view->IsBookmarkBarVisible())
+                                       ? top_container_->height()
+                                       : 0;
   if (base::i18n::IsRTL())
-    bounding_box.set_x(bounding_box.x() + scrollbar_width);
-
+    bounding_box.Inset(gfx::scrollbar_size(), top_container_height, 0, 0);
+  else
+    bounding_box.Inset(0, top_container_height, gfx::scrollbar_size(), 0);
   return bounding_box;
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc
index 10918a9..c7f8bf1 100644
--- a/chrome/browser/ui/views/frame/browser_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -242,8 +242,8 @@
   // The web contents should be flush with the bottom of the header.
   EXPECT_EQ(bottom_of_header, contents_container->y());
 
-  // The find bar should overlap the 1px header/web-contents separator at the
-  // bottom of the header.
-  EXPECT_LT(browser_view()->GetFindBarBoundingBox().y(),
+  // The find bar should butt against the 1px header/web-contents separator at
+  // the bottom of the header.
+  EXPECT_EQ(browser_view()->GetFindBarBoundingBox().y(),
             browser_view()->frame()->GetTopInset(false));
 }
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
new file mode 100644
index 0000000..f678839b
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -0,0 +1,21 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/location_bar/find_bar_icon.h"
+
+#include "components/toolbar/vector_icons.h"
+
+FindBarIcon::FindBarIcon() : BubbleIconView(nullptr, 0) {}
+
+FindBarIcon::~FindBarIcon() {}
+
+void FindBarIcon::OnExecuting(ExecuteSource execute_source) {}
+
+views::BubbleDialogDelegateView* FindBarIcon::GetBubble() const {
+  return nullptr;
+}
+
+const gfx::VectorIcon& FindBarIcon::GetVectorIcon() const {
+  return toolbar::kFindInPageIcon;
+}
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.h b/chrome/browser/ui/views/location_bar/find_bar_icon.h
new file mode 100644
index 0000000..3380ae2
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/find_bar_icon.h
@@ -0,0 +1,27 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_
+#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+
+// The find icon to show when the find bar is visible.
+class FindBarIcon : public BubbleIconView {
+ public:
+  FindBarIcon();
+  ~FindBarIcon() override;
+
+ protected:
+  // BubbleIconView:
+  void OnExecuting(ExecuteSource execute_source) override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
+  const gfx::VectorIcon& GetVectorIcon() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FindBarIcon);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 3b54c95..24a0034 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -29,6 +29,8 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
@@ -37,6 +39,7 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
+#include "chrome/browser/ui/views/location_bar/find_bar_icon.h"
 #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
@@ -59,6 +62,7 @@
 #include "components/search_engines/template_url.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/toolbar/toolbar_model.h"
+#include "components/toolbar/vector_icons.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/variations/variations_associated_data.h"
 #include "components/zoom/zoom_controller.h"
@@ -112,7 +116,6 @@
 using content::WebContents;
 using views::View;
 
-
 // LocationBarView -----------------------------------------------------------
 
 // static
@@ -224,36 +227,23 @@
     AddChildView(image_view);
   }
 
-  zoom_view_ = new ZoomView(delegate_);
-  zoom_view_->Init();
-  AddChildView(zoom_view_);
+  auto add_icon = [this](BubbleIconView* icon_view) -> void {
+    icon_view->Init();
+    icon_view->SetVisible(false);
+    AddChildView(icon_view);
+  };
 
-  manage_passwords_icon_view_ = new ManagePasswordsIconViews(command_updater());
-  manage_passwords_icon_view_->Init();
-  AddChildView(manage_passwords_icon_view_);
-
-  save_credit_card_icon_view_ =
-      new autofill::SaveCardIconView(command_updater(), browser_);
-  save_credit_card_icon_view_->Init();
-  save_credit_card_icon_view_->SetVisible(false);
-  AddChildView(save_credit_card_icon_view_);
-
-  translate_icon_view_ = new TranslateIconView(command_updater());
-  translate_icon_view_->Init();
-  translate_icon_view_->SetVisible(false);
-  AddChildView(translate_icon_view_);
-
+  add_icon(zoom_view_ = new ZoomView(delegate_));
+  add_icon(manage_passwords_icon_view_ =
+               new ManagePasswordsIconViews(command_updater()));
+  add_icon(save_credit_card_icon_view_ =
+               new autofill::SaveCardIconView(command_updater(), browser_));
+  add_icon(translate_icon_view_ = new TranslateIconView(command_updater()));
 #if defined(OS_CHROMEOS)
-  intent_picker_view_ = new IntentPickerView(browser_);
-  intent_picker_view_->Init();
-  intent_picker_view_->SetVisible(false);
-  AddChildView(intent_picker_view_);
-#endif  // defined(OS_CHROMEOS)
-
-  star_view_ = new StarView(command_updater(), browser_);
-  star_view_->Init();
-  star_view_->SetVisible(false);
-  AddChildView(star_view_);
+  add_icon(intent_picker_view_ = new IntentPickerView(browser_));
+#endif
+  add_icon(find_bar_icon_ = new FindBarIcon());
+  add_icon(star_view_ = new StarView(command_updater(), browser_));
 
   clear_all_button_ = views::CreateVectorImageButton(this);
   clear_all_button_->SetTooltipText(
@@ -532,40 +522,28 @@
                                       location_icon_view_);
   }
 
-#if defined(OS_CHROMEOS)
-  if (intent_picker_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       intent_picker_view_);
-  }
-#endif  // defined(OS_CHROMEOS)
-  if (star_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       star_view_);
-  }
-  if (translate_icon_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       translate_icon_view_);
-  }
-  if (save_credit_card_icon_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       save_credit_card_icon_view_);
-  }
-  if (manage_passwords_icon_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       manage_passwords_icon_view_);
-  }
-  if (zoom_view_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       zoom_view_);
-  }
-  for (ContentSettingViews::const_reverse_iterator i(
-           content_setting_views_.rbegin()); i != content_setting_views_.rend();
-       ++i) {
-    if ((*i)->visible()) {
+  auto add_trailing_decoration = [&trailing_decorations, vertical_padding,
+                                  location_height, item_padding](View* view) {
+    if (view->visible()) {
       trailing_decorations.AddDecoration(vertical_padding, location_height,
                                          false, 0, item_padding, item_padding,
-                                         *i);
+                                         view);
     }
+  };
+
+#if defined(OS_CHROMEOS)
+  add_trailing_decoration(intent_picker_view_);
+#endif
+  add_trailing_decoration(star_view_);
+  add_trailing_decoration(find_bar_icon_);
+  add_trailing_decoration(translate_icon_view_);
+  add_trailing_decoration(save_credit_card_icon_view_);
+  add_trailing_decoration(manage_passwords_icon_view_);
+  add_trailing_decoration(zoom_view_);
+  for (ContentSettingViews::const_reverse_iterator i(
+           content_setting_views_.rbegin());
+       i != content_setting_views_.rend(); ++i) {
+    add_trailing_decoration(*i);
   }
   // Because IMEs may eat the tab key, we don't show "press tab to search" while
   // IME composition is in progress.
@@ -578,10 +556,7 @@
     keyword_hint_view_->SetKeyword(keyword);
   }
 
-  if (clear_all_button_->visible()) {
-    trailing_decorations.AddDecoration(vertical_padding, location_height,
-                                       clear_all_button_);
-  }
+  add_trailing_decoration(clear_all_button_);
 
   const int edge_thickness = GetHorizontalEdgeThickness();
 
@@ -787,6 +762,15 @@
   return was_visible != save_credit_card_icon_view_->visible();
 }
 
+bool LocationBarView::RefreshFindBarIcon() {
+  if (!find_bar_icon_)
+    return false;
+  const bool was_visible = find_bar_icon_->visible();
+  find_bar_icon_->SetVisible(
+      browser_->GetFindBarController()->find_bar()->IsFindBarVisible());
+  return was_visible != find_bar_icon_->visible();
+}
+
 void LocationBarView::RefreshTranslateIcon() {
   WebContents* web_contents = GetWebContents();
   if (!web_contents)
@@ -908,6 +892,17 @@
   }
 }
 
+void LocationBarView::UpdateFindBarIconVisibility() {
+  if (RefreshFindBarIcon()) {
+    Layout();
+    find_bar_icon_->AnimateInkDrop(find_bar_icon_->visible()
+                                       ? views::InkDropState::ACTIVATED
+                                       : views::InkDropState::HIDDEN,
+                                   nullptr);
+    SchedulePaint();
+  }
+}
+
 void LocationBarView::UpdateBookmarkStarVisibility() {
   if (star_view_) {
     star_view_->SetVisible(
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index cb6aa95..99c28b2 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -32,6 +32,7 @@
 class CommandUpdater;
 class ContentSettingBubbleModelDelegate;
 class ContentSettingImageView;
+class FindBarIcon;
 class GURL;
 class IntentPickerView;
 class KeywordHintView;
@@ -277,6 +278,9 @@
   // Updates |save_credit_card_icon_view_|. Returns true if visibility changed.
   bool RefreshSaveCreditCardIconView();
 
+  // Updates |find_bar_icon_|. Returns true if visibility changed.
+  bool RefreshFindBarIcon();
+
   // Updates the Translate icon based on the current tab's Translate status.
   void RefreshTranslateIcon();
 
@@ -312,6 +316,7 @@
   void UpdateContentSettingsIcons() override;
   void UpdateManagePasswordsIconAndBubble() override;
   void UpdateSaveCreditCardIcon() override;
+  void UpdateFindBarIconVisibility() override;
   void UpdateBookmarkStarVisibility() override;
   void UpdateZoomViewVisibility() override;
   void UpdateLocationBarVisibility(bool visible, bool animation) override;
@@ -402,6 +407,9 @@
   IntentPickerView* intent_picker_view_ = nullptr;
 #endif  // defined(OS_CHROMEOS)
 
+  // The icon displayed when the find bar is visible.
+  FindBarIcon* find_bar_icon_ = nullptr;
+
   // The star for bookmarking.
   StarView* star_view_ = nullptr;
 
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index b2f1ab9..62e8428 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -167,6 +167,7 @@
     void UpdateContentSettingsIcons() override {}
     void UpdateManagePasswordsIconAndBubble() override {}
     void UpdateSaveCreditCardIcon() override {}
+    void UpdateFindBarIconVisibility() override {}
     void UpdateBookmarkStarVisibility() override {}
     void UpdateZoomViewVisibility() override {}
     void UpdateLocationBarVisibility(bool visible, bool animate) override {}
diff --git a/components/toolbar/BUILD.gn b/components/toolbar/BUILD.gn
index 3a9f304a..bbcadbd5 100644
--- a/components/toolbar/BUILD.gn
+++ b/components/toolbar/BUILD.gn
@@ -16,6 +16,7 @@
   icon_directory = "vector_icons"
 
   icons = [
+    "find_in_page.icon",
     "http.1x.icon",
     "http.icon",
     "https_invalid.1x.icon",
diff --git a/components/toolbar/vector_icons/find_in_page.icon b/components/toolbar/vector_icons/find_in_page.icon
new file mode 100644
index 0000000..15ecfda
--- /dev/null
+++ b/components/toolbar/vector_icons/find_in_page.icon
@@ -0,0 +1,30 @@
+// 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.
+
+CANVAS_DIMENSIONS, 24,
+FLIPS_IN_RTL,
+MOVE_TO, 20, 19.59f,
+V_LINE_TO, 8,
+R_LINE_TO, -6, -6,
+H_LINE_TO, 6,
+R_CUBIC_TO, -1.1f, 0, -1.99f, 0.9f, -1.99f, 2,
+LINE_TO, 4, 20,
+R_CUBIC_TO, 0, 1.1f, 0.89f, 2, 1.99f, 2,
+H_LINE_TO, 18,
+R_CUBIC_TO, 0.45f, 0, 0.85f, -0.15f, 1.19f, -0.4f,
+R_LINE_TO, -4.43f, -4.43f,
+R_CUBIC_TO, -0.8f, 0.52f, -1.74f, 0.83f, -2.76f, 0.83f,
+R_CUBIC_TO, -2.76f, 0, -5, -2.24f, -5, -5,
+R_CUBIC_TO, 0, -2.76f, 2.24f, -5, 5, -5,
+R_CUBIC_TO, 2.76f, 0, 5, 2.24f, 5, 5,
+R_CUBIC_TO, 0, 1.02f, -0.31f, 1.96f, -0.83f, 2.75f,
+LINE_TO, 20, 19.59f,
+CLOSE,
+MOVE_TO, 9, 13,
+R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3,
+R_CUBIC_TO, 1.66f, 0, 3, -1.34f, 3, -3,
+R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3,
+R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3,
+CLOSE,
+END
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc
index 2013efc..2930b8e 100644
--- a/content/browser/background_fetch/background_fetch_context.cc
+++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -13,9 +13,9 @@
 #include "content/browser/background_fetch/background_fetch_registration_notifier.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/public/browser/background_fetch_delegate.h"
-#include "content/public/browser/blob_handle.h"
 #include "content/public/browser/browser_context.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "storage/browser/blob/blob_data_handle.h"
 
 namespace content {
 
@@ -172,7 +172,7 @@
     blink::mojom::BackgroundFetchError error,
     bool background_fetch_succeeded,
     std::vector<BackgroundFetchSettledFetch> settled_fetches,
-    std::vector<std::unique_ptr<BlobHandle>> blob_handles) {
+    std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (error != blink::mojom::BackgroundFetchError::NONE) {
@@ -189,24 +189,24 @@
         base::Bind(&BackgroundFetchContext::CleanupRegistration,
                    weak_factory_.GetWeakPtr(), registration_id,
                    // The blob uuid is sent as part of |settled_fetches|. Bind
-                   // |blob_handles| to the callback to keep them alive until
-                   // the waitUntil event is resolved.
-                   std::move(blob_handles)));
+                   // |blob_data_handles| to the callback to keep them alive
+                   // until the waitUntil event is resolved.
+                   std::move(blob_data_handles)));
   } else {
     event_dispatcher_.DispatchBackgroundFetchFailEvent(
         registration_id, std::move(settled_fetches),
         base::Bind(&BackgroundFetchContext::CleanupRegistration,
                    weak_factory_.GetWeakPtr(), registration_id,
                    // The blob uuid is sent as part of |settled_fetches|. Bind
-                   // |blob_handles| to the callback to keep them alive until
-                   // the waitUntil event is resolved.
-                   std::move(blob_handles)));
+                   // |blob_data_handles| to the callback to keep them alive
+                   // until the waitUntil event is resolved.
+                   std::move(blob_data_handles)));
   }
 }
 
 void BackgroundFetchContext::CleanupRegistration(
     const BackgroundFetchRegistrationId& registration_id,
-    const std::vector<std::unique_ptr<BlobHandle>>& blob_handles) {
+    const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   // If we had an active JobController, it is no longer necessary, as the
diff --git a/content/browser/background_fetch/background_fetch_context.h b/content/browser/background_fetch/background_fetch_context.h
index b6ccbd6..ba8bea397 100644
--- a/content/browser/background_fetch/background_fetch_context.h
+++ b/content/browser/background_fetch/background_fetch_context.h
@@ -20,13 +20,16 @@
 #include "content/public/browser/browser_thread.h"
 #include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
 
+namespace storage {
+class BlobDataHandle;
+}
+
 namespace content {
 
 class BackgroundFetchJobController;
 struct BackgroundFetchOptions;
 class BackgroundFetchRegistrationId;
 class BackgroundFetchRegistrationNotifier;
-class BlobHandle;
 class BrowserContext;
 class ServiceWorkerContextWrapper;
 struct ServiceWorkerFetchRequest;
@@ -111,14 +114,15 @@
       blink::mojom::BackgroundFetchError error,
       bool background_fetch_succeeded,
       std::vector<BackgroundFetchSettledFetch> settled_fetches,
-      std::vector<std::unique_ptr<BlobHandle>> blob_handles);
+      std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
 
   // Called when all processing for the |registration_id| has been finished and
   // the job is ready to be deleted. |blob_handles| are unused, but some callers
   // use it to keep blobs alive for the right duration.
   void CleanupRegistration(
       const BackgroundFetchRegistrationId& registration_id,
-      const std::vector<std::unique_ptr<BlobHandle>>& blob_handles);
+      const std::vector<std::unique_ptr<storage::BlobDataHandle>>&
+          blob_data_handles);
 
   // Called when the last JavaScript BackgroundFetchRegistration object has been
   // garbage collected for a registration marked for deletion, and so it is now
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc
index 9d6ac2ee..32eed21c8 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/containers/flat_set.h"
 #include "base/containers/queue.h"
+#include "base/guid.h"
 #include "base/memory/ptr_util.h"
 #include "base/numerics/checked_math.h"
 #include "base/strings/string_number_conversions.h"
@@ -21,13 +22,17 @@
 #include "content/browser/background_fetch/background_fetch_request_info.h"
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/public/browser/blob_handle.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_interrupt_reasons.h"
 #include "content/public/browser/download_item.h"
+#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "services/network/public/interfaces/fetch_api.mojom.h"
+#include "storage/browser/blob/blob_data_builder.h"
+#include "storage/browser/blob/blob_impl.h"
+#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/WebKit/common/blob/blob.mojom.h"
 
 // Service Worker DB UserData schema
 // =================================
@@ -1039,7 +1044,7 @@
   std::vector<BackgroundFetchSettledFetch> settled_fetches;
   settled_fetches.reserve(requests.size());
 
-  std::vector<std::unique_ptr<BlobHandle>> blob_handles;
+  std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles;
 
   for (const auto& request : requests) {
     BackgroundFetchSettledFetch settled_fetch;
@@ -1063,17 +1068,32 @@
 
       if (request->GetFileSize() > 0) {
         DCHECK(!request->GetFilePath().empty());
-        std::unique_ptr<BlobHandle> blob_handle =
-            blob_storage_context_->CreateFileBackedBlob(
-                request->GetFilePath(), 0 /* offset */, request->GetFileSize(),
-                base::Time() /* expected_modification_time */);
+        DCHECK(blob_storage_context_);
 
-        // TODO(peter): Appropriately handle !blob_handle
-        if (blob_handle) {
-          settled_fetch.response.blob_uuid = blob_handle->GetUUID();
-          settled_fetch.response.blob_size = request->GetFileSize();
+        storage::BlobDataBuilder blob_builder(base::GenerateGUID());
+        blob_builder.AppendFile(request->GetFilePath(), 0 /* offset */,
+                                request->GetFileSize(),
+                                base::Time() /* expected_modification_time */);
 
-          blob_handles.push_back(std::move(blob_handle));
+        auto blob_data_handle =
+            GetBlobStorageContext(blob_storage_context_.get())
+                ->AddFinishedBlob(&blob_builder);
+
+        // TODO(peter): Appropriately handle !blob_data_handle
+        if (blob_data_handle) {
+          settled_fetch.response.blob_uuid = blob_data_handle->uuid();
+          settled_fetch.response.blob_size = blob_data_handle->size();
+          if (features::IsMojoBlobsEnabled()) {
+            blink::mojom::BlobPtr blob_ptr;
+            storage::BlobImpl::Create(
+                std::make_unique<storage::BlobDataHandle>(*blob_data_handle),
+                MakeRequest(&blob_ptr));
+
+            settled_fetch.response.blob =
+                base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
+          }
+
+          blob_data_handles.push_back(std::move(blob_data_handle));
         }
       }
     } else {
@@ -1091,9 +1111,9 @@
     settled_fetches.push_back(settled_fetch);
   }
 
-  std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
-                          background_fetch_succeeded,
-                          std::move(settled_fetches), std::move(blob_handles));
+  std::move(callback).Run(
+      blink::mojom::BackgroundFetchError::NONE, background_fetch_succeeded,
+      std::move(settled_fetches), std::move(blob_data_handles));
 }
 
 void BackgroundFetchDataManager::MarkRegistrationForDeletion(
diff --git a/content/browser/background_fetch/background_fetch_data_manager.h b/content/browser/background_fetch/background_fetch_data_manager.h
index 57b8949..2ac4954 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.h
+++ b/content/browser/background_fetch/background_fetch_data_manager.h
@@ -22,11 +22,14 @@
 #include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
 #include "url/origin.h"
 
+namespace storage {
+class BlobDataHandle;
+}
+
 namespace content {
 
 class BackgroundFetchRequestInfo;
 struct BackgroundFetchSettledFetch;
-class BlobHandle;
 class BrowserContext;
 class ChromeBlobStorageContext;
 class ServiceWorkerContextWrapper;
@@ -48,11 +51,11 @@
       base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
   using MarkedCompleteCallback =
       base::OnceCallback<void(bool /* has_pending_or_active_requests */)>;
-  using SettledFetchesCallback =
-      base::OnceCallback<void(blink::mojom::BackgroundFetchError,
-                              bool /* background_fetch_succeeded */,
-                              std::vector<BackgroundFetchSettledFetch>,
-                              std::vector<std::unique_ptr<BlobHandle>>)>;
+  using SettledFetchesCallback = base::OnceCallback<void(
+      blink::mojom::BackgroundFetchError,
+      bool /* background_fetch_succeeded */,
+      std::vector<BackgroundFetchSettledFetch>,
+      std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
   // Note that this also handles non-error cases where the NONE is NONE.
   using HandleBackgroundFetchErrorCallback =
       base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc
index e1f3688..8b036df 100644
--- a/content/renderer/service_worker/web_service_worker_registration_impl.cc
+++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -418,6 +418,10 @@
                        std::move(active)));
     return;
   }
+
+  if (state_ == LifecycleState::kDetached)
+    return;
+  DCHECK_EQ(LifecycleState::kAttachedAndBound, state_);
   ServiceWorkerDispatcher* dispatcher =
       ServiceWorkerDispatcher::GetThreadSpecificInstance();
   DCHECK(dispatcher);
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h
index 0982c5a..027cd82 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.h
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -59,19 +59,6 @@
   // with this call.
   virtual bool RunsTasksInCurrentSequence() = 0;
 
-  // ---
-
-  // Headless Chrome virtualises time for determinism and performance (fast
-  // forwarding of timers). To make this work some parts of blink (e.g. Timers)
-  // need to use virtual time, however by default new code should use the normal
-  // non-virtual time APIs.
-
-  // Returns a double which is the number of seconds since epoch (Jan 1, 1970).
-  // This may represent either the real time, or a virtual time depending on
-  // whether or not the WebTaskRunner is associated with a virtual time domain
-  // or a real time domain.
-  virtual double VirtualTimeSeconds() const = 0;
-
   // Returns a microsecond resolution platform dependant time source.
   // This may represent either the real time, or a virtual time depending on
   // whether or not the WebTaskRunner is associated with a virtual time domain
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
index d918f88..07a8af9 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
@@ -26,10 +26,6 @@
   return task_queue_->RunsTasksInCurrentSequence();
 }
 
-double WebTaskRunnerImpl::VirtualTimeSeconds() const {
-  return (Now() - base::TimeTicks::UnixEpoch()).InSecondsF();
-}
-
 double WebTaskRunnerImpl::MonotonicallyIncreasingVirtualTimeSeconds() const {
   return Now().ToInternalValue() /
          static_cast<double>(base::Time::kMicrosecondsPerSecond);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
index 0fac5c3..50b23fc 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
@@ -28,7 +28,6 @@
 
   // WebTaskRunner implementation:
   bool RunsTasksInCurrentSequence() override;
-  double VirtualTimeSeconds() const override;
   double MonotonicallyIncreasingVirtualTimeSeconds() const override;
   scoped_refptr<base::SingleThreadTaskRunner> ToSingleThreadTaskRunner()
       override;
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
index fb6510d..e10eb67c 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
+++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
@@ -88,10 +88,6 @@
   return true;
 }
 
-double FakeWebTaskRunner::VirtualTimeSeconds() const {
-  return data_->time_;
-}
-
 double FakeWebTaskRunner::MonotonicallyIncreasingVirtualTimeSeconds() const {
   return data_->time_;
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
index 6dabdc6a..43cb11b 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
+++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
@@ -25,7 +25,6 @@
 
   // WebTaskRunner implementation:
   bool RunsTasksInCurrentSequence() override;
-  double VirtualTimeSeconds() const override;
   double MonotonicallyIncreasingVirtualTimeSeconds() const override;
   SingleThreadTaskRunnerRefPtr ToSingleThreadTaskRunner() override;
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
index 8bab466a..1dede1d 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -470,15 +470,8 @@
             description += 'Build: %s\n\n' % build_link
 
         description += (
-            'Note to sheriffs: This CL imports external tests and adds\n'
-            'expectations for those tests; if this CL is large and causes\n'
-            'a few new failures, please fix the failures by adding new\n'
-            'lines to TestExpectations rather than reverting. See:\n'
-            'https://chromium.googlesource.com'
-            '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n')
-
-        if directory_owners:
-            description += self._format_directory_owners(directory_owners) + '\n\n'
+            'Note to sheriffs: This is an automatically-generated CL. Please\n'
+            'contact ecosystem-infra@chromium.org in case of problems.\n\n')
 
         # Move any No-Export tag to the end of the description.
         description = description.replace('No-Export: true', '')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
index 0015fc6..44d891c 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -4,6 +4,7 @@
 
 import datetime
 import json
+import unittest
 
 from webkitpy.common.checkout.git_mock import MockGit
 from webkitpy.common.host_mock import MockHost
@@ -267,12 +268,8 @@
         self.assertEqual(
             description,
             'Last commit message\n\n'
-            'Note to sheriffs: This CL imports external tests and adds\n'
-            'expectations for those tests; if this CL is large and causes\n'
-            'a few new failures, please fix the failures by adding new\n'
-            'lines to TestExpectations rather than reverting. See:\n'
-            'https://chromium.googlesource.com'
-            '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n'
+            'Note to sheriffs: This is an automatically-generated CL. Please\n'
+            'contact ecosystem-infra@chromium.org in case of problems.\n\n'
             'No-Export: true')
         self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']])
 
@@ -298,6 +295,7 @@
             'No-Export: true',
             description)
 
+    @unittest.skip("http://crbug.com/780055")
     def test_cl_description_with_directory_owners(self):
         host = MockHost()
         host.executive = MockExecutive(output='Last commit message\n\n')
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 25da3e5..d0f94bcb 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -583,7 +583,7 @@
       Source of the autoplay attempt: 0 for attribute; 1 for play().
     </summary>
   </metric>
-  <metric name="UserGestureRequirement">
+  <metric name="UserGestureRequired">
     <summary>
       Whether a user gesture was required per autoplay rules at the time of
       attempt. By definition there is no user gesture on the stack when the
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc
index 48bcccf..017273bf 100644
--- a/ui/views/controls/tree/tree_view.cc
+++ b/ui/views/controls/tree/tree_view.cc
@@ -711,9 +711,10 @@
   if (!model_)
     return;
 
-  preferred_size_.SetSize(root_.GetMaxWidth(text_offset_, root_shown_ ? 1 : 0) +
-                              kTextHorizontalPadding * 2,
-                          row_height_ * GetRowCount());
+  preferred_size_.SetSize(
+      root_.GetMaxWidth(this, text_offset_, root_shown_ ? 1 : 0) +
+          kTextHorizontalPadding * 2,
+      row_height_ * GetRowCount());
 }
 
 void TreeView::LayoutEditor() {
@@ -780,24 +781,8 @@
   if (model_->GetChildCount(node->model_node()))
     PaintExpandControl(canvas, bounds, node->is_expanded());
 
-  // Paint the icon.
-  gfx::ImageSkia icon;
-  int icon_index = model_->GetIconIndex(node->model_node());
-  if (icon_index != -1)
-    icon = icons_[icon_index];
-  else if (node == selected_node_)
-    icon = open_icon_;
-  else
-    icon = closed_icon_;
-  int icon_x = kArrowRegionSize + kImagePadding +
-               (open_icon_.width() - icon.width()) / 2;
-  if (base::i18n::IsRTL())
-    icon_x = bounds.right() - icon_x - open_icon_.width();
-  else
-    icon_x += bounds.x();
-  canvas->DrawImageInt(
-      icon, icon_x,
-      bounds.y() + (bounds.height() - icon.height()) / 2);
+  if (drawing_provider()->ShouldDrawIconForNode(this, node->model_node()))
+    PaintNodeIcon(canvas, node, bounds);
 
   // Paint the text background and text. In edit mode, the selected node is a
   // separate editing control, so it does not need to be painted here.
@@ -863,6 +848,27 @@
                        arrow_bounds.y());
 }
 
+void TreeView::PaintNodeIcon(gfx::Canvas* canvas,
+                             InternalNode* node,
+                             const gfx::Rect& bounds) {
+  gfx::ImageSkia icon;
+  int icon_index = model_->GetIconIndex(node->model_node());
+  if (icon_index != -1)
+    icon = icons_[icon_index];
+  else if (node == selected_node_)
+    icon = open_icon_;
+  else
+    icon = closed_icon_;
+  int icon_x = kArrowRegionSize + kImagePadding +
+               (open_icon_.width() - icon.width()) / 2;
+  if (base::i18n::IsRTL())
+    icon_x = bounds.right() - icon_x - open_icon_.width();
+  else
+    icon_x += bounds.x();
+  canvas->DrawImageInt(icon, icon_x,
+                       bounds.y() + (bounds.height() - icon.height()) / 2);
+}
+
 TreeView::InternalNode* TreeView::GetInternalNodeForModelNode(
     ui::TreeModelNode* model_node,
     GetInternalNodeCreateType create_type) {
@@ -902,7 +908,10 @@
 
 gfx::Rect TreeView::GetTextBoundsForNode(InternalNode* node) {
   gfx::Rect bounds(GetForegroundBoundsForNode(node));
-  bounds.Inset(text_offset_, 0, 0, 0);
+  if (drawing_provider()->ShouldDrawIconForNode(this, node->model_node()))
+    bounds.Inset(text_offset_, 0, 0, 0);
+  else
+    bounds.Inset(kArrowRegionSize, 0, 0, 0);
   return bounds;
 }
 
@@ -1129,13 +1138,14 @@
   return result;
 }
 
-int TreeView::InternalNode::GetMaxWidth(int indent, int depth) {
-  int max_width = text_width_ + indent * depth;
+int TreeView::InternalNode::GetMaxWidth(TreeView* tree, int indent, int depth) {
+  bool has_icon = tree->drawing_provider()->ShouldDrawIconForNode(tree, this);
+  int max_width = (has_icon ? text_width_ : kArrowRegionSize) + indent * depth;
   if (!is_expanded_)
     return max_width;
   for (int i = 0; i < child_count(); ++i) {
-    max_width = std::max(max_width,
-                         GetChild(i)->GetMaxWidth(indent, depth + 1));
+    max_width =
+        std::max(max_width, GetChild(i)->GetMaxWidth(tree, indent, depth + 1));
   }
   return max_width;
 }
diff --git a/ui/views/controls/tree/tree_view.h b/ui/views/controls/tree/tree_view.h
index 11cb38f..2ab62a6b 100644
--- a/ui/views/controls/tree/tree_view.h
+++ b/ui/views/controls/tree/tree_view.h
@@ -212,8 +212,9 @@
 
     // Returns the max width of all descendants (including this node). |indent|
     // is how many pixels each child is indented and |depth| is the depth of
-    // this node from its parent.
-    int GetMaxWidth(int indent, int depth);
+    // this node from its parent. The tree this node is being placed inside is
+    // |tree|.
+    int GetMaxWidth(TreeView* tree, int indent, int depth);
 
    private:
     // The node from the model.
@@ -297,6 +298,11 @@
                           const gfx::Rect& node_bounds,
                           bool expanded);
 
+  // Paints the icon for the specified |node| in |bounds| to |canvas|.
+  void PaintNodeIcon(gfx::Canvas* canvas,
+                     InternalNode* node,
+                     const gfx::Rect& bounds);
+
   // Returns the InternalNode for a model node. |create_type| indicates wheter
   // this should load InternalNode or not.
   InternalNode* GetInternalNodeForModelNode(
diff --git a/ui/views/controls/tree/tree_view_drawing_provider.cc b/ui/views/controls/tree/tree_view_drawing_provider.cc
index cde3a4bd..a1f6249 100644
--- a/ui/views/controls/tree/tree_view_drawing_provider.cc
+++ b/ui/views/controls/tree/tree_view_drawing_provider.cc
@@ -40,4 +40,9 @@
   return base::string16();
 }
 
+bool TreeViewDrawingProvider::ShouldDrawIconForNode(TreeView* tree_view,
+                                                    ui::TreeModelNode* node) {
+  return true;
+}
+
 }  // namespace views
diff --git a/ui/views/controls/tree/tree_view_drawing_provider.h b/ui/views/controls/tree/tree_view_drawing_provider.h
index 49a8a5e..a463581 100644
--- a/ui/views/controls/tree/tree_view_drawing_provider.h
+++ b/ui/views/controls/tree/tree_view_drawing_provider.h
@@ -36,6 +36,10 @@
   // of the node's row in the treeview.
   virtual base::string16 GetAuxiliaryTextForNode(TreeView* tree_view,
                                                  ui::TreeModelNode* node);
+
+  // This method returns whether the icon for |node| should be drawn.
+  virtual bool ShouldDrawIconForNode(TreeView* tree_view,
+                                     ui::TreeModelNode* node);
 };
 
 }  // namespace views
diff --git a/ui/views/examples/tree_view_example.cc b/ui/views/examples/tree_view_example.cc
index b8eff39..061cbef 100644
--- a/ui/views/examples/tree_view_example.cc
+++ b/ui/views/examples/tree_view_example.cc
@@ -29,6 +29,11 @@
     return views::TreeViewDrawingProvider::GetAuxiliaryTextForNode(tree_view,
                                                                    node);
   }
+
+  bool ShouldDrawIconForNode(views::TreeView* tree_view,
+                             ui::TreeModelNode* node) override {
+    return tree_view->GetSelectedNode() != node;
+  }
 };
 
 }  // namespace