diff --git a/DEPS b/DEPS
index d794ed2..223f303 100644
--- a/DEPS
+++ b/DEPS
@@ -88,7 +88,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': 'c948e9b82582e695d16ee6696a484f82239a86d7',
+  'nacl_revision': '42ae93a39e49116f69e1a5b2056c55564a6309f0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -269,7 +269,7 @@
     Var('chromium_git') + '/chromium/deps/mesa.git' + '@' + 'ef811c6bd4de74e13e7035ca882cc77f85793fef',
 
   'src/third_party/ced/src':
-    Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '368a9cc09ad868a3d28f0b5ad4a733f263c46409',
+    Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + 'e21eb6aed10b9f6e2727f136c52420033214d458',
 
   'src/third_party/swiftshader':
     Var('swiftshader_git') + '/SwiftShader.git' + '@' +  Var('swiftshader_revision'),
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 9e94b7c7..debf5f0 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -235,8 +235,6 @@
     "common/system/chromeos/network/network_icon_animation_observer.h",
     "common/system/chromeos/network/network_info.cc",
     "common/system/chromeos/network/network_info.h",
-    "common/system/chromeos/network/network_list.cc",
-    "common/system/chromeos/network/network_list.h",
     "common/system/chromeos/network/network_list_delegate.h",
     "common/system/chromeos/network/network_list_md.cc",
     "common/system/chromeos/network/network_list_md.h",
diff --git a/ash/aura/wm_shell_aura.cc b/ash/aura/wm_shell_aura.cc
index 7400f34f..fd70e3f6 100644
--- a/ash/aura/wm_shell_aura.cc
+++ b/ash/aura/wm_shell_aura.cc
@@ -71,14 +71,6 @@
   return false;
 }
 
-WmWindow* WmShellAura::NewWindow(ui::wm::WindowType window_type,
-                                 ui::LayerType layer_type) {
-  aura::Window* aura_window = new aura::Window(nullptr);
-  aura_window->SetType(window_type);
-  aura_window->Init(layer_type);
-  return WmWindow::Get(aura_window);
-}
-
 WmWindow* WmShellAura::GetFocusedWindow() {
   return WmWindow::Get(
       aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())
diff --git a/ash/aura/wm_shell_aura.h b/ash/aura/wm_shell_aura.h
index d8be1f5..ae1b8cd 100644
--- a/ash/aura/wm_shell_aura.h
+++ b/ash/aura/wm_shell_aura.h
@@ -29,8 +29,6 @@
   // WmShell:
   void Shutdown() override;
   bool IsRunningInMash() const override;
-  WmWindow* NewWindow(ui::wm::WindowType window_type,
-                      ui::LayerType layer_type) override;
   WmWindow* GetFocusedWindow() override;
   WmWindow* GetActiveWindow() override;
   WmWindow* GetCaptureWindow() override;
diff --git a/ash/common/shelf/shelf_background_animator.cc b/ash/common/shelf/shelf_background_animator.cc
index ad0311e..548b826 100644
--- a/ash/common/shelf/shelf_background_animator.cc
+++ b/ash/common/shelf/shelf_background_animator.cc
@@ -203,35 +203,49 @@
     ShelfBackgroundType background_type,
     AnimationValues* shelf_background_values,
     AnimationValues* item_background_values) const {
-  int target_shelf_background_alpha = 0;
-  int target_shelf_item_background_alpha = 0;
+  int target_shelf_color_alpha = 0;
+  int target_item_color_alpha = 0;
 
   switch (background_type) {
     case SHELF_BACKGROUND_DEFAULT:
-      target_shelf_background_alpha = 0;
-      target_shelf_item_background_alpha = kShelfTranslucentAlpha;
+      target_shelf_color_alpha = 0;
+      target_item_color_alpha = kShelfTranslucentAlpha;
       break;
     case SHELF_BACKGROUND_OVERLAP:
-      target_shelf_background_alpha = kShelfTranslucentAlpha;
-      target_shelf_item_background_alpha = 0;
+      target_shelf_color_alpha = kShelfTranslucentAlpha;
+      target_item_color_alpha = 0;
       break;
     case SHELF_BACKGROUND_MAXIMIZED:
-      target_shelf_background_alpha = kMaxAlpha;
-      target_shelf_item_background_alpha = 0;
+      target_shelf_color_alpha = kMaxAlpha;
+      target_item_color_alpha = 0;
       break;
   }
 
   SkColor target_color = wallpaper_controller_
                              ? wallpaper_controller_->prominent_color()
                              : kShelfDefaultBaseColor;
-
-  if (target_color == SK_ColorTRANSPARENT)
+  if (target_color == SK_ColorTRANSPARENT) {
     target_color = kShelfDefaultBaseColor;
+  } else {
+    int darkening_alpha = 0;
+
+    switch (background_type) {
+      case SHELF_BACKGROUND_DEFAULT:
+      case SHELF_BACKGROUND_OVERLAP:
+        darkening_alpha = kShelfTranslucentColorDarkenAlpha;
+        break;
+      case SHELF_BACKGROUND_MAXIMIZED:
+        darkening_alpha = kShelfOpaqueColorDarkenAlpha;
+        break;
+    }
+    target_color = color_utils::GetResultingPaintColor(
+        SkColorSetA(kShelfDefaultBaseColor, darkening_alpha), target_color);
+  }
 
   shelf_background_values->SetTargetValues(
-      SkColorSetA(target_color, target_shelf_background_alpha));
+      SkColorSetA(target_color, target_shelf_color_alpha));
   item_background_values->SetTargetValues(
-      SkColorSetA(target_color, target_shelf_item_background_alpha));
+      SkColorSetA(target_color, target_item_color_alpha));
 }
 
 void ShelfBackgroundAnimator::SetAnimationValues(double t) {
diff --git a/ash/common/shelf/shelf_constants.cc b/ash/common/shelf/shelf_constants.cc
index 80aafcd1..c260855 100644
--- a/ash/common/shelf/shelf_constants.cc
+++ b/ash/common/shelf/shelf_constants.cc
@@ -22,6 +22,8 @@
 const float kShelfInkDropVisibleOpacity = 0.2f;
 const SkColor kShelfIconColor = SK_ColorWHITE;
 const int kShelfTranslucentAlpha = 153;
+const int kShelfTranslucentColorDarkenAlpha = 102;
+const int kShelfOpaqueColorDarkenAlpha = 230;
 const int kOverflowButtonSize = 32;
 const int kOverflowButtonCornerRadius = 2;
 const int kAppListButtonRadius = kOverflowButtonSize / 2;
diff --git a/ash/common/shelf/shelf_constants.h b/ash/common/shelf/shelf_constants.h
index bc783fe..702d523 100644
--- a/ash/common/shelf/shelf_constants.h
+++ b/ash/common/shelf/shelf_constants.h
@@ -61,6 +61,13 @@
 // The alpha value for the shelf background when a window is overlapping.
 ASH_EXPORT extern const int kShelfTranslucentAlpha;
 
+// The alpha value used to darken a colorized shelf when the shelf is
+// translucent.
+extern const int kShelfTranslucentColorDarkenAlpha;
+
+// The alpha vlaue usesd to darken a colorized shelf when the shelf is opaque.
+extern const int kShelfOpaqueColorDarkenAlpha;
+
 // The width and height of the material design overflow button.
 // TODO(tdanderson): Refactor constants which are common between the shelf
 // and the tray. See crbug.com/623987.
diff --git a/ash/common/shelf/shelf_window_watcher_unittest.cc b/ash/common/shelf/shelf_window_watcher_unittest.cc
index f88eaa1..d43acca 100644
--- a/ash/common/shelf/shelf_window_watcher_unittest.cc
+++ b/ash/common/shelf/shelf_window_watcher_unittest.cc
@@ -14,8 +14,11 @@
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/root_window_controller.h"
+#include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
+#include "ui/aura/window.h"
 #include "ui/base/hit_test.h"
+#include "ui/compositor/layer_type.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -345,28 +348,27 @@
 TEST_F(ShelfWindowWatcherTest, DontCreateShelfEntriesForChildWindows) {
   const int initial_item_count = model_->item_count();
 
-  WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                               ui::LAYER_NOT_DRAWN);
-  window->aura_window()->SetProperty(kShelfItemTypeKey,
-                                     static_cast<int32_t>(TYPE_APP));
-  WmShell::Get()
-      ->GetPrimaryRootWindow()
-      ->GetChildByShellWindowId(kShellWindowId_DefaultContainer)
-      ->AddChild(window);
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_NORMAL));
+  window->Init(ui::LAYER_NOT_DRAWN);
+  window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_APP));
+  Shell::GetPrimaryRootWindow()
+      ->GetChildById(kShellWindowId_DefaultContainer)
+      ->AddChild(window.get());
   window->Show();
   EXPECT_EQ(initial_item_count + 1, model_->item_count());
 
-  WmWindow* child_window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                                     ui::LAYER_NOT_DRAWN);
-  child_window->aura_window()->SetProperty(kShelfItemTypeKey,
-                                           static_cast<int32_t>(TYPE_APP));
-  window->AddChild(child_window);
+  std::unique_ptr<aura::Window> child_window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_NORMAL));
+  child_window->Init(ui::LAYER_NOT_DRAWN);
+  child_window->SetProperty(kShelfItemTypeKey, static_cast<int32_t>(TYPE_APP));
+  window->AddChild(child_window.get());
   child_window->Show();
   // |child_window| should not result in adding a new entry.
   EXPECT_EQ(initial_item_count + 1, model_->item_count());
 
-  child_window->Destroy();
-  window->Destroy();
+  child_window.reset();
+  window.reset();
   EXPECT_EQ(initial_item_count, model_->item_count());
 }
 
diff --git a/ash/common/system/chromeos/network/network_list.cc b/ash/common/system/chromeos/network/network_list.cc
deleted file mode 100644
index d53e92d..0000000
--- a/ash/common/system/chromeos/network/network_list.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/common/system/chromeos/network/network_list.h"
-
-#include <stddef.h>
-
-#include "ash/common/system/chromeos/network/network_icon.h"
-#include "ash/common/system/chromeos/network/network_icon_animation.h"
-#include "ash/common/system/chromeos/network/network_info.h"
-#include "ash/common/system/chromeos/network/network_list_delegate.h"
-#include "ash/strings/grit/ash_strings.h"
-#include "base/memory/ptr_util.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
-#include "chromeos/dbus/power_manager_client.h"
-#include "chromeos/login/login_state.h"
-#include "chromeos/network/managed_network_configuration_handler.h"
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "chromeos/network/network_state_handler_observer.h"
-#include "components/device_event_log/device_event_log.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/font.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/view.h"
-
-using chromeos::LoginState;
-using chromeos::NetworkHandler;
-using chromeos::NetworkStateHandler;
-using chromeos::ManagedNetworkConfigurationHandler;
-using chromeos::NetworkTypePattern;
-
-namespace ash {
-
-namespace {
-
-bool IsProhibitedByPolicy(const chromeos::NetworkState* network) {
-  if (!NetworkTypePattern::WiFi().MatchesType(network->type()))
-    return false;
-  if (!LoginState::IsInitialized() || !LoginState::Get()->IsUserLoggedIn())
-    return false;
-  ManagedNetworkConfigurationHandler* managed_configuration_handler =
-      NetworkHandler::Get()->managed_network_configuration_handler();
-  const base::DictionaryValue* global_network_config =
-      managed_configuration_handler->GetGlobalConfigFromPolicy(
-          std::string() /* no username hash, device policy */);
-  bool policy_prohibites_unmanaged = false;
-  if (global_network_config) {
-    global_network_config->GetBooleanWithoutPathExpansion(
-        ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect,
-        &policy_prohibites_unmanaged);
-  }
-  if (!policy_prohibites_unmanaged)
-    return false;
-  return !managed_configuration_handler->FindPolicyByGuidAndProfile(
-      network->guid(), network->profile_path());
-}
-
-}  // namespace
-
-// NetworkListView:
-
-NetworkListView::NetworkListView(NetworkListDelegate* delegate)
-    : delegate_(delegate),
-      no_wifi_networks_view_(nullptr),
-      no_cellular_networks_view_(nullptr) {
-  CHECK(delegate_);
-}
-
-NetworkListView::~NetworkListView() {
-  network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
-}
-
-void NetworkListView::Update() {
-  CHECK(container());
-  NetworkStateHandler::NetworkStateList network_list;
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-  handler->GetVisibleNetworkList(&network_list);
-  UpdateNetworks(network_list);
-  UpdateNetworkIcons();
-  UpdateNetworkListInternal();
-}
-
-bool NetworkListView::IsNetworkEntry(views::View* view,
-                                     std::string* guid) const {
-  std::map<views::View*, std::string>::const_iterator found =
-      network_map_.find(view);
-  if (found == network_map_.end())
-    return false;
-  *guid = found->second;
-  return true;
-}
-
-void NetworkListView::UpdateNetworks(
-    const NetworkStateHandler::NetworkStateList& networks) {
-  SCOPED_NET_LOG_IF_SLOW();
-  network_list_.clear();
-  const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern();
-  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
-           networks.begin();
-       iter != networks.end(); ++iter) {
-    const chromeos::NetworkState* network = *iter;
-    if (!pattern.MatchesType(network->type()))
-      continue;
-    network_list_.push_back(base::MakeUnique<NetworkInfo>(network->guid()));
-  }
-}
-
-void NetworkListView::UpdateNetworkIcons() {
-  SCOPED_NET_LOG_IF_SLOW();
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-
-  // First, update state for all networks
-  bool animating = false;
-
-  for (auto& info : network_list_) {
-    const chromeos::NetworkState* network =
-        handler->GetNetworkStateFromGuid(info->guid);
-    if (!network)
-      continue;
-    bool prohibited_by_policy = IsProhibitedByPolicy(network);
-    info->image =
-        network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST);
-    info->label =
-        network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST);
-    info->highlight =
-        network->IsConnectedState() || network->IsConnectingState();
-    info->disable =
-        (network->activation_state() == shill::kActivationStateActivating) ||
-        prohibited_by_policy;
-    if (network->Matches(NetworkTypePattern::WiFi()))
-      info->type = NetworkInfo::Type::WIFI;
-    else if (network->Matches(NetworkTypePattern::Cellular()))
-      info->type = NetworkInfo::Type::CELLULAR;
-    if (prohibited_by_policy) {
-      info->tooltip =
-          l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED);
-    }
-    if (!animating && network->IsConnectingState())
-      animating = true;
-  }
-  if (animating)
-    network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
-  else
-    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
-}
-
-void NetworkListView::UpdateNetworkListInternal() {
-  SCOPED_NET_LOG_IF_SLOW();
-  // Get the updated list entries
-  network_map_.clear();
-  std::set<std::string> new_guids;
-  bool needs_relayout = UpdateNetworkListEntries(&new_guids);
-
-  // Remove old children
-  std::set<std::string> remove_guids;
-  for (NetworkGuidMap::const_iterator it = network_guid_map_.begin();
-       it != network_guid_map_.end(); ++it) {
-    if (new_guids.find(it->first) == new_guids.end()) {
-      remove_guids.insert(it->first);
-      network_map_.erase(it->second);
-      delete it->second;
-      needs_relayout = true;
-    }
-  }
-
-  for (std::set<std::string>::const_iterator remove_it = remove_guids.begin();
-       remove_it != remove_guids.end(); ++remove_it) {
-    network_guid_map_.erase(*remove_it);
-  }
-
-  if (needs_relayout)
-    HandleRelayout();
-}
-
-void NetworkListView::HandleRelayout() {
-  views::View* selected_view = nullptr;
-  for (auto& iter : network_guid_map_) {
-    if (delegate_->IsViewHovered(iter.second)) {
-      selected_view = iter.second;
-      break;
-    }
-  }
-  container()->SizeToPreferredSize();
-  delegate_->RelayoutScrollList();
-  if (selected_view)
-    container()->ScrollRectToVisible(selected_view->bounds());
-}
-
-bool NetworkListView::UpdateNetworkListEntries(
-    std::set<std::string>* new_guids) {
-  bool needs_relayout = false;
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-
-  // Insert child views
-  int index = 0;
-
-  // Highlighted networks
-  needs_relayout |=
-      UpdateNetworkChildren(new_guids, &index, true /* highlighted */);
-
-  const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern();
-  if (pattern.MatchesPattern(NetworkTypePattern::Cellular())) {
-    // Cellular initializing
-    int message_id = network_icon::GetCellularUninitializedMsg();
-    if (!message_id &&
-        handler->IsTechnologyEnabled(NetworkTypePattern::Mobile()) &&
-        !handler->FirstNetworkByType(NetworkTypePattern::Mobile())) {
-      message_id = IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS;
-    }
-    needs_relayout |=
-        UpdateInfoLabel(message_id, index, &no_cellular_networks_view_);
-
-    if (message_id)
-      ++index;
-  }
-
-  if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) {
-    // "Wifi Enabled / Disabled"
-    int message_id = 0;
-    if (network_list_.empty()) {
-      message_id = handler->IsTechnologyEnabled(NetworkTypePattern::WiFi())
-                       ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED
-                       : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED;
-    }
-    needs_relayout |=
-        UpdateInfoLabel(message_id, index, &no_wifi_networks_view_);
-    if (message_id)
-      ++index;
-  }
-
-  // Un-highlighted networks
-  needs_relayout |=
-      UpdateNetworkChildren(new_guids, &index, false /* not highlighted */);
-
-  // No networks or other messages (fallback)
-  if (index == 0) {
-    needs_relayout |= UpdateInfoLabel(IDS_ASH_STATUS_TRAY_NO_NETWORKS, index,
-                                      &no_wifi_networks_view_);
-  }
-
-  return needs_relayout;
-}
-
-bool NetworkListView::UpdateNetworkChildren(std::set<std::string>* new_guids,
-                                            int* child_index,
-                                            bool highlighted) {
-  bool needs_relayout = false;
-  int index = *child_index;
-  for (auto& info : network_list_) {
-    if (info->highlight != highlighted)
-      continue;
-    needs_relayout |= UpdateNetworkChild(index++, info.get());
-    new_guids->insert(info->guid);
-  }
-  *child_index = index;
-  return needs_relayout;
-}
-
-bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) {
-  bool needs_relayout = false;
-  views::View* network_view = nullptr;
-  NetworkGuidMap::const_iterator found = network_guid_map_.find(info->guid);
-  if (found == network_guid_map_.end()) {
-    network_view = delegate_->CreateViewForNetwork(*info);
-    container()->AddChildViewAt(network_view, index);
-    needs_relayout = true;
-  } else {
-    network_view = found->second;
-    network_view->RemoveAllChildViews(true);
-    delegate_->UpdateViewForNetwork(network_view, *info);
-    network_view->Layout();
-    network_view->SchedulePaint();
-    needs_relayout = PlaceViewAtIndex(network_view, index);
-  }
-  if (info->disable)
-    network_view->SetEnabled(false);
-  network_map_[network_view] = info->guid;
-  network_guid_map_[info->guid] = network_view;
-  return needs_relayout;
-}
-
-bool NetworkListView::PlaceViewAtIndex(views::View* view, int index) {
-  if (container()->child_at(index) == view)
-    return false;
-  container()->ReorderChildView(view, index);
-  return true;
-}
-
-bool NetworkListView::UpdateInfoLabel(int message_id,
-                                      int index,
-                                      views::Label** label) {
-  CHECK(label);
-  bool needs_relayout = false;
-  if (message_id) {
-    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-    base::string16 text = rb.GetLocalizedString(message_id);
-    if (!*label) {
-      *label = delegate_->CreateInfoLabel();
-      (*label)->SetText(text);
-      container()->AddChildViewAt(*label, index);
-      needs_relayout = true;
-    } else {
-      (*label)->SetText(text);
-      needs_relayout = PlaceViewAtIndex(*label, index);
-    }
-  } else if (*label) {
-    delete *label;
-    *label = nullptr;
-    needs_relayout = true;
-  }
-  return needs_relayout;
-}
-
-void NetworkListView::NetworkIconChanged() {
-  Update();
-}
-
-}  // namespace ash
diff --git a/ash/common/system/chromeos/network/network_list.h b/ash/common/system/chromeos/network/network_list.h
deleted file mode 100644
index 2e4090b..0000000
--- a/ash/common/system/chromeos/network/network_list.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
-#define ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "ash/common/system/chromeos/network/network_icon_animation_observer.h"
-#include "ash/common/system/chromeos/network/network_list_view_base.h"
-#include "base/macros.h"
-#include "chromeos/network/network_state_handler.h"
-#include "ui/gfx/image/image_skia.h"
-
-namespace views {
-class Label;
-class View;
-}
-
-namespace ash {
-
-struct NetworkInfo;
-class NetworkListDelegate;
-
-// A list of available networks of a given type. This class is used for all
-// network types except VPNs. For VPNs, see the |VPNList| class.
-class NetworkListView : public NetworkListViewBase,
-                        public network_icon::AnimationObserver {
- public:
-  explicit NetworkListView(NetworkListDelegate* delegate);
-  ~NetworkListView() override;
-
-  // NetworkListViewBase:
-  void Update() override;
-  bool IsNetworkEntry(views::View* view, std::string* guid) const override;
-
- private:
-  void UpdateNetworks(
-      const chromeos::NetworkStateHandler::NetworkStateList& networks);
-  void UpdateNetworkIcons();
-  void UpdateNetworkListInternal();
-  void HandleRelayout();
-  bool UpdateNetworkListEntries(std::set<std::string>* new_guids);
-  bool UpdateNetworkChildren(std::set<std::string>* new_guids,
-                             int* child_index,
-                             bool highlighted);
-  bool UpdateNetworkChild(int index, const NetworkInfo* info);
-  bool PlaceViewAtIndex(views::View* view, int index);
-  bool UpdateInfoLabel(int message_id, int index, views::Label** label);
-
-  // network_icon::AnimationObserver:
-  void NetworkIconChanged() override;
-
-  NetworkListDelegate* delegate_;
-
-  views::Label* no_wifi_networks_view_;
-  views::Label* no_cellular_networks_view_;
-
-  // An owned list of network info.
-  std::vector<std::unique_ptr<NetworkInfo>> network_list_;
-
-  typedef std::map<views::View*, std::string> NetworkMap;
-  NetworkMap network_map_;
-
-  // A map of network guids to their view.
-  typedef std::map<std::string, views::View*> NetworkGuidMap;
-  NetworkGuidMap network_guid_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkListView);
-};
-
-}  // namespace ash
-
-#endif  // ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
diff --git a/ash/common/system/chromeos/network/network_list_md.cc b/ash/common/system/chromeos/network/network_list_md.cc
index 5344666..d0bba2a 100644
--- a/ash/common/system/chromeos/network/network_list_md.cc
+++ b/ash/common/system/chromeos/network/network_list_md.cc
@@ -75,8 +75,8 @@
 // A header row for sections in network detailed view which contains a title and
 // a toggle button to turn on/off the section. Subclasses are given the
 // opportunity to add extra buttons before the toggle button is added.
-class NetworkListViewMd::SectionHeaderRowView : public views::View,
-                                                public views::ButtonListener {
+class NetworkListView::SectionHeaderRowView : public views::View,
+                                              public views::ButtonListener {
  public:
   explicit SectionHeaderRowView(int title_id)
       : title_id_(title_id),
@@ -123,7 +123,7 @@
     // In the event of frequent clicks, helps to prevent a toggle button state
     // from becoming inconsistent with the async operation of enabling /
     // disabling of mobile radio. The toggle will get re-enabled in the next
-    // call to NetworkListViewMd::Update().
+    // call to NetworkListView::Update().
     toggle_->SetEnabled(false);
     OnToggleToggled(toggle_->is_on());
   }
@@ -169,7 +169,7 @@
 
 namespace {
 
-class CellularHeaderRowView : public NetworkListViewMd::SectionHeaderRowView {
+class CellularHeaderRowView : public NetworkListView::SectionHeaderRowView {
  public:
   CellularHeaderRowView()
       : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_MOBILE) {}
@@ -190,7 +190,7 @@
   DISALLOW_COPY_AND_ASSIGN(CellularHeaderRowView);
 };
 
-class TetherHeaderRowView : public NetworkListViewMd::SectionHeaderRowView {
+class TetherHeaderRowView : public NetworkListView::SectionHeaderRowView {
  public:
   TetherHeaderRowView()
       : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_TETHER) {}
@@ -208,7 +208,7 @@
   DISALLOW_COPY_AND_ASSIGN(TetherHeaderRowView);
 };
 
-class WifiHeaderRowView : public NetworkListViewMd::SectionHeaderRowView {
+class WifiHeaderRowView : public NetworkListView::SectionHeaderRowView {
  public:
   explicit WifiHeaderRowView(NetworkListDelegate* network_list_delegate)
       : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_WIFI),
@@ -281,9 +281,9 @@
 
 }  // namespace
 
-// NetworkListViewMd:
+// NetworkListView:
 
-NetworkListViewMd::NetworkListViewMd(NetworkListDelegate* delegate)
+NetworkListView::NetworkListView(NetworkListDelegate* delegate)
     : needs_relayout_(false),
       delegate_(delegate),
       no_wifi_networks_view_(nullptr),
@@ -297,11 +297,11 @@
   CHECK(delegate_);
 }
 
-NetworkListViewMd::~NetworkListViewMd() {
+NetworkListView::~NetworkListView() {
   network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
 }
 
-void NetworkListViewMd::Update() {
+void NetworkListView::Update() {
   CHECK(container());
 
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
@@ -322,8 +322,8 @@
   UpdateNetworkListInternal();
 }
 
-bool NetworkListViewMd::IsNetworkEntry(views::View* view,
-                                       std::string* guid) const {
+bool NetworkListView::IsNetworkEntry(views::View* view,
+                                     std::string* guid) const {
   std::map<views::View*, std::string>::const_iterator found =
       network_map_.find(view);
   if (found == network_map_.end())
@@ -332,7 +332,7 @@
   return true;
 }
 
-void NetworkListViewMd::UpdateNetworks(
+void NetworkListView::UpdateNetworks(
     const NetworkStateHandler::NetworkStateList& networks) {
   SCOPED_NET_LOG_IF_SLOW();
   network_list_.clear();
@@ -343,7 +343,7 @@
   }
 }
 
-void NetworkListViewMd::OrderNetworks() {
+void NetworkListView::OrderNetworks() {
   struct CompareNetwork {
     explicit CompareNetwork(NetworkStateHandler* handler) : handler_(handler) {}
 
@@ -387,7 +387,7 @@
             CompareNetwork(NetworkHandler::Get()->network_state_handler()));
 }
 
-void NetworkListViewMd::UpdateNetworkIcons() {
+void NetworkListView::UpdateNetworkIcons() {
   SCOPED_NET_LOG_IF_SLOW();
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
 
@@ -429,7 +429,7 @@
     network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
 }
 
-void NetworkListViewMd::UpdateNetworkListInternal() {
+void NetworkListView::UpdateNetworkListInternal() {
   SCOPED_NET_LOG_IF_SLOW();
   // Get the updated list entries.
   needs_relayout_ = false;
@@ -467,7 +467,7 @@
 }
 
 std::unique_ptr<std::set<std::string>>
-NetworkListViewMd::UpdateNetworkListEntries() {
+NetworkListView::UpdateNetworkListEntries() {
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
 
   // First add high-priority networks (not Wi-Fi nor cellular).
@@ -556,7 +556,7 @@
   return new_guids;
 }
 
-std::unique_ptr<std::set<std::string>> NetworkListViewMd::UpdateNetworkChildren(
+std::unique_ptr<std::set<std::string>> NetworkListView::UpdateNetworkChildren(
     NetworkInfo::Type type,
     int index) {
   std::unique_ptr<std::set<std::string>> new_guids(new std::set<std::string>);
@@ -569,7 +569,7 @@
   return new_guids;
 }
 
-void NetworkListViewMd::UpdateNetworkChild(int index, const NetworkInfo* info) {
+void NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) {
   views::View* network_view = nullptr;
   NetworkGuidMap::const_iterator found = network_guid_map_.find(info->guid);
   if (found == network_guid_map_.end()) {
@@ -588,7 +588,7 @@
   network_guid_map_[info->guid] = network_view;
 }
 
-void NetworkListViewMd::PlaceViewAtIndex(views::View* view, int index) {
+void NetworkListView::PlaceViewAtIndex(views::View* view, int index) {
   if (view->parent() != container()) {
     container()->AddChildViewAt(view, index);
   } else {
@@ -599,9 +599,9 @@
   needs_relayout_ = true;
 }
 
-void NetworkListViewMd::UpdateInfoLabel(int message_id,
-                                        int insertion_index,
-                                        views::Label** label_ptr) {
+void NetworkListView::UpdateInfoLabel(int message_id,
+                                      int insertion_index,
+                                      views::Label** label_ptr) {
   views::Label* label = *label_ptr;
   if (!message_id) {
     if (label) {
@@ -620,12 +620,11 @@
   *label_ptr = label;
 }
 
-int NetworkListViewMd::UpdateSectionHeaderRow(
-    NetworkTypePattern pattern,
-    bool enabled,
-    int child_index,
-    SectionHeaderRowView** view,
-    views::Separator** separator_view) {
+int NetworkListView::UpdateSectionHeaderRow(NetworkTypePattern pattern,
+                                            bool enabled,
+                                            int child_index,
+                                            SectionHeaderRowView** view,
+                                            views::Separator** separator_view) {
   if (!*view) {
     if (pattern.Equals(NetworkTypePattern::Cellular()))
       *view = new CellularHeaderRowView();
@@ -654,7 +653,7 @@
   return child_index;
 }
 
-void NetworkListViewMd::NetworkIconChanged() {
+void NetworkListView::NetworkIconChanged() {
   Update();
 }
 
diff --git a/ash/common/system/chromeos/network/network_list_md.h b/ash/common/system/chromeos/network/network_list_md.h
index fea2365..a7e94f1 100644
--- a/ash/common/system/chromeos/network/network_list_md.h
+++ b/ash/common/system/chromeos/network/network_list_md.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_MD_H_
-#define ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_MD_H_
+#ifndef ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
+#define ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
 
 #include <map>
 #include <memory>
@@ -32,13 +32,13 @@
 
 // A list of available networks of a given type. This class is used for all
 // network types except VPNs. For VPNs, see the |VPNList| class.
-class NetworkListViewMd : public NetworkListViewBase,
-                          public network_icon::AnimationObserver {
+class NetworkListView : public NetworkListViewBase,
+                        public network_icon::AnimationObserver {
  public:
   class SectionHeaderRowView;
 
-  explicit NetworkListViewMd(NetworkListDelegate* delegate);
-  ~NetworkListViewMd() override;
+  explicit NetworkListView(NetworkListDelegate* delegate);
+  ~NetworkListView() override;
 
   // NetworkListViewBase:
   void Update() override;
@@ -124,9 +124,9 @@
   typedef std::map<std::string, views::View*> NetworkGuidMap;
   NetworkGuidMap network_guid_map_;
 
-  DISALLOW_COPY_AND_ASSIGN(NetworkListViewMd);
+  DISALLOW_COPY_AND_ASSIGN(NetworkListView);
 };
 
 }  // namespace ash
 
-#endif  // ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_MD_H_
+#endif  // ASH_COMMON_SYSTEM_CHROMEOS_NETWORK_NETWORK_LIST_H_
diff --git a/ash/common/system/chromeos/network/network_state_list_detailed_view.cc b/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
index 14e9becd..77f907a 100644
--- a/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
+++ b/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
@@ -8,11 +8,9 @@
 #include <vector>
 
 #include "ash/common/ash_constants.h"
-#include "ash/common/material_design/material_design_controller.h"
 #include "ash/common/system/chromeos/network/network_icon.h"
 #include "ash/common/system/chromeos/network/network_icon_animation.h"
 #include "ash/common/system/chromeos/network/network_info.h"
-#include "ash/common/system/chromeos/network/network_list.h"
 #include "ash/common/system/chromeos/network/network_list_md.h"
 #include "ash/common/system/chromeos/network/network_list_view_base.h"
 #include "ash/common/system/chromeos/network/tray_network_state_observer.h"
@@ -74,10 +72,6 @@
 namespace tray {
 namespace {
 
-bool UseMd() {
-  return MaterialDesignController::IsSystemTrayMenuMaterial();
-}
-
 // Delay between scan requests.
 const int kRequestScanDelaySeconds = 10;
 
@@ -169,95 +163,6 @@
 
 //------------------------------------------------------------------------------
 
-const int kFadeIconMs = 500;
-
-// A throbber view that fades in/out when shown/hidden.
-class ScanningThrobber : public ThrobberView {
- public:
-  ScanningThrobber() {
-    SetPaintToLayer();
-    layer()->SetFillsBoundsOpaquely(false);
-    layer()->SetOpacity(1.0);
-    accessible_name_ =
-        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE);
-  }
-  ~ScanningThrobber() override {}
-
-  // views::View
-  void SetVisible(bool visible) override {
-    layer()->GetAnimator()->StopAnimating();  // Stop any previous animation.
-    ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
-    animation.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFadeIconMs));
-    layer()->SetOpacity(visible ? 1.0 : 0.0);
-  }
-
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override {
-    node_data->SetName(accessible_name_);
-    node_data->role = ui::AX_ROLE_BUSY_INDICATOR;
-  }
-
- private:
-  base::string16 accessible_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScanningThrobber);
-};
-
-//------------------------------------------------------------------------------
-
-// An image button showing the info icon similar to TrayPopupHeaderButton,
-// but without the toggle properties, that fades in/out when shown/hidden.
-class InfoIcon : public views::ImageButton {
- public:
-  explicit InfoIcon(views::ButtonListener* listener)
-      : views::ImageButton(listener) {
-    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
-    SetImage(
-        STATE_NORMAL,
-        bundle.GetImageNamed(IDR_AURA_UBER_TRAY_NETWORK_INFO).ToImageSkia());
-    SetImage(STATE_HOVERED,
-             bundle.GetImageNamed(IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER)
-                 .ToImageSkia());
-    SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
-    SetAccessibleName(
-        bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_INFO));
-    SetPaintToLayer();
-    layer()->SetFillsBoundsOpaquely(false);
-    layer()->SetOpacity(1.0);
-  }
-
-  ~InfoIcon() override {}
-
-  // views::View
-  gfx::Size GetPreferredSize() const override {
-    return gfx::Size(kTrayPopupItemMinHeight, kTrayPopupItemMinHeight);
-  }
-
-  void SetVisible(bool visible) override {
-    layer()->GetAnimator()->StopAnimating();  // Stop any previous animation.
-    ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
-    animation.SetTransitionDuration(
-        base::TimeDelta::FromMilliseconds(kFadeIconMs));
-    layer()->SetOpacity(visible ? 1.0 : 0.0);
-  }
-
-  // views::CustomButton
-  void StateChanged(ButtonState old_state) override {
-    if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
-      set_background(views::Background::CreateSolidBackground(
-          kTrayPopupHoverBackgroundColor));
-    } else {
-      set_background(nullptr);
-    }
-    SchedulePaint();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(InfoIcon);
-};
-
-//------------------------------------------------------------------------------
-
 // Special layout to overlap the scanning throbber and the info button.
 class InfoThrobberLayout : public views::LayoutManager {
  public:
@@ -316,25 +221,16 @@
     : NetworkDetailedView(owner),
       list_type_(list_type),
       login_(login),
-      prev_wifi_scanning_state_(false),
-      info_icon_(nullptr),
-      info_button_md_(nullptr),
-      settings_button_md_(nullptr),
-      proxy_settings_button_md_(nullptr),
-      info_bubble_(nullptr),
-      scanning_throbber_(nullptr) {
+      info_button_(nullptr),
+      settings_button_(nullptr),
+      proxy_settings_button_(nullptr),
+      info_bubble_(nullptr) {
   if (list_type == LIST_TYPE_VPN) {
     // Use a specialized class to list VPNs.
     network_list_view_.reset(new VPNListView(this));
   } else {
     // Use a common class to list any other network types.
-    // TODO(varkha): NetworkListViewMd is a temporary fork of NetworkListView.
-    // NetworkListView will go away when Material Design becomes default.
-    // See crbug.com/614453.
-    if (UseMd())
-      network_list_view_.reset(new NetworkListViewMd(this));
-    else
-      network_list_view_.reset(new NetworkListView(this));
+    network_list_view_.reset(new NetworkListView(this));
   }
 }
 
@@ -353,15 +249,11 @@
 
 void NetworkStateListDetailedView::Init() {
   Reset();
-  info_icon_ = nullptr;
-  info_button_md_ = nullptr;
-  settings_button_md_ = nullptr;
-  proxy_settings_button_md_ = nullptr;
-  scanning_throbber_ = nullptr;
+  info_button_ = nullptr;
+  settings_button_ = nullptr;
+  proxy_settings_button_ = nullptr;
 
   CreateScrollableList();
-  if (!UseMd())
-    CreateNetworkExtra();
   CreateTitleRow(list_type_ == ListType::LIST_TYPE_NETWORK
                      ? IDS_ASH_STATUS_TRAY_NETWORK
                      : IDS_ASH_STATUS_TRAY_VPN);
@@ -380,12 +272,12 @@
 
 void NetworkStateListDetailedView::HandleButtonPressed(views::Button* sender,
                                                        const ui::Event& event) {
-  if (sender == info_button_md_) {
+  if (sender == info_button_) {
     ToggleInfoBubble();
     return;
-  } else if (sender == settings_button_md_) {
+  } else if (sender == settings_button_) {
     ShowSettings();
-  } else if (sender == proxy_settings_button_md_) {
+  } else if (sender == proxy_settings_button_) {
     WmShell::Get()->system_tray_controller()->ShowProxySettings();
   }
 
@@ -427,17 +319,17 @@
   if (login_ == LoginStatus::LOCKED)
     return;
 
-  DCHECK(!info_button_md_);
+  DCHECK(!info_button_);
   tri_view()->SetContainerVisible(TriView::Container::END, true);
 
-  info_button_md_ = new SystemMenuButton(
+  info_button_ = new SystemMenuButton(
       this, TrayPopupInkDropStyle::HOST_CENTERED, kSystemMenuInfoIcon,
       IDS_ASH_STATUS_TRAY_NETWORK_INFO);
-  tri_view()->AddView(TriView::Container::END, info_button_md_);
+  tri_view()->AddView(TriView::Container::END, info_button_);
 
   if (login_ != LoginStatus::NOT_LOGGED_IN) {
-    DCHECK(!settings_button_md_);
-    settings_button_md_ = new SystemMenuButton(
+    DCHECK(!settings_button_);
+    settings_button_ = new SystemMenuButton(
         this, TrayPopupInkDropStyle::HOST_CENTERED, kSystemMenuSettingsIcon,
         IDS_ASH_STATUS_TRAY_NETWORK_SETTINGS);
 
@@ -446,14 +338,14 @@
     // creation flow) when session is started but UI flow continues within
     // login UI, i.e., no browser window is yet avaialable.
     if (!WmShell::Get()->system_tray_delegate()->ShouldShowSettings())
-      settings_button_md_->SetEnabled(false);
+      settings_button_->SetEnabled(false);
 
-    tri_view()->AddView(TriView::Container::END, settings_button_md_);
+    tri_view()->AddView(TriView::Container::END, settings_button_);
   } else {
-    proxy_settings_button_md_ = new SystemMenuButton(
+    proxy_settings_button_ = new SystemMenuButton(
         this, TrayPopupInkDropStyle::HOST_CENTERED, kSystemMenuSettingsIcon,
         IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS);
-    tri_view()->AddView(TriView::Container::END, proxy_settings_button_md_);
+    tri_view()->AddView(TriView::Container::END, proxy_settings_button_);
   }
 }
 
@@ -464,104 +356,32 @@
   WmShell::Get()->system_tray_controller()->ShowNetworkSettings(std::string());
 }
 
-void NetworkStateListDetailedView::CreateNetworkExtra() {
-  DCHECK(!UseMd());
-}
-
-void NetworkStateListDetailedView::SetScanningStateForThrobberView(
-    bool is_scanning) {
-  if (UseMd())
-    return;
-
-  // Hide the network info button if the device is scanning for Wi-Fi networks
-  // and display the WiFi scanning indicator.
-  info_icon_->SetVisible(!is_scanning);
-  scanning_throbber_->SetVisible(is_scanning);
-  // Set the element, network info button or the wifi scanning indicator, as
-  // focusable based on which one is active/visible.
-  // NOTE: As we do not want to lose focus from the network info throbber view,
-  // the order of below operation is important.
-  if (is_scanning) {
-    scanning_throbber_->SetFocusBehavior(FocusBehavior::ALWAYS);
-    info_icon_->SetFocusBehavior(FocusBehavior::NEVER);
-  } else {
-    info_icon_->SetFocusBehavior(FocusBehavior::ALWAYS);
-    scanning_throbber_->SetFocusBehavior(FocusBehavior::NEVER);
-  }
-  // If the Network Info view was in focus while this toggle operation was
-  // being performed then the focus should remain on this view.
-  if (info_icon_->HasFocus() && is_scanning)
-    scanning_throbber_->RequestFocus();
-  else if (scanning_throbber_->HasFocus() && !is_scanning)
-    info_icon_->RequestFocus();
-}
-
-void NetworkStateListDetailedView::UpdateTechnologyButton(
-    TrayPopupHeaderButton* button,
-    const NetworkTypePattern& technology) {
-  NetworkStateHandler::TechnologyState state =
-      NetworkHandler::Get()->network_state_handler()->GetTechnologyState(
-          technology);
-  if (state == NetworkStateHandler::TECHNOLOGY_UNAVAILABLE) {
-    button->SetVisible(false);
-    return;
-  }
-  button->SetVisible(true);
-  if (state == NetworkStateHandler::TECHNOLOGY_AVAILABLE) {
-    button->SetEnabled(true);
-    button->SetToggled(true);
-  } else if (state == NetworkStateHandler::TECHNOLOGY_ENABLED) {
-    button->SetEnabled(true);
-    button->SetToggled(false);
-  } else if (state == NetworkStateHandler::TECHNOLOGY_ENABLING) {
-    button->SetEnabled(false);
-    button->SetToggled(false);
-  } else {  // Initializing
-    button->SetEnabled(false);
-    button->SetToggled(true);
-  }
-}
-
 void NetworkStateListDetailedView::UpdateNetworkList() {
   network_list_view_->Update();
 }
 
 void NetworkStateListDetailedView::UpdateHeaderButtons() {
-  if (proxy_settings_button_md_) {
-    proxy_settings_button_md_->SetEnabled(
+  if (proxy_settings_button_) {
+    proxy_settings_button_->SetEnabled(
         NetworkHandler::Get()->network_state_handler()->DefaultNetwork() !=
         nullptr);
   }
-
   if (list_type_ != LIST_TYPE_VPN) {
     bool scanning =
         NetworkHandler::Get()->network_state_handler()->GetScanningByType(
             NetworkTypePattern::WiFi());
     ShowProgress(-1, scanning);
-    info_button_md_->SetTooltipText(l10n_util::GetStringUTF16(
+    info_button_->SetTooltipText(l10n_util::GetStringUTF16(
         scanning ? IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE
                  : IDS_ASH_STATUS_TRAY_NETWORK_INFO));
   }
 }
 
-bool NetworkStateListDetailedView::OrderChild(views::View* view, int index) {
-  if (scroll_content()->child_at(index) != view) {
-    scroll_content()->ReorderChildView(view, index);
-    return true;
-  }
-  return false;
-}
-
-void NetworkStateListDetailedView::CreateSettingsEntry() {
-  DCHECK(!UseMd());
-}
-
 void NetworkStateListDetailedView::ToggleInfoBubble() {
   if (ResetInfoBubble())
     return;
 
-  info_bubble_ = new InfoBubble(UseMd() ? info_button_md_ : info_icon_,
-                                CreateNetworkInfoView(), this);
+  info_bubble_ = new InfoBubble(info_button_, CreateNetworkInfoView(), this);
   views::BubbleDialogDelegateView::CreateBubble(info_bubble_)->Show();
   info_bubble_->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
 }
@@ -640,18 +460,6 @@
   return container;
 }
 
-const gfx::ImageSkia*
-NetworkStateListDetailedView::GetControlledByExtensionIcon() {
-  // Lazily load the icon from the resource bundle.
-  if (controlled_by_extension_icon_.IsEmpty()) {
-    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-    controlled_by_extension_icon_ =
-        rb.GetImageNamed(IDR_AURA_UBER_TRAY_NETWORK_CONTROLLED);
-  }
-  DCHECK(!controlled_by_extension_icon_.IsEmpty());
-  return controlled_by_extension_icon_.ToImageSkia();
-}
-
 views::View* NetworkStateListDetailedView::CreateControlledByExtensionView(
     const NetworkInfo& info) {
   NetworkingConfigDelegate* networking_config_delegate =
@@ -672,7 +480,9 @@
   views::ImageView* controlled_icon =
       new FixedSizedImageView(kTrayPopupDetailsIconWidth, 0);
 
-  controlled_icon->SetImage(GetControlledByExtensionIcon());
+  controlled_icon->SetImage(
+      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+          IDR_AURA_UBER_TRAY_NETWORK_CONTROLLED));
   controlled_icon->SetTooltipText(tooltip_text);
   return controlled_icon;
 }
@@ -687,13 +497,6 @@
       base::TimeDelta::FromSeconds(kRequestScanDelaySeconds));
 }
 
-void NetworkStateListDetailedView::ToggleMobile() {
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-  bool enabled = handler->IsTechnologyEnabled(NetworkTypePattern::Mobile());
-  chromeos::NetworkConnect::Get()->SetTechnologyEnabled(
-      NetworkTypePattern::Mobile(), !enabled);
-}
-
 views::View* NetworkStateListDetailedView::CreateViewForNetwork(
     const NetworkInfo& info) {
   HoverHighlightView* container = new HoverHighlightView(this);
@@ -704,10 +507,6 @@
   else
     container->AddIconAndLabel(info.image, info.label, info.highlight);
   container->set_tooltip(info.tooltip);
-  if (!UseMd()) {
-    container->SetBorder(
-        views::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, 0, 0));
-  }
   views::View* controlled_icon = CreateControlledByExtensionView(info);
   if (controlled_icon)
     container->AddChildView(controlled_icon);
diff --git a/ash/common/system/chromeos/network/network_state_list_detailed_view.h b/ash/common/system/chromeos/network/network_state_list_detailed_view.h
index a3801c3..d83fa85 100644
--- a/ash/common/system/chromeos/network/network_state_list_detailed_view.h
+++ b/ash/common/system/chromeos/network/network_state_list_detailed_view.h
@@ -27,13 +27,10 @@
 
 namespace views {
 class BubbleDialogDelegateView;
-class ImageButton;
 }
 
 namespace ash {
 class SystemTrayItem;
-class ThrobberView;
-class TrayPopupHeaderButton;
 
 namespace tray {
 
@@ -66,33 +63,15 @@
   // Launches the WebUI settings in a browser and closes the system menu.
   void ShowSettings();
 
-  // Create UI components.
-  void CreateHeaderEntry();
-  void CreateNetworkExtra();
-
   // Update UI components.
-  void UpdateTechnologyButton(TrayPopupHeaderButton* button,
-                              const chromeos::NetworkTypePattern& technology);
   void UpdateNetworkList();
   void UpdateHeaderButtons();
 
-  bool OrderChild(views::View* view, int index);
-
-  // Adds a settings entry when logged in, and an entry for changing proxy
-  // settings otherwise.
-  void CreateSettingsEntry();
-
-  // Sets the visibility and focusability of Network Info Button and
-  // WiFi scanning indicator. This will hide Network info button and display
-  // the scanning indicator when |is_scanning| is true.
-  void SetScanningStateForThrobberView(bool is_scanning);
-
   // Create and manage the network info bubble.
   void ToggleInfoBubble();
   bool ResetInfoBubble();
   void OnInfoBubbleDestroyed();
   views::View* CreateNetworkInfoView();
-  const gfx::ImageSkia* GetControlledByExtensionIcon();
 
   // Creates the view of an extra icon appearing next to the network name
   // indicating that the network is controlled by an extension. If no extension
@@ -102,9 +81,6 @@
   // Periodically request a network scan.
   void CallRequestScan();
 
-  // Handle toggile mobile action
-  void ToggleMobile();
-
   // NetworkListDelegate:
   views::View* CreateViewForNetwork(const NetworkInfo& info) override;
   bool IsViewHovered(views::View* view) override;
@@ -122,27 +98,13 @@
   // Track login state.
   LoginStatus login_;
 
-  // Tracks the WiFi scanning state to help detect if the state has changed. Use
-  // NetworkHandler::GetScanningByType() if you require the current wifi
-  // scanning state.
-  bool prev_wifi_scanning_state_;
-
-  // Not used for material design.
-  views::ImageButton* info_icon_;
-
-  // Only used in material design.
-  views::CustomButton* info_button_md_;
-  views::CustomButton* settings_button_md_;
-  views::CustomButton* proxy_settings_button_md_;
+  views::CustomButton* info_button_;
+  views::CustomButton* settings_button_;
+  views::CustomButton* proxy_settings_button_;
 
   // A small bubble for displaying network info.
   views::BubbleDialogDelegateView* info_bubble_;
 
-  // WiFi scanning throbber.
-  ThrobberView* scanning_throbber_;
-
-  gfx::Image controlled_by_extension_icon_;
-
   std::unique_ptr<NetworkListViewBase> network_list_view_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkStateListDetailedView);
diff --git a/ash/common/system/tray/tray_details_view.cc b/ash/common/system/tray/tray_details_view.cc
index a99790f..a365c0cc 100644
--- a/ash/common/system/tray/tray_details_view.cc
+++ b/ash/common/system/tray/tray_details_view.cc
@@ -217,7 +217,7 @@
     gfx::ShadowValues shadow;
     shadow.emplace_back(gfx::Vector2d(0, kShadowOffsetY), kShadowBlur,
                         kMenuSeparatorColor);
-    flags.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadow));
+    flags.setLooper(gfx::CreateShadowDrawLooper(shadow));
     flags.setAntiAlias(true);
     canvas->ClipRect(shadowed_area, SkClipOp::kDifference);
     canvas->DrawRect(shadowed_area, flags);
diff --git a/ash/common/test/ash_test.cc b/ash/common/test/ash_test.cc
index ba087ec2..5f75506 100644
--- a/ash/common/test/ash_test.cc
+++ b/ash/common/test/ash_test.cc
@@ -14,6 +14,7 @@
 #include "ash/root_window_controller.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
+#include "ui/aura/window.h"
 #include "ui/compositor/layer_type.h"
 #include "ui/display/display.h"
 
@@ -68,13 +69,14 @@
 std::unique_ptr<WindowOwner> AshTest::CreateChildWindow(WmWindow* parent,
                                                         const gfx::Rect& bounds,
                                                         int shell_window_id) {
+  aura::Window* window = new aura::Window(nullptr, ui::wm::WINDOW_TYPE_NORMAL);
+  window->Init(ui::LAYER_NOT_DRAWN);
   std::unique_ptr<WindowOwner> window_owner =
-      base::MakeUnique<WindowOwner>(WmShell::Get()->NewWindow(
-          ui::wm::WINDOW_TYPE_NORMAL, ui::LAYER_NOT_DRAWN));
-  window_owner->window()->SetBounds(bounds);
-  window_owner->window()->SetShellWindowId(shell_window_id);
-  parent->AddChild(window_owner->window());
-  window_owner->window()->Show();
+      base::MakeUnique<WindowOwner>(WmWindow::Get(window));
+  window->SetBounds(bounds);
+  window->set_id(shell_window_id);
+  parent->aura_window()->AddChild(window);
+  window->Show();
   return window_owner;
 }
 
diff --git a/ash/common/wm/window_dimmer.cc b/ash/common/wm/window_dimmer.cc
index c90d806..d5db5815 100644
--- a/ash/common/wm/window_dimmer.cc
+++ b/ash/common/wm/window_dimmer.cc
@@ -24,8 +24,9 @@
 
 WindowDimmer::WindowDimmer(WmWindow* parent)
     : parent_(parent),
-      window_(WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                        ui::LAYER_SOLID_COLOR)) {
+      window_(WmWindow::Get(
+          new aura::Window(nullptr, ui::wm::WINDOW_TYPE_NORMAL))) {
+  window_->aura_window()->Init(ui::LAYER_SOLID_COLOR);
   window_->SetVisibilityChangesAnimated();
   window_->SetVisibilityAnimationType(
       ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
diff --git a/ash/common/wm/workspace/workspace_layout_manager_unittest.cc b/ash/common/wm/workspace/workspace_layout_manager_unittest.cc
index 0b916c1a..167fb31 100644
--- a/ash/common/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/common/wm/workspace/workspace_layout_manager_unittest.cc
@@ -29,8 +29,10 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "ui/aura/env.h"
+#include "ui/aura/window.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/base/ui_base_types.h"
+#include "ui/compositor/layer_type.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
@@ -335,29 +337,29 @@
 // doesn't effect the restore bounds.
 TEST_F(WorkspaceLayoutManagerTest, DontClobberRestoreBounds) {
   DontClobberRestoreBoundsWindowObserver window_observer;
-  WindowOwner window_owner(WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                                     ui::LAYER_TEXTURED));
-  WmWindow* window = window_owner.window();
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_NORMAL));
+  window->Init(ui::LAYER_TEXTURED);
   window->SetBounds(gfx::Rect(10, 20, 30, 40));
   // NOTE: for this test to exercise the failure the observer needs to be added
   // before the parent set. This mimics what BrowserFrameAsh does.
-  window->aura_window()->AddObserver(&window_observer);
-  ParentWindowInPrimaryRootWindow(window);
+  window->AddObserver(&window_observer);
+  ParentWindowInPrimaryRootWindow(WmWindow::Get(window.get()));
   window->Show();
 
-  wm::WindowState* window_state = window->GetWindowState();
+  wm::WindowState* window_state = wm::GetWindowState(window.get());
   window_state->Activate();
 
   std::unique_ptr<WindowOwner> window2_owner(
       CreateTestWindow(gfx::Rect(12, 20, 30, 40)));
   WmWindow* window2 = window2_owner->window();
-  AddTransientChild(window, window2);
+  AddTransientChild(WmWindow::Get(window.get()), window2);
   window2->Show();
 
   window_observer.set_window(window2);
   window_state->Maximize();
   EXPECT_EQ("10,20 30x40", window_state->GetRestoreBoundsInScreen().ToString());
-  window->aura_window()->RemoveObserver(&window_observer);
+  window->RemoveObserver(&window_observer);
 }
 
 // Verifies when a window is maximized all descendant windows have a size.
@@ -378,14 +380,14 @@
 // Verifies a window created with maximized state has the maximized
 // bounds.
 TEST_F(WorkspaceLayoutManagerTest, MaximizeWithEmptySize) {
-  WindowOwner window_owner(WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                                     ui::LAYER_TEXTURED));
-  WmWindow* window = window_owner.window();
-  window->GetWindowState()->Maximize();
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_NORMAL));
+  window->Init(ui::LAYER_TEXTURED);
+  wm::GetWindowState(window.get())->Maximize();
   WmWindow* default_container =
       WmShell::Get()->GetPrimaryRootWindowController()->GetWmContainer(
           kShellWindowId_DefaultContainer);
-  default_container->AddChild(window);
+  default_container->aura_window()->AddChild(window.get());
   window->Show();
   gfx::Rect work_area(
       display::Screen::GetScreen()->GetPrimaryDisplay().work_area());
@@ -575,21 +577,22 @@
 TEST_F(WorkspaceLayoutManagerTest,
        DoNotAdjustTransientWindowBoundsToEnsureMinimumVisibility) {
   UpdateDisplay("300x400");
-  WindowOwner window_owner(WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_NORMAL,
-                                                     ui::LAYER_TEXTURED));
-  WmWindow* window = window_owner.window();
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_NORMAL));
+  window->Init(ui::LAYER_TEXTURED);
   window->SetBounds(gfx::Rect(10, 0, 100, 200));
-  ParentWindowInPrimaryRootWindow(window);
+  ParentWindowInPrimaryRootWindow(WmWindow::Get(window.get()));
   window->Show();
 
   std::unique_ptr<WindowOwner> window2_owner(
       CreateTestWindow(gfx::Rect(10, 0, 40, 20)));
   WmWindow* window2 = window2_owner->window();
-  AddTransientChild(window, window2);
+  AddTransientChild(WmWindow::Get(window.get()), window2);
   window2->Show();
 
   gfx::Rect expected_bounds = window2->GetBounds();
-  WmShell::Get()->SetDisplayWorkAreaInsets(window, gfx::Insets(50, 0, 0, 0));
+  WmShell::Get()->SetDisplayWorkAreaInsets(WmWindow::Get(window.get()),
+                                           gfx::Insets(50, 0, 0, 0));
   EXPECT_EQ(expected_bounds.ToString(), window2->GetBounds().ToString());
 }
 
diff --git a/ash/common/wm_shell.h b/ash/common/wm_shell.h
index 240c0a15..42ac186 100644
--- a/ash/common/wm_shell.h
+++ b/ash/common/wm_shell.h
@@ -19,6 +19,7 @@
 #include "components/ui_devtools/devtools_server.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/compositor/layer_type.h"
+#include "ui/wm/public/activation_change_observer.h"
 #include "ui/wm/public/window_types.h"
 
 namespace app_list {
@@ -213,9 +214,6 @@
   // Returns true when ash is running as a service_manager::Service.
   virtual bool IsRunningInMash() const = 0;
 
-  virtual WmWindow* NewWindow(ui::wm::WindowType window_type,
-                              ui::LayerType layer_type) = 0;
-
   virtual WmWindow* GetFocusedWindow() = 0;
   virtual WmWindow* GetActiveWindow() = 0;
 
diff --git a/ash/common/wm_window_user_data_unittest.cc b/ash/common/wm_window_user_data_unittest.cc
index 3c65711..64fb42c 100644
--- a/ash/common/wm_window_user_data_unittest.cc
+++ b/ash/common/wm_window_user_data_unittest.cc
@@ -11,6 +11,8 @@
 #include "ash/common/wm_window.h"
 #include "ash/common/wm_window_user_data.h"
 #include "base/memory/ptr_util.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer_type.h"
 
 namespace ash {
 namespace {
@@ -35,31 +37,35 @@
 // Verifies clear() deletes the data associated with a window.
 TEST_F(WmWindowUserDataTest, ClearDestroys) {
   WmWindowUserData<Data> user_data;
-  WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN,
-                                               ui::LAYER_NOT_DRAWN);
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_UNKNOWN));
+  window->Init(ui::LAYER_NOT_DRAWN);
   bool data_deleted = false;
-  user_data.Set(window, base::MakeUnique<Data>(&data_deleted));
+  user_data.Set(WmWindow::Get(window.get()),
+                base::MakeUnique<Data>(&data_deleted));
   EXPECT_FALSE(data_deleted);
   user_data.clear();
   EXPECT_TRUE(data_deleted);
-  window->Destroy();
 }
 
 // Verifies Set() called with an existing window replaces the existing data.
 TEST_F(WmWindowUserDataTest, ReplaceDestroys) {
   WmWindowUserData<Data> user_data;
-  WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN,
-                                               ui::LAYER_NOT_DRAWN);
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_UNKNOWN));
+  window->Init(ui::LAYER_NOT_DRAWN);
   bool data1_deleted = false;
-  user_data.Set(window, base::MakeUnique<Data>(&data1_deleted));
+  user_data.Set(WmWindow::Get(window.get()),
+                base::MakeUnique<Data>(&data1_deleted));
   EXPECT_FALSE(data1_deleted);
   bool data2_deleted = false;
-  user_data.Set(window, base::MakeUnique<Data>(&data2_deleted));
+  user_data.Set(WmWindow::Get(window.get()),
+                base::MakeUnique<Data>(&data2_deleted));
   EXPECT_TRUE(data1_deleted);
   EXPECT_FALSE(data2_deleted);
   ASSERT_EQ(1u, user_data.GetWindows().size());
-  EXPECT_EQ(window, *user_data.GetWindows().begin());
-  window->Destroy();
+  EXPECT_EQ(WmWindow::Get(window.get()), *user_data.GetWindows().begin());
+  window.reset();
   EXPECT_TRUE(data2_deleted);
   EXPECT_TRUE(user_data.GetWindows().empty());
 }
@@ -67,15 +73,16 @@
 // Verifies Set() with null deletes existing data.
 TEST_F(WmWindowUserDataTest, NullClears) {
   WmWindowUserData<Data> user_data;
-  WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN,
-                                               ui::LAYER_NOT_DRAWN);
+  std::unique_ptr<aura::Window> window(
+      base::MakeUnique<aura::Window>(nullptr, ui::wm::WINDOW_TYPE_UNKNOWN));
+  window->Init(ui::LAYER_NOT_DRAWN);
   bool data1_deleted = false;
-  user_data.Set(window, base::MakeUnique<Data>(&data1_deleted));
+  user_data.Set(WmWindow::Get(window.get()),
+                base::MakeUnique<Data>(&data1_deleted));
   EXPECT_FALSE(data1_deleted);
-  user_data.Set(window, nullptr);
+  user_data.Set(WmWindow::Get(window.get()), nullptr);
   EXPECT_TRUE(data1_deleted);
   EXPECT_TRUE(user_data.GetWindows().empty());
-  window->Destroy();
 }
 
 }  // namespace ash
diff --git a/ash/magnifier/partial_magnification_controller.cc b/ash/magnifier/partial_magnification_controller.cc
index 3cbedb8..fd9e04e 100644
--- a/ash/magnifier/partial_magnification_controller.cc
+++ b/ash/magnifier/partial_magnification_controller.cc
@@ -162,8 +162,7 @@
     cc::PaintFlags shadow_flags;
     shadow_flags.setAntiAlias(true);
     shadow_flags.setColor(SK_ColorTRANSPARENT);
-    shadow_flags.setLooper(
-        gfx::CreateShadowDrawLooperCorrectBlur(magnifier_shadows_));
+    shadow_flags.setLooper(gfx::CreateShadowDrawLooper(magnifier_shadows_));
     gfx::Rect shadow_bounds(magnifier_window_bounds_.size());
     recorder.canvas()->DrawCircle(
         shadow_bounds.CenterPoint(),
diff --git a/ash/mus/bridge/wm_shell_mus.cc b/ash/mus/bridge/wm_shell_mus.cc
index 6e23391..f23863e 100644
--- a/ash/mus/bridge/wm_shell_mus.cc
+++ b/ash/mus/bridge/wm_shell_mus.cc
@@ -171,11 +171,6 @@
   return window_manager_->window_tree_client();
 }
 
-void WmShellMus::Initialize(
-    const scoped_refptr<base::SequencedWorkerPool>& pool) {
-  WmShell::Initialize(pool);
-}
-
 void WmShellMus::Shutdown() {
   WmShell::Shutdown();
 
@@ -186,14 +181,6 @@
   return true;
 }
 
-WmWindow* WmShellMus::NewWindow(ui::wm::WindowType window_type,
-                                ui::LayerType layer_type) {
-  aura::Window* window = new aura::Window(nullptr);
-  window->SetType(window_type);
-  window->Init(layer_type);
-  return WmWindow::Get(window);
-}
-
 WmWindow* WmShellMus::GetFocusedWindow() {
   // TODO: remove as both WmShells use same implementation.
   return WmWindow::Get(
diff --git a/ash/mus/bridge/wm_shell_mus.h b/ash/mus/bridge/wm_shell_mus.h
index cc9b6557..fd73293 100644
--- a/ash/mus/bridge/wm_shell_mus.h
+++ b/ash/mus/bridge/wm_shell_mus.h
@@ -58,12 +58,8 @@
   WindowManager* window_manager() { return window_manager_; }
 
   // WmShell:
-  void Initialize(
-      const scoped_refptr<base::SequencedWorkerPool>& pool) override;
   void Shutdown() override;
   bool IsRunningInMash() const override;
-  WmWindow* NewWindow(ui::wm::WindowType window_type,
-                      ui::LayerType layer_type) override;
   WmWindow* GetFocusedWindow() override;
   WmWindow* GetActiveWindow() override;
   WmWindow* GetCaptureWindow() override;
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd
index 401d5c7..b5cfaceb 100644
--- a/ash/resources/ash_resources.grd
+++ b/ash/resources/ash_resources.grd
@@ -98,8 +98,6 @@
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_CHILD_USER" file="cros/status/status_child_user.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_ENTERPRISE" file="cros/status/status_managed.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_SUPERVISED_USER" file="cros/status/status_managed_mode_user.png" />
-        <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_INFO" file="cros/network/status_network_info.png" />
-        <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER" file="cros/network/status_network_info_hover.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT" file="cros/notification/notification_session_length_timer.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL" file="cros/status/status_power_small_all.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE" file="cros/status/status_power_small_all_fluctuating.png" />
diff --git a/ash/resources/default_100_percent/cros/network/status_network_info.png b/ash/resources/default_100_percent/cros/network/status_network_info.png
deleted file mode 100644
index 8ee22ee..0000000
--- a/ash/resources/default_100_percent/cros/network/status_network_info.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/cros/network/status_network_info_hover.png b/ash/resources/default_100_percent/cros/network/status_network_info_hover.png
deleted file mode 100644
index 51fb984..0000000
--- a/ash/resources/default_100_percent/cros/network/status_network_info_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/network/status_network_info.png b/ash/resources/default_200_percent/cros/network/status_network_info.png
deleted file mode 100644
index 98a9209..0000000
--- a/ash/resources/default_200_percent/cros/network/status_network_info.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/cros/network/status_network_info_hover.png b/ash/resources/default_200_percent/cros/network/status_network_info_hover.png
deleted file mode 100644
index db3e2662..0000000
--- a/ash/resources/default_200_percent/cros/network/status_network_info_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index c0cc36a..87b54b4cb 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -253,19 +253,18 @@
 // Creates a new window for use as a container.
 // TODO(sky): This should create an aura::Window. http://crbug.com/671246.
 WmWindow* CreateContainer(int window_id, const char* name, WmWindow* parent) {
-  WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN,
-                                               ui::LAYER_NOT_DRAWN);
+  aura::Window* window = new aura::Window(nullptr, ui::wm::WINDOW_TYPE_UNKNOWN);
+  window->Init(ui::LAYER_NOT_DRAWN);
   if (WmShell::Get()->IsRunningInMash()) {
-    aura::WindowPortMus::Get(window->aura_window())
-        ->SetEventTargetingPolicy(
-            ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
+    aura::WindowPortMus::Get(window)->SetEventTargetingPolicy(
+        ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
   }
-  window->SetShellWindowId(window_id);
+  window->set_id(window_id);
   window->SetName(name);
-  parent->AddChild(window);
+  parent->aura_window()->AddChild(window);
   if (window_id != kShellWindowId_UnparentedControlContainer)
     window->Show();
-  return window;
+  return WmWindow::Get(window);
 }
 
 // TODO(sky): This should take an aura::Window. http://crbug.com/671246.
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index 46229bb..90017ef 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -423,6 +423,67 @@
   fallback_child_factory.EvictSurface();
 }
 
+// This test verifies that in the presence of both primary Surface and fallback
+// Surface, the fallback will not be used.
+TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
+  SurfaceFactory primary_child_factory(kArbitraryChildFrameSinkId1, &manager_,
+                                       &empty_client_);
+  LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId primary_child_surface_id(primary_child_factory.frame_sink_id(),
+                                     primary_child_local_surface_id);
+  test::Quad primary_child_quads[] = {
+      test::Quad::SolidColorQuad(SK_ColorGREEN)};
+  test::Pass primary_child_passes[] = {
+      test::Pass(primary_child_quads, arraysize(primary_child_quads))};
+
+  // Submit a CompositorFrame to the primary Surface containing a green
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(&primary_child_factory, primary_child_passes,
+                        arraysize(primary_child_passes),
+                        primary_child_local_surface_id);
+
+  SurfaceFactory fallback_child_factory(kArbitraryChildFrameSinkId2, &manager_,
+                                        &empty_client_);
+  LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId fallback_child_surface_id(fallback_child_factory.frame_sink_id(),
+                                      fallback_child_local_surface_id);
+
+  test::Quad fallback_child_quads[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
+  test::Pass fallback_child_passes[] = {
+      test::Pass(fallback_child_quads, arraysize(fallback_child_quads))};
+
+  // Submit a CompositorFrame to the fallback Surface containing a red
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(&fallback_child_factory, fallback_child_passes,
+                        arraysize(fallback_child_passes),
+                        fallback_child_local_surface_id);
+
+  // Try to embed |primary_child_surface_id| and if unavailabe, embed
+  // |fallback_child_surface_id|.
+  test::Quad root_quads[] = {test::Quad::SurfaceQuad(
+      primary_child_surface_id, fallback_child_surface_id, 1.f)};
+  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
+
+  SubmitCompositorFrame(&factory_, root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  // The CompositorFrame is submitted to |primary_child_surface_id|, so
+  // |fallback_child_surface_id| will not be used and we should see a green
+  // SolidColorDrawQuad.
+  test::Quad expected_quads1[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
+  test::Pass expected_passes1[] = {
+      test::Pass(expected_quads1, arraysize(expected_quads1))};
+
+  SurfaceId root_surface_id(factory_.frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, primary_child_surface_id,
+                     fallback_child_surface_id};
+  AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids,
+                     arraysize(ids));
+
+  primary_child_factory.EvictSurface();
+  fallback_child_factory.EvictSurface();
+}
+
 TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
   SurfaceFactory embedded_factory(kArbitraryChildFrameSinkId1, &manager_,
                                   &empty_client_);
diff --git a/chrome/VERSION b/chrome/VERSION
index 65b77df..ada8ec3 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=59
 MINOR=0
-BUILD=3036
+BUILD=3037
 PATCH=0
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c39213e..12e6eb4 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -626,6 +626,10 @@
     "metrics/network_quality_estimator_provider_impl.h",
     "metrics/perf/perf_provider_chromeos.cc",
     "metrics/perf/perf_provider_chromeos.h",
+    "metrics/renderer_uptime_tracker.cc",
+    "metrics/renderer_uptime_tracker.h",
+    "metrics/renderer_uptime_web_contents_observer.cc",
+    "metrics/renderer_uptime_web_contents_observer.h",
     "metrics/sampling_metrics_provider.cc",
     "metrics/sampling_metrics_provider.h",
     "metrics/subprocess_metrics_provider.cc",
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index a1267013..765ca42 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -68,6 +68,7 @@
 #include "chrome/browser/memory/tab_manager.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/metrics/field_trial_synchronizer.h"
+#include "chrome/browser/metrics/renderer_uptime_tracker.h"
 #include "chrome/browser/metrics/thread_watcher.h"
 #include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
 #include "chrome/browser/net/crl_set_fetcher.h"
@@ -765,6 +766,7 @@
     (defined(OS_LINUX) && !defined(OS_CHROMEOS))
   metrics::DesktopSessionDurationTracker::Initialize();
 #endif
+  metrics::RendererUptimeTracker::Initialize();
 
 #if defined(OS_WIN)
   // Cleanup the PreRead field trial registry key.
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
index df9f467..fe09ee9f 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -19,6 +19,7 @@
 #include "components/arc/common/file_system.mojom.h"
 #include "components/arc/test/fake_file_system_instance.h"
 #include "content/public/test/test_browser_thread_bundle.h"
+#include "storage/browser/fileapi/watcher_manager.h"
 #include "storage/common/fileapi/directory_entry.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -317,7 +318,7 @@
 
   EXPECT_EQ(0, num_called);
   fake_file_system_.TriggerWatchers(kAuthority, kDirSpec.document_id,
-                                    mojom::ChangeType::CHANGED);
+                                    storage::WatcherManager::CHANGED);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, num_called);
 
@@ -359,7 +360,7 @@
 
   EXPECT_EQ(0, num_called);
   fake_file_system_.TriggerWatchers(kAuthority, kDirSpec.document_id,
-                                    mojom::ChangeType::DELETED);
+                                    storage::WatcherManager::DELETED);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, num_called);
 
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
index 85c094ae..d597e1ae 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
@@ -20,23 +20,6 @@
 
 namespace arc {
 
-namespace {
-
-// TODO(nya): Use typemaps.
-ArcFileSystemOperationRunner::ChangeType FromMojoChangeType(
-    mojom::ChangeType type) {
-  switch (type) {
-    case mojom::ChangeType::CHANGED:
-      return ArcFileSystemOperationRunner::ChangeType::CHANGED;
-    case mojom::ChangeType::DELETED:
-      return ArcFileSystemOperationRunner::ChangeType::DELETED;
-  }
-  NOTREACHED();
-  return ArcFileSystemOperationRunner::ChangeType::CHANGED;
-}
-
-}  // namespace
-
 // static
 const char ArcFileSystemOperationRunner::kArcServiceName[] =
     "arc::ArcFileSystemOperationRunner";
@@ -245,7 +228,7 @@
 }
 
 void ArcFileSystemOperationRunner::OnDocumentChanged(int64_t watcher_id,
-                                                     mojom::ChangeType type) {
+                                                     ChangeType type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   auto iter = watcher_callbacks_.find(watcher_id);
   if (iter == watcher_callbacks_.end()) {
@@ -254,7 +237,7 @@
     return;
   }
   WatcherCallback watcher_callback = iter->second;
-  watcher_callback.Run(FromMojoChangeType(type));
+  watcher_callback.Run(type);
 }
 
 void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) {
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h
index 0e5bd29..e378270b 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h
@@ -113,7 +113,7 @@
   void RemoveWatcher(int64_t watcher_id, const RemoveWatcherCallback& callback);
 
   // FileSystemHost overrides:
-  void OnDocumentChanged(int64_t watcher_id, mojom::ChangeType type) override;
+  void OnDocumentChanged(int64_t watcher_id, ChangeType type) override;
 
   // ArcSessionManager::Observer overrides:
   void OnArcPlayStoreEnabledChanged(bool enabled) override;
diff --git a/chrome/browser/metrics/renderer_uptime_tracker.cc b/chrome/browser/metrics/renderer_uptime_tracker.cc
new file mode 100644
index 0000000..94148a5
--- /dev/null
+++ b/chrome/browser/metrics/renderer_uptime_tracker.cc
@@ -0,0 +1,114 @@
+// 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/metrics/renderer_uptime_tracker.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+#include "extensions/features/features.h"
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/process_map.h"
+#endif
+
+namespace metrics {
+
+namespace {
+
+RendererUptimeTracker* g_instance = nullptr;
+
+}  // namespace
+
+// static
+void RendererUptimeTracker::Initialize() {
+  DCHECK(!g_instance);
+  g_instance = new RendererUptimeTracker;
+}
+
+// static
+RendererUptimeTracker* RendererUptimeTracker::Get() {
+  DCHECK(g_instance);
+  return g_instance;
+}
+
+RendererUptimeTracker::RendererUptimeTracker() {
+  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+                 content::NotificationService::AllBrowserContextsAndSources());
+  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+                 content::NotificationService::AllBrowserContextsAndSources());
+  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
+                 content::NotificationService::AllBrowserContextsAndSources());
+}
+
+RendererUptimeTracker::~RendererUptimeTracker() {}
+
+void RendererUptimeTracker::OnRendererStarted(int pid) {
+  info_map_[pid] = RendererInfo{base::TimeTicks::Now(), 0};
+}
+
+void RendererUptimeTracker::OnRendererTerminated(int pid) {
+  auto it = info_map_.find(pid);
+  // The pid may not exist when process fails to start up or when process is
+  // terminated without reuse.
+  if (it != info_map_.end()) {
+    auto uptime = base::TimeTicks::Now() - it->second.launched_at_;
+    UMA_HISTOGRAM_CUSTOM_TIMES("Memory.Experimental.Renderer.Uptime", uptime,
+                               base::TimeDelta::FromHours(1),
+                               base::TimeDelta::FromDays(7), 50);
+    UMA_HISTOGRAM_COUNTS_10000(
+        "Memory.Experimental.Renderer.LoadsInMainFrameDuringUptime",
+        it->second.num_loads_in_main_frame_);
+    info_map_.erase(it);
+  }
+}
+
+void RendererUptimeTracker::OnLoadInMainFrame(int pid) {
+  auto it = info_map_.find(pid);
+  // The pid may not exist in an in-process browser test.
+  if (it != info_map_.end()) {
+    it->second.num_loads_in_main_frame_++;
+  }
+}
+
+void RendererUptimeTracker::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  switch (type) {
+    case content::NOTIFICATION_RENDERER_PROCESS_CREATED: {
+      content::RenderProcessHost* host =
+          content::Source<content::RenderProcessHost>(source).ptr();
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+      if (extensions::ProcessMap::Get(host->GetBrowserContext())
+              ->Contains(host->GetID())) {
+        break;
+      }
+#endif
+      OnRendererStarted(host->GetID());
+      break;
+    }
+
+    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
+      content::RenderProcessHost* host =
+          content::Source<content::RenderProcessHost>(source).ptr();
+      OnRendererTerminated(host->GetID());
+      break;
+    }
+
+    case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
+      content::RenderProcessHost* host =
+          content::Source<content::RenderProcessHost>(source).ptr();
+      OnRendererTerminated(host->GetID());
+      break;
+    }
+
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+}  // namespace metrics
diff --git a/chrome/browser/metrics/renderer_uptime_tracker.h b/chrome/browser/metrics/renderer_uptime_tracker.h
new file mode 100644
index 0000000..3c4cf24
--- /dev/null
+++ b/chrome/browser/metrics/renderer_uptime_tracker.h
@@ -0,0 +1,57 @@
+// 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_METRICS_RENDERER_UPTIME_TRACKER_H_
+#define CHROME_BROWSER_METRICS_RENDERER_UPTIME_TRACKER_H_
+
+#include <map>
+
+#include "base/time/time.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+namespace metrics {
+
+// Class for tracking and renderer uptime info.
+class RendererUptimeTracker : public content::NotificationObserver {
+ public:
+  // Creates the |RendererUptimeTracker| instance and initializes the
+  // observers that notify to it.
+  static void Initialize();
+
+  // Returns the |RendererUptimeTracker| instance.
+  static RendererUptimeTracker* Get();
+
+  // Called when a load happens in a main frame.
+  void OnLoadInMainFrame(int pid);
+
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+ private:
+  RendererUptimeTracker();
+  ~RendererUptimeTracker() override;
+
+  void OnRendererStarted(int pid);
+  void OnRendererTerminated(int pid);
+
+  // Object for registering notification requests.
+  content::NotificationRegistrar registrar_;
+
+  struct RendererInfo {
+    base::TimeTicks launched_at_;
+    int num_loads_in_main_frame_;
+  };
+
+  // Maps RenderProcessHost ID to its info on uptime.
+  std::map<int, RendererInfo> info_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(RendererUptimeTracker);
+};
+
+}  // namespace metrics
+
+#endif  // CHROME_BROWSER_METRICS_RENDERER_UPTIME_TRACKER_H_
diff --git a/chrome/browser/metrics/renderer_uptime_web_contents_observer.cc b/chrome/browser/metrics/renderer_uptime_web_contents_observer.cc
new file mode 100644
index 0000000..70110193
--- /dev/null
+++ b/chrome/browser/metrics/renderer_uptime_web_contents_observer.cc
@@ -0,0 +1,37 @@
+// 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/metrics/renderer_uptime_web_contents_observer.h"
+
+#include "chrome/browser/metrics/renderer_uptime_tracker.h"
+#include "content/public/browser/render_process_host.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(metrics::RendererUptimeWebContentsObserver);
+
+namespace metrics {
+
+RendererUptimeWebContentsObserver::RendererUptimeWebContentsObserver(
+    content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents) {}
+
+// static
+RendererUptimeWebContentsObserver*
+RendererUptimeWebContentsObserver::CreateForWebContents(
+    content::WebContents* web_contents) {
+  DCHECK(web_contents);
+
+  RendererUptimeWebContentsObserver* observer = FromWebContents(web_contents);
+  if (!observer) {
+    observer = new RendererUptimeWebContentsObserver(web_contents);
+    web_contents->SetUserData(UserDataKey(), observer);
+  }
+  return observer;
+}
+
+void RendererUptimeWebContentsObserver::DocumentAvailableInMainFrame() {
+  RendererUptimeTracker::Get()->OnLoadInMainFrame(
+      web_contents()->GetRenderProcessHost()->GetID());
+}
+
+}  // namespace metrics
diff --git a/chrome/browser/metrics/renderer_uptime_web_contents_observer.h b/chrome/browser/metrics/renderer_uptime_web_contents_observer.h
new file mode 100644
index 0000000..d461882e
--- /dev/null
+++ b/chrome/browser/metrics/renderer_uptime_web_contents_observer.h
@@ -0,0 +1,36 @@
+// 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_METRICS_RENDERER_UPTIME_WEB_CONTENTS_OBSERVER_H_
+#define CHROME_BROWSER_METRICS_RENDERER_UPTIME_WEB_CONTENTS_OBSERVER_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace metrics {
+
+// Observer for tracking web contents events.
+class RendererUptimeWebContentsObserver
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<RendererUptimeWebContentsObserver> {
+ public:
+  static RendererUptimeWebContentsObserver* CreateForWebContents(
+      content::WebContents* web_contents);
+
+ private:
+  friend class content::WebContentsUserData<RendererUptimeWebContentsObserver>;
+
+  explicit RendererUptimeWebContentsObserver(
+      content::WebContents* web_contents);
+
+  // content::WebContentsObserver:
+  void DocumentAvailableInMainFrame() override;
+
+  DISALLOW_COPY_AND_ASSIGN(RendererUptimeWebContentsObserver);
+};
+
+}  // namespace metrics
+
+#endif  // CHROME_BROWSER_METRICS_RENDERER_UPTIME_WEB_CONTENTS_OBSERVER_H_
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index e3e0151..1a04c4d 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/history/top_sites_factory.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.h"
+#include "chrome/browser/metrics/renderer_uptime_web_contents_observer.h"
 #include "chrome/browser/net/net_error_tab_helper.h"
 #include "chrome/browser/net/predictor_tab_helper.h"
 #include "chrome/browser/ntp_snippets/bookmark_last_visit_updater.h"
@@ -204,6 +205,8 @@
   TabSpecificContentSettings::CreateForWebContents(web_contents);
   if (content::IsBrowserSideNavigationEnabled())
     MixedContentSettingsTabHelper::CreateForWebContents(web_contents);
+  metrics::RendererUptimeWebContentsObserver::CreateForWebContents(
+      web_contents);
 
   // --- Platform-specific tab helpers ---
 
diff --git a/chrome/browser/ui/views/message_center/message_center_frame_view.cc b/chrome/browser/ui/views/message_center/message_center_frame_view.cc
index 7cd4c70..9f4090d 100644
--- a/chrome/browser/ui/views/message_center/message_center_frame_view.cc
+++ b/chrome/browser/ui/views/message_center/message_center_frame_view.cc
@@ -20,7 +20,7 @@
   SetBorder(views::CreateSolidBorder(
       kBorderWidth, message_center::kMessageCenterBorderColor));
 #else
-  const int kShadowBlur = 8;
+  const int kShadowBlur = 16;
   SetBorder(std::unique_ptr<views::Border>(new views::ShadowBorder(
       gfx::ShadowValue(gfx::Vector2d(0, 0), kShadowBlur,
                        message_center::kMessageCenterShadowColor))));
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 8ff0e78..d32de66 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -21,6 +21,8 @@
     "clipboard/arc_clipboard_bridge.h",
     "crash_collector/arc_crash_collector_bridge.cc",
     "crash_collector/arc_crash_collector_bridge.h",
+    "file_system/file_system_struct_traits.cc",
+    "file_system/file_system_struct_traits.h",
     "ime/arc_ime_bridge.h",
     "ime/arc_ime_bridge_impl.cc",
     "ime/arc_ime_bridge_impl.h",
diff --git a/components/arc/DEPS b/components/arc/DEPS
index b0c29d21..25269a0 100644
--- a/components/arc/DEPS
+++ b/components/arc/DEPS
@@ -7,6 +7,7 @@
   "+components/signin/core/account_id",
   "+components/user_manager",
   "+mojo",
+  "+storage/browser/fileapi",
   "+third_party/re2",
   "+third_party/skia",
   "+ui/gfx/geometry/rect.h",
diff --git a/components/arc/common/OWNERS b/components/arc/common/OWNERS
index 16f082a..253d946 100644
--- a/components/arc/common/OWNERS
+++ b/components/arc/common/OWNERS
@@ -1,5 +1,8 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
 
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
+
 per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
\ No newline at end of file
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/arc/common/file_system.typemap b/components/arc/common/file_system.typemap
new file mode 100644
index 0000000..cb71bf2d6
--- /dev/null
+++ b/components/arc/common/file_system.typemap
@@ -0,0 +1,11 @@
+# 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.
+
+mojom = "//components/arc/common/file_system.mojom"
+public_headers = [ "//storage/browser/fileapi/watcher_manager.h" ]
+public_deps = [
+  "//storage/browser",
+]
+traits_headers = [ "//components/arc/file_system/file_system_struct_traits.h" ]
+type_mappings = [ "arc.mojom.ChangeType=storage::WatcherManager::ChangeType" ]
diff --git a/components/arc/common/typemaps.gni b/components/arc/common/typemaps.gni
index ca0c1675..c130ddc 100644
--- a/components/arc/common/typemaps.gni
+++ b/components/arc/common/typemaps.gni
@@ -6,6 +6,7 @@
   "//components/arc/common/app.typemap",
   "//components/arc/common/bitmap.typemap",
   "//components/arc/common/bluetooth.typemap",
+  "//components/arc/common/file_system.typemap",
   "//components/arc/common/intent_helper.typemap",
   "//components/arc/common/video_accelerator.typemap",
 ]
diff --git a/components/arc/file_system/OWNERS b/components/arc/file_system/OWNERS
new file mode 100644
index 0000000..bb65116
--- /dev/null
+++ b/components/arc/file_system/OWNERS
@@ -0,0 +1,2 @@
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/arc/file_system/file_system_struct_traits.cc b/components/arc/file_system/file_system_struct_traits.cc
new file mode 100644
index 0000000..df97e6bb
--- /dev/null
+++ b/components/arc/file_system/file_system_struct_traits.cc
@@ -0,0 +1,42 @@
+// 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 "components/arc/file_system/file_system_struct_traits.h"
+
+#include "base/logging.h"
+#include "components/arc/common/file_system.mojom.h"
+
+namespace mojo {
+
+// static
+arc::mojom::ChangeType
+EnumTraits<arc::mojom::ChangeType, storage::WatcherManager::ChangeType>::
+    ToMojom(storage::WatcherManager::ChangeType type) {
+  switch (type) {
+    case storage::WatcherManager::CHANGED:
+      return arc::mojom::ChangeType::CHANGED;
+    case storage::WatcherManager::DELETED:
+      return arc::mojom::ChangeType::DELETED;
+  }
+  NOTREACHED();
+  return arc::mojom::ChangeType::CHANGED;
+}
+
+// static
+bool EnumTraits<arc::mojom::ChangeType, storage::WatcherManager::ChangeType>::
+    FromMojom(arc::mojom::ChangeType mojom_type,
+              storage::WatcherManager::ChangeType* type) {
+  switch (mojom_type) {
+    case arc::mojom::ChangeType::CHANGED:
+      *type = storage::WatcherManager::CHANGED;
+      return true;
+    case arc::mojom::ChangeType::DELETED:
+      *type = storage::WatcherManager::DELETED;
+      return true;
+  }
+  NOTREACHED();
+  return false;
+}
+
+}  // namespace mojo
diff --git a/components/arc/file_system/file_system_struct_traits.h b/components/arc/file_system/file_system_struct_traits.h
new file mode 100644
index 0000000..eae87efd
--- /dev/null
+++ b/components/arc/file_system/file_system_struct_traits.h
@@ -0,0 +1,23 @@
+// 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 COMPONENTS_ARC_FILE_SYSTEM_FILE_SYSTEM_STRUCT_TRAITS_H_
+#define COMPONENTS_ARC_FILE_SYSTEM_FILE_SYSTEM_STRUCT_TRAITS_H_
+
+#include "components/arc/common/file_system.mojom.h"
+#include "storage/browser/fileapi/watcher_manager.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<arc::mojom::ChangeType, storage::WatcherManager::ChangeType> {
+  static arc::mojom::ChangeType ToMojom(
+      storage::WatcherManager::ChangeType type);
+  static bool FromMojom(arc::mojom::ChangeType mojom_type,
+                        storage::WatcherManager::ChangeType* type);
+};
+
+}  // namespace mojo
+
+#endif  // COMPONENTS_ARC_FILE_SYSTEM_FILE_SYSTEM_STRUCT_TRAITS_H_
diff --git a/components/arc/test/fake_file_system_instance.cc b/components/arc/test/fake_file_system_instance.cc
index 4a3dcc89..f522024 100644
--- a/components/arc/test/fake_file_system_instance.cc
+++ b/components/arc/test/fake_file_system_instance.cc
@@ -121,9 +121,10 @@
   }
 }
 
-void FakeFileSystemInstance::TriggerWatchers(const std::string& authority,
-                                             const std::string& document_id,
-                                             mojom::ChangeType type) {
+void FakeFileSystemInstance::TriggerWatchers(
+    const std::string& authority,
+    const std::string& document_id,
+    storage::WatcherManager::ChangeType type) {
   DCHECK(thread_checker_.CalledOnValidThread());
   if (!host_) {
     LOG(ERROR) << "FileSystemHost is not available.";
diff --git a/components/arc/test/fake_file_system_instance.h b/components/arc/test/fake_file_system_instance.h
index a019368..b852244 100644
--- a/components/arc/test/fake_file_system_instance.h
+++ b/components/arc/test/fake_file_system_instance.h
@@ -17,6 +17,7 @@
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "components/arc/common/file_system.mojom.h"
+#include "storage/browser/fileapi/watcher_manager.h"
 
 namespace arc {
 
@@ -115,7 +116,7 @@
   // Triggers watchers installed to a document.
   void TriggerWatchers(const std::string& authority,
                        const std::string& document_id,
-                       mojom::ChangeType type);
+                       storage::WatcherManager::ChangeType type);
 
   // mojom::FileSystemInstance:
   void AddWatcher(const std::string& authority,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index aaf790f..c21bf44 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -514,19 +514,22 @@
   DCHECK(!request.url().SchemeIsCryptographic());
   DCHECK(request.url().SchemeIsHTTPOrHTTPS());
 
-  if (!params::IsAddChromeProxyECTHeaderEnabled())
-    return;
-
   DCHECK(!request_headers->HasHeader(chrome_proxy_ect_header()));
 
-  if (!request.context()->network_quality_estimator())
-    return;
-
-  net::EffectiveConnectionType ect = request.context()
-                                         ->network_quality_estimator()
-                                         ->GetEffectiveConnectionType();
-  if (ect <= net::EFFECTIVE_CONNECTION_TYPE_OFFLINE)
-    return;
+  if (request.context()->network_quality_estimator()) {
+    net::EffectiveConnectionType type = request.context()
+                                            ->network_quality_estimator()
+                                            ->GetEffectiveConnectionType();
+    if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) {
+      DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_LAST, type);
+      request_headers->SetHeader(chrome_proxy_ect_header(),
+                                 net::GetNameForEffectiveConnectionType(type));
+      return;
+    }
+  }
+  request_headers->SetHeader(chrome_proxy_ect_header(),
+                             net::GetNameForEffectiveConnectionType(
+                                 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN));
 
   static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 ==
                     net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
@@ -534,9 +537,6 @@
   static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 ==
                     net::EFFECTIVE_CONNECTION_TYPE_LAST,
                 "ECT enum value is not handled.");
-
-  request_headers->SetHeader(chrome_proxy_ect_header(),
-                             net::GetNameForEffectiveConnectionType(ect));
 }
 
 void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 0153127..a669795 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -364,6 +364,8 @@
                                       const std::string& response_headers,
                                       bool expect_cached,
                                       bool expect_brotli) {
+    test_network_quality_estimator()->set_effective_connection_type(
+        net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
     GURL url(kTestURL);
 
     int response_body_size = 140;
@@ -396,6 +398,10 @@
                                          "User-Agent:\r\n");
 
     std::string accept_language_header("Accept-Language: en-us,fr\r\n");
+    std::string ect_header = "chrome-proxy-ect: " +
+                             std::string(net::GetNameForEffectiveConnectionType(
+                                 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)) +
+                             "\r\n";
 
     // Brotli is included in accept-encoding header only if the request went
     // to the network (i.e., it was not a cached response), and if data
@@ -411,13 +417,14 @@
         std::string("\r\n\r\n");
 
     std::string mock_write = prefix_headers + accept_language_header +
-                             accept_encoding_header + suffix_headers;
+                             ect_header + accept_encoding_header +
+                             suffix_headers;
 
     if (expect_cached || !expect_brotli) {
       // Order of headers is different if the headers were modified by data
       // reduction proxy network delegate.
       mock_write = prefix_headers + accept_encoding_header +
-                   accept_language_header + suffix_headers;
+                   accept_language_header + ect_header + suffix_headers;
     }
 
     net::MockWrite writes[] = {net::MockWrite(mock_write.c_str())};
@@ -470,8 +477,6 @@
       net::EffectiveConnectionType effective_connection_type,
       bool expect_ect_header,
       bool expect_cached) {
-    EXPECT_EQ(expect_ect_header, params::IsAddChromeProxyECTHeaderEnabled());
-
     test_network_quality_estimator()->set_effective_connection_type(
         effective_connection_type);
 
@@ -1209,10 +1214,6 @@
 TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithVary) {
   Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
 
-  base::FieldTrialList field_trial_list(nullptr);
-  base::FieldTrialList::CreateFieldTrial(
-      "DataReductionProxyAddChromeProxyECTHeader", "Enabled");
-
   std::string response_headers =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 140\r\n"
@@ -1255,10 +1256,6 @@
 TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) {
   Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
 
-  base::FieldTrialList field_trial_list(nullptr);
-  base::FieldTrialList::CreateFieldTrial(
-      "DataReductionProxyAddChromeProxyECTHeader", "Enabled");
-
   std::string response_headers =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 140\r\n"
@@ -1294,40 +1291,6 @@
   FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true);
 }
 
-// Test that effective connection type is not added to the request headers when
-// the field trial is not enabled.
-TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderNotEnabled) {
-  Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
-
-  std::string response_headers =
-      "HTTP/1.1 200 OK\r\n"
-      "Content-Length: 140\r\n"
-      "Via: 1.1 Chrome-Compression-Proxy\r\n"
-      "Cache-Control: max-age=1200\r\n"
-      "Vary: chrome-proxy-ect\r\n"
-      "x-original-content-length: 200\r\n\r\n";
-
-  int response_body_size = 140;
-  std::string response_body(base::checked_cast<size_t>(response_body_size),
-                            ' ');
-
-  std::vector<net::MockRead> reads_list;
-  std::vector<std::string> mock_writes;
-  std::vector<net::MockWrite> writes_list;
-
-  std::vector<net::EffectiveConnectionType> effective_connection_types;
-  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
-
-  BuildSocket(response_headers, response_body, false,
-              effective_connection_types, &reads_list, &mock_writes,
-              &writes_list);
-
-  // Add 1 socket provider since 1 request in this test is fetched from the
-  // network.
-  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], false,
-                                    false);
-}
-
 }  // namespace
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index a1069e3c..ac08fb10 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -260,12 +260,6 @@
                            kDisabled, base::CompareCase::SENSITIVE);
 }
 
-bool IsAddChromeProxyECTHeaderEnabled() {
-  return base::StartsWith(base::FieldTrialList::FindFullName(
-                              "DataReductionProxyAddChromeProxyECTHeader"),
-                          kEnabled, base::CompareCase::SENSITIVE);
-}
-
 bool IsConfigClientEnabled() {
   // Config client is enabled by default. It can be disabled only if Chromium
   // belongs to a field trial group whose name starts with "Disabled".
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index 401f78e7..02b3d9c 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -130,10 +130,6 @@
 // Returns true if Brotli should be added to the accept-encoding header.
 bool IsBrotliAcceptEncodingEnabled();
 
-// Returns true if the effective connection type should be added to the data
-// saver requests using chrome-proxy-ect header.
-bool IsAddChromeProxyECTHeaderEnabled();
-
 // Returns true if the Data Reduction Proxy config client should be used.
 bool IsConfigClientEnabled();
 
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 4f5fc90..cc91602 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -83,7 +83,6 @@
   // buttons are allowed to have content.)
   switch (GetRole()) {
     case ui::AX_ROLE_IMAGE:
-    case ui::AX_ROLE_MATH:
     case ui::AX_ROLE_METER:
     case ui::AX_ROLE_SCROLL_BAR:
     case ui::AX_ROLE_SLIDER:
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 5ccbc393..3f8b414 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -4317,31 +4317,20 @@
   auto text_style =
       static_cast<ui::AXTextStyle>(GetIntAttribute(ui::AX_ATTR_TEXT_STYLE));
   if (text_style == ui::AX_TEXT_STYLE_NONE) {
-    attributes.push_back(L"font-weight:normal");
     attributes.push_back(L"font-style:normal");
+    attributes.push_back(L"font-weight:normal");
   } else {
+    if (text_style & ui::AX_TEXT_STYLE_ITALIC) {
+      attributes.push_back(L"font-style:italic");
+    } else {
+      attributes.push_back(L"font-style:normal");
+    }
+
     if (text_style & ui::AX_TEXT_STYLE_BOLD) {
       attributes.push_back(L"font-weight:bold");
     } else {
       attributes.push_back(L"font-weight:normal");
     }
-
-    base::string16 font_style;
-    if (text_style & ui::AX_TEXT_STYLE_ITALIC)
-      font_style += L",italic";
-    if (text_style & ui::AX_TEXT_STYLE_UNDERLINE)
-      font_style += L",underline";
-    if (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH)
-      font_style += L",line-through";
-    // TODO(nektar): Support more font style attributes in Blink.
-
-    if (font_style.empty()) {
-      font_style = L"normal";
-    } else {
-      // Remove the leading comma.
-      font_style.erase(0, 1);
-    }
-    attributes.push_back(L"font-style:" + font_style);
   }
 
   auto invalid_state = static_cast<ui::AXInvalidState>(
@@ -4392,17 +4381,33 @@
   // TODO(nektar): Add Blink support for the following attributes.
   // Currently set to their default values as dictated by the IA2 Spec.
   attributes.push_back(L"text-line-through-mode:continuous");
-  attributes.push_back(L"text-line-through-style:none");
+  if (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH) {
+    // TODO(nektar): Figure out a more specific value.
+    attributes.push_back(L"text-line-through-style:solid");
+  } else {
+    attributes.push_back(L"text-line-through-style:none");
+  }
   // Default value must be the empty string.
   attributes.push_back(L"text-line-through-text:");
-  attributes.push_back(L"text-line-through-type:none");
+  if (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH) {
+    // TODO(nektar): Figure out a more specific value.
+    attributes.push_back(L"text-line-through-type:single");
+  } else {
+    attributes.push_back(L"text-line-through-type:none");
+  }
   attributes.push_back(L"text-line-through-width:auto");
   attributes.push_back(L"text-outline:false");
   attributes.push_back(L"text-position:baseline");
   attributes.push_back(L"text-shadow:none");
   attributes.push_back(L"text-underline-mode:continuous");
-  attributes.push_back(L"text-underline-style:none");
-  attributes.push_back(L"text-underline-type:none");
+  if (text_style & ui::AX_TEXT_STYLE_UNDERLINE) {
+    // TODO(nektar): Figure out a more specific value.
+    attributes.push_back(L"text-underline-style:solid");
+    attributes.push_back(L"text-underline-type:single");
+  } else {
+    attributes.push_back(L"text-underline-style:none");
+    attributes.push_back(L"text-underline-type:none");
+  }
   attributes.push_back(L"text-underline-width:auto");
 
   auto text_direction = static_cast<ui::AXTextDirection>(
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index dfa63aaa..077173d 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -1858,7 +1858,13 @@
   EXPECT_NE(base::string16::npos,
             base::string16(text_attributes).find(L"font-weight:normal"));
   EXPECT_NE(base::string16::npos,
-            base::string16(text_attributes).find(L"font-style:underline"));
+            base::string16(text_attributes).find(L"font-style:normal"));
+  EXPECT_NE(
+      base::string16::npos,
+      base::string16(text_attributes).find(L"text-underline-style:solid"));
+  EXPECT_NE(
+      base::string16::npos,
+      base::string16(text_attributes).find(L"text-underline-type:single"));
   text_attributes.Reset();
 
   hr = ax_link_text->get_attributes(2, &start_offset, &end_offset,
@@ -1871,7 +1877,13 @@
   EXPECT_NE(base::string16::npos,
             base::string16(text_attributes).find(L"font-weight:normal"));
   EXPECT_NE(base::string16::npos,
-            base::string16(text_attributes).find(L"font-style:underline"));
+            base::string16(text_attributes).find(L"font-style:normal"));
+  EXPECT_NE(
+      base::string16::npos,
+      base::string16(text_attributes).find(L"text-underline-style:solid"));
+  EXPECT_NE(
+      base::string16::npos,
+      base::string16(text_attributes).find(L"text-underline-type:single"));
   EXPECT_NE(base::string16::npos,
             base::string16(text_attributes).find(L"invalid:spelling"));
   text_attributes.Reset();
@@ -1887,6 +1899,12 @@
     EXPECT_NE(base::string16::npos, attributes.find(L"font-family:Helvetica"));
     EXPECT_NE(base::string16::npos, attributes.find(L"font-weight:normal"));
     EXPECT_NE(base::string16::npos, attributes.find(L"font-style:normal"));
+    EXPECT_NE(
+        base::string16::npos,
+        base::string16(text_attributes).find(L"text-underline-style:none"));
+    EXPECT_NE(
+        base::string16::npos,
+        base::string16(text_attributes).find(L"text-underline-type:none"));
     EXPECT_EQ(base::string16::npos, attributes.find(L"invalid:spelling"));
     text_attributes.Reset();
   }
@@ -1918,6 +1936,10 @@
             base::string16(text_attributes).find(L"font-weight:normal"));
   EXPECT_NE(base::string16::npos,
             base::string16(text_attributes).find(L"font-style:normal"));
+  EXPECT_NE(base::string16::npos,
+            base::string16(text_attributes).find(L"text-underline-style:none"));
+  EXPECT_NE(base::string16::npos,
+            base::string16(text_attributes).find(L"text-underline-type:none"));
   EXPECT_EQ(base::string16::npos,
             base::string16(text_attributes).find(L"invalid:spelling"));
   text_attributes.Reset();
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS
index b49f115b..33dfffd 100644
--- a/content/browser/loader/DEPS
+++ b/content/browser/loader/DEPS
@@ -22,7 +22,6 @@
     "+content/browser/loader/resource_request_info_impl.h",
     "+content/browser/loader/upload_progress_tracker.h",
     "+content/common/content_export.h",
-    "+content/public/browser/resource_dispatcher_host_delegate.h",
     "+content/public/common/resource_response.h",
 
     # TODO: these all have to be removed.
@@ -101,7 +100,6 @@
     "+content/common/resource_request_completion_status.h",
     "+content/common/url_loader.mojom.h",
     "+content/public/browser/global_request_id.h",
-    "+content/public/browser/resource_dispatcher_host_delegate.h",
     "+content/public/common/resource_response.h",
     "+content/public/common/resource_type.h",
   ],
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc
index 8168f10..38433ab7 100644
--- a/content/browser/loader/async_resource_handler.cc
+++ b/content/browser/loader/async_resource_handler.cc
@@ -28,7 +28,6 @@
 #include "content/common/resource_messages.h"
 #include "content/common/resource_request_completion_status.h"
 #include "content/common/view_messages.h"
-#include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/resource_response.h"
 #include "ipc/ipc_message_macros.h"
@@ -308,11 +307,6 @@
   }
 
   const ResourceRequestInfoImpl* info = GetRequestInfo();
-  if (rdh_->delegate()) {
-    rdh_->delegate()->OnResponseStarted(request(), info->GetContext(),
-                                        response);
-  }
-
   ResourceMessageFilter* filter = GetFilter();
   if (!filter) {
     controller->Cancel();
diff --git a/content/browser/loader/async_resource_handler_unittest.cc b/content/browser/loader/async_resource_handler_unittest.cc
index 900baa9..293ca999 100644
--- a/content/browser/loader/async_resource_handler_unittest.cc
+++ b/content/browser/loader/async_resource_handler_unittest.cc
@@ -224,7 +224,8 @@
   void DidReceiveRedirect(ResourceLoader* loader,
                           const GURL& new_url,
                           ResourceResponse* response) override {}
-  void DidReceiveResponse(ResourceLoader* loader) override {}
+  void DidReceiveResponse(ResourceLoader* loader,
+                          ResourceResponse* response) override {}
   void DidFinishLoading(ResourceLoader* loader) override {
     loader_.reset();
     finish_waiter_->Quit();
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index af1f98a..246133d 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -25,7 +25,6 @@
 #include "content/browser/loader/upload_progress_tracker.h"
 #include "content/common/resource_request_completion_status.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/common/resource_response.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/cpp/bindings/message.h"
@@ -180,11 +179,6 @@
   }
 
   const ResourceRequestInfoImpl* info = GetRequestInfo();
-  if (rdh_->delegate()) {
-    rdh_->delegate()->OnResponseStarted(request(), info->GetContext(),
-                                        response);
-  }
-
   NetLogObserver::PopulateResponseInfo(request(), response);
   response->head.encoded_data_length = request()->raw_header_size();
   reported_total_received_bytes_ = response->head.encoded_data_length;
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc
index fc47d15c..1e6ed74c 100644
--- a/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -99,10 +99,7 @@
     : public ResourceDispatcherHostDelegate {
  public:
   TestResourceDispatcherHostDelegate() = default;
-  ~TestResourceDispatcherHostDelegate() override {
-    EXPECT_EQ(num_on_response_started_calls_expectation_,
-              num_on_response_started_calls_);
-  }
+  ~TestResourceDispatcherHostDelegate() override = default;
 
   bool ShouldBeginRequest(const std::string& method,
                           const GURL& url,
@@ -168,7 +165,6 @@
   void OnResponseStarted(net::URLRequest* request,
                          ResourceContext* resource_context,
                          ResourceResponse* response) override {
-    ++num_on_response_started_calls_;
   }
 
   void OnRequestRedirected(const GURL& redirect_url,
@@ -200,17 +196,7 @@
     return nullptr;
   }
 
-  int num_on_response_started_calls() const {
-    return num_on_response_started_calls_;
-  }
-  void set_num_on_response_started_calls_expectation(int expectation) {
-    num_on_response_started_calls_expectation_ = expectation;
-  }
-
  private:
-  int num_on_response_started_calls_ = 0;
-  int num_on_response_started_calls_expectation_ = 0;
-
   DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
 };
 
@@ -398,7 +384,6 @@
 
   // Returns false if something bad happens.
   bool CallOnResponseStarted() {
-    rdh_delegate_.set_num_on_response_started_calls_expectation(1);
     MockResourceLoader::Status result = mock_loader_->OnResponseStarted(
         make_scoped_refptr(new ResourceResponse()));
     EXPECT_EQ(MockResourceLoader::Status::IDLE, result);
@@ -483,7 +468,6 @@
 }
 
 TEST_F(MojoAsyncResourceHandlerTest, OnResponseStarted) {
-  rdh_delegate_.set_num_on_response_started_calls_expectation(1);
   scoped_refptr<net::IOBufferWithSize> metadata = new net::IOBufferWithSize(5);
   memcpy(metadata->data(), "hello", 5);
   handler_->SetMetadata(metadata);
@@ -498,7 +482,6 @@
   response->head.response_start =
       base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(28);
 
-  EXPECT_EQ(0, rdh_delegate_.num_on_response_started_calls());
   base::TimeTicks now1 = base::TimeTicks::Now();
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnResponseStarted(response));
@@ -507,7 +490,6 @@
   EXPECT_EQ(request_->creation_time(), response->head.request_start);
   EXPECT_LE(now1, response->head.response_start);
   EXPECT_LE(response->head.response_start, now2);
-  EXPECT_EQ(1, rdh_delegate_.num_on_response_started_calls());
 
   url_loader_client_.RunUntilResponseReceived();
   EXPECT_EQ(response->head.request_start,
@@ -1104,8 +1086,6 @@
 }
 
 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, RedirectHandling) {
-  rdh_delegate_.set_num_on_response_started_calls_expectation(1);
-
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnWillStart(request_->url()));
 
@@ -1178,7 +1158,6 @@
 TEST_P(
     MojoAsyncResourceHandlerWithAllocationSizeTest,
     OnWillStartThenOnResponseStartedThenOnWillReadThenOnReadCompletedThenOnResponseCompleted) {
-  rdh_delegate_.set_num_on_response_started_calls_expectation(1);
 
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnWillStart(request_->url()));
@@ -1229,7 +1208,6 @@
 TEST_P(
     MojoAsyncResourceHandlerWithAllocationSizeTest,
     OnWillStartThenOnWillReadThenOnResponseStartedThenOnReadCompletedThenOnResponseCompleted) {
-  rdh_delegate_.set_num_on_response_started_calls_expectation(1);
 
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnWillStart(request_->url()));
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 081d917..2aaa3bec 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -774,7 +774,9 @@
       info->GetWebContentsGetterForRequest(), std::move(detail));
 }
 
-void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
+void ResourceDispatcherHostImpl::DidReceiveResponse(
+    ResourceLoader* loader,
+    ResourceResponse* response) {
   ResourceRequestInfoImpl* info = loader->GetRequestInfo();
   net::URLRequest* request = loader->request();
   if (request->was_fetched_via_proxy() &&
@@ -792,9 +794,8 @@
 
   ProcessRequestForLinkHeaders(request);
 
-  int render_process_id, render_frame_host;
-  if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host))
-    return;
+  if (delegate_)
+    delegate_->OnResponseStarted(request, info->GetContext(), response);
 
   // Don't notify WebContents observers for requests known to be
   // downloads; they aren't really associated with the Webcontents.
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index c30b304c..86e9e5b 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -420,7 +420,8 @@
   void DidStartRequest(ResourceLoader* loader) override;
   void DidReceiveRedirect(ResourceLoader* loader, const GURL& new_url,
                           ResourceResponse* response) override;
-  void DidReceiveResponse(ResourceLoader* loader) override;
+  void DidReceiveResponse(ResourceLoader* loader,
+                          ResourceResponse* response) override;
   void DidFinishLoading(ResourceLoader* loader) override;
   std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
       ResourceLoader* loader) override;
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 7c707c09..6e9610b 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -634,7 +634,7 @@
   scoped_refptr<ResourceResponse> response = new ResourceResponse();
   PopulateResourceResponse(info, request_.get(), response.get());
 
-  delegate_->DidReceiveResponse(this);
+  delegate_->DidReceiveResponse(this, response.get());
 
   read_deferral_start_time_ = base::TimeTicks::Now();
   // Using a ScopedDeferral here would result in calling ReadMore(true) on sync
diff --git a/content/browser/loader/resource_loader_delegate.h b/content/browser/loader/resource_loader_delegate.h
index a6b2be9..3eefb79 100644
--- a/content/browser/loader/resource_loader_delegate.h
+++ b/content/browser/loader/resource_loader_delegate.h
@@ -32,7 +32,8 @@
   virtual void DidReceiveRedirect(ResourceLoader* loader,
                                   const GURL& new_url,
                                   ResourceResponse* response) = 0;
-  virtual void DidReceiveResponse(ResourceLoader* loader) = 0;
+  virtual void DidReceiveResponse(ResourceLoader* loader,
+                                  ResourceResponse* response) = 0;
 
   // This method informs the delegate that the loader is done, and the loader
   // expects to be destroyed as a side-effect of this call.
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc
index 8ef2da03..6ebcb72 100644
--- a/content/browser/loader/resource_loader_unittest.cc
+++ b/content/browser/loader/resource_loader_unittest.cc
@@ -492,7 +492,8 @@
     EXPECT_EQ(1, did_start_request_);
     ++did_received_redirect_;
   }
-  void DidReceiveResponse(ResourceLoader* loader) override {
+  void DidReceiveResponse(ResourceLoader* loader,
+                          ResourceResponse* response) override {
     EXPECT_EQ(loader, loader_.get());
     EXPECT_EQ(0, did_finish_loading_);
     EXPECT_EQ(0, did_receive_response_);
diff --git a/content/browser/web_contents/aura/gesture_nav_simple.cc b/content/browser/web_contents/aura/gesture_nav_simple.cc
index 7ea7792..c67d8617 100644
--- a/content/browser/web_contents/aura/gesture_nav_simple.cc
+++ b/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -277,7 +277,7 @@
   gfx::ShadowValues shadow;
   shadow.emplace_back(gfx::Vector2d(0, kBgShadowOffsetY), kBgShadowBlurRadius,
                       kBgShadowColor);
-  bg_flags.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadow));
+  bg_flags.setLooper(gfx::CreateShadowDrawLooper(shadow));
   canvas->DrawCircle(center_point, kBackgroundRadius, bg_flags);
 
   // Draw the arrow.
diff --git a/content/test/data/accessibility/aria/aria-math-expected-mac.txt b/content/test/data/accessibility/aria/aria-math-expected-mac.txt
index af70c5b..70676613 100644
--- a/content/test/data/accessibility/aria/aria-math-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-math-expected-mac.txt
@@ -1,2 +1,3 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXGroup AXSubrole=AXDocumentMath AXRoleDescription='math'
+++++AXStaticText AXRoleDescription='text' AXValue='ARIA role math.'
diff --git a/content/test/data/accessibility/aria/aria-math-expected-win.txt b/content/test/data/accessibility/aria/aria-math-expected-win.txt
index 41bb7b47..eb7d71c 100644
--- a/content/test/data/accessibility/aria/aria-math-expected-win.txt
+++ b/content/test/data/accessibility/aria/aria-math-expected-win.txt
@@ -1,2 +1,3 @@
 ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
 ++ROLE_SYSTEM_EQUATION xml-roles:math
+++++ROLE_SYSTEM_STATICTEXT name='ARIA role math.'
diff --git a/content/test/data/accessibility/css/color-expected-win.txt b/content/test/data/accessibility/css/color-expected-win.txt
index 946c6f1..45a1594 100644
--- a/content/test/data/accessibility/css/color-expected-win.txt
+++ b/content/test/data/accessibility/css/color-expected-win.txt
@@ -1,7 +1,7 @@
-ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) ia2_hypertext='<obj0><obj1>'
-++IA2_ROLE_PARAGRAPH background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) ia2_hypertext='Red on blue.'
-++++ROLE_SYSTEM_STATICTEXT name='Red on blue.' background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) ia2_hypertext='Red on blue.'
-++IA2_ROLE_SECTION FOCUSABLE background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) background-color:rgb(0\,0\,255) color:rgb(0\,0\,0) background-color:rgb(255\,255\,255) color:rgb(0\,255\,0) ia2_hypertext='Default.Blue background.Green text.'
-++++ROLE_SYSTEM_STATICTEXT name='Default.' background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) ia2_hypertext='Default.'
-++++ROLE_SYSTEM_STATICTEXT name='Blue background.' background-color:rgb(0\,0\,255) color:rgb(0\,0\,0) ia2_hypertext='Blue background.'
-++++ROLE_SYSTEM_STATICTEXT name='Green text.' background-color:rgb(255\,255\,255) color:rgb(0\,255\,0) ia2_hypertext='Green text.'
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE offset:0 background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) offset:1 background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) ia2_hypertext='<obj0><obj1>'
+++IA2_ROLE_PARAGRAPH offset:0 background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) ia2_hypertext='Red on blue.'
+++++ROLE_SYSTEM_STATICTEXT name='Red on blue.' offset:0 background-color:rgb(0\,0\,255) color:rgb(255\,0\,0) ia2_hypertext='Red on blue.'
+++IA2_ROLE_SECTION FOCUSABLE offset:0 background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) offset:8 background-color:rgb(0\,0\,255) color:rgb(0\,0\,0) offset:24 background-color:rgb(255\,255\,255) color:rgb(0\,255\,0) ia2_hypertext='Default.Blue background.Green text.'
+++++ROLE_SYSTEM_STATICTEXT name='Default.' offset:0 background-color:rgb(255\,255\,255) color:rgb(0\,0\,0) ia2_hypertext='Default.'
+++++ROLE_SYSTEM_STATICTEXT name='Blue background.' offset:0 background-color:rgb(0\,0\,255) color:rgb(0\,0\,0) ia2_hypertext='Blue background.'
+++++ROLE_SYSTEM_STATICTEXT name='Green text.' offset:0 background-color:rgb(255\,255\,255) color:rgb(0\,255\,0) ia2_hypertext='Green text.'
diff --git a/content/test/data/accessibility/css/color.html b/content/test/data/accessibility/css/color.html
index b5db005..fa3f55d0 100644
--- a/content/test/data/accessibility/css/color.html
+++ b/content/test/data/accessibility/css/color.html
@@ -4,6 +4,7 @@
 @WIN-ALLOW:background-color:*
 @WIN-ALLOW:color:*
 @WIN-ALLOW:ia2_hypertext=*
+@WIN-ALLOW:offset:*
 -->
 <!DOCTYPE html>
 <html>
diff --git a/content/test/data/accessibility/css/font-family-expected-win.txt b/content/test/data/accessibility/css/font-family-expected-win.txt
new file mode 100644
index 0000000..2aa8f99b
--- /dev/null
+++ b/content/test/data/accessibility/css/font-family-expected-win.txt
@@ -0,0 +1,5 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE offset:0 font-family:-webkit-serif
+++IA2_ROLE_SECTION offset:0 font-family:-webkit-monospace offset:1 font-family:-webkit-sans-serif
+++++IA2_ROLE_PARAGRAPH offset:0 font-family:-webkit-monospace
+++++++ROLE_SYSTEM_STATICTEXT name='Monospace' offset:0 font-family:-webkit-monospace
+++++ROLE_SYSTEM_STATICTEXT name='Sans serif' offset:0 font-family:-webkit-sans-serif
diff --git a/content/test/data/accessibility/css/font-family.html b/content/test/data/accessibility/css/font-family.html
index 9fa2e43..da60143 100644
--- a/content/test/data/accessibility/css/font-family.html
+++ b/content/test/data/accessibility/css/font-family.html
@@ -1,5 +1,7 @@
 <!--
 @BLINK-ALLOW:fontFamily=*
+@WIN-ALLOW:font-family:*
+@WIN-ALLOW:offset:*
 -->
 <!DOCTYPE html>
 <html>
diff --git a/content/test/data/accessibility/css/font-style-expected-blink.txt b/content/test/data/accessibility/css/font-style-expected-blink.txt
index 0be2e0a..e23203fb 100644
--- a/content/test/data/accessibility/css/font-style-expected-blink.txt
+++ b/content/test/data/accessibility/css/font-style-expected-blink.txt
@@ -1,11 +1,19 @@
 rootWebArea
 ++paragraph
-++++staticText name='Normal '
-++++++inlineTextBox name='Normal '
-++++staticText name='bold' textStyle=1
-++++++inlineTextBox name='bold'
-++++staticText name='italic' textStyle=2
-++++++inlineTextBox name='italic'
+++++staticText name='The '
+++++++inlineTextBox name='The '
+++++staticText name='quick' textStyle=1
+++++++inlineTextBox name='quick'
+++++staticText name='brown' textStyle=2
+++++++inlineTextBox name='brown'
+++++staticText name='fox' textStyle=4
+++++++inlineTextBox name='fox'
+++++staticText name='jumped' textStyle=3
+++++++inlineTextBox name='jumped'
+++++staticText name='over' textStyle=6
+++++++inlineTextBox name='over'
+++++staticText name='dog' textStyle=7
+++++++inlineTextBox name='dog'
 ++div
 ++++staticText name='Normal'
 ++++++inlineTextBox name='Normal'
@@ -13,3 +21,7 @@
 ++++++inlineTextBox name='bold'
 ++++staticText name='italic' textStyle=2
 ++++++inlineTextBox name='italic'
+++++staticText name='underline' textStyle=4
+++++++inlineTextBox name='underline'
+++++staticText name='line-through' textStyle=8
+++++++inlineTextBox name='line-through'
diff --git a/content/test/data/accessibility/css/font-style-expected-win.txt b/content/test/data/accessibility/css/font-style-expected-win.txt
index fe68934..ce99610 100644
--- a/content/test/data/accessibility/css/font-style-expected-win.txt
+++ b/content/test/data/accessibility/css/font-style-expected-win.txt
@@ -1,9 +1,15 @@
-ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE font-weight:normal font-style:normal ia2_hypertext='<obj0><obj1>'
-++IA2_ROLE_PARAGRAPH font-weight:normal font-style:normal font-weight:bold font-style:normal font-weight:normal font-style:italic ia2_hypertext='Normal bolditalic'
-++++ROLE_SYSTEM_STATICTEXT name='Normal ' font-weight:normal font-style:normal ia2_hypertext='Normal '
-++++ROLE_SYSTEM_STATICTEXT name='bold' font-weight:bold font-style:normal ia2_hypertext='bold'
-++++ROLE_SYSTEM_STATICTEXT name='italic' font-weight:normal font-style:italic ia2_hypertext='italic'
-++IA2_ROLE_SECTION FOCUSABLE font-weight:normal font-style:normal font-weight:bold font-style:normal font-weight:normal font-style:italic ia2_hypertext='Normalbolditalic'
-++++ROLE_SYSTEM_STATICTEXT name='Normal' font-weight:normal font-style:normal ia2_hypertext='Normal'
-++++ROLE_SYSTEM_STATICTEXT name='bold' font-weight:bold font-style:normal ia2_hypertext='bold'
-++++ROLE_SYSTEM_STATICTEXT name='italic' font-weight:normal font-style:italic ia2_hypertext='italic'
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='<obj0><obj1>'
+++IA2_ROLE_PARAGRAPH offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:4 font-style:normal font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:9 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:14 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single offset:17 font-style:italic font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:23 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single offset:27 font-style:italic font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single ia2_hypertext='The quickbrownfoxjumpedoverdog'
+++++ROLE_SYSTEM_STATICTEXT name='The ' offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='The '
+++++ROLE_SYSTEM_STATICTEXT name='quick' offset:0 font-style:normal font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='quick'
+++++ROLE_SYSTEM_STATICTEXT name='brown' offset:0 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='brown'
+++++ROLE_SYSTEM_STATICTEXT name='fox' offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single ia2_hypertext='fox'
+++++ROLE_SYSTEM_STATICTEXT name='jumped' offset:0 font-style:italic font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='jumped'
+++++ROLE_SYSTEM_STATICTEXT name='over' offset:0 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single ia2_hypertext='over'
+++++ROLE_SYSTEM_STATICTEXT name='dog' offset:0 font-style:italic font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single ia2_hypertext='dog'
+++IA2_ROLE_SECTION FOCUSABLE offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:6 font-style:normal font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:10 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none offset:16 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single offset:25 font-style:normal font-weight:normal text-line-through-style:solid text-line-through-type:single text-underline-style:none text-underline-type:none ia2_hypertext='Normalbolditalicunderlineline-through'
+++++ROLE_SYSTEM_STATICTEXT name='Normal' offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='Normal'
+++++ROLE_SYSTEM_STATICTEXT name='bold' offset:0 font-style:normal font-weight:bold text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='bold'
+++++ROLE_SYSTEM_STATICTEXT name='italic' offset:0 font-style:italic font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:none text-underline-type:none ia2_hypertext='italic'
+++++ROLE_SYSTEM_STATICTEXT name='underline' offset:0 font-style:normal font-weight:normal text-line-through-style:none text-line-through-type:none text-underline-style:solid text-underline-type:single ia2_hypertext='underline'
+++++ROLE_SYSTEM_STATICTEXT name='line-through' offset:0 font-style:normal font-weight:normal text-line-through-style:solid text-line-through-type:single text-underline-style:none text-underline-type:none ia2_hypertext='line-through'
diff --git a/content/test/data/accessibility/css/font-style.html b/content/test/data/accessibility/css/font-style.html
index 5df21b4..d9cab1a 100644
--- a/content/test/data/accessibility/css/font-style.html
+++ b/content/test/data/accessibility/css/font-style.html
@@ -3,14 +3,21 @@
 @WIN-ALLOW:font-weight:*
 @WIN-ALLOW:font-style:*
 @WIN-ALLOW:ia2_hypertext=*
+@WIN-ALLOW:offset:*
+@WIN-ALLOW:text-line-through-style:*
+@WIN-ALLOW:text-line-through-type:*
+@WIN-ALLOW:text-underline-style:*
+@WIN-ALLOW:text-underline-type:*
 -->
 <!DOCTYPE html>
 <html>
   <body>
-    <p>Normal <b>bold</b> <i>italic</i></p>
+    <p>The <b>quick</b> <i>brown</i> <u>fox</u> <b><i>jumped</i></b> <i><u>over</u></i> <b><i><u>dog</u></i></b></p>
     <div contentEditable><span>Normal</span>
         <span style="font-weight: bold;">bold</span>
         <span style="font-style: italic;">italic</span>
+        <span style="text-decoration: underline;">underline</span>
+        <span style="text-decoration: line-through;">line-through</span>
     </div>
   </body>
 </html>
diff --git a/content/test/data/accessibility/css/language-expected-win.txt b/content/test/data/accessibility/css/language-expected-win.txt
index 829d791..149c3a87 100644
--- a/content/test/data/accessibility/css/language-expected-win.txt
+++ b/content/test/data/accessibility/css/language-expected-win.txt
@@ -1,4 +1,4 @@
-ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE language:en-US language:fr-FR ia2_hypertext='<obj0>Comment allez-vous?'
-++IA2_ROLE_PARAGRAPH language:en-US ia2_hypertext='How are you?'
-++++ROLE_SYSTEM_STATICTEXT name='How are you?' language:en-US ia2_hypertext='How are you?'
-++ROLE_SYSTEM_STATICTEXT name='Comment allez-vous?' language:fr-FR ia2_hypertext='Comment allez-vous?'
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE offset:0 language:en-US offset:1 language:fr-FR ia2_hypertext='<obj0>Comment allez-vous?'
+++IA2_ROLE_PARAGRAPH offset:0 language:en-US ia2_hypertext='How are you?'
+++++ROLE_SYSTEM_STATICTEXT name='How are you?' offset:0 language:en-US ia2_hypertext='How are you?'
+++ROLE_SYSTEM_STATICTEXT name='Comment allez-vous?' offset:0 language:fr-FR ia2_hypertext='Comment allez-vous?'
diff --git a/content/test/data/accessibility/css/language.html b/content/test/data/accessibility/css/language.html
index 38742de..b8bb643 100644
--- a/content/test/data/accessibility/css/language.html
+++ b/content/test/data/accessibility/css/language.html
@@ -2,6 +2,7 @@
 @BLINK-ALLOW:language=*
 @WIN-ALLOW:ia2_hypertext=*
 @WIN-ALLOW:language:*
+@WIN-ALLOW:offset:*
 -->
 <!DOCTYPE html>
 <html>
diff --git a/content/test/data/accessibility/html/math-expected-mac.txt b/content/test/data/accessibility/html/math-expected-mac.txt
index b0f74f5..c99b0d23 100644
--- a/content/test/data/accessibility/html/math-expected-mac.txt
+++ b/content/test/data/accessibility/html/math-expected-mac.txt
@@ -1,3 +1,8 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXGroup AXRoleDescription='group'
 ++++AXGroup AXSubrole=AXDocumentMath AXRoleDescription='math'
+++++++AXStaticText AXRoleDescription='text' AXValue='a'
+++++++AXStaticText AXRoleDescription='text' AXValue='2'
+++++++AXStaticText AXRoleDescription='text' AXValue='+'
+++++++AXStaticText AXRoleDescription='text' AXValue='b'
+++++++AXStaticText AXRoleDescription='text' AXValue='2'
diff --git a/content/test/data/accessibility/html/math-expected-win.txt b/content/test/data/accessibility/html/math-expected-win.txt
index 99306aa4d..fd6bdb0 100644
--- a/content/test/data/accessibility/html/math-expected-win.txt
+++ b/content/test/data/accessibility/html/math-expected-win.txt
@@ -1,3 +1,8 @@
 ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
 ++IA2_ROLE_SECTION
 ++++ROLE_SYSTEM_EQUATION
+++++++ROLE_SYSTEM_STATICTEXT name='a'
+++++++ROLE_SYSTEM_STATICTEXT name='2'
+++++++ROLE_SYSTEM_STATICTEXT name='+'
+++++++ROLE_SYSTEM_STATICTEXT name='b'
+++++++ROLE_SYSTEM_STATICTEXT name='2'
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.cc b/headless/lib/browser/headless_devtools_manager_delegate.cc
index 0842569..3ecf23d 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.cc
+++ b/headless/lib/browser/headless_devtools_manager_delegate.cc
@@ -108,6 +108,18 @@
   return cmd_result.release();
 }
 
+scoped_refptr<content::DevToolsAgentHost>
+HeadlessDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
+  HeadlessBrowserContext* context = browser_->GetDefaultBrowserContext();
+  HeadlessWebContentsImpl* web_contents_impl = HeadlessWebContentsImpl::From(
+      context->CreateWebContentsBuilder()
+          .SetInitialURL(url)
+          .SetWindowSize(browser_->options()->window_size)
+          .Build());
+  return content::DevToolsAgentHost::GetOrCreateFor(
+      web_contents_impl->web_contents());
+}
+
 std::string HeadlessDevToolsManagerDelegate::GetDiscoveryPageHTML() {
   return ResourceBundle::GetSharedInstance()
       .GetRawDataResource(IDR_HEADLESS_LIB_DEVTOOLS_DISCOVERY_PAGE)
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.h b/headless/lib/browser/headless_devtools_manager_delegate.h
index c891e82..29c8c1d 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.h
+++ b/headless/lib/browser/headless_devtools_manager_delegate.h
@@ -27,6 +27,8 @@
   // DevToolsManagerDelegate implementation:
   base::DictionaryValue* HandleCommand(content::DevToolsAgentHost* agent_host,
                                        base::DictionaryValue* command) override;
+  scoped_refptr<content::DevToolsAgentHost> CreateNewTarget(
+      const GURL& url) override;
   std::string GetDiscoveryPageHTML() override;
   std::string GetFrontendResource(const std::string& path) override;
 
diff --git a/net/cert/asn1_util.cc b/net/cert/asn1_util.cc
index 97e12dfc..1cbd201f 100644
--- a/net/cert/asn1_util.cc
+++ b/net/cert/asn1_util.cc
@@ -340,6 +340,58 @@
   return false;
 }
 
+bool ExtractSignatureAlgorithmsFromDERCert(
+    base::StringPiece cert,
+    base::StringPiece* cert_signature_algorithm_sequence,
+    base::StringPiece* tbs_signature_algorithm_sequence) {
+  // From RFC 5280, section 4.1
+  //    Certificate  ::=  SEQUENCE  {
+  //      tbsCertificate       TBSCertificate,
+  //      signatureAlgorithm   AlgorithmIdentifier,
+  //      signatureValue       BIT STRING  }
+
+  // TBSCertificate  ::=  SEQUENCE  {
+  //      version         [0]  EXPLICIT Version DEFAULT v1,
+  //      serialNumber         CertificateSerialNumber,
+  //      signature            AlgorithmIdentifier,
+  //      issuer               Name,
+  //      validity             Validity,
+  //      subject              Name,
+  //      subjectPublicKeyInfo SubjectPublicKeyInfo,
+  //      ... }
+
+  der::Parser parser((der::Input(cert)));
+  der::Parser certificate;
+  if (!parser.ReadSequence(&certificate))
+    return false;
+
+  der::Parser tbs_certificate;
+  if (!certificate.ReadSequence(&tbs_certificate))
+    return false;
+
+  bool unused;
+  if (!tbs_certificate.SkipOptionalTag(
+          der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
+    return false;
+  }
+
+  // serialNumber
+  if (!tbs_certificate.SkipTag(der::kInteger))
+    return false;
+  // signature
+  der::Input tbs_algorithm;
+  if (!tbs_certificate.ReadRawTLV(&tbs_algorithm))
+    return false;
+
+  der::Input cert_algorithm;
+  if (!certificate.ReadRawTLV(&cert_algorithm))
+    return false;
+
+  *cert_signature_algorithm_sequence = cert_algorithm.AsStringPiece();
+  *tbs_signature_algorithm_sequence = tbs_algorithm.AsStringPiece();
+  return true;
+}
+
 } // namespace asn1
 
 } // namespace net
diff --git a/net/cert/asn1_util.h b/net/cert/asn1_util.h
index fb64bfb..725072a 100644
--- a/net/cert/asn1_util.h
+++ b/net/cert/asn1_util.h
@@ -50,6 +50,23 @@
 // present or if there was a parsing failure.
 NET_EXPORT_PRIVATE bool HasTLSFeatureExtension(base::StringPiece cert);
 
+// Extracts the two (SEQUENCE) tag-length-values for the signature
+// AlgorithmIdentifiers in a DER encoded certificate. Does not use strict
+// parsing or validate the resulting AlgorithmIdentifiers.
+//
+// On success returns true, and assigns |cert_signature_algorithm_sequence| and
+// |tbs_signature_algorithm_sequence| to point into |cert|:
+//
+// * |cert_signature_algorithm_sequence| points at the TLV for
+//   Certificate.signatureAlgorithm.
+//
+// * |tbs_signature_algorithm_sequence| points at the TLV for
+//   TBSCertificate.algorithm.
+NET_EXPORT_PRIVATE bool ExtractSignatureAlgorithmsFromDERCert(
+    base::StringPiece cert,
+    base::StringPiece* cert_signature_algorithm_sequence,
+    base::StringPiece* tbs_signature_algorithm_sequence);
+
 } // namespace asn1
 
 } // namespace net
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc
index 7ce4eae..da496885 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -25,6 +25,7 @@
 #include "net/cert/cert_verify_result.h"
 #include "net/cert/crl_set.h"
 #include "net/cert/internal/parse_ocsp.h"
+#include "net/cert/internal/signature_algorithm.h"
 #include "net/cert/ocsp_revocation_status.h"
 #include "net/cert/x509_certificate.h"
 #include "net/der/encode_values.h"
@@ -372,64 +373,129 @@
 // Sets the "has_*" boolean members in |verify_result| that correspond with
 // the the presence of |hash| somewhere in the certificate chain (excluding the
 // trust anchor).
-void MapHashAlgorithmToBool(X509Certificate::SignatureHashAlgorithm hash,
-                            CertVerifyResult* verify_result) {
+void MapAlgorithmToBool(DigestAlgorithm hash, CertVerifyResult* verify_result) {
   switch (hash) {
-    case X509Certificate::kSignatureHashAlgorithmMd2:
+    case DigestAlgorithm::Md2:
       verify_result->has_md2 = true;
       break;
-    case X509Certificate::kSignatureHashAlgorithmMd4:
+    case DigestAlgorithm::Md4:
       verify_result->has_md4 = true;
       break;
-    case X509Certificate::kSignatureHashAlgorithmMd5:
+    case DigestAlgorithm::Md5:
       verify_result->has_md5 = true;
       break;
-    case X509Certificate::kSignatureHashAlgorithmSha1:
+    case DigestAlgorithm::Sha1:
       verify_result->has_sha1 = true;
       break;
-    case X509Certificate::kSignatureHashAlgorithmOther:
+    case DigestAlgorithm::Sha256:
+    case DigestAlgorithm::Sha384:
+    case DigestAlgorithm::Sha512:
       break;
   }
 }
 
-// Sets to true the |verify_result->has_*| boolean members for the hash
-// algorithms present in the certificate chain.
+// Inspects the signature algorithms in a single certificate |cert|.
 //
-// This considers the hash algorithms in all certificates except trusted
-// certificates.
+//   * Sets |verify_result->has_md2| to true if the certificate uses MD2.
+//   * Sets |verify_result->has_md4| to true if the certificate uses MD4.
+//   * Sets |verify_result->has_md5| to true if the certificate uses MD5.
+//   * Sets |verify_result->has_sha1| to true if the certificate uses SHA1.
 //
-// In the case of a successful verification the trust anchor is the final
-// certificate in the chain (either the final intermediate, or the leaf
-// certificate).
+// Returns false if the signature algorithm was unknown or mismatched.
+WARN_UNUSED_RESULT bool InspectSignatureAlgorithmForCert(
+    X509Certificate::OSCertHandle cert,
+    CertVerifyResult* verify_result) {
+  std::string cert_der;
+  base::StringPiece cert_algorithm_sequence;
+  base::StringPiece tbs_algorithm_sequence;
+
+  // Extract the AlgorithmIdentifier SEQUENCEs
+  if (!X509Certificate::GetDEREncoded(cert, &cert_der) ||
+      !asn1::ExtractSignatureAlgorithmsFromDERCert(
+          cert_der, &cert_algorithm_sequence, &tbs_algorithm_sequence)) {
+    return false;
+  }
+
+  if (!SignatureAlgorithm::IsEquivalent(der::Input(cert_algorithm_sequence),
+                                        der::Input(tbs_algorithm_sequence))) {
+    return false;
+  }
+
+  std::unique_ptr<SignatureAlgorithm> algorithm =
+      SignatureAlgorithm::Create(der::Input(cert_algorithm_sequence), nullptr);
+  if (!algorithm)
+    return false;
+
+  MapAlgorithmToBool(algorithm->digest(), verify_result);
+
+  // Check algorithm-specific parameters.
+  switch (algorithm->algorithm()) {
+    case SignatureAlgorithmId::RsaPkcs1:
+    case SignatureAlgorithmId::Ecdsa:
+      DCHECK(!algorithm->has_params());
+      break;
+    case SignatureAlgorithmId::RsaPss:
+      MapAlgorithmToBool(algorithm->ParamsForRsaPss()->mgf1_hash(),
+                         verify_result);
+      break;
+  }
+
+  return true;
+}
+
+// InspectSignatureAlgorithmsInChain() sets |verify_result->has_*| based on
+// the signature algorithms used in the chain, and also checks that certificates
+// don't have contradictory signature algorithms.
 //
-// Whereas if verification was uncessful, the chain may be partial, and the
-// final certificate may not be a trust anchor. This heuristic is used
-// in both successful and failed verifications, despite this ambiguity (failure
-// to tag one of the signature algorithms should only affect the final error).
-void ComputeSignatureHashAlgorithms(CertVerifyResult* verify_result) {
+// Returns false if any signature algorithm in the chain is unknown or
+// mismatched.
+//
+// Background:
+//
+// X.509 certificates contain two redundant descriptors for the signature
+// algorithm; one is covered by the signature, but in order to verify the
+// signature, the other signature algorithm is untrusted.
+//
+// RFC 5280 states that the two should be equal, in order to mitigate risk of
+// signature substitution attacks, but also discourages verifiers from enforcing
+// the profile of RFC 5280.
+//
+// System verifiers are inconsistent - some use the unsigned signature, some use
+// the signed signature, and they generally do not enforce that both match. This
+// creates confusion, as it's possible that the signature itself may be checked
+// using algorithm A, but if subsequent consumers report the certificate
+// algorithm, they may end up reporting algorithm B, which was not used to
+// verify the certificate. This function enforces that the two signatures match
+// in order to prevent such confusion.
+WARN_UNUSED_RESULT bool InspectSignatureAlgorithmsInChain(
+    CertVerifyResult* verify_result) {
   const X509Certificate::OSCertHandles& intermediates =
       verify_result->verified_cert->GetIntermediateCertificates();
 
   // If there are no intermediates, then the leaf is trusted or verification
   // failed.
   if (intermediates.empty())
-    return;
+    return true;
 
   DCHECK(!verify_result->has_sha1);
 
   // Fill in hash algorithms for the leaf certificate.
-  MapHashAlgorithmToBool(X509Certificate::GetSignatureHashAlgorithm(
-                             verify_result->verified_cert->os_cert_handle()),
-                         verify_result);
+  if (!InspectSignatureAlgorithmForCert(
+          verify_result->verified_cert->os_cert_handle(), verify_result)) {
+    return false;
+  }
+
   verify_result->has_sha1_leaf = verify_result->has_sha1;
 
   // Fill in hash algorithms for the intermediate cerificates, excluding the
-  // final one (which is the trust anchor).
+  // final one (which is presumably the trust anchor; may be incorrect for
+  // partial chains).
   for (size_t i = 0; i + 1 < intermediates.size(); ++i) {
-    MapHashAlgorithmToBool(
-        X509Certificate::GetSignatureHashAlgorithm(intermediates[i]),
-        verify_result);
+    if (!InspectSignatureAlgorithmForCert(intermediates[i], verify_result))
+      return false;
   }
+
+  return true;
 }
 
 }  // namespace
@@ -483,7 +549,13 @@
   int rv = VerifyInternal(cert, hostname, ocsp_response, flags, crl_set,
                           additional_trust_anchors, verify_result);
 
-  ComputeSignatureHashAlgorithms(verify_result);
+  // Check for mismatched signature algorithms and unknown signature algorithms
+  // in the chain. Also fills in the has_* booleans for the digest algorithms
+  // present in the chain.
+  if (!InspectSignatureAlgorithmsInChain(verify_result)) {
+    verify_result->cert_status |= CERT_STATUS_INVALID;
+    rv = MapCertStatusToNetError(verify_result->cert_status);
+  }
 
   bool allow_common_name_fallback =
       !verify_result->is_issued_by_known_root &&
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc
index 60621d6b..f31e402 100644
--- a/net/cert/cert_verify_proc_mac.cc
+++ b/net/cert/cert_verify_proc_mac.cc
@@ -204,6 +204,39 @@
       X509Certificate::CreateFromHandle(verified_cert, verified_chain);
 }
 
+// Returns true if the certificate uses MD2, MD4, MD5, or SHA1, and false
+// otherwise. A return of false also includes the case where the signature
+// algorithm couldn't be conclusively labeled as weak.
+bool CertUsesWeakHash(X509Certificate::OSCertHandle cert_handle) {
+  x509_util::CSSMCachedCertificate cached_cert;
+  OSStatus status = cached_cert.Init(cert_handle);
+  if (status)
+    return false;
+
+  x509_util::CSSMFieldValue signature_field;
+  status =
+      cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field);
+  if (status || !signature_field.field())
+    return false;
+
+  const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm =
+      signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>();
+  if (!sig_algorithm)
+    return false;
+
+  const CSSM_OID* alg_oid = &sig_algorithm->algorithm;
+
+  return (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
+          CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1));
+}
+
 // Returns true if the intermediates (excluding trusted certificates) use a
 // weak hashing algorithm, but the target does not use a weak hash.
 bool IsWeakChainBasedOnHashingAlgorithms(
@@ -228,22 +261,12 @@
       continue;
     }
 
-    X509Certificate::SignatureHashAlgorithm hash_algorithm =
-        X509Certificate::GetSignatureHashAlgorithm(chain_cert);
-
-    switch (hash_algorithm) {
-      case X509Certificate::kSignatureHashAlgorithmMd2:
-      case X509Certificate::kSignatureHashAlgorithmMd4:
-      case X509Certificate::kSignatureHashAlgorithmMd5:
-      case X509Certificate::kSignatureHashAlgorithmSha1:
-        if (i == 0) {
-          leaf_uses_weak_hash = true;
-        } else {
-          intermediates_contain_weak_hash = true;
-        }
-        break;
-      case X509Certificate::kSignatureHashAlgorithmOther:
-        break;
+    if (CertUsesWeakHash(chain_cert)) {
+      if (i == 0) {
+        leaf_uses_weak_hash = true;
+      } else {
+        intermediates_contain_weak_hash = true;
+      }
     }
   }
 
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index eb778132..66ce713 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -24,8 +24,11 @@
 #include "net/cert/cert_verify_result.h"
 #include "net/cert/crl_set.h"
 #include "net/cert/crl_set_storage.h"
+#include "net/cert/internal/signature_algorithm.h"
 #include "net/cert/test_root_certs.h"
 #include "net/cert/x509_certificate.h"
+#include "net/der/input.h"
+#include "net/der/parser.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/gtest_util.h"
 #include "net/test/test_certificate_data.h"
@@ -621,6 +624,363 @@
   EXPECT_EQ(0U, verify_result.cert_status);
 }
 
+// This fixture is for testing the verification of a certificate chain which
+// has some sort of mismatched signature algorithm (i.e.
+// Certificate.signatureAlgorithm and TBSCertificate.algorithm are different).
+class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test {
+ protected:
+  // In the test setup, SHA384 is given special treatment as an unknown
+  // algorithm.
+  static constexpr DigestAlgorithm kUnknownDigestAlgorithm =
+      DigestAlgorithm::Sha384;
+
+  struct CertParams {
+    // Certificate.signatureAlgorithm
+    DigestAlgorithm cert_algorithm;
+
+    // TBSCertificate.algorithm
+    DigestAlgorithm tbs_algorithm;
+  };
+
+  // On iOS trying to import a certificate with mismatched signature will
+  // fail. Consequently the rest of the tests can't be performed.
+  WARN_UNUSED_RESULT bool SupportsImportingMismatchedAlgorithms() const {
+#if defined(OS_IOS)
+    LOG(INFO) << "Skipping test on iOS because certs with mismatched "
+                 "algorithms cannot be imported";
+    return false;
+#else
+    return true;
+#endif
+  }
+
+  // Shorthand for VerifyChain() where only the leaf's parameters need
+  // to be specified.
+  WARN_UNUSED_RESULT int VerifyLeaf(const CertParams& leaf_params) {
+    return VerifyChain({// Target
+                        leaf_params,
+                        // Root
+                        {DigestAlgorithm::Sha256, DigestAlgorithm::Sha256}});
+  }
+
+  // Shorthand for VerifyChain() where only the intermediate's parameters need
+  // to be specified.
+  WARN_UNUSED_RESULT int VerifyIntermediate(
+      const CertParams& intermediate_params) {
+    return VerifyChain({// Target
+                        {DigestAlgorithm::Sha256, DigestAlgorithm::Sha256},
+                        // Intermediate
+                        intermediate_params,
+                        // Root
+                        {DigestAlgorithm::Sha256, DigestAlgorithm::Sha256}});
+  }
+
+  // Shorthand for VerifyChain() where only the root's parameters need to be
+  // specified.
+  WARN_UNUSED_RESULT int VerifyRoot(const CertParams& root_params) {
+    return VerifyChain({// Target
+                        {DigestAlgorithm::Sha256, DigestAlgorithm::Sha256},
+                        // Intermediate
+                        {DigestAlgorithm::Sha256, DigestAlgorithm::Sha256},
+                        // Root
+                        root_params});
+  }
+
+  // Manufactures a certificate chain where each certificate has the indicated
+  // signature algorithms, and then returns the result of verifying this chain.
+  //
+  // TODO(eroman): Instead of building certificates at runtime, move their
+  //               generation to external scripts.
+  WARN_UNUSED_RESULT int VerifyChain(
+      const std::vector<CertParams>& chain_params) {
+    auto chain = CreateChain(chain_params);
+    if (!chain) {
+      ADD_FAILURE() << "Failed creating certificate chain";
+      return ERR_UNEXPECTED;
+    }
+
+    int flags = 0;
+    CertVerifyResult dummy_result;
+    CertVerifyResult verify_result;
+
+    scoped_refptr<CertVerifyProc> verify_proc =
+        new MockCertVerifyProc(dummy_result);
+
+    return verify_proc->Verify(chain.get(), "test.example.com", std::string(),
+                               flags, NULL, CertificateList(), &verify_result);
+  }
+
+ private:
+  // Overwrites the AlgorithmIdentifier pointed to by |algorithm_sequence| with
+  // |algorithm|. Note this violates the constness of StringPiece.
+  WARN_UNUSED_RESULT static bool SetAlgorithmSequence(
+      DigestAlgorithm algorithm,
+      base::StringPiece* algorithm_sequence) {
+    // This string of bytes is the full SEQUENCE for an AlgorithmIdentifier.
+    std::vector<uint8_t> replacement_sequence;
+    switch (algorithm) {
+      case DigestAlgorithm::Sha1:
+        // sha1WithRSAEncryption
+        replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+                                0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
+        break;
+      case DigestAlgorithm::Sha256:
+        // sha256WithRSAEncryption
+        replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+                                0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
+        break;
+      case kUnknownDigestAlgorithm:
+        // This shouldn't be anything meaningful (modified numbers at random).
+        replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x8a, 0x87, 0x18, 0x46,
+                                0xd7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
+        break;
+      default:
+        ADD_FAILURE() << "Unsupported digest algorithm";
+        return false;
+    }
+
+    // For this simple replacement to work (without modifying any
+    // other sequence lengths) the original algorithm and replacement
+    // algorithm must have the same encoded length.
+    if (algorithm_sequence->size() != replacement_sequence.size()) {
+      ADD_FAILURE() << "AlgorithmIdentifier must have length "
+                    << replacement_sequence.size();
+      return false;
+    }
+
+    memcpy(const_cast<char*>(algorithm_sequence->data()),
+           replacement_sequence.data(), replacement_sequence.size());
+    return true;
+  }
+
+  // Locate the serial number bytes.
+  WARN_UNUSED_RESULT static bool ExtractSerialNumberFromDERCert(
+      base::StringPiece der_cert,
+      base::StringPiece* serial_value) {
+    der::Parser parser((der::Input(der_cert)));
+    der::Parser certificate;
+    if (!parser.ReadSequence(&certificate))
+      return false;
+
+    der::Parser tbs_certificate;
+    if (!certificate.ReadSequence(&tbs_certificate))
+      return false;
+
+    bool unused;
+    if (!tbs_certificate.SkipOptionalTag(
+            der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
+      return false;
+    }
+
+    // serialNumber
+    der::Input serial_value_der;
+    if (!tbs_certificate.ReadTag(der::kInteger, &serial_value_der))
+      return false;
+
+    *serial_value = serial_value_der.AsStringPiece();
+    return true;
+  }
+
+  // Creates a certificate (based on some base certificate file) using the
+  // specified signature algorithms.
+  static scoped_refptr<X509Certificate> CreateCertificate(
+      const CertParams& params) {
+    // Dosn't really matter which base certificate is used, so long as it is
+    // valid and uses a signature AlgorithmIdentifier with the same encoded
+    // length as sha1WithRSASignature.
+    const char* kLeafFilename = "name_constraint_good.pem";
+
+    auto cert = CreateCertificateChainFromFile(
+        GetTestCertsDirectory(), kLeafFilename, X509Certificate::FORMAT_AUTO);
+    if (!cert) {
+      ADD_FAILURE() << "Failed to load certificate: " << kLeafFilename;
+      return nullptr;
+    }
+
+    // Start with the DER bytes of a valid certificate. This will be the basis
+    // for building a modified certificate.
+    std::string cert_der;
+    if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &cert_der)) {
+      ADD_FAILURE() << "Failed getting DER bytes";
+      return nullptr;
+    }
+
+    // Parse the certificate and identify the locations of interest within
+    // |cert_der|.
+    base::StringPiece cert_algorithm_sequence;
+    base::StringPiece tbs_algorithm_sequence;
+    if (!asn1::ExtractSignatureAlgorithmsFromDERCert(
+            cert_der, &cert_algorithm_sequence, &tbs_algorithm_sequence)) {
+      ADD_FAILURE() << "Failed parsing certificate algorithms";
+      return nullptr;
+    }
+
+    base::StringPiece serial_value;
+    if (!ExtractSerialNumberFromDERCert(cert_der, &serial_value)) {
+      ADD_FAILURE() << "Failed parsing certificate serial number";
+      return nullptr;
+    }
+
+    // Give each certificate a unique serial number based on its content (which
+    // in turn is a function of |params|, otherwise importing it may fail.
+
+    // Upper bound for last entry in DigestAlgorithm
+    const int kNumDigestAlgorithms = 15;
+    *const_cast<char*>(serial_value.data()) +=
+        static_cast<int>(params.tbs_algorithm) * kNumDigestAlgorithms +
+        static_cast<int>(params.cert_algorithm);
+
+    // Change the signature AlgorithmIdentifiers.
+    if (!SetAlgorithmSequence(params.cert_algorithm,
+                              &cert_algorithm_sequence) ||
+        !SetAlgorithmSequence(params.tbs_algorithm, &tbs_algorithm_sequence)) {
+      return nullptr;
+    }
+
+    // NOTE: The signature is NOT recomputed over TBSCertificate -- for these
+    // tests it isn't needed.
+    return X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
+  }
+
+  static scoped_refptr<X509Certificate> CreateChain(
+      const std::vector<CertParams>& params) {
+    // Manufacture a chain with the given combinations of signature algorithms.
+    // This chain isn't actually a valid chain, but it is good enough for
+    // testing the base CertVerifyProc.
+    CertificateList certs;
+    for (const auto& cert_params : params) {
+      certs.push_back(CreateCertificate(cert_params));
+      if (!certs.back())
+        return nullptr;
+    }
+
+    X509Certificate::OSCertHandles intermediates;
+    for (size_t i = 1; i < certs.size(); ++i)
+      intermediates.push_back(certs[i]->os_cert_handle());
+
+    return X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
+                                             intermediates);
+  }
+};
+
+// This is a control test to make sure that the test helper
+// VerifyLeaf() works as expected. There is no actual mismatch in the
+// algorithms used here.
+//
+//  Certificate.signatureAlgorithm:  sha1WithRSASignature
+//  TBSCertificate.algorithm:        sha1WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha1) {
+  int rv = VerifyLeaf({DigestAlgorithm::Sha1, DigestAlgorithm::Sha1});
+  ASSERT_THAT(rv, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
+}
+
+// This is a control test to make sure that the test helper
+// VerifyLeaf() works as expected. There is no actual mismatch in the
+// algorithms used here.
+//
+//  Certificate.signatureAlgorithm:  sha256WithRSASignature
+//  TBSCertificate.algorithm:        sha256WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha256) {
+  int rv = VerifyLeaf({DigestAlgorithm::Sha256, DigestAlgorithm::Sha256});
+  ASSERT_THAT(rv, IsOk());
+}
+
+// Mismatched signature algorithms in the leaf certificate.
+//
+//  Certificate.signatureAlgorithm:  sha1WithRSASignature
+//  TBSCertificate.algorithm:        sha256WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha256) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyLeaf({DigestAlgorithm::Sha1, DigestAlgorithm::Sha256});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Mismatched signature algorithms in the leaf certificate.
+//
+//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
+//  TBSCertificate.algorithm:        sha1WithRSASignature
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha1) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyLeaf({DigestAlgorithm::Sha256, DigestAlgorithm::Sha1});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Unrecognized signature algorithm in the leaf certificate.
+//
+//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
+//  TBSCertificate.algorithm:        ?
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Unknown) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyLeaf({DigestAlgorithm::Sha256, kUnknownDigestAlgorithm});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Unrecognized signature algorithm in the leaf certificate.
+//
+//  Certificate.signatureAlgorithm:  ?
+//  TBSCertificate.algorithm:        sha256WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafUnknownSha256) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyLeaf({kUnknownDigestAlgorithm, DigestAlgorithm::Sha256});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Mismatched signature algorithms in the intermediate certificate.
+//
+//  Certificate.signatureAlgorithm:  sha1WithRSASignature
+//  TBSCertificate.algorithm:        sha256WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha1Sha256) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyIntermediate({DigestAlgorithm::Sha1, DigestAlgorithm::Sha256});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Mismatched signature algorithms in the intermediate certificate.
+//
+//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
+//  TBSCertificate.algorithm:        sha1WithRSASignature
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha256Sha1) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyIntermediate({DigestAlgorithm::Sha256, DigestAlgorithm::Sha1});
+  ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
+}
+
+// Mismatched signature algorithms in the root certificate.
+//
+//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
+//  TBSCertificate.algorithm:        sha1WithRSASignature
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootSha256Sha1) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyRoot({DigestAlgorithm::Sha256, DigestAlgorithm::Sha1});
+  ASSERT_THAT(rv, IsOk());
+}
+
+// Unrecognized signature algorithm in the root certificate.
+//
+//  Certificate.signatureAlgorithm:  ?
+//  TBSCertificate.algorithm:        sha256WithRSAEncryption
+TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootUnknownSha256) {
+  if (!SupportsImportingMismatchedAlgorithms())
+    return;
+
+  int rv = VerifyRoot({kUnknownDigestAlgorithm, DigestAlgorithm::Sha256});
+  ASSERT_THAT(rv, IsOk());
+}
+
 TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) {
   if (!SupportsReturningVerifiedChain()) {
     LOG(INFO) << "Skipping this test in this platform.";
diff --git a/net/cert/internal/signature_algorithm.cc b/net/cert/internal/signature_algorithm.cc
index 9853ac02..285ae61d 100644
--- a/net/cert/internal/signature_algorithm.cc
+++ b/net/cert/internal/signature_algorithm.cc
@@ -513,7 +513,7 @@
 
 }  // namespace
 
-WARN_UNUSED_RESULT bool ParseHashAlgorithm(const der::Input input,
+WARN_UNUSED_RESULT bool ParseHashAlgorithm(const der::Input& input,
                                            DigestAlgorithm* out) {
   der::Input oid;
   der::Input params;
@@ -638,6 +638,39 @@
   return nullptr;
 }
 
+bool SignatureAlgorithm::IsEquivalent(const der::Input& alg1_tlv,
+                                      const der::Input& alg2_tlv) {
+  if (alg1_tlv == alg2_tlv)
+    return true;
+
+  std::unique_ptr<SignatureAlgorithm> alg1 = Create(alg1_tlv, nullptr);
+  std::unique_ptr<SignatureAlgorithm> alg2 = Create(alg2_tlv, nullptr);
+
+  // Do checks that apply to all algorithms.
+  if (!alg1 || !alg2 || (alg1->algorithm() != alg2->algorithm()) ||
+      (alg1->digest() != alg2->digest())) {
+    return false;
+  }
+
+  // Check algorithm-specific parameters for equality.
+  switch (alg1->algorithm()) {
+    case SignatureAlgorithmId::RsaPkcs1:
+    case SignatureAlgorithmId::Ecdsa:
+      DCHECK(!alg1->has_params());
+      DCHECK(!alg2->has_params());
+      return true;
+    case SignatureAlgorithmId::RsaPss: {
+      const RsaPssParameters* params1 = alg1->ParamsForRsaPss();
+      const RsaPssParameters* params2 = alg2->ParamsForRsaPss();
+      return params1 && params2 &&
+             (params1->salt_length() == params2->salt_length()) &&
+             (params1->mgf1_hash() == params2->mgf1_hash());
+    }
+  }
+
+  return false;
+}
+
 SignatureAlgorithm::SignatureAlgorithm(
     SignatureAlgorithmId algorithm,
     DigestAlgorithm digest,
diff --git a/net/cert/internal/signature_algorithm.h b/net/cert/internal/signature_algorithm.h
index 0f316de9..58b9582 100644
--- a/net/cert/internal/signature_algorithm.h
+++ b/net/cert/internal/signature_algorithm.h
@@ -52,7 +52,7 @@
 //         { IDENTIFIER id-sha384 PARAMS TYPE NULL ARE preferredPresent } |
 //         { IDENTIFIER id-sha512 PARAMS TYPE NULL ARE preferredPresent }
 //     }
-WARN_UNUSED_RESULT bool ParseHashAlgorithm(const der::Input input,
+WARN_UNUSED_RESULT bool ParseHashAlgorithm(const der::Input& input,
                                            DigestAlgorithm* out);
 
 // Base class for describing algorithm parameters.
@@ -118,6 +118,13 @@
   // The returned pointer is non-owned, and has the same lifetime as |this|.
   const RsaPssParameters* ParamsForRsaPss() const;
 
+  bool has_params() const { return !!params_; }
+
+  // Returns true if |alg1_tlv| and |alg2_tlv| represent an equivalent
+  // AlgorithmIdentifier once parsed.
+  static bool IsEquivalent(const der::Input& alg1_tlv,
+                           const der::Input& alg2_tlv);
+
  private:
   SignatureAlgorithm(SignatureAlgorithmId algorithm,
                      DigestAlgorithm digest,
diff --git a/net/cert/internal/verify_certificate_chain.cc b/net/cert/internal/verify_certificate_chain.cc
index 33f831e..041a6fc7 100644
--- a/net/cert/internal/verify_certificate_chain.cc
+++ b/net/cert/internal/verify_certificate_chain.cc
@@ -135,18 +135,6 @@
   return true;
 }
 
-// Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for
-// RSA with SHA1.
-WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm(
-    const der::Input& signature_algorithm_tlv) {
-  std::unique_ptr<SignatureAlgorithm> algorithm =
-      SignatureAlgorithm::Create(signature_algorithm_tlv, nullptr);
-
-  return algorithm &&
-         algorithm->algorithm() == SignatureAlgorithmId::RsaPkcs1 &&
-         algorithm->digest() == DigestAlgorithm::Sha1;
-}
-
 // Returns true if |cert| has internally consistent signature algorithms.
 //
 // X.509 certificates contain two different signature algorithms:
@@ -177,9 +165,10 @@
   if (alg1_tlv == alg2_tlv)
     return true;
 
-  // But make a compatibility concession for RSA with SHA1.
-  if (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) &&
-      IsRsaWithSha1SignatureAlgorithm(alg2_tlv)) {
+  // But make a compatibility concession if alternate encodings are used
+  // TODO(eroman): Turn this warning into an error.
+  // TODO(eroman): Add a unit-test that exercises this case.
+  if (SignatureAlgorithm::IsEquivalent(alg1_tlv, alg2_tlv)) {
     errors->AddWarning(
         kSignatureAlgorithmsDifferentEncoding,
         CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv,
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h
index 4567f0e..aa123fc 100644
--- a/net/cert/x509_certificate.h
+++ b/net/cert/x509_certificate.h
@@ -80,14 +80,6 @@
     kPublicKeyTypeECDH
   };
 
-  enum SignatureHashAlgorithm {
-    kSignatureHashAlgorithmMd2,
-    kSignatureHashAlgorithmMd4,
-    kSignatureHashAlgorithmMd5,
-    kSignatureHashAlgorithmSha1,
-    kSignatureHashAlgorithmOther,
-  };
-
   enum Format {
     // The data contains a single DER-encoded certificate, or a PEM-encoded
     // DER certificate with the PEM encoding block name of "CERTIFICATE".
@@ -323,15 +315,6 @@
                                size_t* size_bits,
                                PublicKeyType* type);
 
-  // Returns the digest algorithm used in |cert_handle|'s signature.
-  // If the digest algorithm cannot be determined, or if it is not one
-  // of the explicitly enumerated values, kSignatureHashAlgorithmOther
-  // will be returned.
-  // NOTE: No validation of the signature is performed, and thus invalid
-  // signatures may result in seemingly meaningful values.
-  static SignatureHashAlgorithm GetSignatureHashAlgorithm(
-      OSCertHandle cert_handle);
-
   // Returns the OSCertHandle of this object. Because of caching, this may
   // differ from the OSCertHandle originally supplied during initialization.
   // Note: On Windows, CryptoAPI may return unexpected results if this handle
diff --git a/net/cert/x509_certificate_ios.cc b/net/cert/x509_certificate_ios.cc
index 18ce828d..7379707 100644
--- a/net/cert/x509_certificate_ios.cc
+++ b/net/cert/x509_certificate_ios.cc
@@ -358,29 +358,6 @@
   *size_bits = EVP_PKEY_bits(key);
 }
 
-// static
-X509Certificate::SignatureHashAlgorithm
-X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
-  bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(cert_handle);
-  if (!cert)
-    return kSignatureHashAlgorithmOther;
-
-  // TODO(eroman): This duplicates code with x509_certificate_openssl.cc
-  int sig_alg = OBJ_obj2nid(cert->sig_alg->algorithm);
-  if (sig_alg == NID_md2WithRSAEncryption)
-    return kSignatureHashAlgorithmMd2;
-  if (sig_alg == NID_md4WithRSAEncryption)
-    return kSignatureHashAlgorithmMd4;
-  if (sig_alg == NID_md5WithRSAEncryption || sig_alg == NID_md5WithRSA)
-    return kSignatureHashAlgorithmMd5;
-  if (sig_alg == NID_sha1WithRSAEncryption || sig_alg == NID_dsaWithSHA ||
-      sig_alg == NID_dsaWithSHA1 || sig_alg == NID_dsaWithSHA1_2 ||
-      sig_alg == NID_sha1WithRSA || sig_alg == NID_ecdsa_with_SHA1) {
-    return kSignatureHashAlgorithmSha1;
-  }
-  return kSignatureHashAlgorithmOther;
-}
-
 bool X509Certificate::SupportsSSLClientAuth() const {
   return false;
 }
diff --git a/net/cert/x509_certificate_mac.cc b/net/cert/x509_certificate_mac.cc
index 2686640..3c3c8cf 100644
--- a/net/cert/x509_certificate_mac.cc
+++ b/net/cert/x509_certificate_mac.cc
@@ -518,43 +518,6 @@
   }
 }
 
-X509Certificate::SignatureHashAlgorithm
-X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
-  x509_util::CSSMCachedCertificate cached_cert;
-  OSStatus status = cached_cert.Init(cert_handle);
-  if (status)
-    return kSignatureHashAlgorithmOther;
-
-  x509_util::CSSMFieldValue signature_field;
-  status =
-      cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field);
-  if (status || !signature_field.field())
-    return kSignatureHashAlgorithmOther;
-
-  const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm =
-      signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>();
-  if (!sig_algorithm)
-    return kSignatureHashAlgorithmOther;
-
-  const CSSM_OID* alg_oid = &sig_algorithm->algorithm;
-  if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA))
-    return kSignatureHashAlgorithmMd2;
-  if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA))
-    return kSignatureHashAlgorithmMd4;
-  if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA))
-    return kSignatureHashAlgorithmMd5;
-  if (CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) ||
-      CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
-      CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
-      CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
-      CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
-      CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
-    return kSignatureHashAlgorithmSha1;
-  }
-
-  return kSignatureHashAlgorithmOther;
-}
-
 // static
 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
   x509_util::CSSMCachedCertificate cached_cert;
diff --git a/net/cert/x509_certificate_nss.cc b/net/cert/x509_certificate_nss.cc
index 2f2f977..822102fe 100644
--- a/net/cert/x509_certificate_nss.cc
+++ b/net/cert/x509_certificate_nss.cc
@@ -239,28 +239,6 @@
 }
 
 // static
-X509Certificate::SignatureHashAlgorithm
-X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
-  SECAlgorithmID& signature = cert_handle->signature;
-  SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm);
-  switch (oid_tag) {
-    case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
-      return kSignatureHashAlgorithmMd5;
-    case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
-      return kSignatureHashAlgorithmMd2;
-    case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
-      return kSignatureHashAlgorithmMd4;
-    case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
-    case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
-    case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
-    case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
-      return kSignatureHashAlgorithmSha1;
-    default:
-      return kSignatureHashAlgorithmOther;
-  }
-}
-
-// static
 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
   crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert_handle));
   if (!public_key.get())
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc
index 730eef0..30d9598 100644
--- a/net/cert/x509_certificate_openssl.cc
+++ b/net/cert/x509_certificate_openssl.cc
@@ -377,24 +377,6 @@
   }
 }
 
-// static
-X509Certificate::SignatureHashAlgorithm
-X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
-  int sig_alg = OBJ_obj2nid(cert_handle->sig_alg->algorithm);
-  if (sig_alg == NID_md2WithRSAEncryption)
-    return kSignatureHashAlgorithmMd2;
-  if (sig_alg == NID_md4WithRSAEncryption)
-    return kSignatureHashAlgorithmMd4;
-  if (sig_alg == NID_md5WithRSAEncryption || sig_alg == NID_md5WithRSA)
-    return kSignatureHashAlgorithmMd5;
-  if (sig_alg == NID_sha1WithRSAEncryption || sig_alg == NID_dsaWithSHA ||
-      sig_alg == NID_dsaWithSHA1 || sig_alg == NID_dsaWithSHA1_2 ||
-      sig_alg == NID_sha1WithRSA || sig_alg == NID_ecdsa_with_SHA1) {
-    return kSignatureHashAlgorithmSha1;
-  }
-  return kSignatureHashAlgorithmOther;
-}
-
 bool X509Certificate::IsIssuedByEncoded(
     const std::vector<std::string>& valid_issuers) {
   if (valid_issuers.empty())
diff --git a/net/cert/x509_certificate_win.cc b/net/cert/x509_certificate_win.cc
index ef3d040e..c67011e 100644
--- a/net/cert/x509_certificate_win.cc
+++ b/net/cert/x509_certificate_win.cc
@@ -421,33 +421,6 @@
   }
 }
 
-X509Certificate::SignatureHashAlgorithm
-X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
-  const char* algorithm = cert_handle->pCertInfo->SignatureAlgorithm.pszObjId;
-  if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) {
-    // md5WithRSAEncryption: 1.2.840.113549.1.1.4
-    return kSignatureHashAlgorithmMd5;
-  }
-  if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) {
-    // md2WithRSAEncryption: 1.2.840.113549.1.1.2
-    return kSignatureHashAlgorithmMd2;
-  }
-  if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) {
-    // md4WithRSAEncryption: 1.2.840.113549.1.1.3
-    return kSignatureHashAlgorithmMd4;
-  }
-  if (strcmp(algorithm, szOID_RSA_SHA1RSA) == 0 ||
-      strcmp(algorithm, szOID_X957_SHA1DSA) == 0 ||
-      strcmp(algorithm, szOID_ECDSA_SHA1) == 0) {
-    // sha1WithRSAEncryption: 1.2.840.113549.1.1.5
-    // id-dsa-with-sha1: 1.2.840.10040.4.3
-    // ecdsa-with-SHA1: 1.2.840.10045.4.1
-    return kSignatureHashAlgorithmSha1;
-  }
-
-  return kSignatureHashAlgorithmOther;
-}
-
 bool X509Certificate::IsIssuedByEncoded(
     const std::vector<std::string>& valid_issuers) {
 
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index d701ae0..4439780 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -156,6 +156,7 @@
     "fileapi/timed_task_helper.h",
     "fileapi/transient_file_util.cc",
     "fileapi/transient_file_util.h",
+    "fileapi/watcher_manager.h",
     "quota/client_usage_tracker.cc",
     "quota/client_usage_tracker.h",
     "quota/quota_callbacks.h",
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
index a7e3a80..9876a12 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -37,7 +37,6 @@
 crbug.com/695072 virtual/mojo-loading/http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure ]
 
 # These tests are flaky.
-Bug(none) external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Crash ]
 Bug(none) http/tests/misc/window-open-then-write.html [ Timeout ]
 Bug(none) external/wpt/html/browsers/browsing-the-web/unloading-documents/beforeunload-on-history-back.html [ Failure ]
 Bug(none) virtual/mojo-loading/http/tests/misc/window-open-then-write.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 3b49ea3..99a5ebad 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2475,6 +2475,3 @@
 
 crbug.com/698520 external/wpt/preload/fetch-destination.https.html [ Failure Pass ]
 crbug.com/698521 external/wpt/preload/preload-with-type.html [ Failure Pass ]
-
-# Sheriff failures 2017-03-06
-crbug.com/698872 [ Linux Debug ] external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor-expected.txt
deleted file mode 100644
index 46cdf12c..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS Image constructor works 
-FAIL Image and HTMLImageElement share a prototype assert_true: expected true got false
-PASS Image localName is img 
-PASS Image namespace URI is correct 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor.html
index 1119f81..aa838ec 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/Image-constructor.html
@@ -26,4 +26,12 @@
     assert_true((new Image()).namespaceURI === "http://www.w3.org/1999/xhtml");
   }, "Image namespace URI is correct");
 
+  test(function() {
+      assert_equals(Image.name, "Image", "Image name should be Image (not HTMLImageElement)");
+      assert_equals(Image.__proto__, Function.prototype, "Image __proto__ is Function prototype");
+      assert_equals(Image.prototype, HTMLImageElement.prototype, "Image.prototype is same as HTMLImageElement.prototype");
+      assert_equals(new Image().__proto__, HTMLImageElement.prototype, "Image __proto__ is HTMLImageElement prototype ");
+      assert_equals(Image.prototype.__proto__, HTMLElement.prototype, "Image.prototype __proto__ is HTMLElement prototype");
+  }, "NamedConstructor creates the correct object structure.");
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https.html
index 54eb4bc..2227d390 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https.html
@@ -23,7 +23,7 @@
 
 function redirect_fetch_test(t, test) {
   var scope = baseScope + test.name;
-  service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
+  return service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
     return wait_for_state(t, reg.installing, 'activated');
   }).then(function() {
     return with_iframe(scope + '?url=' + encodeURIComponent(frameURL));
@@ -102,8 +102,8 @@
 // TODO: verify CORS redirect results in all further redirects being
 //       considered cross origin
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -121,8 +121,8 @@
    'same-origin without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -140,8 +140,8 @@
    'no-cors without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -159,8 +159,8 @@
    'cors without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -178,8 +178,8 @@
    'same-origin without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -197,8 +197,8 @@
    'no-cors without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -216,8 +216,8 @@
    'cors without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -235,8 +235,8 @@
    'same-origin without credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -252,8 +252,8 @@
    'no-cors without credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -269,8 +269,8 @@
    'cors without credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -288,8 +288,8 @@
    'same-origin with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -307,8 +307,8 @@
    'no-cors with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-cors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -326,8 +326,8 @@
    'cors with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -345,8 +345,8 @@
    'same-origin with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -364,8 +364,8 @@
    'no-cors with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-sameorigin-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -383,8 +383,8 @@
    'cors with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -402,8 +402,8 @@
    'same-origin with credentials should fail opaqueredirect interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -419,8 +419,8 @@
    'no-cors with credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-manual-nocors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -436,8 +436,8 @@
    'cors with credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -453,8 +453,8 @@
    'same-origin without credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -472,8 +472,8 @@
    'no-cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -489,8 +489,8 @@
    'cors without credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -506,8 +506,8 @@
    'same-origin without credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -525,8 +525,8 @@
    'no-cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -544,8 +544,8 @@
    'cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -561,8 +561,8 @@
    'same-origin without credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -578,8 +578,8 @@
    'no-cors without credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -595,8 +595,8 @@
    'cors without credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -612,8 +612,8 @@
    'same-origin with credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -631,8 +631,8 @@
    'no-cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-cors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -651,8 +651,8 @@
    'cors with credentials should fail interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -668,8 +668,8 @@
    'same-origin with credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -687,8 +687,8 @@
    'no-cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-sameorigin-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -706,8 +706,8 @@
    'cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -723,8 +723,8 @@
    'same-origin with credentials should succeed interception ' +
    'and response should be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -740,8 +740,8 @@
    'no-cors with credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-follow-nocors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -757,8 +757,8 @@
    'cors with credentials should succeed interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -776,8 +776,8 @@
    'same-origin without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -795,8 +795,8 @@
    'no-cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -814,8 +814,8 @@
    'cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -833,8 +833,8 @@
    'same-origin without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -852,8 +852,8 @@
    'no-cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -871,8 +871,8 @@
    'cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-sameorigin-nocreds',
     redirect_dest: 'same-origin',
     url_credentials: false,
@@ -890,8 +890,8 @@
    'same-origin without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-nocors-nocreds',
     redirect_dest: 'no-cors',
     url_credentials: false,
@@ -909,8 +909,8 @@
    'no-cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-cors-nocreds',
     redirect_dest: 'cors',
     url_credentials: false,
@@ -928,8 +928,8 @@
    'cors without credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -947,8 +947,8 @@
    'same-origin with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -966,8 +966,8 @@
    'no-cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-cors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -985,8 +985,8 @@
    'cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -1004,8 +1004,8 @@
    'same-origin with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -1023,8 +1023,8 @@
    'no-cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-sameorigin-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
@@ -1042,8 +1042,8 @@
    'cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-sameorigin-creds',
     redirect_dest: 'same-origin',
     url_credentials: true,
@@ -1061,8 +1061,8 @@
    'same-origin with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-nocors-creds',
     redirect_dest: 'no-cors',
     url_credentials: true,
@@ -1080,8 +1080,8 @@
    'no-cors with credentials should fail interception ' +
    'and response should not be redirected');
 
-async_test(function(t) {
-  redirect_fetch_test(t, {
+promise_test(function(t) {
+  return redirect_fetch_test(t, {
     name: 'nonav-error-nocors-redirects-to-cors-creds',
     redirect_dest: 'cors',
     url_credentials: true,
diff --git a/third_party/WebKit/LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake-expected.txt
index c9d8e2cf..795df178 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/custom/document-register-reentrant-returning-fake-expected.txt
@@ -3,6 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+Constructor object isn't created.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
index 0b448d4..19191793 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -79,6 +79,7 @@
     method constructor
     setter value
 interface Audio
+    attribute @@toStringTag
     method constructor
 interface AudioBuffer
     attribute @@toStringTag
@@ -3081,7 +3082,48 @@
     method constructor
     method timeRemaining
 interface Image
+    attribute @@toStringTag
+    getter align
+    getter alt
+    getter border
+    getter complete
+    getter crossOrigin
+    getter currentSrc
+    getter height
+    getter hspace
+    getter isMap
+    getter longDesc
+    getter lowsrc
+    getter name
+    getter naturalHeight
+    getter naturalWidth
+    getter referrerPolicy
+    getter sizes
+    getter src
+    getter srcset
+    getter useMap
+    getter vspace
+    getter width
+    getter x
+    getter y
     method constructor
+    setter align
+    setter alt
+    setter border
+    setter crossOrigin
+    setter height
+    setter hspace
+    setter isMap
+    setter longDesc
+    setter lowsrc
+    setter name
+    setter referrerPolicy
+    setter sizes
+    setter src
+    setter srcset
+    setter useMap
+    setter vspace
+    setter width
 interface ImageBitmap
     attribute @@toStringTag
     getter height
@@ -3694,7 +3736,22 @@
     method suspend
     setter oncomplete
 interface Option
+    attribute @@toStringTag
+    getter defaultSelected
+    getter disabled
+    getter form
+    getter index
+    getter label
+    getter selected
+    getter text
+    getter value
     method constructor
+    setter defaultSelected
+    setter disabled
+    setter label
+    setter selected
+    setter text
+    setter value
 interface OscillatorNode : AudioScheduledSourceNode
     attribute @@toStringTag
     getter detune
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
index 796890f..e018d60 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -79,6 +79,7 @@
     method constructor
     setter value
 interface Audio
+    attribute @@toStringTag
     method constructor
 interface AudioBuffer
     attribute @@toStringTag
@@ -3010,7 +3011,48 @@
     method constructor
     method timeRemaining
 interface Image
+    attribute @@toStringTag
+    getter align
+    getter alt
+    getter border
+    getter complete
+    getter crossOrigin
+    getter currentSrc
+    getter height
+    getter hspace
+    getter isMap
+    getter longDesc
+    getter lowsrc
+    getter name
+    getter naturalHeight
+    getter naturalWidth
+    getter referrerPolicy
+    getter sizes
+    getter src
+    getter srcset
+    getter useMap
+    getter vspace
+    getter width
+    getter x
+    getter y
     method constructor
+    setter align
+    setter alt
+    setter border
+    setter crossOrigin
+    setter height
+    setter hspace
+    setter isMap
+    setter longDesc
+    setter lowsrc
+    setter name
+    setter referrerPolicy
+    setter sizes
+    setter src
+    setter srcset
+    setter useMap
+    setter vspace
+    setter width
 interface ImageBitmap
     attribute @@toStringTag
     getter height
@@ -3622,7 +3664,22 @@
     method suspend
     setter oncomplete
 interface Option
+    attribute @@toStringTag
+    getter defaultSelected
+    getter disabled
+    getter form
+    getter index
+    getter label
+    getter selected
+    getter text
+    getter value
     method constructor
+    setter defaultSelected
+    setter disabled
+    setter label
+    setter selected
+    setter text
+    setter value
 interface OscillatorNode : AudioScheduledSourceNode
     attribute @@toStringTag
     getter detune
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 8be874f..e5c4deb9 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -136,6 +136,7 @@
     method constructor
     setter value
 interface Audio
+    attribute @@toStringTag
     method constructor
 interface AudioBuffer
     attribute @@toStringTag
@@ -3669,7 +3670,48 @@
     method constructor
     method timeRemaining
 interface Image
+    attribute @@toStringTag
+    getter align
+    getter alt
+    getter border
+    getter complete
+    getter crossOrigin
+    getter currentSrc
+    getter height
+    getter hspace
+    getter isMap
+    getter longDesc
+    getter lowsrc
+    getter name
+    getter naturalHeight
+    getter naturalWidth
+    getter referrerPolicy
+    getter sizes
+    getter src
+    getter srcset
+    getter useMap
+    getter vspace
+    getter width
+    getter x
+    getter y
     method constructor
+    setter align
+    setter alt
+    setter border
+    setter crossOrigin
+    setter height
+    setter hspace
+    setter isMap
+    setter longDesc
+    setter lowsrc
+    setter name
+    setter referrerPolicy
+    setter sizes
+    setter src
+    setter srcset
+    setter useMap
+    setter vspace
+    setter width
 interface ImageBitmap
     attribute @@toStringTag
     getter height
@@ -4504,7 +4546,22 @@
     setter shadowOffsetY
     setter strokeStyle
 interface Option
+    attribute @@toStringTag
+    getter defaultSelected
+    getter disabled
+    getter form
+    getter index
+    getter label
+    getter selected
+    getter text
+    getter value
     method constructor
+    setter defaultSelected
+    setter disabled
+    setter label
+    setter selected
+    setter text
+    setter value
 interface OscillatorNode : AudioScheduledSourceNode
     attribute @@toStringTag
     getter detune
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h b/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h
index baf58f6..6d86798 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h
@@ -34,6 +34,7 @@
   X(IntersectionObserver, Callback)                   \
   X(MessageEvent, CachedData)                         \
   X(MutationObserver, Callback)                       \
+  X(NamedConstructor, Initialized)                    \
   X(PerformanceObserver, Callback)                    \
   X(SameObject, NotificationActions)                  \
   X(SameObject, NotificationData)                     \
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
index 109b010..9f56eb2f 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -155,6 +155,7 @@
         'is_lenient_this': 'LenientThis' in extended_attributes,
         'is_nullable': idl_type.is_nullable,
         'is_explicit_nullable': idl_type.is_explicit_nullable,
+        'is_named_constructor': is_named_constructor_attribute(attribute),
         'is_partial_interface_member':
             'PartialInterfaceImplementedAs' in extended_attributes,
         'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
@@ -553,14 +554,16 @@
 ################################################################################
 
 idl_types.IdlType.constructor_type_name = property(
-    # FIXME: replace this with a [ConstructorAttribute] extended attribute
     lambda self: strip_suffix(self.base_type, 'Constructor'))
 
 
 def is_constructor_attribute(attribute):
-    # FIXME: replace this with [ConstructorAttribute] extended attribute
     return attribute.idl_type.name.endswith('Constructor')
 
 
+def is_named_constructor_attribute(attribute):
+    return attribute.idl_type.name.endswith('ConstructorConstructor')
+
+
 def update_constructor_attribute_context(interface, attribute, context):
     context['needs_constructor_getter_callback'] = context['measure_as'] or context['deprecate_as']
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
index 9f1c8b23..c405fb8 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -297,6 +297,8 @@
             raise Exception('[Constructor] and [NamedConstructor] MUST NOT be'
                             ' specified on partial interface definitions: '
                             '%s' % interface.name)
+        if named_constructor:
+            includes.add('bindings/core/v8/V8PrivateProperty.h')
 
         includes.add('bindings/core/v8/V8ObjectConstructor.h')
         includes.add('core/frame/LocalDOMWindow.h')
diff --git a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
index a1be921..6d4c167 100644
--- a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl
@@ -461,10 +461,12 @@
 {% macro attribute_configuration(attribute) %}
 {% from 'utilities.cpp.tmpl' import property_location %}
 {% if attribute.constructor_type %}
-{% set getter_callback =
-       '%s::%sConstructorGetterCallback' % (v8_class_or_partial, attribute.name)
-       if attribute.needs_constructor_getter_callback else
-       'v8ConstructorAttributeGetter' %}
+  {% if attribute.needs_constructor_getter_callback %}
+    {% set getter_callback = '%s::%sConstructorGetterCallback' % (v8_class_or_partial, attribute.name) %}
+  {% else %}
+    {% set getter_callback = 'V8%s::NamedConstructorAttributeGetter' % (attribute.constructor_type)
+       if attribute.is_named_constructor else 'v8ConstructorAttributeGetter' %}
+  {% endif %}
 {% set setter_callback = 'nullptr' %}
 {% else %}{# regular attributes #}
 {% set getter_callback = '%s::%sAttributeGetterCallback' %
diff --git a/third_party/WebKit/Source/bindings/templates/interface.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/interface.cpp.tmpl
index 3d037f89..99161351 100644
--- a/third_party/WebKit/Source/bindings/templates/interface.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/interface.cpp.tmpl
@@ -542,12 +542,41 @@
   result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
   v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
   instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
-  result->SetClassName(v8AtomicString(isolate, "{{cpp_class}}"));
+  result->SetClassName(v8AtomicString(isolate, "{{named_constructor.name}}"));
   result->Inherit({{v8_class}}::domTemplate(isolate, world));
   data->setInterfaceTemplate(world, &domTemplateKey, result);
   return result;
 }
 
+void {{v8_class}}Constructor::NamedConstructorAttributeGetter(
+    v8::Local<v8::Name> propertyName,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
+  V8PerContextData* perContextData = V8PerContextData::from(creationContext);
+  if (!perContextData) {
+    // TODO(yukishiino): Return a valid named constructor even after the context is detached
+    return;
+  }
+
+  v8::Local<v8::Function> namedConstructor = perContextData->constructorForType(&{{v8_class}}Constructor::wrapperTypeInfo);
+
+  // Set the prototype of named constructors to the regular constructor.
+  auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info.GetIsolate());
+  v8::Local<v8::Context> currentContext = info.GetIsolate()->GetCurrentContext();
+  v8::Local<v8::Value> privateValue = privateProperty.get(currentContext, namedConstructor);
+
+  if (privateValue.IsEmpty()) {
+    v8::Local<v8::Function> interface = perContextData->constructorForType(&{{v8_class}}::wrapperTypeInfo);
+    v8::Local<v8::Value> interfacePrototype = interface->Get(currentContext, v8AtomicString(info.GetIsolate(), "prototype")).ToLocalChecked();
+    bool result = namedConstructor->Set(currentContext, v8AtomicString(info.GetIsolate(), "prototype"), interfacePrototype).ToChecked();
+    if (!result)
+      return;
+    privateProperty.set(currentContext, namedConstructor, v8::True(info.GetIsolate()));
+  }
+
+  v8SetReturnValue(info, namedConstructor);
+}
+
 {% endif %}
 {% endblock %}
 
diff --git a/third_party/WebKit/Source/bindings/templates/interface.h.tmpl b/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
index 396a62f..f88656b1 100644
--- a/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
@@ -21,6 +21,7 @@
   STATIC_ONLY({{v8_class}}Constructor);
  public:
   static v8::Local<v8::FunctionTemplate> domTemplate(v8::Isolate*, const DOMWrapperWorld&);
+  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> propertyName, const v8::PropertyCallbackInfo<v8::Value>& info);
   {{exported}}static const WrapperTypeInfo wrapperTypeInfo;
 };
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
index 1741b13..be04ade 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
@@ -18,6 +18,7 @@
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
+#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8TestDictionary.h"
 #include "bindings/core/v8/V8TestInterfaceEmpty.h"
 #include "core/dom/Document.h"
@@ -360,12 +361,41 @@
   result = v8::FunctionTemplate::New(isolate, V8TestInterfaceConstructorConstructorCallback);
   v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
   instanceTemplate->SetInternalFieldCount(V8TestInterfaceConstructor::internalFieldCount);
-  result->SetClassName(v8AtomicString(isolate, "TestInterfaceConstructor"));
+  result->SetClassName(v8AtomicString(isolate, "Audio"));
   result->Inherit(V8TestInterfaceConstructor::domTemplate(isolate, world));
   data->setInterfaceTemplate(world, &domTemplateKey, result);
   return result;
 }
 
+void V8TestInterfaceConstructorConstructor::NamedConstructorAttributeGetter(
+    v8::Local<v8::Name> propertyName,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
+  V8PerContextData* perContextData = V8PerContextData::from(creationContext);
+  if (!perContextData) {
+    // TODO(yukishiino): Return a valid named constructor even after the context is detached
+    return;
+  }
+
+  v8::Local<v8::Function> namedConstructor = perContextData->constructorForType(&V8TestInterfaceConstructorConstructor::wrapperTypeInfo);
+
+  // Set the prototype of named constructors to the regular constructor.
+  auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info.GetIsolate());
+  v8::Local<v8::Context> currentContext = info.GetIsolate()->GetCurrentContext();
+  v8::Local<v8::Value> privateValue = privateProperty.get(currentContext, namedConstructor);
+
+  if (privateValue.IsEmpty()) {
+    v8::Local<v8::Function> interface = perContextData->constructorForType(&V8TestInterfaceConstructor::wrapperTypeInfo);
+    v8::Local<v8::Value> interfacePrototype = interface->Get(currentContext, v8AtomicString(info.GetIsolate(), "prototype")).ToLocalChecked();
+    bool result = namedConstructor->Set(currentContext, v8AtomicString(info.GetIsolate(), "prototype"), interfacePrototype).ToChecked();
+    if (!result)
+      return;
+    privateProperty.set(currentContext, namedConstructor, v8::True(info.GetIsolate()));
+  }
+
+  v8SetReturnValue(info, namedConstructor);
+}
+
 void V8TestInterfaceConstructor::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
   UseCounter::count(currentExecutionContext(info.GetIsolate()), UseCounter::TestFeature);
   if (!info.IsConstructCall()) {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
index 74bb6a4..5bf1dbd 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
@@ -30,6 +30,7 @@
   STATIC_ONLY(V8TestInterfaceConstructorConstructor);
  public:
   static v8::Local<v8::FunctionTemplate> domTemplate(v8::Isolate*, const DOMWrapperWorld&);
+  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> propertyName, const v8::PropertyCallbackInfo<v8::Value>& info);
   CORE_EXPORT static const WrapperTypeInfo wrapperTypeInfo;
 };
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
index 6d998bb..e720341c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
@@ -14,6 +14,7 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
+#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "wtf/GetPtr.h"
@@ -93,12 +94,41 @@
   result = v8::FunctionTemplate::New(isolate, V8TestInterfaceEventTargetConstructorCallback);
   v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
   instanceTemplate->SetInternalFieldCount(V8TestInterfaceEventTarget::internalFieldCount);
-  result->SetClassName(v8AtomicString(isolate, "TestInterfaceEventTarget"));
+  result->SetClassName(v8AtomicString(isolate, "Name"));
   result->Inherit(V8TestInterfaceEventTarget::domTemplate(isolate, world));
   data->setInterfaceTemplate(world, &domTemplateKey, result);
   return result;
 }
 
+void V8TestInterfaceEventTargetConstructor::NamedConstructorAttributeGetter(
+    v8::Local<v8::Name> propertyName,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
+  V8PerContextData* perContextData = V8PerContextData::from(creationContext);
+  if (!perContextData) {
+    // TODO(yukishiino): Return a valid named constructor even after the context is detached
+    return;
+  }
+
+  v8::Local<v8::Function> namedConstructor = perContextData->constructorForType(&V8TestInterfaceEventTargetConstructor::wrapperTypeInfo);
+
+  // Set the prototype of named constructors to the regular constructor.
+  auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info.GetIsolate());
+  v8::Local<v8::Context> currentContext = info.GetIsolate()->GetCurrentContext();
+  v8::Local<v8::Value> privateValue = privateProperty.get(currentContext, namedConstructor);
+
+  if (privateValue.IsEmpty()) {
+    v8::Local<v8::Function> interface = perContextData->constructorForType(&V8TestInterfaceEventTarget::wrapperTypeInfo);
+    v8::Local<v8::Value> interfacePrototype = interface->Get(currentContext, v8AtomicString(info.GetIsolate(), "prototype")).ToLocalChecked();
+    bool result = namedConstructor->Set(currentContext, v8AtomicString(info.GetIsolate(), "prototype"), interfacePrototype).ToChecked();
+    if (!result)
+      return;
+    privateProperty.set(currentContext, namedConstructor, v8::True(info.GetIsolate()));
+  }
+
+  v8SetReturnValue(info, namedConstructor);
+}
+
 static void installV8TestInterfaceEventTargetTemplate(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interfaceTemplate) {
   // Initialize the interface object's template.
   V8DOMConfiguration::initializeDOMInterfaceTemplate(isolate, interfaceTemplate, V8TestInterfaceEventTarget::wrapperTypeInfo.interfaceName, V8EventTarget::domTemplate(isolate, world), V8TestInterfaceEventTarget::internalFieldCount);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
index 2b76fb3..7adf54e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
@@ -30,6 +30,7 @@
   STATIC_ONLY(V8TestInterfaceEventTargetConstructor);
  public:
   static v8::Local<v8::FunctionTemplate> domTemplate(v8::Isolate*, const DOMWrapperWorld&);
+  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> propertyName, const v8::PropertyCallbackInfo<v8::Value>& info);
   CORE_EXPORT static const WrapperTypeInfo wrapperTypeInfo;
 };
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
index 795a36a..a7ac9d1 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
@@ -16,6 +16,7 @@
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
+#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "wtf/GetPtr.h"
@@ -63,7 +64,7 @@
 #pragma clang diagnostic ignored "-Wglobal-constructors"
 #endif
 const V8DOMConfiguration::AttributeConfiguration V8TestInterfaceNamedConstructorLazyDataAttributes[] = {
-    {"testNamedConstructorConstructorAttribute", v8ConstructorAttributeGetter, nullptr, nullptr, nullptr, nullptr, const_cast<WrapperTypeInfo*>(&V8TestNamedConstructor::wrapperTypeInfo), static_cast<v8::PropertyAttribute>(v8::DontEnum), V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"testNamedConstructorConstructorAttribute", V8TestNamedConstructor::NamedConstructorAttributeGetter, nullptr, nullptr, nullptr, nullptr, const_cast<WrapperTypeInfo*>(&V8TestNamedConstructor::wrapperTypeInfo), static_cast<v8::PropertyAttribute>(v8::DontEnum), V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
 };
 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
 #pragma clang diagnostic pop
@@ -168,12 +169,41 @@
   result = v8::FunctionTemplate::New(isolate, V8TestInterfaceNamedConstructorConstructorCallback);
   v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
   instanceTemplate->SetInternalFieldCount(V8TestInterfaceNamedConstructor::internalFieldCount);
-  result->SetClassName(v8AtomicString(isolate, "TestInterfaceNamedConstructor"));
+  result->SetClassName(v8AtomicString(isolate, "Audio"));
   result->Inherit(V8TestInterfaceNamedConstructor::domTemplate(isolate, world));
   data->setInterfaceTemplate(world, &domTemplateKey, result);
   return result;
 }
 
+void V8TestInterfaceNamedConstructorConstructor::NamedConstructorAttributeGetter(
+    v8::Local<v8::Name> propertyName,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
+  V8PerContextData* perContextData = V8PerContextData::from(creationContext);
+  if (!perContextData) {
+    // TODO(yukishiino): Return a valid named constructor even after the context is detached
+    return;
+  }
+
+  v8::Local<v8::Function> namedConstructor = perContextData->constructorForType(&V8TestInterfaceNamedConstructorConstructor::wrapperTypeInfo);
+
+  // Set the prototype of named constructors to the regular constructor.
+  auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info.GetIsolate());
+  v8::Local<v8::Context> currentContext = info.GetIsolate()->GetCurrentContext();
+  v8::Local<v8::Value> privateValue = privateProperty.get(currentContext, namedConstructor);
+
+  if (privateValue.IsEmpty()) {
+    v8::Local<v8::Function> interface = perContextData->constructorForType(&V8TestInterfaceNamedConstructor::wrapperTypeInfo);
+    v8::Local<v8::Value> interfacePrototype = interface->Get(currentContext, v8AtomicString(info.GetIsolate(), "prototype")).ToLocalChecked();
+    bool result = namedConstructor->Set(currentContext, v8AtomicString(info.GetIsolate(), "prototype"), interfacePrototype).ToChecked();
+    if (!result)
+      return;
+    privateProperty.set(currentContext, namedConstructor, v8::True(info.GetIsolate()));
+  }
+
+  v8SetReturnValue(info, namedConstructor);
+}
+
 static void installV8TestInterfaceNamedConstructorTemplate(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interfaceTemplate) {
   // Initialize the interface object's template.
   V8DOMConfiguration::initializeDOMInterfaceTemplate(isolate, interfaceTemplate, V8TestInterfaceNamedConstructor::wrapperTypeInfo.interfaceName, v8::Local<v8::FunctionTemplate>(), V8TestInterfaceNamedConstructor::internalFieldCount);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
index 0f04428..dc6fd8b 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
@@ -29,6 +29,7 @@
   STATIC_ONLY(V8TestInterfaceNamedConstructorConstructor);
  public:
   static v8::Local<v8::FunctionTemplate> domTemplate(v8::Isolate*, const DOMWrapperWorld&);
+  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> propertyName, const v8::PropertyCallbackInfo<v8::Value>& info);
   CORE_EXPORT static const WrapperTypeInfo wrapperTypeInfo;
 };
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
index 5938d94..e230dd3f 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
@@ -16,6 +16,7 @@
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
+#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "wtf/GetPtr.h"
@@ -104,12 +105,41 @@
   result = v8::FunctionTemplate::New(isolate, V8TestInterfaceNamedConstructor2ConstructorCallback);
   v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
   instanceTemplate->SetInternalFieldCount(V8TestInterfaceNamedConstructor2::internalFieldCount);
-  result->SetClassName(v8AtomicString(isolate, "TestInterfaceNamedConstructor2"));
+  result->SetClassName(v8AtomicString(isolate, "Audio"));
   result->Inherit(V8TestInterfaceNamedConstructor2::domTemplate(isolate, world));
   data->setInterfaceTemplate(world, &domTemplateKey, result);
   return result;
 }
 
+void V8TestInterfaceNamedConstructor2Constructor::NamedConstructorAttributeGetter(
+    v8::Local<v8::Name> propertyName,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
+  V8PerContextData* perContextData = V8PerContextData::from(creationContext);
+  if (!perContextData) {
+    // TODO(yukishiino): Return a valid named constructor even after the context is detached
+    return;
+  }
+
+  v8::Local<v8::Function> namedConstructor = perContextData->constructorForType(&V8TestInterfaceNamedConstructor2Constructor::wrapperTypeInfo);
+
+  // Set the prototype of named constructors to the regular constructor.
+  auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info.GetIsolate());
+  v8::Local<v8::Context> currentContext = info.GetIsolate()->GetCurrentContext();
+  v8::Local<v8::Value> privateValue = privateProperty.get(currentContext, namedConstructor);
+
+  if (privateValue.IsEmpty()) {
+    v8::Local<v8::Function> interface = perContextData->constructorForType(&V8TestInterfaceNamedConstructor2::wrapperTypeInfo);
+    v8::Local<v8::Value> interfacePrototype = interface->Get(currentContext, v8AtomicString(info.GetIsolate(), "prototype")).ToLocalChecked();
+    bool result = namedConstructor->Set(currentContext, v8AtomicString(info.GetIsolate(), "prototype"), interfacePrototype).ToChecked();
+    if (!result)
+      return;
+    privateProperty.set(currentContext, namedConstructor, v8::True(info.GetIsolate()));
+  }
+
+  v8SetReturnValue(info, namedConstructor);
+}
+
 static void installV8TestInterfaceNamedConstructor2Template(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interfaceTemplate) {
   // Initialize the interface object's template.
   V8DOMConfiguration::initializeDOMInterfaceTemplate(isolate, interfaceTemplate, V8TestInterfaceNamedConstructor2::wrapperTypeInfo.interfaceName, v8::Local<v8::FunctionTemplate>(), V8TestInterfaceNamedConstructor2::internalFieldCount);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
index e0971555..1b0a014 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
@@ -29,6 +29,7 @@
   STATIC_ONLY(V8TestInterfaceNamedConstructor2Constructor);
  public:
   static v8::Local<v8::FunctionTemplate> domTemplate(v8::Isolate*, const DOMWrapperWorld&);
+  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> propertyName, const v8::PropertyCallbackInfo<v8::Value>& info);
   CORE_EXPORT static const WrapperTypeInfo wrapperTypeInfo;
 };
 
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index 478c8b7..8aa2e61d 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -2077,7 +2077,7 @@
     return "";
   Element* formatBlockElement =
       FormatBlockCommand::elementForFormatBlockCommand(
-          createRange(firstEphemeralRangeOf(selection)));
+          firstEphemeralRangeOf(selection));
   if (!formatBlockElement)
     return "";
   return formatBlockElement->localName();
diff --git a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp
index e85532b..ef9aa38 100644
--- a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.cpp
@@ -139,18 +139,17 @@
     insertBlockPlaceholder(lastParagraphInBlockNode, editingState);
 }
 
-Element* FormatBlockCommand::elementForFormatBlockCommand(Range* range) {
-  if (!range)
-    return 0;
-
-  Node* commonAncestor = range->commonAncestorContainer();
+Element* FormatBlockCommand::elementForFormatBlockCommand(
+    const EphemeralRange& range) {
+  Node* commonAncestor = range.commonAncestorContainer();
   while (commonAncestor && !isElementForFormatBlock(commonAncestor))
     commonAncestor = commonAncestor->parentNode();
 
   if (!commonAncestor)
     return 0;
 
-  Element* element = rootEditableElement(*range->startContainer());
+  Element* element =
+      rootEditableElement(*range.startPosition().computeContainerNode());
   if (!element || commonAncestor->contains(element))
     return 0;
 
diff --git a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.h b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.h
index b069081..0ac8aca 100644
--- a/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.h
+++ b/third_party/WebKit/Source/core/editing/commands/FormatBlockCommand.h
@@ -27,6 +27,7 @@
 #define FormatBlockCommand_h
 
 #include "core/dom/QualifiedName.h"
+#include "core/editing/EphemeralRange.h"
 #include "core/editing/Position.h"
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/commands/ApplyBlockElementCommand.h"
@@ -35,7 +36,6 @@
 
 class Document;
 class Element;
-class Range;
 
 class CORE_EXPORT FormatBlockCommand final : public ApplyBlockElementCommand {
  public:
@@ -46,7 +46,7 @@
 
   bool preservesTypingStyle() const override { return true; }
 
-  static Element* elementForFormatBlockCommand(Range*);
+  static Element* elementForFormatBlockCommand(const EphemeralRange&);
   bool didApply() const { return m_didApply; }
 
  private:
diff --git a/third_party/WebKit/Source/core/frame/FrameHost.cpp b/third_party/WebKit/Source/core/frame/FrameHost.cpp
index 0af55d1..ce9e70d2 100644
--- a/third_party/WebKit/Source/core/frame/FrameHost.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameHost.cpp
@@ -30,7 +30,6 @@
 
 #include "core/frame/FrameHost.h"
 
-#include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/VisualViewport.h"
 #include "core/inspector/ConsoleMessageStorage.h"
@@ -52,7 +51,6 @@
       m_overscrollController(
           OverscrollController::create(*m_visualViewport,
                                        m_page->chromeClient())),
-      m_eventHandlerRegistry(new EventHandlerRegistry(page)),
       m_consoleMessageStorage(new ConsoleMessageStorage()),
       m_globalRootScrollerController(
           TopDocumentRootScrollerController::create(*this)),
@@ -94,11 +92,11 @@
 }
 
 EventHandlerRegistry& FrameHost::eventHandlerRegistry() {
-  return *m_eventHandlerRegistry;
+  return page().eventHandlerRegistry();
 }
 
 const EventHandlerRegistry& FrameHost::eventHandlerRegistry() const {
-  return *m_eventHandlerRegistry;
+  return page().eventHandlerRegistry();
 }
 
 ConsoleMessageStorage& FrameHost::consoleMessageStorage() {
@@ -118,7 +116,6 @@
   visitor->trace(m_page);
   visitor->trace(m_visualViewport);
   visitor->trace(m_overscrollController);
-  visitor->trace(m_eventHandlerRegistry);
   visitor->trace(m_consoleMessageStorage);
   visitor->trace(m_globalRootScrollerController);
 }
diff --git a/third_party/WebKit/Source/core/frame/FrameHost.h b/third_party/WebKit/Source/core/frame/FrameHost.h
index cdefcf1..fb17cc01 100644
--- a/third_party/WebKit/Source/core/frame/FrameHost.h
+++ b/third_party/WebKit/Source/core/frame/FrameHost.h
@@ -106,12 +106,10 @@
   const Member<Page> m_page;
   const Member<VisualViewport> m_visualViewport;
   const Member<OverscrollController> m_overscrollController;
-  const Member<EventHandlerRegistry> m_eventHandlerRegistry;
   const Member<ConsoleMessageStorage> m_consoleMessageStorage;
   const Member<TopDocumentRootScrollerController>
       m_globalRootScrollerController;
 
-  AtomicString m_overrideEncoding;
   int m_subframeCount;
 };
 
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp
index 65140b7..0aa6889 100644
--- a/third_party/WebKit/Source/core/page/Page.cpp
+++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -32,6 +32,7 @@
 #include "core/events/Event.h"
 #include "core/frame/BrowserControls.h"
 #include "core/frame/DOMTimer.h"
+#include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
@@ -105,6 +106,7 @@
       m_pageScaleConstraintsSet(PageScaleConstraintsSet::create()),
       m_pointerLockController(PointerLockController::create(this)),
       m_browserControls(BrowserControls::create(*this)),
+      m_eventHandlerRegistry(new EventHandlerRegistry(*this)),
       m_mainFrame(nullptr),
       m_editorClient(pageClients.editorClient),
       m_spellCheckerClient(pageClients.spellCheckerClient),
@@ -171,6 +173,14 @@
   return *m_browserControls;
 }
 
+EventHandlerRegistry& Page::eventHandlerRegistry() {
+  return *m_eventHandlerRegistry;
+}
+
+const EventHandlerRegistry& Page::eventHandlerRegistry() const {
+  return *m_eventHandlerRegistry;
+}
+
 ClientRectList* Page::nonFastScrollableRects(const LocalFrame* frame) {
   DisableCompositingQueryAsserts disabler;
   if (ScrollingCoordinator* scrollingCoordinator =
@@ -550,6 +560,7 @@
   visitor->trace(m_pointerLockController);
   visitor->trace(m_scrollingCoordinator);
   visitor->trace(m_browserControls);
+  visitor->trace(m_eventHandlerRegistry);
   visitor->trace(m_mainFrame);
   visitor->trace(m_validationMessageClient);
   visitor->trace(m_useCounter);
diff --git a/third_party/WebKit/Source/core/page/Page.h b/third_party/WebKit/Source/core/page/Page.h
index ac118b6..738c031e 100644
--- a/third_party/WebKit/Source/core/page/Page.h
+++ b/third_party/WebKit/Source/core/page/Page.h
@@ -56,6 +56,7 @@
 class DragCaret;
 class DragController;
 class EditorClient;
+class EventHandlerRegistry;
 class FocusController;
 class Frame;
 class FrameHost;
@@ -189,6 +190,9 @@
   BrowserControls& browserControls();
   const BrowserControls& browserControls() const;
 
+  EventHandlerRegistry& eventHandlerRegistry();
+  const EventHandlerRegistry& eventHandlerRegistry() const;
+
   void setTabKeyCyclesThroughElements(bool b) {
     m_tabKeyCyclesThroughElements = b;
   }
@@ -275,6 +279,7 @@
   const Member<PointerLockController> m_pointerLockController;
   Member<ScrollingCoordinator> m_scrollingCoordinator;
   const Member<BrowserControls> m_browserControls;
+  const Member<EventHandlerRegistry> m_eventHandlerRegistry;
 
   // Typically, the main frame and Page should both be owned by the embedder,
   // which must call Page::willBeDestroyed() prior to destroying Page. This
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
index de39a5d4..bf339c7 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -235,23 +235,27 @@
 
 void PrePaintTreeWalk::walk(const LayoutObject& object,
                             const PrePaintTreeWalkContext& parentContext) {
-  PrePaintTreeWalkContext context(parentContext);
-
   if (shouldEndWalkBefore(object, parentContext))
     return;
 
+  // PrePaintTreeWalkContext is large and can lead to stack overflows when
+  // recursion is deep so this context object is allocated on the heap.
+  // See: https://crbug.com/698653.
+  std::unique_ptr<PrePaintTreeWalkContext> context =
+      WTF::wrapUnique(new PrePaintTreeWalkContext(parentContext));
+
   // This must happen before updatePropertiesForSelf, because the latter reads
   // some of the state computed here.
-  updateAuxiliaryObjectProperties(object, context);
+  updateAuxiliaryObjectProperties(object, *context);
 
   m_propertyTreeBuilder.updatePropertiesForSelf(object,
-                                                context.treeBuilderContext);
+                                                context->treeBuilderContext);
   m_paintInvalidator.invalidatePaintIfNeeded(object,
-                                             context.paintInvalidatorContext);
-  m_propertyTreeBuilder.updatePropertiesForChildren(object,
-                                                    context.treeBuilderContext);
+                                             context->paintInvalidatorContext);
+  m_propertyTreeBuilder.updatePropertiesForChildren(
+      object, context->treeBuilderContext);
 
-  invalidatePaintLayerOptimizationsIfNeeded(object, context);
+  invalidatePaintLayerOptimizationsIfNeeded(object, *context);
 
   for (const LayoutObject* child = object.slowFirstChild(); child;
        child = child->nextSibling()) {
@@ -259,19 +263,19 @@
       child->getMutableForPainting().clearPaintFlags();
       continue;
     }
-    walk(*child, context);
+    walk(*child, *context);
   }
 
   if (object.isLayoutPart()) {
     const LayoutPart& layoutPart = toLayoutPart(object);
     FrameViewBase* frameViewBase = layoutPart.frameViewBase();
     if (frameViewBase && frameViewBase->isFrameView()) {
-      context.treeBuilderContext.current.paintOffset +=
+      context->treeBuilderContext.current.paintOffset +=
           layoutPart.replacedContentRect().location() -
           frameViewBase->frameRect().location();
-      context.treeBuilderContext.current.paintOffset =
-          roundedIntPoint(context.treeBuilderContext.current.paintOffset);
-      walk(*toFrameView(frameViewBase), context);
+      context->treeBuilderContext.current.paintOffset =
+          roundedIntPoint(context->treeBuilderContext.current.paintOffset);
+      walk(*toFrameView(frameViewBase), *context);
     }
     // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
   }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc b/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc
index 2465b0f..b46e2bf 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc
@@ -203,7 +203,15 @@
 inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
 
 # Good variable names which should always be accepted, separated by a comma.
-good-names=i,j,k,ex,Run,_,_log
+# These short names are acceptable in the following cases:
+#  _        - unused value
+#  i/j/k    - for XXX in range():
+#  k/v      - for k, v in x.items():
+#  x/y/z    - coordinates
+#  e        - except XXXError as e:
+#  f/fd     - with open('blah') as f:
+#  _log/Run - webkitpy functions
+good-names=_,i,j,k,v,x,y,z,e,f,fd,_log,Run
 
 # Bad variable names which should always be refused, separated by a comma.
 bad-names=foo,bar,baz,toto,tutu,tata
diff --git a/third_party/closure_compiler/compiled_resources.gyp b/third_party/closure_compiler/compiled_resources.gyp
index e58b09af..f1cdce1 100644
--- a/third_party/closure_compiler/compiled_resources.gyp
+++ b/third_party/closure_compiler/compiled_resources.gyp
@@ -28,7 +28,6 @@
         '../../chrome/browser/resources/ntp4/compiled_resources.gyp:*',
         # '../../remoting/remoting_webapp_compile.gypi:*',
         '../../ui/file_manager/file_manager/foreground/js/compiled_resources.gyp:*',
-        '../../ui/file_manager/gallery/js/compiled_resources.gyp:*',
       ],
     },
   ]
diff --git a/tools/md_browser/.gitignore b/tools/md_browser/.gitignore
new file mode 100644
index 0000000..0d20b648
--- /dev/null
+++ b/tools/md_browser/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index bdbb9a92..87f6a354 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -28130,6 +28130,23 @@
   <summary>The renderer process's memory usage after a page load.</summary>
 </histogram>
 
+<histogram name="Memory.Experimental.Renderer.LoadsInMainFrameDuringUptime"
+    units="loads">
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    The number of loads in a main frame during the lifetime of a render process
+    (excludes extensions). Emitted when the processes quits.
+  </summary>
+</histogram>
+
+<histogram name="Memory.Experimental.Renderer.Uptime" units="ms">
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    The uptime of a render process in time ticks (excludes extensions). Emitted
+    when the processes quits.
+  </summary>
+</histogram>
+
 <histogram name="Memory.Extension" units="KB">
   <owner>hajimehoshi@chromium.org</owner>
   <owner>kenjibaheux@google.com</owner>
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc
index 730535d..0891e38 100644
--- a/ui/app_list/app_list_constants.cc
+++ b/ui/app_list/app_list_constants.cc
@@ -154,27 +154,27 @@
 
   switch (z_height) {
     case 1:
-      return gfx::ShadowValue(gfx::Vector2d(0, 1), 2,
+      return gfx::ShadowValue(gfx::Vector2d(0, 1), 4,
                               SkColorSetARGB(0x4C, 0, 0, 0));
     case 2:
-      return gfx::ShadowValue(gfx::Vector2d(0, 2), 4,
+      return gfx::ShadowValue(gfx::Vector2d(0, 2), 8,
                               SkColorSetARGB(0x33, 0, 0, 0));
     default:
-      return gfx::ShadowValue(gfx::Vector2d(0, 8), 12,
+      return gfx::ShadowValue(gfx::Vector2d(0, 8), 24,
                               SkColorSetARGB(0x3F, 0, 0, 0));
   }
 }
 
 const gfx::ShadowValues& IconStartShadows() {
   CR_DEFINE_STATIC_LOCAL(const gfx::ShadowValues, icon_shadows,
-                         (1, gfx::ShadowValue(gfx::Vector2d(0, 1), 2,
+                         (1, gfx::ShadowValue(gfx::Vector2d(0, 1), 4,
                                               SkColorSetARGB(0x33, 0, 0, 0))));
   return icon_shadows;
 }
 
 const gfx::ShadowValues& IconEndShadows() {
   CR_DEFINE_STATIC_LOCAL(const gfx::ShadowValues, icon_shadows,
-                         (1, gfx::ShadowValue(gfx::Vector2d(0, 4), 4,
+                         (1, gfx::ShadowValue(gfx::Vector2d(0, 4), 8,
                                               SkColorSetARGB(0x50, 0, 0, 0))));
   return icon_shadows;
 }
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 40a77de4..481b0394 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -46,13 +46,16 @@
 
 namespace aura {
 
-Window::Window(WindowDelegate* delegate) : Window(delegate, nullptr) {}
+Window::Window(WindowDelegate* delegate, ui::wm::WindowType type)
+    : Window(delegate, nullptr, type) {}
 
-Window::Window(WindowDelegate* delegate, std::unique_ptr<WindowPort> port)
+Window::Window(WindowDelegate* delegate,
+               std::unique_ptr<WindowPort> port,
+               ui::wm::WindowType type)
     : port_owner_(std::move(port)),
       port_(port_owner_.get()),
       host_(nullptr),
-      type_(ui::wm::WINDOW_TYPE_UNKNOWN),
+      type_(type),
       owned_by_parent_(true),
       delegate_(delegate),
       parent_(nullptr),
diff --git a/ui/aura/window.h b/ui/aura/window.h
index 313ea888..f0581827 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -80,8 +80,11 @@
 
   typedef std::vector<Window*> Windows;
 
-  explicit Window(WindowDelegate* delegate);
-  Window(WindowDelegate* delegate, std::unique_ptr<WindowPort> port);
+  explicit Window(WindowDelegate* delegate,
+                  ui::wm::WindowType type = ui::wm::WINDOW_TYPE_UNKNOWN);
+  Window(WindowDelegate* delegate,
+         std::unique_ptr<WindowPort> port,
+         ui::wm::WindowType type = ui::wm::WINDOW_TYPE_UNKNOWN);
   ~Window() override;
 
   // Initializes the window. This creates the window's layer.
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp
index a4cc5dc..2ff25d7 100644
--- a/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp
+++ b/ui/file_manager/file_manager/foreground/js/compiled_resources2.gyp
@@ -167,10 +167,21 @@
 #      'target_name': 'search_controller',
 #      'includes': ['../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'share_client',
-#      'includes': ['../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'share_client',
+      'dependencies': [
+        '../../../externs/compiled_resources2.gyp:entry_location',
+        '../../../externs/compiled_resources2.gyp:gallery_foreground',
+        '../../../externs/compiled_resources2.gyp:volume_info',
+        '../../../externs/compiled_resources2.gyp:volume_info_list',
+        '../../../externs/compiled_resources2.gyp:volume_manager',
+        '../../../externs/compiled_resources2.gyp:webview_tag',
+        '../../common/js/compiled_resources2.gyp:volume_manager_common',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target',
+        '<(EXTERNS_GYP):chrome_extensions',
+      ],
+      'includes': ['../../../compile_js2.gypi'],
+    },
 #    {
 #      'target_name': 'sort_menu_controller',
 #      'includes': ['../../../compile_js2.gypi'],
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 45251ce..f17131c 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -879,9 +879,6 @@
     var dom = this.dialogDom_;
     assert(dom);
 
-    // Initialize the dialog.
-    FileManagerDialogBase.setFileManager(this);
-
     var table = queryRequiredElement('.detail-table', dom);
     FileTable.decorate(
         table,
diff --git a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
index 3cdceed..12aee82 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
+++ b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
@@ -51,10 +51,16 @@
 #      'target_name': 'file_list_selection_model',
 #      'includes': ['../../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'file_manager_dialog_base',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'file_manager_dialog_base',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:dialogs',
+        '<(EXTERNS_GYP):chrome_extensions',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
 #    {
 #      'target_name': 'file_manager_ui',
 #      'includes': ['../../../../compile_js2.gypi'],
@@ -78,10 +84,15 @@
       ],
       'includes': ['../../../../compile_js2.gypi'],
     },
-#    {
-#      'target_name': 'files_confirm_dialog',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'files_confirm_dialog',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:dialogs',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
 #    {
 #      'target_name': 'files_menu',
 #      'includes': ['../../../../compile_js2.gypi'],
@@ -118,10 +129,17 @@
 #      'target_name': 'search_box',
 #      'includes': ['../../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'share_dialog',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'share_dialog',
+      'dependencies': [
+        '../../../common/js/compiled_resources2.gyp:async_util',
+        '../../../common/js/compiled_resources2.gyp:util',
+        '../compiled_resources2.gyp:share_client',
+        '<(EXTERNS_GYP):file_manager_private',
+        'file_manager_dialog_base',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
 #    {
 #      'target_name': 'suggest_apps_dialog',
 #      'includes': ['../../../../compile_js2.gypi'],
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
index 2d5ec04..9e9a38f0 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
@@ -18,23 +18,6 @@
 };
 
 /**
- * The FileManager object. This is used to notify events of showing or hiding
- * dialog to file manager.
- *
- * @type {FileManager}
- * @private
- */
-FileManagerDialogBase.fileManager_ = null;
-
-/**
- * Setter of FileManagerDialogBase.fileManager_.
- * @param {FileManager} fileManager The fileManager object.
- */
-FileManagerDialogBase.setFileManager = function(fileManager) {
-  FileManagerDialogBase.fileManager_ = fileManager;
-};
-
-/**
  * The flag if any dialog is shown. True if a dialog is visible, false
  *     otherwise.
  * @type {boolean}
diff --git a/ui/file_manager/gallery/js/compiled_resources.gyp b/ui/file_manager/gallery/js/compiled_resources.gyp
deleted file mode 100644
index 954ccbbd..0000000
--- a/ui/file_manager/gallery/js/compiled_resources.gyp
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'targets': [
-    {
-      'target_name': 'background',
-      'variables': {
-        'depends': [
-          '../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
-          '../../../webui/resources/js/cr.js',
-          '../../../webui/resources/js/cr/event_target.js',
-          '../../../webui/resources/js/cr/ui.js',
-          '../../../webui/resources/js/cr/ui/array_data_model.js',
-          '../../../webui/resources/js/load_time_data.js',
-          '../../../webui/resources/js/promise_resolver.js',
-          '../../../webui/resources/js/util.js',
-          '../../file_manager/common/js/util.js',
-          '../../file_manager/common/js/async_util.js',
-          '../../file_manager/common/js/volume_manager_common.js',
-          '../../file_manager/common/js/error_util.js',
-          '../../file_manager/common/js/file_type.js',
-          '../../file_manager/common/js/metrics_base.js',
-          '../../file_manager/common/js/metrics_events.js',
-          '../../file_manager/common/js/metrics.js',
-          '../../file_manager/background/js/app_window_wrapper.js',
-          '../../file_manager/background/js/app_windows.js',
-          '../../file_manager/background/js/background_base.js',
-          '../../file_manager/background/js/entry_location_impl.js',
-          '../../file_manager/background/js/volume_info_impl.js',
-          '../../file_manager/background/js/volume_info_list_impl.js',
-          '../../file_manager/background/js/volume_manager_factory.js',
-          '../../file_manager/background/js/volume_manager_impl.js',
-          '../../file_manager/background/js/volume_manager_util.js',
-        ],
-        'externs': [
-          '<(EXTERNS_DIR)/chrome_extensions.js',
-          '<(EXTERNS_DIR)/chrome_send.js',
-          '<(EXTERNS_DIR)/file_manager_private.js',
-          '<(EXTERNS_DIR)/metrics_private.js',
-          '../../../../third_party/analytics/externs.js',
-          '../../externs/app_window_common.js',
-          '../../externs/chrome_test.js',
-          '../../externs/entry_location.js',
-          '../../externs/es6_workaround.js',
-          '../../externs/gallery_background.js',
-          '../../externs/platform.js',
-          '../../externs/volume_info.js',
-          '../../externs/volume_info_list.js',
-          '../../externs/volume_manager.js',
-        ],
-      },
-      'includes': [
-        '../../compile_js.gypi',
-      ],
-    },
-    {
-      'target_name': 'gallery',
-      'variables': {
-        'depends': [
-          '../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-checked-element-behavior/iron-checked-element-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-checked-element-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-ripple-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-input/paper-input-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-progress/paper-progress-extracted.js',
-          '../../../../third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js',
-          '../../../webui/resources/js/promise_resolver.js',
-          '../../../webui/resources/js/util.js',
-          '../../../webui/resources/js/event_tracker.js',
-          '../../../webui/resources/js/load_time_data.js',
-          '../../../webui/resources/js/cr.js',
-          '../../../webui/resources/js/cr/ui.js',
-          '../../../webui/resources/js/cr/event_target.js',
-          '../../../webui/resources/js/cr/ui/touch_handler.js',
-          '../../../webui/resources/js/cr/ui/array_data_model.js',
-          '../../../webui/resources/js/cr/ui/dialogs.js',
-          '../../../webui/resources/js/cr/ui/list_item.js',
-          '../../../webui/resources/js/cr/ui/list_selection_model.js',
-          '../../../webui/resources/js/cr/ui/list_single_selection_model.js',
-          '../../../webui/resources/js/cr/ui/list_selection_controller.js',
-          '../../../webui/resources/js/cr/ui/list.js',
-          '../../../webui/resources/js/cr/ui/grid.js',
-          '../../../webui/resources/js/compiled_resources.gyp:i18n_template_no_process',
-          '../../file_manager/common/js/volume_manager_common.js',
-          '../../file_manager/common/js/lru_cache.js',
-          '../../file_manager/common/js/async_util.js',
-          '../../file_manager/common/js/file_type.js',
-          '../../file_manager/common/js/util.js',
-          '../../file_manager/common/js/metrics_base.js',
-          '../../file_manager/common/js/metrics_events.js',
-          '../../file_manager/common/js/metrics.js',
-          '../../file_manager/foreground/elements/files_tooltip.js',
-          '../../file_manager/foreground/js/metrics_start.js',
-          '../../file_manager/foreground/js/metadata/content_metadata_provider.js',
-          '../../file_manager/foreground/js/metadata/exif_constants.js',
-          '../../file_manager/foreground/js/metadata/external_metadata_provider.js',
-          '../../file_manager/foreground/js/metadata/file_system_metadata_provider.js',
-          '../../file_manager/foreground/js/metadata/metadata_cache_item.js',
-          '../../file_manager/foreground/js/metadata/metadata_cache_set.js',
-          '../../file_manager/foreground/js/metadata/metadata_item.js',
-          '../../file_manager/foreground/js/metadata/metadata_model.js',
-          '../../file_manager/foreground/js/metadata/metadata_provider.js',
-          '../../file_manager/foreground/js/metadata/metadata_request.js',
-          '../../file_manager/foreground/js/metadata/multi_metadata_provider.js',
-          '../../file_manager/foreground/js/metadata/thumbnail_model.js',
-          '../../file_manager/foreground/js/share_client.js',
-          '../../file_manager/foreground/js/thumbnail_loader.js',
-          '../../file_manager/foreground/js/ui/file_manager_dialog_base.js',
-          '../../file_manager/foreground/js/ui/files_alert_dialog.js',
-          '../../file_manager/foreground/js/ui/files_confirm_dialog.js',
-          '../../file_manager/foreground/js/ui/share_dialog.js',
-          '../../file_manager/foreground/js/volume_manager_wrapper.js',
-          '../../image_loader/image_loader_client.js',
-          './image_editor/image_util.js',
-          './image_editor/image_loader.js',
-          './image_editor/viewport.js',
-          './image_editor/image_buffer.js',
-          './image_editor/image_view.js',
-          './image_editor/commands.js',
-          './image_editor/image_editor_mode.js',
-          './image_editor/image_editor_toolbar.js',
-          './image_editor/image_editor.js',
-          './image_editor/image_editor_prompt.js',
-          './image_editor/image_transform.js',
-          './image_editor/image_adjust.js',
-          './image_editor/image_resize.js',
-          './image_editor/filter.js',
-          './image_editor/image_encoder.js',
-          './image_editor/exif_encoder.js',
-          './gallery_constants.js',
-          './dimmable_ui_controller.js',
-          './entry_list_watcher.js',
-          './error_banner.js',
-          './gallery_data_model.js',
-          './gallery_item.js',
-          './gallery_util.js',
-          './ribbon.js',
-          './slide_mode.js',
-          './thumbnail_mode.js',
-        ],
-        'externs': [
-          '<(EXTERNS_DIR)/chrome_extensions.js',
-          '<(EXTERNS_DIR)/chrome_send.js',
-          '<(EXTERNS_DIR)/file_manager_private.js',
-          '<(EXTERNS_DIR)/metrics_private.js',
-          '<(EXTERNS_DIR)/web_animations.js',
-          '../../../../third_party/analytics/externs.js',
-          '../../../../third_party/closure_compiler/externs/polymer-1.0.js',
-          '../../externs/app_window_common.js',
-          '../../externs/background_window_common.js',
-          '../../externs/chrome_test.js',
-          '../../externs/entry_location.js',
-          '../../externs/es6_workaround.js',
-          '../../externs/exif_entry.js',
-          '../../externs/files_elements.js',
-          '../../externs/gallery_foreground.js',
-          '../../externs/paper_elements.js',
-          '../../externs/platform.js',
-          '../../externs/volume_info.js',
-          '../../externs/volume_info_list.js',
-          '../../externs/volume_manager.js',
-          '../../externs/webview_tag.js',
-        ],
-      },
-      'includes': [
-        '../../compile_js.gypi',
-      ],
-    }
-  ],
-}
diff --git a/ui/file_manager/gallery/js/compiled_resources2.gyp b/ui/file_manager/gallery/js/compiled_resources2.gyp
index 36700b60..1a4be4c 100644
--- a/ui/file_manager/gallery/js/compiled_resources2.gyp
+++ b/ui/file_manager/gallery/js/compiled_resources2.gyp
@@ -1,13 +1,17 @@
 # Copyright 2016 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-# TODO(oka): Compile all the targets.
 {
   'targets': [
-#    {
-#      'target_name': 'background',
-#      'includes': ['../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'background',
+      'dependencies': [
+        '../../file_manager/background/js/compiled_resources2.gyp:app_window_wrapper',
+        '../../file_manager/background/js/compiled_resources2.gyp:background_base',
+        '../../file_manager/common/js/compiled_resources2.gyp:util',
+      ],
+      'includes': ['../../compile_js2.gypi'],
+    },
     {
       'target_name': 'dimmable_ui_controller',
       'dependencies': [
@@ -35,10 +39,22 @@
       ],
       'includes': ['../../compile_js2.gypi'],
     },
-#    {
-#      'target_name': 'gallery',
-#      'includes': ['../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'gallery',
+      'dependencies': [
+        '../../externs/compiled_resources2.gyp:volume_manager',
+        '../../file_manager/common/js/compiled_resources2.gyp:util',
+        '../../file_manager/foreground/js/compiled_resources2.gyp:volume_manager_wrapper',
+        '../../file_manager/foreground/js/ui/compiled_resources2.gyp:files_confirm_dialog',
+        '../../file_manager/foreground/js/ui/compiled_resources2.gyp:share_dialog',
+        '../../gallery/js/compiled_resources2.gyp:slide_mode',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_template_no_process',
+        'gallery_constants',
+        'gallery_item',
+        'thumbnail_mode',
+      ],
+      'includes': ['../../compile_js2.gypi'],
+    },
     {
       'target_name': 'gallery_constants',
       'includes': ['../../compile_js2.gypi'],
@@ -68,10 +84,6 @@
       ],
       'includes': ['../../compile_js2.gypi'],
     },
-#    {
-#      'target_name': 'gallery_scripts',
-#      'includes': ['../../compile_js2.gypi'],
-#    },
     {
       'target_name': 'gallery_util',
       'dependencies': [
diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc
index f469b3c8..f48d2e1b9 100644
--- a/ui/gfx/image/image_skia_operations.cc
+++ b/ui/gfx/image/image_skia_operations.cc
@@ -410,7 +410,7 @@
   // CanvasImageSource overrides:
   void Draw(Canvas* canvas) override {
     cc::PaintFlags flags;
-    flags.setLooper(CreateShadowDrawLooperCorrectBlur(shadows_));
+    flags.setLooper(CreateShadowDrawLooper(shadows_));
     canvas->DrawRect(RectF(0, fades_down_ ? -1 : size().height(), 1, 1), flags);
   }
 
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index e3a15e6..42cb2a3b 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -1332,7 +1332,7 @@
 }
 
 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) {
-  renderer->SetDrawLooper(CreateShadowDrawLooperCorrectBlur(shadows_));
+  renderer->SetDrawLooper(CreateShadowDrawLooper(shadows_));
 }
 
 base::i18n::TextDirection RenderText::GetTextDirection(
diff --git a/ui/gfx/shadow_util.cc b/ui/gfx/shadow_util.cc
index d58a5df..1d98204 100644
--- a/ui/gfx/shadow_util.cc
+++ b/ui/gfx/shadow_util.cc
@@ -37,7 +37,7 @@
   // CanvasImageSource overrides:
   void Draw(Canvas* canvas) override {
     cc::PaintFlags flags;
-    flags.setLooper(CreateShadowDrawLooperCorrectBlur(shadows_));
+    flags.setLooper(CreateShadowDrawLooper(shadows_));
     Insets insets = -ShadowValue::GetMargin(shadows_);
     gfx::Rect bounds(size());
     bounds.Inset(insets);
diff --git a/ui/gfx/skia_paint_util.cc b/ui/gfx/skia_paint_util.cc
index e162b37..dcaea71b 100644
--- a/ui/gfx/skia_paint_util.cc
+++ b/ui/gfx/skia_paint_util.cc
@@ -53,13 +53,6 @@
       grad_points, grad_colors, NULL, 2, cc::PaintShader::kClamp_TileMode));
 }
 
-// TODO(estade): remove. Only exists to support legacy CreateShadowDrawLooper.
-static SkScalar DeprecatedRadiusToSigma(double radius) {
-  // This captures historically what skia did under the hood. Now skia accepts
-  // sigma, not radius, so we perform the conversion.
-  return radius > 0 ? SkDoubleToScalar(0.57735f * radius + 0.5) : 0;
-}
-
 // This is copied from
 // third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h
 static SkScalar RadiusToSigma(double radius) {
@@ -89,41 +82,6 @@
     SkPaint* paint = looper_builder.addLayer(layer_info);
     // SkBlurMaskFilter's blur radius defines the range to extend the blur from
     // original mask, which is half of blur amount as defined in ShadowValue.
-    // Note that because this function uses DeprecatedRadiusToSigma, it actually
-    // creates a draw looper with roughly twice the desired blur.
-    paint->setMaskFilter(SkBlurMaskFilter::Make(
-        kNormal_SkBlurStyle, DeprecatedRadiusToSigma(shadow.blur() / 2),
-        SkBlurMaskFilter::kHighQuality_BlurFlag));
-    paint->setColorFilter(
-        SkColorFilter::MakeModeFilter(shadow.color(), SkBlendMode::kSrcIn));
-  }
-
-  return looper_builder.detach();
-}
-
-sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur(
-    const std::vector<ShadowValue>& shadows) {
-  if (shadows.empty())
-    return nullptr;
-
-  SkLayerDrawLooper::Builder looper_builder;
-
-  looper_builder.addLayer();  // top layer of the original.
-
-  SkLayerDrawLooper::LayerInfo layer_info;
-  layer_info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit;
-  layer_info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit;
-  layer_info.fColorMode = SkBlendMode::kSrc;
-
-  for (size_t i = 0; i < shadows.size(); ++i) {
-    const ShadowValue& shadow = shadows[i];
-
-    layer_info.fOffset.set(SkIntToScalar(shadow.x()),
-                           SkIntToScalar(shadow.y()));
-
-    SkPaint* paint = looper_builder.addLayer(layer_info);
-    // SkBlurMaskFilter's blur radius defines the range to extend the blur from
-    // original mask, which is half of blur amount as defined in ShadowValue.
     paint->setMaskFilter(SkBlurMaskFilter::Make(
         kNormal_SkBlurStyle, RadiusToSigma(shadow.blur() / 2),
         SkBlurMaskFilter::kHighQuality_BlurFlag));
diff --git a/ui/gfx/skia_paint_util.h b/ui/gfx/skia_paint_util.h
index 1cf2006..f7e5d82d 100644
--- a/ui/gfx/skia_paint_util.h
+++ b/ui/gfx/skia_paint_util.h
@@ -47,17 +47,9 @@
 // Creates a draw looper to generate |shadows|. The caller owns the draw looper.
 // NULL is returned if |shadows| is empty since no draw looper is needed in
 // this case.
-// DEPRECATED: See below. TODO(estade): remove this: crbug.com/624175
 GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooper(
     const std::vector<ShadowValue>& shadows);
 
-// Creates a draw looper to generate |shadows|. This creates a looper with the
-// correct amount of blur. Callers of the existing CreateShadowDrawLooper may
-// rely on the wrong amount of blur being applied but new code should use this
-// function.
-GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur(
-    const std::vector<ShadowValue>& shadows);
-
 }  // namespace gfx
 
 #endif  // UI_GFX_SKIA_UTIL_H_
diff --git a/ui/views/animation/ink_drop_painted_layer_delegates.cc b/ui/views/animation/ink_drop_painted_layer_delegates.cc
index 388fa7b..0c62049 100644
--- a/ui/views/animation/ink_drop_painted_layer_delegates.cc
+++ b/ui/views/animation/ink_drop_painted_layer_delegates.cc
@@ -168,7 +168,7 @@
   recorder.canvas()->sk_canvas()->drawRRect(r_rect, flags);
 
   // Now the shadow.
-  flags.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows_));
+  flags.setLooper(gfx::CreateShadowDrawLooper(shadows_));
   recorder.canvas()->sk_canvas()->clipRRect(r_rect, SkClipOp::kDifference,
                                             true);
   recorder.canvas()->sk_canvas()->drawRRect(r_rect, flags);
diff --git a/ui/views/bubble/bubble_border.cc b/ui/views/bubble/bubble_border.cc
index f81e8ad..d946ebc4 100644
--- a/ui/views/bubble/bubble_border.cc
+++ b/ui/views/bubble/bubble_border.cc
@@ -539,7 +539,7 @@
                        2 * kSmallShadowBlur, kSmallShadowColor);
   shadows.emplace_back(gfx::Vector2d(0, kLargeShadowVerticalOffset),
                        2 * kLargeShadowBlur, kLargeShadowColor);
-  flags.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows));
+  flags.setLooper(gfx::CreateShadowDrawLooper(shadows));
   flags.setColor(SkColorSetA(SK_ColorBLACK, 0x26));
   flags.setAntiAlias(true);
 
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc
index 7f01ba3..45e99d6 100644
--- a/ui/views/controls/button/toggle_button.cc
+++ b/ui/views/controls/button/toggle_button.cc
@@ -79,7 +79,7 @@
                     0x99));
     shadows.push_back(shadow.Scale(dsf));
     cc::PaintFlags thumb_flags;
-    thumb_flags.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows));
+    thumb_flags.setLooper(gfx::CreateShadowDrawLooper(shadows));
     thumb_flags.setAntiAlias(true);
     const SkColor thumb_on_color = GetNativeTheme()->GetSystemColor(
         ui::NativeTheme::kColorId_ProminentButtonColor);