diff --git a/DEPS b/DEPS
index ed6ef328c..1e043ec 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '544e0ad49c11bd349782618de6430bdf8cec0106',
+  'skia_revision': '5338f99a8a75d0e7622a37c5d1c05fcce49f55f5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -217,7 +217,7 @@
     Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '7da28c6c7c6a1387217352ce02b31754deb54d2a',
 
   'src/third_party/libjpeg_turbo':
-    Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + '7260e4d8b8e1e40b17f03fafdf1cd83296900f76',
+    Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'a1750dbc79a8792dde3d3f7d7d8ac28ba01ac9dd',
 
   'src/third_party/flac':
     Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'd0c35f878ec26f969c1631350b1d36fbd88ad8bb',
@@ -915,6 +915,16 @@
     ],
   },
   {
+    'name': 'checkstyle',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--no_auth',
+                '--bucket', 'chromium-android-tools/checkstyle',
+                '-s', 'src/third_party/checkstyle/checkstyle-7.6.1-all.jar.sha1'
+    ],
+  },
+  {
     'name': 'gvr_static_shim_android_arm',
     'pattern': '\\.sha1',
     'action': [ 'download_from_google_storage',
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc
index d5c5b3fb..962a3ff 100644
--- a/ash/system/bluetooth/tray_bluetooth.cc
+++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -288,7 +288,7 @@
       return;
     }
 
-    // Add paired devices (and their section header in MD) in the list.
+    // Add paired devices and their section header to the list.
     size_t num_paired_devices = connected_devices_.size() +
                                 connecting_devices_.size() +
                                 paired_not_connected_devices_.size();
@@ -302,7 +302,8 @@
                                         false, bluetooth_enabled);
     }
 
-    // Add paired devices (and their section header in MD) in the list.
+    // Add unpaired devices to the list. If at least one paired device is
+    // present, also add a section header above the unpaired devices.
     if (discovered_not_paired_devices_.size() > 0) {
       if (num_paired_devices > 0)
         AddSubHeader(IDS_ASH_STATUS_TRAY_BLUETOOTH_UNPAIRED_DEVICES);
@@ -311,15 +312,9 @@
     }
 
     // Show user Bluetooth state if there is no bluetooth devices in list.
-    if (device_map_.size() == 0) {
-      if (bluetooth_available && bluetooth_enabled) {
-        HoverHighlightView* container = new HoverHighlightView(this);
-        container->AddLabelDeprecated(
-            l10n_util::GetStringUTF16(
-                IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING),
-            gfx::ALIGN_LEFT, false);
-        scroll_content()->AddChildView(container);
-      }
+    if (device_map_.size() == 0 && bluetooth_available && bluetooth_enabled) {
+      scroll_content()->AddChildView(TrayPopupUtils::CreateInfoLabelRowView(
+          IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING));
     }
 
     // Focus the device which was focused before the device-list update.
diff --git a/ash/system/network/network_info.cc b/ash/system/network/network_info.cc
index d6832d6..7d4ecd6 100644
--- a/ash/system/network/network_info.cc
+++ b/ash/system/network/network_info.cc
@@ -8,7 +8,6 @@
 
 NetworkInfo::NetworkInfo()
     : disable(false),
-      highlight(false),
       connected(false),
       connecting(false),
       type(Type::UNKNOWN) {}
@@ -16,7 +15,6 @@
 NetworkInfo::NetworkInfo(const std::string& guid)
     : guid(guid),
       disable(false),
-      highlight(false),
       connected(false),
       connecting(false),
       type(Type::UNKNOWN) {}
@@ -26,9 +24,8 @@
 bool NetworkInfo::operator==(const NetworkInfo& other) const {
   return guid == other.guid && label == other.label &&
          tooltip == other.tooltip && image.BackedBySameObjectAs(other.image) &&
-         disable == other.disable && highlight == other.highlight &&
-         connected == other.connected && connecting == other.connecting &&
-         type == other.type;
+         disable == other.disable && connected == other.connected &&
+         connecting == other.connecting && type == other.type;
 }
 
 }  // namespace ash
diff --git a/ash/system/network/network_info.h b/ash/system/network/network_info.h
index 814a6be..d0055fd 100644
--- a/ash/system/network/network_info.h
+++ b/ash/system/network/network_info.h
@@ -18,7 +18,6 @@
 
 // Includes information necessary about a network for displaying the appropriate
 // UI to the user.
-// TODO(tdanderson): Remove the |highlight| member. See crbug.com/708190.
 struct NetworkInfo {
   enum class Type { UNKNOWN, WIFI, TETHER, CELLULAR };
 
@@ -34,7 +33,6 @@
   base::string16 tooltip;
   gfx::ImageSkia image;
   bool disable;
-  bool highlight;
   bool connected;
   bool connecting;
   Type type;
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc
index cdb1001..9e308af 100644
--- a/ash/system/network/network_list.cc
+++ b/ash/system/network/network_list.cc
@@ -371,8 +371,6 @@
         return network1->connected;
       if (network1->connecting != network2->connecting)
         return network1->connecting;
-      if (network1->highlight != network2->highlight)
-        return network1->highlight;
       return network1->guid.compare(network2->guid) < 0;
     }
 
@@ -419,7 +417,6 @@
         prohibited_by_policy;
     info->connected = network->IsConnectedState();
     info->connecting = network->IsConnectingState();
-    info->highlight = info->connected || info->connecting;
     if (network->Matches(NetworkTypePattern::WiFi()))
       info->type = NetworkInfo::Type::WIFI;
     else if (network->Matches(NetworkTypePattern::Cellular()))
diff --git a/ash/system/network/network_state_list_detailed_view.cc b/ash/system/network/network_state_list_detailed_view.cc
index a270762..0a674735 100644
--- a/ash/system/network/network_state_list_detailed_view.cc
+++ b/ash/system/network/network_state_list_detailed_view.cc
@@ -497,7 +497,7 @@
     SetupConnectingItem(container, info.label, info.image);
   else
     container->AddIconAndLabel(info.image, info.label);
-  container->set_tooltip(info.tooltip);
+  container->SetTooltipText(info.tooltip);
   views::View* controlled_icon = CreateControlledByExtensionView(info);
   if (controlled_icon)
     container->AddChildView(controlled_icon);
@@ -521,7 +521,7 @@
   else
     container->AddIconAndLabel(info.image, info.label);
   views::View* controlled_icon = CreateControlledByExtensionView(info);
-  container->set_tooltip(info.tooltip);
+  container->SetTooltipText(info.tooltip);
   if (controlled_icon)
     view->AddChildView(controlled_icon);
 }
diff --git a/ash/system/palette/common_palette_tool.cc b/ash/system/palette/common_palette_tool.cc
index 3d2436bb6b..7aae0ed 100644
--- a/ash/system/palette/common_palette_tool.cc
+++ b/ash/system/palette/common_palette_tool.cc
@@ -19,7 +19,6 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
-#include "ui/views/border.h"
 #include "ui/views/controls/label.h"
 
 namespace ash {
@@ -80,14 +79,9 @@
 views::View* CommonPaletteTool::CreateDefaultView(const base::string16& name) {
   gfx::ImageSkia icon =
       CreateVectorIcon(GetPaletteIcon(), kMenuIconSize, gfx::kChromeIconGrey);
-
   highlight_view_ = new HoverHighlightView(this);
-  highlight_view_->SetBorder(views::CreateEmptyBorder(0, 0, 0, 0));
   highlight_view_->AddIconAndLabel(icon, name);
-  highlight_view_->set_custom_height(kMenuButtonSize);
-
   TrayPopupUtils::InitializeAsCheckableRow(highlight_view_, enabled());
-
   return highlight_view_;
 }
 
diff --git a/ash/system/tray/hover_highlight_view.cc b/ash/system/tray/hover_highlight_view.cc
index 50ce0bc1..c3f7cfa3 100644
--- a/ash/system/tray/hover_highlight_view.cc
+++ b/ash/system/tray/hover_highlight_view.cc
@@ -10,27 +10,14 @@
 #include "ash/system/tray/tri_view.h"
 #include "ash/system/tray/view_click_listener.h"
 #include "ui/accessibility/ax_node_data.h"
-#include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
-#include "ui/gfx/font_list.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/resources/grit/ui_resources.h"
-#include "ui/views/border.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
-#include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/resources/grit/views_resources.h"
 
-namespace {
-
-const gfx::FontList& GetFontList(bool highlight) {
-  return ui::ResourceBundle::GetSharedInstance().GetFontList(
-      highlight ? ui::ResourceBundle::BoldFont : ui::ResourceBundle::BaseFont);
-}
-
-}  // namespace
-
 namespace ash {
 
 HoverHighlightView::HoverHighlightView(ViewClickListener* listener)
@@ -42,14 +29,6 @@
 
 HoverHighlightView::~HoverHighlightView() {}
 
-bool HoverHighlightView::GetTooltipText(const gfx::Point& p,
-                                        base::string16* tooltip) const {
-  if (tooltip_.empty())
-    return false;
-  *tooltip = tooltip_;
-  return true;
-}
-
 void HoverHighlightView::AddRightIcon(const gfx::ImageSkia& image,
                                       int icon_size) {
   DCHECK(!right_view_);
@@ -68,9 +47,6 @@
   tri_view_->SetContainerVisible(TriView::Container::END, true);
 }
 
-// TODO(tdanderson): Ensure all checkable detailed view rows use this
-// mechanism, and share the code that sets the accessible state for
-// a checkbox. See crbug.com/652674.
 void HoverHighlightView::SetRightViewVisible(bool visible) {
   if (!right_view_)
     return;
@@ -142,38 +118,6 @@
   SetAccessibleName(text);
 }
 
-views::Label* HoverHighlightView::AddLabelDeprecated(
-    const base::string16& text,
-    gfx::HorizontalAlignment alignment,
-    bool highlight) {
-  box_layout_ = new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
-  SetLayoutManager(box_layout_);
-  text_label_ = new views::Label(text);
-  int left_margin = kTrayPopupPaddingHorizontal;
-  int right_margin = kTrayPopupPaddingHorizontal;
-  if (alignment != gfx::ALIGN_CENTER) {
-    if (base::i18n::IsRTL())
-      right_margin += kTrayPopupDetailsLabelExtraLeftMargin;
-    else
-      left_margin += kTrayPopupDetailsLabelExtraLeftMargin;
-  }
-  text_label_->SetBorder(
-      views::CreateEmptyBorder(5, left_margin, 5, right_margin));
-  text_label_->SetHorizontalAlignment(alignment);
-  text_label_->SetFontList(GetFontList(highlight));
-  // Do not set alpha value in disable color. It will have issue with elide
-  // blending filter in disabled state for rendering label text color.
-  text_label_->SetDisabledColor(SkColorSetARGB(255, 127, 127, 127));
-  if (text_default_color_)
-    text_label_->SetEnabledColor(text_default_color_);
-  text_label_->SetEnabled(enabled());
-  AddChildView(text_label_);
-  box_layout_->SetFlexForView(text_label_, 1);
-
-  SetAccessibleName(text);
-  return text_label_;
-}
-
 void HoverHighlightView::AddLabelRow(const base::string16& text) {
   SetLayoutManager(new views::FillLayout);
   tri_view_ = TrayPopupUtils::CreateDefaultRowView();
@@ -230,9 +174,7 @@
 gfx::Size HoverHighlightView::GetPreferredSize() const {
   gfx::Size size = ActionableView::GetPreferredSize();
 
-  if (custom_height_)
-    size.set_height(custom_height_);
-  else if (!expandable_ || size.height() < kTrayPopupItemMinHeight)
+  if (!expandable_ || size.height() < kTrayPopupItemMinHeight)
     size.set_height(kTrayPopupItemMinHeight);
 
   return size;
diff --git a/ash/system/tray/hover_highlight_view.h b/ash/system/tray/hover_highlight_view.h
index 91243c7a..300a6e3 100644
--- a/ash/system/tray/hover_highlight_view.h
+++ b/ash/system/tray/hover_highlight_view.h
@@ -14,7 +14,6 @@
 namespace views {
 class ImageView;
 class Label;
-class BoxLayout;
 }
 
 namespace ash {
@@ -38,10 +37,6 @@
   explicit HoverHighlightView(ViewClickListener* listener);
   ~HoverHighlightView() override;
 
-  // views::View:
-  bool GetTooltipText(const gfx::Point& p,
-                      base::string16* tooltip) const override;
-
   // Convenience function for adding an icon and a label. This also sets the
   // accessible name. Primarily used for scrollable rows in detailed views.
   void AddIconAndLabel(const gfx::ImageSkia& image, const base::string16& text);
@@ -58,15 +53,6 @@
   void AddIconAndLabelForDefaultView(const gfx::ImageSkia& image,
                                      const base::string16& text);
 
-  // Convenience function for adding a label with padding on the left for a
-  // blank icon. This also sets the accessible name. Returns label after
-  // parenting it.
-  // TODO(tdanderson): Remove this function and use AddLabelRow() instead.
-  // See crbug.com/708190.
-  views::Label* AddLabelDeprecated(const base::string16& text,
-                                   gfx::HorizontalAlignment alignment,
-                                   bool highlight);
-
   // Adds a row containing only a text label, inset on the left by the
   // horizontal space that would normally be occupied by an icon.
   void AddLabelRow(const base::string16& text);
@@ -86,10 +72,6 @@
   // equals to kTrayPopupItemHeight.
   void SetExpandable(bool expandable);
 
-  // Set a custom height for the view. A value of 0 means that no custom height
-  // is set.
-  void set_custom_height(int custom_height) { custom_height_ = custom_height; }
-
   // Changes the view's current accessibility state. This will fire an
   // accessibility event if needed.
   void SetAccessiblityState(AccessibilityState accessibility_state);
@@ -97,8 +79,6 @@
   views::Label* text_label() { return text_label_; }
   views::Label* sub_text_label() { return sub_text_label_; }
 
-  void set_tooltip(const base::string16& tooltip) { tooltip_ = tooltip; }
-
  protected:
   // views::View:
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
@@ -132,15 +112,11 @@
   ViewClickListener* listener_ = nullptr;
   views::Label* text_label_ = nullptr;
   views::Label* sub_text_label_ = nullptr;
-  views::BoxLayout* box_layout_ = nullptr;
   views::ImageView* left_icon_ = nullptr;
   views::View* right_view_ = nullptr;
   TriView* tri_view_ = nullptr;
-  SkColor text_default_color_ = 0;
   bool expandable_ = false;
-  int custom_height_ = 0;
   AccessibilityState accessibility_state_ = AccessibilityState::DEFAULT;
-  base::string16 tooltip_;
 
   DISALLOW_COPY_AND_ASSIGN(HoverHighlightView);
 };
diff --git a/ash/system/tray/tray_constants.cc b/ash/system/tray/tray_constants.cc
index 16a4eaf..c3ae671b 100644
--- a/ash/system/tray/tray_constants.cc
+++ b/ash/system/tray/tray_constants.cc
@@ -59,7 +59,6 @@
 const int kTrayPopupLabelRightPadding = 8;
 
 const int kTrayPopupDetailsIconWidth = 25;
-const int kTrayPopupDetailsLabelExtraLeftMargin = 8;
 const SkColor kTrayPopupHoverBackgroundColor = SkColorSetRGB(0xe4, 0xe4, 0xe4);
 const int kTrayRoundedBorderRadius = 2;
 
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h
index 6443155f..f2977a3 100644
--- a/ash/system/tray/tray_constants.h
+++ b/ash/system/tray/tray_constants.h
@@ -71,7 +71,6 @@
 extern const int kTrayPopupLabelRightPadding;
 
 extern const int kTrayPopupDetailsIconWidth;
-extern const int kTrayPopupDetailsLabelExtraLeftMargin;
 extern const SkColor kTrayPopupHoverBackgroundColor;
 extern const int kTrayRoundedBorderRadius;
 
diff --git a/ash/system/tray/tray_popup_item_style.h b/ash/system/tray/tray_popup_item_style.h
index 8d1c5dc..36c017e 100644
--- a/ash/system/tray/tray_popup_item_style.h
+++ b/ash/system/tray/tray_popup_item_style.h
@@ -41,7 +41,8 @@
     SUB_HEADER,
     // Main text used by detailed view rows.
     DETAILED_VIEW_LABEL,
-    // System information text (e.g. date/time, battery status, etc).
+    // System information text (e.g. date/time, battery status, "Scanning for
+    // devices..." seen in the Bluetooth detailed view, etc).
     SYSTEM_INFO,
     // Child buttons within rows that have a visible border (e.g. Cast's
     // "Stop", etc).
diff --git a/ash/system/tray/tray_popup_utils.cc b/ash/system/tray/tray_popup_utils.cc
index c2d5237d9..d5bdd0a6 100644
--- a/ash/system/tray/tray_popup_utils.cc
+++ b/ash/system/tray/tray_popup_utils.cc
@@ -184,6 +184,21 @@
   return tri_view;
 }
 
+views::View* TrayPopupUtils::CreateInfoLabelRowView(int message_id) {
+  views::Label* label = TrayPopupUtils::CreateDefaultLabel();
+  label->SetText(l10n_util::GetStringUTF16(message_id));
+  TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::SYSTEM_INFO);
+  style.SetupLabel(label);
+
+  TriView* tri_view = CreateMultiTargetRowView();
+  tri_view->SetInsets(gfx::Insets(0, kTrayPopupPaddingHorizontal, 0, 0));
+  tri_view->SetContainerVisible(TriView::Container::START, false);
+  tri_view->SetContainerVisible(TriView::Container::END, false);
+  tri_view->AddView(TriView::Container::CENTER, label);
+
+  return tri_view;
+}
+
 TriView* TrayPopupUtils::CreateMultiTargetRowView() {
   TriView* tri_view = new TriView(0 /* padding_between_items */);
 
diff --git a/ash/system/tray/tray_popup_utils.h b/ash/system/tray/tray_popup_utils.h
index a839061..d674034 100644
--- a/ash/system/tray/tray_popup_utils.h
+++ b/ash/system/tray/tray_popup_utils.h
@@ -62,6 +62,13 @@
   // flexible width.
   static TriView* CreateSubHeaderRowView();
 
+  // Creates a view containing only a label (corresponding to |message_id|),
+  // which is to be inserted as a non-targetable row within a system menu
+  // detailed view (e.g., the "Scanning for devices..." message that can appear
+  // at the top of the Bluetooth detailed view). The caller takes over ownership
+  // of the created view.
+  static views::View* CreateInfoLabelRowView(int message_id);
+
   // Creates a container view to be used by system menu rows that want to embed
   // a targetable area within one (or more) of the containers OR by any row
   // that requires a non-default layout within the container views. The returned
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 7714190..e6b2c64 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2664,7 +2664,7 @@
     sources = [
       "android/java/templates/BuildConfig.template",
     ]
-    package_name = "org/chromium/base"
+    package_path = "org/chromium/base"
 
     defines = []
     if (is_java_debug || dcheck_always_on) {
@@ -2676,7 +2676,7 @@
     sources = [
       "android/java/templates/NativeLibraries.template",
     ]
-    package_name = "org/chromium/base/library_loader"
+    package_path = "org/chromium/base/library_loader"
   }
 
   android_library("base_java_unittest_support") {
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 5f217ea..ed73b9e7 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -742,8 +742,7 @@
 
   // The results struct to fill.
   // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
-  base::Optional<MemoryDumpCallbackResult> result_opt;
-
+  base::Optional<MemoryDumpCallbackResult> result;
   for (const auto& kv : pmd_async_state->process_dumps) {
     ProcessId pid = kv.first;  // kNullProcessId for the current process.
     ProcessMemoryDump* process_memory_dump = kv.second.get();
@@ -771,28 +770,28 @@
     if (pmd_async_state->req_args.level_of_detail ==
         MemoryDumpLevelOfDetail::DETAILED)
       continue;
-    MemoryDumpCallbackResult result;
+    if (!result.has_value())
+      result = MemoryDumpCallbackResult();
     // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
     if (pid == kNullProcessId) {
-      result.chrome_dump.malloc_total_kb =
+      result->chrome_dump.malloc_total_kb =
           GetDumpsSumKb("malloc", process_memory_dump);
-      result.chrome_dump.v8_total_kb =
+      result->chrome_dump.v8_total_kb =
           GetDumpsSumKb("v8/*", process_memory_dump);
 
       // partition_alloc reports sizes for both allocated_objects and
       // partitions. The memory allocated_objects uses is a subset of
       // the partitions memory so to avoid double counting we only
       // count partitions memory.
-      result.chrome_dump.partition_alloc_total_kb =
+      result->chrome_dump.partition_alloc_total_kb =
           GetDumpsSumKb("partition_alloc/partitions/*", process_memory_dump);
-      result.chrome_dump.blink_gc_total_kb =
+      result->chrome_dump.blink_gc_total_kb =
           GetDumpsSumKb("blink_gc", process_memory_dump);
-      FillOsDumpFromProcessMemoryDump(process_memory_dump, &result.os_dump);
+      FillOsDumpFromProcessMemoryDump(process_memory_dump, &result->os_dump);
     } else {
-      auto& os_dump = result.extra_processes_dump[pid];
+      auto& os_dump = result->extra_processes_dump[pid];
       FillOsDumpFromProcessMemoryDump(process_memory_dump, &os_dump);
     }
-    result_opt = result;
   }
 
   bool tracing_still_enabled;
@@ -805,7 +804,7 @@
 
   if (!pmd_async_state->callback.is_null()) {
     pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful,
-                                  result_opt);
+                                  result);
     pmd_async_state->callback.Reset();
   }
 
diff --git a/build/android/update_deps/update_third_party_deps.py b/build/android/update_deps/update_third_party_deps.py
index 612be89..972e3988 100755
--- a/build/android/update_deps/update_third_party_deps.py
+++ b/build/android/update_deps/update_third_party_deps.py
@@ -5,6 +5,8 @@
 
 """
 Uploads or downloads third party libraries to or from google cloud storage.
+
+This script will only work for Android checkouts.
 """
 
 import argparse
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index ba8930f..4455732 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -354,7 +354,7 @@
   #     FooBar.java.
   #   inputs: additional compile-time dependencies. Any files
   #     `#include`-ed in the templates should be listed here.
-  #   package_name: this will be the subdirectory for each .java file in the
+  #   package_path: this will be the subdirectory for each .java file in the
   #     .srcjar.
   #
   # Example
@@ -366,7 +366,7 @@
   #       "android/java/templates/native_foo_header.h",
   #     ]
   #
-  #     package_name = "org/chromium/base/library_loader"
+  #     package_path = "org/chromium/base/library_loader"
   #     include_path = "android/java/templates"
   #   }
   template("java_cpp_template") {
@@ -381,6 +381,15 @@
     _apply_gcc_target_name = "${target_name}__apply_gcc"
     _base_gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template"
 
+    if (defined(invoker.package_path)) {
+      package_path = invoker.package_path
+    } else {
+      # TODO(jbudorick): Back this out once all clients have been switched to
+      # package_path.
+      assert(defined(invoker.package_name))
+      package_path = invoker.package_name
+    }
+
     action_foreach(_apply_gcc_target_name) {
       forward_variables_from(invoker,
                              [
@@ -398,7 +407,7 @@
       sources = invoker.sources
 
       outputs = [
-        "$_base_gen_dir/${invoker.package_name}/{{source_name_part}}.java",
+        "$_base_gen_dir/${package_path}/{{source_name_part}}.java",
       ]
 
       args = [
@@ -1810,7 +1819,7 @@
       }
 
       java_cpp_template("${_template_name}__native_libraries_java") {
-        package_name = "org/chromium/base/library_loader"
+        package_path = "org/chromium/base/library_loader"
         sources = [
           "//base/android/java/templates/NativeLibraries.template",
         ]
@@ -1844,7 +1853,7 @@
 
     if (_generate_buildconfig_java) {
       java_cpp_template("${_template_name}__build_config_java") {
-        package_name = "org/chromium/base"
+        package_path = "org/chromium/base"
         sources = [
           "//base/android/java/templates/BuildConfig.template",
         ]
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index cfb412e..c2b244d 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -326,7 +326,7 @@
   sources = [
     "java/ResourceId.template",
   ]
-  package_name = "org/chromium/chrome/browser"
+  package_path = "org/chromium/chrome/browser"
   inputs = [
     "../browser/android/resource_id.h",
   ]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
index 4515d97..66b409b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.support.annotation.CallSuper;
 import android.support.annotation.Nullable;
+import android.text.TextUtils;
 import android.view.View;
 import android.view.View.OnClickListener;
 
@@ -24,6 +25,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetMetrics;
+import org.chromium.content_public.browser.LoadUrlParams;
 
 /**
  * The base class for the new tab pages displayed in Chrome Home.
@@ -90,6 +92,14 @@
                 mFadingBackgroundView.setEnabled(true);
                 if (!mTab.isClosing()) mShowOverviewOnClose = false;
             }
+
+            @Override
+            public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) {
+                // If the NTP is loading, the sheet state will be set to SHEET_STATE_HALF.
+                if (TextUtils.equals(tab.getUrl(), getUrl())) return;
+
+                mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_PEEK, true);
+            }
         };
         mTab.addObserver(mTabObserver);
 
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn
index bd96ffa..8d22e4e 100644
--- a/chrome/android/webapk/libs/client/BUILD.gn
+++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -24,7 +24,7 @@
 }
 
 java_cpp_template("runtime_library_version_java") {
-  package_name = "org/chromium/webapk/lib/client"
+  package_path = "org/chromium/webapk/lib/client"
   sources = [
     "src/org/chromium/webapk/lib/client/WebApkVersion.template",
   ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 6adc45b..70e3b51 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -604,6 +604,8 @@
     "memory_details_win.cc",
     "metrics/antivirus_metrics_provider_win.cc",
     "metrics/antivirus_metrics_provider_win.h",
+    "metrics/browser_window_histogram_helper.cc",
+    "metrics/browser_window_histogram_helper.h",
     "metrics/chrome_browser_main_extra_parts_metrics.cc",
     "metrics/chrome_browser_main_extra_parts_metrics.h",
     "metrics/chrome_browser_main_extra_parts_metrics_mac.mm",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 7e3b7ad..86e7c646 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2752,6 +2752,12 @@
      FEATURE_VALUE_TYPE(features::kQuickUnlockPinSignin)},
 #endif  // OS_CHROMEOS
 
+#if defined(OS_ANDROID)
+    {"enable-webnfc", flag_descriptions::kEnableWebNfcName,
+     flag_descriptions::kEnableWebNfcDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(features::kWebNfc)},
+#endif
+
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms.xml. See note in
     // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/apps/drive/drive_app_provider_browsertest.cc b/chrome/browser/apps/drive/drive_app_provider_browsertest.cc
index b60fff1..cb46e96 100644
--- a/chrome/browser/apps/drive/drive_app_provider_browsertest.cc
+++ b/chrome/browser/apps/drive/drive_app_provider_browsertest.cc
@@ -277,11 +277,11 @@
       kDriveAppId, kDriveAppName, kChromeAppId, kLaunchUrl, true);
   RefreshDriveAppRegistry();
   WaitForPendingDriveAppConverters();
+  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
 
   // An Url app should be created.
-  const Extension* url_app =
-      ExtensionRegistry::Get(profile())->GetExtensionById(
-          mapping()->GetChromeApp(kDriveAppId), ExtensionRegistry::EVERYTHING);
+  const Extension* url_app = registry->GetExtensionById(
+      mapping()->GetChromeApp(kDriveAppId), ExtensionRegistry::EVERYTHING);
   EXPECT_TRUE(url_app->is_hosted_app());
   EXPECT_TRUE(url_app->from_bookmark());
 
@@ -290,16 +290,20 @@
   EXPECT_EQ(url_app_id, mapping()->GetChromeApp(kDriveAppId));
   EXPECT_TRUE(mapping()->IsChromeAppGenerated(url_app_id));
 
-  // Installs a chrome app with matching id.
-  InstallChromeApp(0);
+  // Install a chrome app with matching id.
+  size_t num_before = registry->enabled_extensions().size();
+  InstallChromeApp(1);
+  // Url app should be auto uninstalled. This happens asynchronously after the
+  // installation of the app that replaces it, so the task might still be
+  // pending.
+  content::RunAllPendingInMessageLoop();
+  EXPECT_FALSE(
+      registry->GetExtensionById(url_app_id, ExtensionRegistry::EVERYTHING));
+  EXPECT_EQ(num_before, registry->enabled_extensions().size());
 
   // The Drive app should be mapped to chrome app.
   EXPECT_EQ(kChromeAppId, mapping()->GetChromeApp(kDriveAppId));
   EXPECT_FALSE(mapping()->IsChromeAppGenerated(kChromeAppId));
-
-  // Url app should be auto uninstalled.
-  EXPECT_FALSE(ExtensionRegistry::Get(profile())->GetExtensionById(
-      url_app_id, ExtensionRegistry::EVERYTHING));
 }
 
 // Tests that the corresponding URL app is uninstalled when a Drive app is
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 06724eee..dd819bc 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -57,6 +57,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "components/startup_metric_utils/browser/startup_metric_utils.h"
 #include "content/public/browser/notification_service.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/constants.h"
@@ -717,6 +718,8 @@
   if (in_background_mode_)
     return;
 
+  startup_metric_utils::SetBackgroundModeEnabled();
+
   // Mark ourselves as running in background mode.
   in_background_mode_ = true;
 
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index c52fbbf9..15af285 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -822,8 +822,8 @@
 
 void ChromeBrowserMainParts::RecordBrowserStartupTime() {
   // Don't record any metrics if UI was displayed before this point e.g.
-  // warning dialogs.
-  if (startup_metric_utils::WasNonBrowserUIDisplayed())
+  // warning dialogs or browser was started in background mode.
+  if (startup_metric_utils::WasMainWindowStartupInterrupted())
     return;
 
   bool is_first_run = false;
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
index 01008ae..c3109b0 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
+++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
@@ -312,10 +312,8 @@
   loader_->StopCache(shutdown_run_loop.QuitClosure());
   VerifyAndResetVisitorCallExpectations();
 
-  // Spin the loop until the cache shutdown callback is invoked. Verify that at
-  // that point, no further file I/O tasks are pending.
+  // Spin the loop until the cache shutdown callback is invoked.
   shutdown_run_loop.Run();
-  EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index ac0b973..cc76175 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -201,6 +201,8 @@
   const UserContext user_context = CreateUserContext(user_id);
   SetExpectedCredentials(user_context);
   EXPECT_TRUE(TryToLogin(user_context));
+  // Let LoginDisplayHostImpl delete itself.
+  content::RunAllPendingInMessageLoop();
 }
 
 void LoginManagerTest::AddUser(const std::string& user_id) {
diff --git a/chrome/browser/extensions/chrome_extension_test_notification_observer.cc b/chrome/browser/extensions/chrome_extension_test_notification_observer.cc
index 7a34f448..cf28829 100644
--- a/chrome/browser/extensions/chrome_extension_test_notification_observer.cc
+++ b/chrome/browser/extensions/chrome_extension_test_notification_observer.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/test/test_utils.h"
 #include "extensions/browser/notification_types.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/common/extension.h"
@@ -80,6 +81,10 @@
 }
 
 bool ChromeExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() {
+  // Some views might be not created yet. This call may become insufficient if
+  // e.g. implementation of ExtensionHostQueue changes.
+  content::RunAllPendingInMessageLoop();
+
   ProcessManager* manager = ProcessManager::Get(GetBrowserContext());
   NotificationSet notification_set;
   notification_set.Add(content::NOTIFICATION_WEB_CONTENTS_DESTROYED);
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e42bd86f5..d1ba3ed 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3027,6 +3027,10 @@
     "to enter into the search bar. The data is indexed locally, and never sent "
     "to the server. It's disabled in incognito mode.";
 
+const char kEnableWebNfcName[] = "WebNFC";
+
+const char kEnableWebNfcDescription[] = "Enable WebNFC support.";
+
 #endif  // defined(OS_ANDROID)
 
 }  // namespace flag_descriptions
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index e271f36f..41117360 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3287,6 +3287,12 @@
 // Description of the flag that enables Copyless Paste.
 extern const char kEnableCopylessPasteDescription[];
 
+// Title for the flag to enable WebNFC.
+extern const char kEnableWebNfcName[];
+
+// Description for the flag to enable WebNFC.
+extern const char kEnableWebNfcDescription[];
+
 #endif  // defined(OS_ANDROID)
 
 }  // namespace flag_descriptions
diff --git a/chrome/browser/metrics/browser_window_histogram_helper.cc b/chrome/browser/metrics/browser_window_histogram_helper.cc
new file mode 100644
index 0000000..ff6fb56e
--- /dev/null
+++ b/chrome/browser/metrics/browser_window_histogram_helper.cc
@@ -0,0 +1,56 @@
+// 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/browser_window_histogram_helper.h"
+
+#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "ui/compositor/compositor.h"
+
+BrowserWindowHistogramHelper::~BrowserWindowHistogramHelper() {}
+
+// static
+std::unique_ptr<BrowserWindowHistogramHelper>
+BrowserWindowHistogramHelper::MaybeRecordValueAndCreateInstanceOnBrowserPaint(
+    ui::Compositor* compositor) {
+  static bool did_first_paint = false;
+  if (did_first_paint)
+    return std::unique_ptr<BrowserWindowHistogramHelper>();
+
+  did_first_paint = true;
+
+  return std::unique_ptr<BrowserWindowHistogramHelper>(
+      new BrowserWindowHistogramHelper(compositor));
+}
+
+BrowserWindowHistogramHelper::BrowserWindowHistogramHelper(
+    ui::Compositor* compositor)
+    : scoped_observer_(this) {
+  startup_metric_utils::RecordBrowserWindowFirstPaint(base::TimeTicks::Now());
+
+#if defined(OS_MACOSX)
+  if (!compositor) {
+    // In Cocoa version of Chromium, UI is rendered inside the main process
+    // using CoreAnimation compositor, and at this point everything is already
+    // visible to the user.
+    startup_metric_utils::RecordBrowserWindowFirstPaintCompositingEnded(
+        base::TimeTicks::Now());
+    return;
+  }
+#endif  // OS_MACOSX
+
+  scoped_observer_.Add(compositor);
+}
+
+void BrowserWindowHistogramHelper::OnCompositingEnded(
+    ui::Compositor* compositor) {
+  startup_metric_utils::RecordBrowserWindowFirstPaintCompositingEnded(
+      base::TimeTicks::Now());
+
+  scoped_observer_.RemoveAll();
+}
+
+void BrowserWindowHistogramHelper::OnCompositingShuttingDown(
+    ui::Compositor* compositor) {
+  scoped_observer_.RemoveAll();
+}
diff --git a/chrome/browser/metrics/browser_window_histogram_helper.h b/chrome/browser/metrics/browser_window_histogram_helper.h
new file mode 100644
index 0000000..ab305264
--- /dev/null
+++ b/chrome/browser/metrics/browser_window_histogram_helper.h
@@ -0,0 +1,49 @@
+// 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_BROWSER_WINDOW_HISTOGRAM_HELPER_H_
+#define CHROME_BROWSER_METRICS_BROWSER_WINDOW_HISTOGRAM_HELPER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "base/time/time.h"
+#include "ui/compositor/compositor_observer.h"
+
+// Class that encapsulates logic of recording
+// Startup.BrowserWindow.FirstPaint* histograms.
+//
+// There's a dependency on ui/compositor therefore it can't be moved to
+// components/startup_metrics_utils.
+class BrowserWindowHistogramHelper : public ui::CompositorObserver {
+ public:
+  ~BrowserWindowHistogramHelper() override;
+
+  // Call this when the Browser finishes painting its UI, and the user will see
+  // it after next Compositor frame swap.
+  // |compositor| is the compositor that composites the just-painted Browser
+  // widget, or nullptr in Cocoa (we're using CoreAnimation's compositor there).
+  // Returned object should stay alive until next |OnCompositingStarted|
+  // callback.
+  static std::unique_ptr<BrowserWindowHistogramHelper>
+  MaybeRecordValueAndCreateInstanceOnBrowserPaint(ui::Compositor* compositor);
+
+ private:
+  explicit BrowserWindowHistogramHelper(ui::Compositor* compositor);
+
+  // ui::CompositorObserver:
+  void OnCompositingDidCommit(ui::Compositor* compositor) override {}
+  void OnCompositingStarted(ui::Compositor* compositor,
+                            base::TimeTicks start_time) override {}
+  void OnCompositingEnded(ui::Compositor* compositor) override;
+  void OnCompositingLockStateChanged(ui::Compositor* compositor) override {}
+  void OnCompositingShuttingDown(ui::Compositor* compositor) override;
+
+  ScopedObserver<ui::Compositor, ui::CompositorObserver> scoped_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserWindowHistogramHelper);
+};
+
+#endif  // CHROME_BROWSER_METRICS_BROWSER_WINDOW_HISTOGRAM_HELPER_H_
diff --git a/chrome/browser/metrics/first_web_contents_profiler.cc b/chrome/browser/metrics/first_web_contents_profiler.cc
index 89cd3b2..e67831b 100644
--- a/chrome/browser/metrics/first_web_contents_profiler.cc
+++ b/chrome/browser/metrics/first_web_contents_profiler.cc
@@ -99,7 +99,7 @@
 void FirstWebContentsProfiler::DidFirstVisuallyNonEmptyPaint() {
   if (collected_paint_metric_)
     return;
-  if (startup_metric_utils::WasNonBrowserUIDisplayed()) {
+  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
     FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
     return;
   }
@@ -118,7 +118,7 @@
 void FirstWebContentsProfiler::DocumentOnLoadCompletedInMainFrame() {
   if (collected_load_metric_)
     return;
-  if (startup_metric_utils::WasNonBrowserUIDisplayed()) {
+  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
     FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
     return;
   }
@@ -135,7 +135,7 @@
     content::NavigationHandle* navigation_handle) {
   if (collected_main_navigation_start_metric_)
     return;
-  if (startup_metric_utils::WasNonBrowserUIDisplayed()) {
+  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
     FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
     return;
   }
@@ -172,7 +172,7 @@
     return;
   }
 
-  if (startup_metric_utils::WasNonBrowserUIDisplayed()) {
+  if (startup_metric_utils::WasMainWindowStartupInterrupted()) {
     FinishedCollectingMetrics(FinishReason::ABANDON_BLOCKING_UI);
     return;
   }
diff --git a/chrome/browser/metrics/startup_metrics_browsertest.cc b/chrome/browser/metrics/startup_metrics_browsertest.cc
new file mode 100644
index 0000000..71932af
--- /dev/null
+++ b/chrome/browser/metrics/startup_metrics_browsertest.cc
@@ -0,0 +1,47 @@
+// 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 <set>
+
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/run_loop.h"
+#include "chrome/test/base/in_process_browser_test.h"
+
+using StartupMetricsTest = InProcessBrowserTest;
+
+namespace {
+
+constexpr const char* kStartupMetrics[] = {
+    "Startup.BrowserMainToRendererMain",
+    "Startup.BrowserOpenTabs",
+    "Startup.BrowserWindow.FirstPaint",
+    "Startup.BrowserWindow.FirstPaint.CompositingEnded",
+    "Startup.BrowserWindowDisplay",
+    "Startup.FirstWebContents.MainFrameLoad2",
+    "Startup.FirstWebContents.MainNavigationFinished",
+    "Startup.FirstWebContents.MainNavigationStart",
+    "Startup.FirstWebContents.NonEmptyPaint2",
+
+    // The following histograms depend on normal browser startup through
+    // BrowserMain and are as such not caught by this browser test.
+    // "Startup.BrowserMessageLoopStartHardFaultCount",
+    // "Startup.BrowserMessageLoopStartTime",
+    // "Startup.BrowserMessageLoopStartTimeFromMainEntry2",
+    // "Startup.LoadTime.ExeMainToDllMain2",
+    // "Startup.LoadTime.ProcessCreateToDllMain2",
+    // "Startup.LoadTime.ProcessCreateToExeMain2",
+    // "Startup.SystemUptime",
+    // "Startup.Temperature",
+};
+
+}  // namespace
+
+// Verify that startup histograms are logged on browser startup.
+IN_PROC_BROWSER_TEST_F(StartupMetricsTest, ReportsValues) {
+  for (auto* const histogram : kStartupMetrics) {
+    while (!base::StatisticsRecorder::FindHistogram(histogram))
+      base::RunLoop().RunUntilIdle();
+  }
+}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index fdac9ca6..0c13cbc 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -314,8 +314,8 @@
     ~DestructionMessageFilter() override {
       content::BrowserThread::PostTask(
           content::BrowserThread::UI, FROM_HERE,
-          base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
-                     base::Unretained(watcher_)));
+          base::BindOnce(&ChannelDestructionWatcher::OnChannelDestroyed,
+                         base::Unretained(watcher_)));
     }
 
     bool OnMessageReceived(const IPC::Message& message) override {
@@ -2462,8 +2462,8 @@
   RequestCounter unload_counter;
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateCountingInterceptorOnIO,
-                 unload_url, empty_file, unload_counter.AsWeakPtr()));
+      base::BindOnce(&CreateCountingInterceptorOnIO, unload_url, empty_file,
+                     unload_counter.AsWeakPtr()));
 
   set_loader_path("/prerender/prerender_loader_with_unload.html");
   PrerenderTestURL("/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
@@ -2484,8 +2484,8 @@
   RequestCounter request_counter;
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateCountingInterceptorOnIO,
-                 beforeunload_url, empty_file, request_counter.AsWeakPtr()));
+      base::BindOnce(&CreateCountingInterceptorOnIO, beforeunload_url,
+                     empty_file, request_counter.AsWeakPtr()));
 
   set_loader_path("/prerender/prerender_loader_with_beforeunload.html");
   PrerenderTestURL("/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
@@ -3003,7 +3003,7 @@
   base::FilePath file(GetTestPath("prerender_page.html"));
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateMockInterceptorOnIO, webstore_url, file));
+      base::BindOnce(&CreateMockInterceptorOnIO, webstore_url, file));
 
   PrerenderTestURL(CreateClientRedirect(webstore_url.spec()),
                    FINAL_STATUS_OPEN_URL, 1);
@@ -3196,8 +3196,8 @@
   RequestCounter ping_counter;
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateCountingInterceptorOnIO,
-                 kPingURL, empty_file, ping_counter.AsWeakPtr()));
+      base::BindOnce(&CreateCountingInterceptorOnIO, kPingURL, empty_file,
+                     ping_counter.AsWeakPtr()));
 
   PrerenderTestURL("/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   OpenDestURLViaClickPing(kPingURL);
@@ -3288,8 +3288,8 @@
   RequestCounter done_counter;
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateCountingInterceptorOnIO,
-                 done_url, empty_file, done_counter.AsWeakPtr()));
+      base::BindOnce(&CreateCountingInterceptorOnIO, done_url, empty_file,
+                     done_counter.AsWeakPtr()));
   // Loading may finish or be interrupted. The final result is important only.
   DisableLoadEventCheck();
   // TestPrenderContents is always created before the Autosignin JS can run, so
@@ -3365,7 +3365,7 @@
       *out_request = request;
     content::BrowserThread::PostTask(
         content::BrowserThread::UI, FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             [](net::RequestPriority priority,
                net::RequestPriority* out_priority, base::Closure closure) {
               *out_priority = priority;
@@ -3408,8 +3408,8 @@
     base::RunLoop loop;
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(io_lambda, nullptr, base::Unretained(&priority),
-                   loop.QuitClosure(), base::Unretained(url_request)));
+        base::BindOnce(io_lambda, nullptr, base::Unretained(&priority),
+                       loop.QuitClosure(), base::Unretained(url_request)));
     loop.Run();
   } while (priority <= net::IDLE);
   EXPECT_GT(priority, net::IDLE);
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index f533a2b..e96112b 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -763,7 +763,7 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&ResumeThrottles, resource_throttles_, idle_resources_));
+      base::BindOnce(&ResumeThrottles, resource_throttles_, idle_resources_));
   resource_throttles_.clear();
   idle_resources_.clear();
 }
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 74ee653..cbab1bf 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -121,8 +121,9 @@
     tab_->SetDelegate(this);
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&OnCloseWebContentsDeleter::ScheduleWebContentsForDeletion,
-                   AsWeakPtr(), true),
+        base::BindOnce(
+            &OnCloseWebContentsDeleter::ScheduleWebContentsForDeletion,
+            AsWeakPtr(), true),
         base::TimeDelta::FromSeconds(kDeleteWithExtremePrejudiceSeconds));
   }
 
@@ -1081,8 +1082,8 @@
 void PrerenderManager::PostCleanupTask() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&PrerenderManager::PeriodicCleanup,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&PrerenderManager::PeriodicCleanup,
+                                weak_factory_.GetWeakPtr()));
 }
 
 base::TimeTicks PrerenderManager::GetExpiryTimeForNewPrerender(
diff --git a/chrome/browser/prerender/prerender_message_filter.cc b/chrome/browser/prerender/prerender_message_filter.cc
index 438ee4d..46c1b9e 100644
--- a/chrome/browser/prerender/prerender_message_filter.cc
+++ b/chrome/browser/prerender/prerender_message_filter.cc
@@ -95,7 +95,8 @@
 void PrerenderMessageFilter::OnChannelClosing() {
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&PrerenderMessageFilter::OnChannelClosingInUIThread, this));
+      base::BindOnce(&PrerenderMessageFilter::OnChannelClosingInUIThread,
+                     this));
 }
 
 void PrerenderMessageFilter::OnDestruct() const {
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
index 34ac7f9..3d9b817 100644
--- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
+++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -93,8 +93,8 @@
         base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str));
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&prerender::test_utils::CreateCountingInterceptorOnIO, url,
-                   url_file, counter->AsWeakPtr()));
+        base::BindOnce(&prerender::test_utils::CreateCountingInterceptorOnIO,
+                       url, url_file, counter->AsWeakPtr()));
   }
 
   base::SimpleTestTickClock* OverridePrerenderManagerTimeTicks() {
@@ -117,8 +117,8 @@
       base::RunLoop wait_loop;
       content::BrowserThread::PostTask(
           content::BrowserThread::IO, FROM_HERE,
-          base::Bind(WaitForAppcacheOnIO, manifest_url, appcache_service,
-                     wait_loop.QuitClosure(), &found_manifest));
+          base::BindOnce(WaitForAppcacheOnIO, manifest_url, appcache_service,
+                         wait_loop.QuitClosure(), &found_manifest));
       wait_loop.Run();
     } while (!found_manifest);
   }
diff --git a/chrome/browser/prerender/prerender_resource_throttle.cc b/chrome/browser/prerender/prerender_resource_throttle.cc
index b6ed41fd..0cd4fdd3 100644
--- a/chrome/browser/prerender/prerender_resource_throttle.cc
+++ b/chrome/browser/prerender/prerender_resource_throttle.cc
@@ -120,10 +120,10 @@
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&PrerenderResourceThrottle::WillStartRequestOnUI, AsWeakPtr(),
-                 request_->method(), info->GetResourceType(), request_->url(),
-                 info->GetWebContentsGetterForRequest(),
-                 prerender_throttle_info_));
+      base::BindOnce(&PrerenderResourceThrottle::WillStartRequestOnUI,
+                     AsWeakPtr(), request_->method(), info->GetResourceType(),
+                     request_->url(), info->GetWebContentsGetterForRequest(),
+                     prerender_throttle_info_));
 }
 
 void PrerenderResourceThrottle::WillRedirectRequest(
@@ -138,10 +138,11 @@
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&PrerenderResourceThrottle::WillRedirectRequestOnUI,
-                 AsWeakPtr(), header, info->GetResourceType(), info->IsAsync(),
-                 IsNoStoreResponse(*request_), redirect_info.new_url,
-                 info->GetWebContentsGetterForRequest()));
+      base::BindOnce(&PrerenderResourceThrottle::WillRedirectRequestOnUI,
+                     AsWeakPtr(), header, info->GetResourceType(),
+                     info->IsAsync(), IsNoStoreResponse(*request_),
+                     redirect_info.new_url,
+                     info->GetWebContentsGetterForRequest()));
 }
 
 void PrerenderResourceThrottle::WillProcessResponse(bool* defer) {
@@ -157,10 +158,10 @@
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&PrerenderResourceThrottle::WillProcessResponseOnUI,
-                 content::IsResourceTypeFrame(info->GetResourceType()),
-                 IsNoStoreResponse(*request_), redirect_count,
-                 prerender_throttle_info_));
+      base::BindOnce(&PrerenderResourceThrottle::WillProcessResponseOnUI,
+                     content::IsResourceTypeFrame(info->GetResourceType()),
+                     IsNoStoreResponse(*request_), redirect_count,
+                     prerender_throttle_info_));
 }
 
 const char* PrerenderResourceThrottle::GetNameForLogging() const {
@@ -202,8 +203,8 @@
                                  prerender_contents->prerender_manager());
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&PrerenderResourceThrottle::SetPrerenderMode, throttle,
-                   prerender_contents->prerender_mode()));
+        base::BindOnce(&PrerenderResourceThrottle::SetPrerenderMode, throttle,
+                       prerender_contents->prerender_mode()));
 
     // Abort any prerenders that spawn requests that use unsupported HTTP
     // methods or schemes.
@@ -250,9 +251,9 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(cancel ? &PrerenderResourceThrottle::Cancel
-                        : &PrerenderResourceThrottle::ResumeHandler,
-                 throttle));
+      base::BindOnce(cancel ? &PrerenderResourceThrottle::Cancel
+                            : &PrerenderResourceThrottle::ResumeHandler,
+                     throttle));
 }
 
 // static
@@ -297,9 +298,9 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(cancel ? &PrerenderResourceThrottle::Cancel
-                        : &PrerenderResourceThrottle::ResumeHandler,
-                 throttle));
+      base::BindOnce(cancel ? &PrerenderResourceThrottle::Cancel
+                            : &PrerenderResourceThrottle::ResumeHandler,
+                     throttle));
 }
 
 // static
diff --git a/chrome/browser/prerender/prerender_test_utils.cc b/chrome/browser/prerender/prerender_test_utils.cc
index 15f46ca..f3d0c5a 100644
--- a/chrome/browser/prerender/prerender_test_utils.cc
+++ b/chrome/browser/prerender/prerender_test_utils.cc
@@ -99,7 +99,7 @@
   void RequestStarted() {
     content::BrowserThread::PostTask(
         content::BrowserThread::UI, FROM_HERE,
-        base::Bind(&RequestCounter::RequestStarted, counter_));
+        base::BindOnce(&RequestCounter::RequestStarted, counter_));
   }
 
  private:
@@ -119,8 +119,8 @@
                          base::Callback<void(net::URLRequest*)> callback_io) {
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&CountingInterceptorWithCallback::CreateAndAddOnIO, url,
-                   counter->AsWeakPtr(), callback_io));
+        base::BindOnce(&CountingInterceptorWithCallback::CreateAndAddOnIO, url,
+                       counter->AsWeakPtr(), callback_io));
   }
 
   // net::URLRequestInterceptor:
@@ -133,7 +133,7 @@
     // Ping the request counter.
     content::BrowserThread::PostTask(
         content::BrowserThread::UI, FROM_HERE,
-        base::Bind(&RequestCounter::RequestStarted, counter_));
+        base::BindOnce(&RequestCounter::RequestStarted, counter_));
     return nullptr;
   }
 
@@ -295,8 +295,8 @@
 
   content::BrowserThread::PostTask(
       content::BrowserThread::IO, FROM_HERE,
-      base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone, this,
-                 gurl, client));
+      base::BindOnce(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
+                     this, gurl, client));
   return false;
 }
 
@@ -827,8 +827,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   content::BrowserThread::PostTask(
       content::BrowserThread::IO, FROM_HERE,
-      base::Bind(&CreateHangingFirstRequestInterceptorOnIO, url, file,
-                 callback_io));
+      base::BindOnce(&CreateHangingFirstRequestInterceptorOnIO, url, file,
+                     callback_io));
 }
 
 }  // namespace test_utils
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index 335becff..ecf843a 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -266,6 +266,11 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   content::WaitForLoadStop(
       browser()->tab_strip_model()->GetActiveWebContents());
+  // When Widget::Close is called, a task is posted that will destroy the
+  // widget. Here the widget is closed when the navigation commits. Load stop
+  // may occur right after the commit, before the widget is destroyed.
+  // Execute pending tasks to account for this.
+  base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
 
   // Try printing again.
diff --git a/chrome/browser/profiles/OWNERS b/chrome/browser/profiles/OWNERS
index 57502e8..d76ec1f 100644
--- a/chrome/browser/profiles/OWNERS
+++ b/chrome/browser/profiles/OWNERS
@@ -1,5 +1,6 @@
 anthonyvd@chromium.org
-mlerman@chromium.org
+bauerb@chromium.org
+msarda@chromium.org
 
 # ProfileKeyedServiceFactory and related
 per-file chrome_browser_main_extra_parts_profiles*=erg@chromium.org
diff --git a/chrome/browser/profiles/net_http_session_params_observer.cc b/chrome/browser/profiles/net_http_session_params_observer.cc
index 2ce3814..cc14716 100644
--- a/chrome/browser/profiles/net_http_session_params_observer.cc
+++ b/chrome/browser/profiles/net_http_session_params_observer.cc
@@ -85,8 +85,8 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&DisableQuicOnIOThread, disable_quic_callback_, io_thread,
-                 base::Unretained(safe_browsing_service)));
+      base::BindOnce(&DisableQuicOnIOThread, disable_quic_callback_, io_thread,
+                     base::Unretained(safe_browsing_service)));
 }
 
 // static
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 8c330f9..48c445d 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -163,7 +163,7 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
+      base::BindOnce(&NotifyOTRProfileCreatedOnIOThread, profile_, this));
 #endif
 
   // The DomDistillerViewerSource is not a normal WebUI so it must be registered
@@ -185,7 +185,7 @@
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&NotifyOTRProfileDestroyedOnIOThread, profile_, this));
+      base::BindOnce(&NotifyOTRProfileDestroyedOnIOThread, profile_, this));
 #endif
 
   if (pref_proxy_config_tracker_)
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index 2aa5692..dd3f2bf 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -145,8 +145,8 @@
   base::WaitableEvent unblock(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                               base::WaitableEvent::InitialState::NOT_SIGNALED);
 
-  runner->PostTask(FROM_HERE,
-      base::Bind(&base::WaitableEvent::Signal, base::Unretained(&unblock)));
+  runner->PostTask(FROM_HERE, base::BindOnce(&base::WaitableEvent::Signal,
+                                             base::Unretained(&unblock)));
 
   unblock.Wait();
 }
@@ -233,13 +233,13 @@
   void SetUpOnMainThread() override {
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
+        base::BindOnce(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
   }
 
   void TearDownOnMainThread() override {
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, false));
+        base::BindOnce(&chrome_browser_net::SetUrlRequestMocksEnabled, false));
   }
 
   std::unique_ptr<Profile> CreateProfile(const base::FilePath& path,
@@ -590,8 +590,8 @@
     base::RunLoop run_loop;
     content::BrowserThread::PostTaskAndReply(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&CompareURLRequestContexts, extension_context_getter,
-                   main_context_getter),
+        base::BindOnce(&CompareURLRequestContexts, extension_context_getter,
+                       main_context_getter),
         run_loop.QuitClosure());
     run_loop.Run();
   }
@@ -625,8 +625,8 @@
     base::RunLoop run_loop;
     content::BrowserThread::PostTaskAndReply(
         content::BrowserThread::IO, FROM_HERE,
-        base::Bind(&CompareURLRequestContexts, extension_context_getter,
-                   main_context_getter),
+        base::BindOnce(&CompareURLRequestContexts, extension_context_getter,
+                       main_context_getter),
         run_loop.QuitClosure());
     run_loop.Run();
   }
@@ -811,7 +811,7 @@
 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, SendHPKPReport) {
   content::BrowserThread::PostTask(
       content::BrowserThread::IO, FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &DisablePinningBypass,
           make_scoped_refptr(browser()->profile()->GetRequestContext())));
 
@@ -847,7 +847,7 @@
 IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, SendHPKPReportServerHangs) {
   content::BrowserThread::PostTask(
       content::BrowserThread::IO, FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &DisablePinningBypass,
           make_scoped_refptr(browser()->profile()->GetRequestContext())));
 
diff --git a/chrome/browser/profiles/profile_destroyer.cc b/chrome/browser/profiles/profile_destroyer.cc
index 1bfeb09..7eacc9b 100644
--- a/chrome/browser/profiles/profile_destroyer.cc
+++ b/chrome/browser/profiles/profile_destroyer.cc
@@ -148,8 +148,8 @@
     // Delay the destruction one step further in case other observers need to
     // look at the profile attached to the host.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&ProfileDestroyer::DestroyProfile,
-                              weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&ProfileDestroyer::DestroyProfile,
+                                  weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 0e6340d..2e05484 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -237,14 +237,13 @@
       new base::WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                               base::WaitableEvent::InitialState::NOT_SIGNALED);
   sequenced_task_runner->PostTask(
-      FROM_HERE, base::Bind(&CreateDirectoryAndSignal, path, done_creating,
-                            create_readme));
+      FROM_HERE, base::BindOnce(&CreateDirectoryAndSignal, path, done_creating,
+                                create_readme));
   // Block the FILE thread until directory is created on I/O pool to make sure
   // that we don't attempt any operation until that part completes.
-  BrowserThread::PostTask(
-      BrowserThread::FILE, FROM_HERE,
-      base::Bind(&BlockFileThreadOnDirectoryCreate,
-                 base::Owned(done_creating)));
+  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+                          base::BindOnce(&BlockFileThreadOnDirectoryCreate,
+                                         base::Owned(done_creating)));
 }
 
 base::FilePath GetCachePath(const base::FilePath& base) {
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index d35e404..f2526a0 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -359,11 +359,8 @@
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(
-          &ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread,
-          base::Unretained(io_data_),
-          time,
-          completion));
+      base::BindOnce(&ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread,
+                     base::Unretained(io_data_), time, completion));
 }
 
 void ProfileImplIOData::Handle::LazyInitialize() const {
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index 7707f2b..945344b 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -748,7 +748,7 @@
     if (!old_file_name.empty()) {
       base::FilePath image_path = path.AppendASCII(old_file_name);
       BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-                              base::Bind(&DeleteBitmap, image_path));
+                              base::BindOnce(&DeleteBitmap, image_path));
     }
   } else {
     // Save the new bitmap to disk.
@@ -924,8 +924,9 @@
                  AsWeakPtr(),
                  icon_index,
                  profile_path);
-  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-      base::Bind(&RunCallbackIfFileMissing, file_path, callback));
+  BrowserThread::PostTask(
+      BrowserThread::FILE, FROM_HERE,
+      base::BindOnce(&RunCallbackIfFileMissing, file_path, callback));
 }
 
 void ProfileInfoCache::SaveAvatarImageAtPath(
@@ -955,8 +956,9 @@
   } else {
     base::Closure callback = base::Bind(&ProfileInfoCache::OnAvatarPictureSaved,
         AsWeakPtr(), key, profile_path);
-    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-        base::Bind(&SaveBitmap, base::Passed(&data), image_path, callback));
+    BrowserThread::PostTask(
+        BrowserThread::FILE, FROM_HERE,
+        base::BindOnce(&SaveBitmap, base::Passed(&data), image_path, callback));
   }
 }
 
@@ -1098,11 +1100,12 @@
   cached_avatar_images_loading_[key] = true;
 
   gfx::Image** image = new gfx::Image*;
-  BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
-      base::Bind(&ReadBitmap, image_path, image),
-      base::Bind(&ProfileInfoCache::OnAvatarPictureLoaded,
-          const_cast<ProfileInfoCache*>(this)->AsWeakPtr(),
-          profile_path, key, image));
+  BrowserThread::PostTaskAndReply(
+      BrowserThread::FILE, FROM_HERE,
+      base::BindOnce(&ReadBitmap, image_path, image),
+      base::BindOnce(&ProfileInfoCache::OnAvatarPictureLoaded,
+                     const_cast<ProfileInfoCache*>(this)->AsWeakPtr(),
+                     profile_path, key, image));
   return NULL;
 }
 
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 6bda90f..7f5eb85 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -1241,8 +1241,8 @@
     if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
       BrowserThread::PostTask(
           BrowserThread::IO, FROM_HERE,
-          base::Bind(&NotifyContextGettersOfShutdownOnIO,
-              base::Passed(&context_getters)));
+          base::BindOnce(&NotifyContextGettersOfShutdownOnIO,
+                         base::Passed(&context_getters)));
     }
   }
 
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 26308bf..f9d0beb8 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -889,7 +889,7 @@
   // ProfileInfoCache will modify indices.
   for (const base::FilePath& profile_path : profiles_to_delete) {
     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-                            base::Bind(&NukeProfileFromDisk, profile_path));
+                            base::BindOnce(&NukeProfileFromDisk, profile_path));
 
     storage.RemoveProfile(profile_path);
   }
@@ -915,12 +915,12 @@
                         "Cleaning up now.";
         BrowserThread::PostTaskAndReply(
             BrowserThread::FILE, FROM_HERE,
-            base::Bind(&NukeProfileFromDisk, profile_path),
-            base::Bind(&ProfileCleanedUp, &value));
+            base::BindOnce(&NukeProfileFromDisk, profile_path),
+            base::BindOnce(&ProfileCleanedUp, &value));
       } else {
         // Everything is fine, the profile was removed on shutdown.
         BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                                base::Bind(&ProfileCleanedUp, &value));
+                                base::BindOnce(&ProfileCleanedUp, &value));
       }
     } else {
       LOG(ERROR) << "Found invalid profile path in deleted_profiles: "
@@ -1304,7 +1304,7 @@
   // Log the profile size after a reasonable startup delay.
   BrowserThread::PostDelayedTask(
       BrowserThread::FILE, FROM_HERE,
-      base::Bind(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
+      base::BindOnce(&ProfileSizeTask, profile->GetPath(), enabled_app_count),
       base::TimeDelta::FromSeconds(112));
 }
 
@@ -1525,9 +1525,8 @@
     profiles::RemoveBrowsingDataForProfile(profile_dir);
   } else {
     // It is safe to delete a not yet loaded Profile from disk.
-    BrowserThread::PostTask(
-        BrowserThread::FILE, FROM_HERE,
-        base::Bind(&NukeProfileFromDisk, profile_dir));
+    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+                            base::BindOnce(&NukeProfileFromDisk, profile_dir));
   }
 
   // Queue even a profile that was nuked so it will be MarkedForDeletion and so
@@ -1592,7 +1591,8 @@
           !entry->IsAuthenticated()) {
         BrowserThread::PostTask(
             BrowserThread::UI, FROM_HERE,
-            base::Bind(&SignOut, static_cast<SigninManager*>(signin_manager)));
+            base::BindOnce(&SignOut,
+                           static_cast<SigninManager*>(signin_manager)));
       }
 #endif
       return;
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 6e0bb93..4e3f002 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -89,7 +89,7 @@
     // This is safe while all file operations are done on the FILE thread.
     BrowserThread::PostTask(
         BrowserThread::FILE, FROM_HERE,
-        base::Bind(base::IgnoreResult(&base::CreateDirectory), path));
+        base::BindOnce(base::IgnoreResult(&base::CreateDirectory), path));
 
     return new TestingProfile(path, this);
   }
diff --git a/chrome/browser/profiles/profile_statistics_aggregator.cc b/chrome/browser/profiles/profile_statistics_aggregator.cc
index 7949b8f5..26d47ecb 100644
--- a/chrome/browser/profiles/profile_statistics_aggregator.cc
+++ b/chrome/browser/profiles/profile_statistics_aggregator.cc
@@ -107,7 +107,7 @@
       content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
           .get(),
       FROM_HERE,
-      base::Bind(&ProfileStatisticsAggregator::WaitOrCountBookmarks, this));
+      base::BindOnce(&ProfileStatisticsAggregator::WaitOrCountBookmarks, this));
 
   // Initiate history counting (async).
   history::HistoryService* history_service =
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 0a7208b..594dbf7b 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -109,8 +109,8 @@
       // added. Post the callback to the message loop so it gets executed after
       // the tabs are created.
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE,
-          base::Bind(callback_, profile_, Profile::CREATE_STATUS_INITIALIZED));
+          FROM_HERE, base::BindOnce(callback_, profile_,
+                                    Profile::CREATE_STATUS_INITIALIZED));
       base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
     }
   }
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
index c9da53c..e4eac62b 100644
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -525,21 +525,21 @@
 class WindowDestroyer : public content::WebContentsObserver {
  public:
   WindowDestroyer(content::WebContents* web_contents, TabStripModel* model)
-      : content::WebContentsObserver(web_contents), tab_strip_model_(model) {}
+      : content::WebContentsObserver(web_contents),
+        tab_strip_model_(model),
+        browser_closed_observer_(chrome::NOTIFICATION_BROWSER_CLOSED,
+                                 content::NotificationService::AllSources()) {}
+
+  // Wait for the browser window to be destroyed.
+  void Wait() { browser_closed_observer_.Wait(); }
 
   void RenderProcessGone(base::TerminationStatus status) override {
-    // Wait for the window to be destroyed, which will ensure all other
-    // RenderViewHost objects are deleted before we return and proceed with
-    // the next iteration of notifications.
-    content::WindowedNotificationObserver observer(
-        chrome::NOTIFICATION_BROWSER_CLOSED,
-        content::NotificationService::AllSources());
     tab_strip_model_->CloseAllTabs();
-    observer.Wait();
   }
 
  private:
   TabStripModel* tab_strip_model_;
+  content::WindowedNotificationObserver browser_closed_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowDestroyer);
 };
@@ -572,16 +572,12 @@
   // Create an object that will close the window on a process crash.
   WindowDestroyer destroyer(wc1, browser()->tab_strip_model());
 
-  content::WindowedNotificationObserver observer(
-      chrome::NOTIFICATION_BROWSER_CLOSED,
-      content::NotificationService::AllSources());
-
   // Kill the renderer process, simulating a crash. This should the ProcessDied
   // method to be called. Alternatively, RenderProcessHost::OnChannelError can
   // be called to directly force a call to ProcessDied.
   wc1->GetRenderProcessHost()->Shutdown(-1, true);
 
-  observer.Wait();
+  destroyer.Wait();
 }
 
 // Sets up the browser in order to start the tests with two tabs open: one
diff --git a/chrome/browser/signin/OWNERS b/chrome/browser/signin/OWNERS
index 931d7ff..6032d4c 100644
--- a/chrome/browser/signin/OWNERS
+++ b/chrome/browser/signin/OWNERS
@@ -1,4 +1,3 @@
-mlerman@chromium.org
 msarda@chromium.org
 rogerta@chromium.org
 
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
index 02b40db..8b564dc 100644
--- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
+++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -17,6 +17,7 @@
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/subresource_filter/content/browser/content_ruleset_service.h"
+#include "content/public/browser/navigation_handle.h"
 
 ChromeSubresourceFilterClient::ChromeSubresourceFilterClient(
     content::WebContents* web_contents)
@@ -53,9 +54,12 @@
   }
 }
 
-bool ChromeSubresourceFilterClient::IsWhitelistedByContentSettings(
-    const GURL& url) {
-  return GetContentSettingForUrl(url) == CONTENT_SETTING_BLOCK;
+bool ChromeSubresourceFilterClient::ShouldSuppressActivation(
+    content::NavigationHandle* navigation_handle) {
+  const GURL& url(navigation_handle->GetURL());
+  return navigation_handle->IsInMainFrame() &&
+         (whitelisted_hosts_.find(url.host()) != whitelisted_hosts_.end() ||
+          GetContentSettingForUrl(url) == CONTENT_SETTING_BLOCK);
 }
 
 void ChromeSubresourceFilterClient::WhitelistByContentSettings(
@@ -73,6 +77,12 @@
   LogAction(kActionContentSettingsBlockedFromUI);
 }
 
+void ChromeSubresourceFilterClient::WhitelistInCurrentWebContents(
+    const GURL& url) {
+  if (url.SchemeIsHTTPOrHTTPS())
+    whitelisted_hosts_.insert(url.host());
+}
+
 // static
 void ChromeSubresourceFilterClient::LogAction(SubresourceFilterAction action) {
   UMA_HISTOGRAM_ENUMERATION("SubresourceFilter.Actions", action,
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
index e706577..218fd72 100644
--- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
+++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_SUBRESOURCE_FILTER_CHROME_SUBRESOURCE_FILTER_CLIENT_H_
 #define CHROME_BROWSER_SUBRESOURCE_FILTER_CHROME_SUBRESOURCE_FILTER_CLIENT_H_
 
+#include <set>
+#include <string>
+
 #include "base/macros.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/subresource_filter/content/browser/subresource_filter_client.h"
@@ -12,6 +15,7 @@
 class GURL;
 
 namespace content {
+class NavigationHandle;
 class WebContents;
 }  // namespace content
 
@@ -65,8 +69,10 @@
 
   // SubresourceFilterClient:
   void ToggleNotificationVisibility(bool visibility) override;
-  bool IsWhitelistedByContentSettings(const GURL& url) override;
+  bool ShouldSuppressActivation(
+      content::NavigationHandle* navigation_handle) override;
   void WhitelistByContentSettings(const GURL& url) override;
+  void WhitelistInCurrentWebContents(const GURL& url) override;
   subresource_filter::VerifiedRulesetDealer::Handle* GetRulesetDealer()
       override;
 
@@ -74,6 +80,7 @@
 
  private:
   ContentSetting GetContentSettingForUrl(const GURL& url);
+  std::set<std::string> whitelisted_hosts_;
   content::WebContents* web_contents_;
   bool shown_for_navigation_;
 
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
index 72b15bc..5f03bad 100644
--- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
@@ -43,6 +43,37 @@
 
 namespace {
 
+class AppWindowObserver : public extensions::AppWindowRegistry::Observer {
+ public:
+  AppWindowObserver(Profile* profile)
+      : registry_(extensions::AppWindowRegistry::Get(profile)) {
+    registry_->AddObserver(this);
+  }
+
+  ~AppWindowObserver() override { registry_->RemoveObserver(this); }
+
+  void Wait(int window_count) {
+    if (windows_added_count_ < window_count) {
+      windows_added_count_expected_ = window_count;
+      run_loop_.Run();
+    }
+  }
+
+ private:
+  void OnAppWindowAdded(AppWindow* app_window) override {
+    ++windows_added_count_;
+    if (windows_added_count_expected_ > 0 &&
+        windows_added_count_ >= windows_added_count_expected_) {
+      run_loop_.Quit();
+    }
+  }
+
+  extensions::AppWindowRegistry* registry_;
+  int windows_added_count_ = 0;
+  int windows_added_count_expected_ = 0;
+  base::RunLoop run_loop_;
+};
+
 // The param selects whether to use ChromeNativeAppWindowViewsMac, otherwise it
 // will use NativeAppWindowCocoa.
 class NativeAppWindowCocoaBrowserTest
@@ -63,15 +94,13 @@
         test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal"), 1);
     EXPECT_TRUE(app_);
 
+    AppWindowObserver window_observer(profile());
     for (int i = 0; i < num_windows; ++i) {
-      content::WindowedNotificationObserver app_loaded_observer(
-          content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
-          content::NotificationService::AllSources());
       OpenApplication(AppLaunchParams(
           profile(), app_, extensions::LAUNCH_CONTAINER_NONE,
           WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST));
-      app_loaded_observer.Wait();
     }
+    window_observer.Wait(num_windows);
   }
 
   const extensions::Extension* app_;
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 7e1c93c..36f0ab7c 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -16,6 +16,7 @@
 #include "chrome/browser/download/download_shelf.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/tab_helper.h"
+#include "chrome/browser/metrics/browser_window_histogram_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "chrome/browser/shell_integration.h"
@@ -175,6 +176,12 @@
     // substantial part of startup time when any CALayers are part of the
     // window's NSView heirarchy.
     [window() makeKeyAndOrderFront:controller_];
+
+    // At this point all the Browser's UI is painted on the screen. There's no
+    // need to wait for the compositor, so pass the nullptr instead and don't
+    // store the returned instance.
+    BrowserWindowHistogramHelper::
+        MaybeRecordValueAndCreateInstanceOnBrowserPaint(nullptr);
   }
 
   // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc
index aea1ff0..9274f5f 100644
--- a/chrome/browser/ui/login/login_handler_browsertest.cc
+++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -99,6 +99,7 @@
 
 const char kMultiRealmTestPage[] = "/login/multi_realm.html";
 const int  kMultiRealmTestRealmCount = 2;
+const int kMultiRealmTestAuthRequestsCount = 4;
 
 const char kSingleRealmTestPage[] = "/login/single_realm.html";
 
@@ -462,104 +463,102 @@
 // Test handling of resources that require authentication even though
 // the page they are included on doesn't.  In this case we should only
 // present the minimal number of prompts necessary for successfully
-// displaying the page.  First we check whether cancelling works as
-// expected.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) {
+// displaying the page.
+class MultiRealmLoginPromptBrowserTest : public LoginPromptBrowserTest {
+ public:
+  void TearDownOnMainThread() override {
+    login_prompt_observer_.UnregisterAll();
+    LoginPromptBrowserTest::TearDownOnMainThread();
+  }
+
+  // Load the multi-realm test page, waits for LoginHandlers to be created, then
+  // calls |for_each_realm_func| once for each authentication realm, passing a
+  // LoginHandler for the realm as an argument. The page should stop loading
+  // after that.
+  template <class F>
+  void RunTest(const F& for_each_realm_func);
+
+  NavigationController* GetNavigationController() {
+    return &browser()
+                ->tab_strip_model()
+                ->GetActiveWebContents()
+                ->GetController();
+  }
+
+  LoginPromptBrowserTestObserver* login_prompt_observer() {
+    return &login_prompt_observer_;
+  }
+
+ private:
+  LoginPromptBrowserTestObserver login_prompt_observer_;
+};
+
+template <class F>
+void MultiRealmLoginPromptBrowserTest::RunTest(const F& for_each_realm_func) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  NavigationController* controller = GetNavigationController();
 
-  observer.Register(content::Source<NavigationController>(controller));
+  login_prompt_observer_.Register(
+      content::Source<NavigationController>(controller));
 
   WindowedLoadStopObserver load_stop_waiter(controller, 1);
 
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
+  browser()->OpenURL(OpenURLParams(test_page, Referrer(),
+                                   WindowOpenDisposition::CURRENT_TAB,
+                                   ui::PAGE_TRANSITION_TYPED, false));
 
-  int n_handlers = 0;
+  // Need to have LoginHandlers created for all requests that need
+  // authentication.
+  while (login_prompt_observer_.handlers().size() <
+         kMultiRealmTestAuthRequestsCount)
+    WindowedAuthNeededObserver(controller).Wait();
 
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
+  // Now confirm or cancel auth once per realm.
+  std::set<std::string> seen_realms;
+  for (int i = 0; i < kMultiRealmTestRealmCount; ++i) {
+    auto it = std::find_if(
+        login_prompt_observer_.handlers().begin(),
+        login_prompt_observer_.handlers().end(),
+        [&seen_realms](LoginHandler* handler) {
+          return seen_realms.count(handler->auth_info()->realm) == 0;
+        });
+    ASSERT_TRUE(it != login_prompt_observer_.handlers().end());
+    seen_realms.insert((*it)->auth_info()->realm);
 
-    while (!observer.handlers().empty()) {
-      WindowedAuthCancelledObserver auth_cancelled_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      handler->CancelAuth();
-      auth_cancelled_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
+    for_each_realm_func(*it);
   }
 
   load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_EQ(0, observer.auth_supplied_count());
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_cancelled_count());
 }
 
-// Similar to the MultipleRealmCancellation test above, but tests
-// whether supplying credentials work as exepcted.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmConfirmation) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
+// Checks that cancelling works as expected.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmCancellation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthCancelledObserver waiter(GetNavigationController());
+    handler->CancelAuth();
+    waiter.Wait();
+  });
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  EXPECT_EQ(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_cancelled_count());
+}
 
-  observer.Register(content::Source<NavigationController>(controller));
+// Checks that supplying credentials works as expected.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmConfirmation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthSuppliedObserver waiter(GetNavigationController());
+    SetAuthFor(handler);
+    waiter.Wait();
+  });
 
-  WindowedLoadStopObserver load_stop_waiter(controller, 1);
-  int n_handlers = 0;
-
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
-
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    while (!observer.handlers().empty()) {
-      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      SetAuthFor(handler);
-      auth_supplied_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
-  }
-
-  load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_supplied_count());
-  EXPECT_EQ(0, observer.auth_cancelled_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_EQ(0, login_prompt_observer()->auth_cancelled_count());
 }
 
 // Testing for recovery from an incorrect password for the case where
diff --git a/chrome/browser/ui/login/login_handler_test_utils.cc b/chrome/browser/ui/login/login_handler_test_utils.cc
index a0814c6b..d1c419d7 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.cc
+++ b/chrome/browser/ui/login/login_handler_test_utils.cc
@@ -57,6 +57,10 @@
   registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, source);
 }
 
+void LoginPromptBrowserTestObserver::UnregisterAll() {
+  registrar_.RemoveAll();
+}
+
 WindowedLoadStopObserver::WindowedLoadStopObserver(
     content::NavigationController* controller,
     int notification_count)
diff --git a/chrome/browser/ui/login/login_handler_test_utils.h b/chrome/browser/ui/login/login_handler_test_utils.h
index 8f32a54f..bf277a0 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.h
+++ b/chrome/browser/ui/login/login_handler_test_utils.h
@@ -31,6 +31,7 @@
   void RemoveHandler(LoginHandler* handler);
 
   void Register(const content::NotificationSource& source);
+  void UnregisterAll();
 
   const std::list<LoginHandler*>& handlers() const { return handlers_; }
 
diff --git a/chrome/browser/ui/views/constrained_window_views_browsertest.cc b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
index 5db441f..a78c73c2 100644
--- a/chrome/browser/ui/views/constrained_window_views_browsertest.cc
+++ b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
@@ -211,6 +211,12 @@
   content::RunAllPendingInMessageLoop();
   content::WaitForLoadStop(web_contents);
 
+  // When Widget::Close is called, a task is posted that will destroy the
+  // widget. Here the widget is closed when the navigation commits. Load stop
+  // may occur right after the commit, before the widget is destroyed.
+  // Execute pending tasks to account for this.
+  base::RunLoop().RunUntilIdle();
+
   EXPECT_EQ(nullptr, dialog->GetWidget());
   EXPECT_EQ(original_url, web_contents->GetURL());
 }
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
index 46b21878..892670e1f 100644
--- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
+++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -85,6 +85,14 @@
     return details;
   }
 
+  FindNotificationDetails WaitForFinalFindResult() {
+    while (true) {
+      auto details = WaitForFindResult();
+      if (details.final_update())
+        return details;
+    }
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(FindInPageTest);
 };
@@ -183,28 +191,28 @@
 
   // Clicking the next and previous buttons should not alter the focused view.
   ClickOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
   ClickOnView(previous_button);
-  EXPECT_EQ(1, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
 
   // Tapping the next and previous buttons should not alter the focused view.
   TapOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
   TapOnView(previous_button);
-  EXPECT_EQ(1, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
 
   // The same should be true even when the previous button is focused.
   previous_button->RequestFocus();
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
   ClickOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
   TapOnView(next_button);
-  EXPECT_EQ(3, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(3, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 4d3c09b..f614c240 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -419,8 +419,7 @@
       handling_theme_changed_(false),
       in_process_fullscreen_(false),
       force_location_bar_focus_(false),
-      activate_modal_dialog_factory_(this) {
-}
+      activate_modal_dialog_factory_(this) {}
 
 BrowserView::~BrowserView() {
   // All the tabs should have been destroyed already. If we were closed by the
@@ -2000,6 +1999,16 @@
   }
 }
 
+void BrowserView::PaintChildren(const ui::PaintContext& context) {
+  views::ClientView::PaintChildren(context);
+  // Don't reset the instance before it had a chance to get compositor callback.
+  if (!histogram_helper_) {
+    histogram_helper_ = BrowserWindowHistogramHelper::
+        MaybeRecordValueAndCreateInstanceOnBrowserPaint(
+            GetWidget()->GetCompositor());
+  }
+}
+
 void BrowserView::ChildPreferredSizeChanged(View* child) {
   Layout();
 }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index e0f70e8..c1a2b41 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -19,6 +19,7 @@
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_commands_global_registry.h"
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
+#include "chrome/browser/metrics/browser_window_histogram_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
@@ -438,6 +439,7 @@
   void OnGestureEvent(ui::GestureEvent* event) override;
   void ViewHierarchyChanged(
       const ViewHierarchyChangedDetails& details) override;
+  void PaintChildren(const ui::PaintContext& context) override;
   void ChildPreferredSizeChanged(View* child) override;
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   void OnThemeChanged() override;
@@ -712,6 +714,8 @@
   std::unique_ptr<ExtensionKeybindingRegistryViews>
       extension_keybinding_registry_;
 
+  std::unique_ptr<BrowserWindowHistogramHelper> histogram_helper_;
+
   mutable base::WeakPtrFactory<BrowserView> activate_modal_dialog_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserView);
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc
index d26b78ec..375ec5f 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.cc
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -288,7 +288,7 @@
   if (shipping_option) {
     std::unique_ptr<views::Label> shipping_label =
         base::MakeUnique<views::Label>(
-            base::ASCIIToUTF16(shipping_option->label));
+            base::UTF8ToUTF16(shipping_option->label));
     shipping_label->set_id(
         static_cast<int>(DialogViewID::SHIPPING_OPTION_DESCRIPTION));
     container->AddChildView(shipping_label.release());
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 5d390b8..2aab0f02 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -429,7 +429,7 @@
   for (size_t i = 0; i < items.size() && i < kMaxNumberOfItemsShown; ++i) {
     item_summaries_layout->StartRow(0, 0);
     item_summaries_layout->AddView(
-        new views::Label(base::ASCIIToUTF16(items[i]->label)));
+        new views::Label(base::UTF8ToUTF16(items[i]->label)));
 
     item_amounts_layout->StartRow(0, 0);
     item_amounts_layout->AddView(new views::Label(
@@ -453,7 +453,7 @@
 
   item_summaries_layout->StartRow(0, 0);
   item_summaries_layout->AddView(
-      CreateBoldLabel(base::ASCIIToUTF16(spec()->details().total->label))
+      CreateBoldLabel(base::UTF8ToUTF16(spec()->details().total->label))
           .release());
 
   item_amounts_layout->StartRow(0, 0);
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
index d0378734..048a005a 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
@@ -96,6 +96,13 @@
 
 base::string16 ShippingAddressEditorViewController::GetInitialValueForType(
     autofill::ServerFieldType type) {
+  // Temporary profile has precedence over profile to edit since its existence
+  // is based on having unsaved stated to restore.
+  if (temporary_profile_.get()) {
+    return temporary_profile_->GetInfo(autofill::AutofillType(type),
+                                       state()->GetApplicationLocale());
+  }
+
   if (!profile_to_edit_)
     return base::string16();
 
@@ -104,36 +111,10 @@
 }
 
 bool ShippingAddressEditorViewController::ValidateModelAndSave() {
-  const std::string& locale = state()->GetApplicationLocale();
   // To validate the profile first, we use a temporary object.
   autofill::AutofillProfile profile;
-  for (const auto& field : text_fields()) {
-    // Force a blur in case the value was left untouched.
-    field.first->OnBlur();
-    // ValidatingTextfield* is the key, EditorField is the value.
-    if (field.first->invalid())
-      return false;
-
-    profile.SetInfo(autofill::AutofillType(field.second.type),
-                    field.first->text(), locale);
-  }
-  for (const auto& field : comboboxes()) {
-    // ValidatingCombobox* is the key, EditorField is the value.
-    ValidatingCombobox* combobox = field.first;
-    if (combobox->invalid())
-      return false;
-
-    if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) {
-      profile.SetInfo(
-          autofill::AutofillType(field.second.type),
-          base::UTF8ToUTF16(country_codes_[combobox->selected_index()]),
-          locale);
-    } else {
-      profile.SetInfo(autofill::AutofillType(field.second.type),
-                      combobox->GetTextForRow(combobox->selected_index()),
-                      locale);
-    }
-  }
+  if (!SaveFieldsToProfile(&profile, /*ignore_errors=*/false))
+    return false;
 
   if (!profile_to_edit_) {
     // Add the profile (will not add a duplicate).
@@ -144,18 +125,9 @@
     // method to copying |profile| into |profile_to_edit_|, because the latter
     // object needs to retain other properties (use count, use date, guid,
     // etc.).
-    for (const auto& field : text_fields()) {
-      profile_to_edit_->SetInfo(
-          autofill::AutofillType(field.second.type),
-          profile.GetInfo(autofill::AutofillType(field.second.type), locale),
-          locale);
-    }
-    for (const auto& field : comboboxes()) {
-      profile_to_edit_->SetInfo(
-          autofill::AutofillType(field.second.type),
-          profile.GetInfo(autofill::AutofillType(field.second.type), locale),
-          locale);
-    }
+    bool success = SaveFieldsToProfile(profile_to_edit_,
+                                       /*ignore_errors=*/false);
+    DCHECK(success);
     profile_to_edit_->set_origin(autofill::kSettingsOrigin);
     state()->GetPersonalDataManager()->UpdateProfile(*profile_to_edit_);
   }
@@ -234,6 +206,8 @@
     DCHECK(country_combo_box);
     country_combo_box->SetSelectedIndex(chosen_country_index_);
   }
+  // Ignore temporary profile once the editor view has been updated.
+  temporary_profile_.reset(nullptr);
 }
 
 base::string16 ShippingAddressEditorViewController::GetSheetTitle() {
@@ -320,8 +294,9 @@
 }
 
 void ShippingAddressEditorViewController::OnDataChanged() {
-  // TODO(crbug.com/703764): save the current state so we can map it to the new
-  // country fields as best we can.
+  temporary_profile_.reset(new autofill::AutofillProfile);
+
+  SaveFieldsToProfile(temporary_profile_.get(), /*ignore_errors*/ true);
   UpdateEditorFields();
 
   // The editor can't be updated while in the middle of a combobox event.
@@ -331,6 +306,46 @@
                  base::Unretained(this)));
 }
 
+bool ShippingAddressEditorViewController::SaveFieldsToProfile(
+    autofill::AutofillProfile* profile,
+    bool ignore_errors) {
+  const std::string& locale = state()->GetApplicationLocale();
+  bool success = true;
+  for (const auto& field : text_fields()) {
+    // Force a blur in case the value was left untouched.
+    field.first->OnBlur();
+    // ValidatingTextfield* is the key, EditorField is the value.
+    if (field.first->invalid()) {
+      success = false;
+      if (!ignore_errors)
+        return false;
+    }
+    profile->SetInfo(autofill::AutofillType(field.second.type),
+                     field.first->text(), locale);
+  }
+  for (const auto& field : comboboxes()) {
+    // ValidatingCombobox* is the key, EditorField is the value.
+    ValidatingCombobox* combobox = field.first;
+    if (combobox->invalid()) {
+      success = false;
+      if (!ignore_errors)
+        return false;
+    }
+
+    if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) {
+      profile->SetInfo(
+          autofill::AutofillType(field.second.type),
+          base::UTF8ToUTF16(country_codes_[combobox->selected_index()]),
+          locale);
+    } else {
+      profile->SetInfo(autofill::AutofillType(field.second.type),
+                       combobox->GetTextForRow(combobox->selected_index()),
+                       locale);
+    }
+  }
+  return success;
+}
+
 void ShippingAddressEditorViewController::OnComboboxModelChanged(
     views::Combobox* combobox) {
   if (combobox->id() != autofill::ADDRESS_HOME_STATE)
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
index bca043d..13e44b8 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.h
@@ -78,6 +78,10 @@
   // this controller.
   autofill::AutofillProfile* profile_to_edit_;
 
+  // A temporary profile to keep unsaved data in between relayout (e.g., when
+  // the country is changed and fields set may be different).
+  std::unique_ptr<autofill::AutofillProfile> temporary_profile_;
+
   // List of fields, reset everytime the current country changes.
   std::vector<EditorField> editor_fields_;
 
@@ -99,6 +103,11 @@
   // Called when data changes need to force a view update.
   void OnDataChanged();
 
+  // Saves the current state of the |editor_fields_| in |profile| and ignore
+  // errors if |ignore_errors| is true. Return false on errors, ignored or not.
+  bool SaveFieldsToProfile(autofill::AutofillProfile* profile,
+                           bool ignore_errors);
+
   // When a combobox model has changed, a view update might be needed, e.g., if
   // there is no data in the combobox and it must be converted to a text field.
   void OnComboboxModelChanged(views::Combobox* combobox);
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
index 6936308..bcfd5ca1 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
@@ -52,14 +52,79 @@
     return base::MakeUnique<::i18n::addressinput::NullStorage>();
   }
 
-  void SetRequiredFields() {
-    SetEditorTextfieldValue(base::ASCIIToUTF16(kNameFull), autofill::NAME_FULL);
-    SetEditorTextfieldValue(base::ASCIIToUTF16(kHomeAddress),
-                            autofill::ADDRESS_HOME_STREET_ADDRESS);
-    SetEditorTextfieldValue(base::ASCIIToUTF16(kHomeCity),
-                            autofill::ADDRESS_HOME_CITY);
-    SetEditorTextfieldValue(base::ASCIIToUTF16(kHomeZip),
-                            autofill::ADDRESS_HOME_ZIP);
+  void SetFieldTestValue(autofill::ServerFieldType type) {
+    base::string16 textfield_text;
+    switch (type) {
+      case (autofill::NAME_FULL): {
+        textfield_text = base::ASCIIToUTF16(kNameFull);
+        break;
+      }
+      case (autofill::ADDRESS_HOME_STREET_ADDRESS): {
+        textfield_text = base::ASCIIToUTF16(kHomeAddress);
+        break;
+      }
+      case (autofill::ADDRESS_HOME_CITY): {
+        textfield_text = base::ASCIIToUTF16(kHomeCity);
+        break;
+      }
+      case (autofill::ADDRESS_HOME_ZIP): {
+        textfield_text = base::ASCIIToUTF16(kHomeZip);
+        break;
+      }
+      default:
+        ADD_FAILURE() << "Unexpected type: " << type;
+    }
+    SetEditorTextfieldValue(textfield_text, type);
+  }
+
+  void SetCommonFields() {
+    SetFieldTestValue(autofill::NAME_FULL);
+    SetFieldTestValue(autofill::ADDRESS_HOME_STREET_ADDRESS);
+    SetFieldTestValue(autofill::ADDRESS_HOME_CITY);
+    SetFieldTestValue(autofill::ADDRESS_HOME_ZIP);
+  }
+
+  // First check if the requested field of |type| exists, if so set it's value
+  // in |textfield_text| and return true.
+  bool GetEditorTextfieldValueIfExists(autofill::ServerFieldType type,
+                                       base::string16* textfield_text) {
+    ValidatingTextfield* textfield = static_cast<ValidatingTextfield*>(
+        dialog_view()->GetViewByID(static_cast<int>(type)));
+    if (!textfield)
+      return false;
+    *textfield_text = textfield->text();
+    return true;
+  }
+
+  void ExpectExistingRequiredFields(
+      std::set<autofill::ServerFieldType>* unset_types) {
+    base::string16 textfield_text;
+    if (GetEditorTextfieldValueIfExists(autofill::NAME_FULL, &textfield_text)) {
+      EXPECT_EQ(base::ASCIIToUTF16(kNameFull), textfield_text);
+    } else if (unset_types) {
+      unset_types->insert(autofill::NAME_FULL);
+    }
+
+    if (GetEditorTextfieldValueIfExists(autofill::ADDRESS_HOME_STREET_ADDRESS,
+                                        &textfield_text)) {
+      EXPECT_EQ(base::ASCIIToUTF16(kHomeAddress), textfield_text);
+    } else if (unset_types) {
+      unset_types->insert(autofill::ADDRESS_HOME_STREET_ADDRESS);
+    }
+
+    if (GetEditorTextfieldValueIfExists(autofill::ADDRESS_HOME_CITY,
+                                        &textfield_text)) {
+      EXPECT_EQ(base::ASCIIToUTF16(kHomeCity), textfield_text);
+    } else if (unset_types) {
+      unset_types->insert(autofill::ADDRESS_HOME_CITY);
+    }
+
+    if (GetEditorTextfieldValueIfExists(autofill::ADDRESS_HOME_ZIP,
+                                        &textfield_text)) {
+      EXPECT_EQ(base::ASCIIToUTF16(kHomeZip), textfield_text);
+    } else if (unset_types) {
+      unset_types->insert(autofill::ADDRESS_HOME_ZIP);
+    }
   }
 
   std::string GetSelectedCountryCode() {
@@ -156,7 +221,7 @@
 
   std::string country_code(GetSelectedCountryCode());
 
-  SetRequiredFields();
+  SetCommonFields();
 
   ResetEventObserver(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
 
@@ -176,18 +241,11 @@
   DCHECK(profile);
   EXPECT_EQ(base::ASCIIToUTF16(country_code),
             profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
-  EXPECT_EQ(base::ASCIIToUTF16(kNameFull),
-            profile->GetRawInfo(autofill::NAME_FULL));
-  EXPECT_EQ(base::ASCIIToUTF16(kHomeAddress),
-            profile->GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS));
-  EXPECT_EQ(base::ASCIIToUTF16(kHomeCity),
-            profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
-  EXPECT_EQ(base::ASCIIToUTF16(kHomeZip),
-            profile->GetRawInfo(autofill::ADDRESS_HOME_ZIP));
+  ExpectExistingRequiredFields(nullptr);
 }
 
 IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressEditorTest,
-                       SwitchingCountryUpdatesView) {
+                       SwitchingCountryUpdatesViewAndKeepsValues) {
   InvokePaymentRequestUI();
 
   SetDefaultCountryData();
@@ -198,6 +256,8 @@
 
   OpenShippingAddressEditorScreen();
 
+  SetCommonFields();
+
   views::Combobox* country_combobox =
       static_cast<views::Combobox*>(dialog_view()->GetViewByID(
           static_cast<int>(autofill::ADDRESS_HOME_COUNTRY)));
@@ -208,6 +268,7 @@
   size_t num_countries = model->countries().size();
   ASSERT_GT(num_countries, 10UL);
   bool without_region_data = true;
+  std::set<autofill::ServerFieldType> unset_types;
   for (size_t country_index = 10; country_index < num_countries;
        country_index += num_countries / 10) {
     // The editor updates asynchronously when the country changes.
@@ -223,11 +284,28 @@
         AddCountryData(code);
       without_region_data = !without_region_data;
     }
+
     // The view update will invalidate the country_combobox / model pointers.
     country_combobox = nullptr;
     model = nullptr;
     WaitForObservedEvent();
 
+    // Some types could have been lost in previous countries and may now
+    // available in this country.
+    std::set<autofill::ServerFieldType> set_types;
+    for (auto type : unset_types) {
+      ValidatingTextfield* textfield = static_cast<ValidatingTextfield*>(
+          dialog_view()->GetViewByID(static_cast<int>(type)));
+      if (textfield) {
+        EXPECT_TRUE(textfield->text().empty());
+        SetFieldTestValue(type);
+        set_types.insert(type);
+      }
+    }
+    for (auto type : set_types) {
+      unset_types.erase(type);
+    }
+
     // Make sure the country combo box was properly reset to the chosen country.
     country_combobox = static_cast<views::Combobox*>(dialog_view()->GetViewByID(
         static_cast<int>(autofill::ADDRESS_HOME_COUNTRY)));
@@ -235,12 +313,14 @@
     EXPECT_EQ(country_index,
               static_cast<size_t>(country_combobox->GetSelectedRow()));
 
-    country_combobox = static_cast<views::Combobox*>(dialog_view()->GetViewByID(
-        static_cast<int>(autofill::ADDRESS_HOME_COUNTRY)));
-    DCHECK(country_combobox);
+    // And that the number of countries is still the same.
     model =
         static_cast<autofill::CountryComboboxModel*>(country_combobox->model());
     ASSERT_EQ(num_countries, model->countries().size());
+
+    // And that the fields common between previous and new country have been
+    // properly restored.
+    ExpectExistingRequiredFields(&unset_types);
   }
 }
 
@@ -274,7 +354,7 @@
   // Now any textual value can be set as the state.
   SetEditorTextfieldValue(base::ASCIIToUTF16("any state"),
                           autofill::ADDRESS_HOME_STATE);
-  SetRequiredFields();
+  SetCommonFields();
   ResetEventObserver(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
 
   // Verifying the data is in the DB.
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index c11dfe2..d6abca1 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -104,6 +104,12 @@
  private:
   void RegisterMessages() override;
 
+  void RegisterMessage(const std::string& message,
+                       const content::WebUI::MessageCallback& handler);
+
+  void HandleMessage(const content::WebUI::MessageCallback& handler,
+                     const base::ListValue* data);
+
   // Runs NetInternalsTest.callback with the given value.
   void RunJavascriptCallback(base::Value* value);
 
@@ -162,39 +168,59 @@
 }
 
 void NetInternalsTest::MessageHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback("getTestServerURL",
+  RegisterMessage(
+      "getTestServerURL",
       base::Bind(&NetInternalsTest::MessageHandler::GetTestServerURL,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("addCacheEntry",
-      base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
-      "changeNetwork",
-      base::Bind(&NetInternalsTest::MessageHandler::ChangeNetwork,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("loadPage",
-      base::Bind(&NetInternalsTest::MessageHandler::LoadPage,
-                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("prerenderPage",
-      base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage,
-                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("navigateToPrerender",
+  RegisterMessage("addCacheEntry",
+                  base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry,
+                             base::Unretained(this)));
+  RegisterMessage("changeNetwork",
+                  base::Bind(&NetInternalsTest::MessageHandler::ChangeNetwork,
+                             base::Unretained(this)));
+  RegisterMessage("loadPage",
+                  base::Bind(&NetInternalsTest::MessageHandler::LoadPage,
+                             base::Unretained(this)));
+  RegisterMessage("prerenderPage",
+                  base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage,
+                             base::Unretained(this)));
+  RegisterMessage(
+      "navigateToPrerender",
       base::Bind(&NetInternalsTest::MessageHandler::NavigateToPrerender,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("createIncognitoBrowser",
+  RegisterMessage(
+      "createIncognitoBrowser",
       base::Bind(&NetInternalsTest::MessageHandler::CreateIncognitoBrowser,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("closeIncognitoBrowser",
+  RegisterMessage(
+      "closeIncognitoBrowser",
       base::Bind(&NetInternalsTest::MessageHandler::CloseIncognitoBrowser,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("getNetLogFileContents",
-      base::Bind(
-          &NetInternalsTest::MessageHandler::GetNetLogFileContents,
-          base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("enableDataReductionProxy",
-      base::Bind(
-          &NetInternalsTest::MessageHandler::EnableDataReductionProxy,
-          base::Unretained(this)));
+  RegisterMessage(
+      "getNetLogFileContents",
+      base::Bind(&NetInternalsTest::MessageHandler::GetNetLogFileContents,
+                 base::Unretained(this)));
+  RegisterMessage(
+      "enableDataReductionProxy",
+      base::Bind(&NetInternalsTest::MessageHandler::EnableDataReductionProxy,
+                 base::Unretained(this)));
+}
+
+void NetInternalsTest::MessageHandler::RegisterMessage(
+    const std::string& message,
+    const content::WebUI::MessageCallback& handler) {
+  web_ui()->RegisterMessageCallback(
+      message, base::Bind(&NetInternalsTest::MessageHandler::HandleMessage,
+                          base::Unretained(this), handler));
+}
+
+void NetInternalsTest::MessageHandler::HandleMessage(
+    const content::WebUI::MessageCallback& handler,
+    const base::ListValue* data) {
+  // The handler might run a nested loop to wait for something.
+  base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
+      base::MessageLoop::current());
+  handler.Run(data);
 }
 
 void NetInternalsTest::MessageHandler::RunJavascriptCallback(
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index ae66d8c..9948a1874 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -151,10 +151,15 @@
         base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
   }
 
-  void CheckTitle(const char* expected_title) {
+  void CheckTitle(const char* expected_title, bool wait = false) {
+    auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
     base::string16 expected = base::ASCIIToUTF16(expected_title);
-    EXPECT_EQ(expected,
-              browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
+    base::string16 actual;
+    if (wait)
+      actual = content::TitleWatcher(web_contents, expected).WaitAndGetTitle();
+    else
+      actual = web_contents->GetTitle();
+    EXPECT_EQ(expected, actual);
   }
 
   void NavigateToDataURL(const char* html_content, const char* expected_title) {
@@ -612,15 +617,13 @@
   content::WindowedNotificationObserver observer(
         chrome::NOTIFICATION_TAB_ADDED,
         content::NotificationService::AllSources());
-  content::WindowedNotificationObserver load_stop_observer(
-      content::NOTIFICATION_LOAD_STOP,
-      content::NotificationService::AllSources());
   content::SimulateMouseClick(
       browser()->tab_strip_model()->GetActiveWebContents(), 0,
       blink::WebMouseEvent::Button::kLeft);
   observer.Wait();
-  load_stop_observer.Wait();
-  CheckTitle("popup");
+  // Need to wait for the title, because the initial page (about:blank) can stop
+  // loading before the click handler calls document.write.
+  CheckTitle("popup", true);
 
   content::WebContentsDestroyedWatcher destroyed_watcher(
       browser()->tab_strip_model()->GetActiveWebContents());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f4787108..5c3a720 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1623,6 +1623,7 @@
       "../browser/memory/tab_manager_observer_browsertest.cc",
       "../browser/metrics/metrics_memory_details_browsertest.cc",
       "../browser/metrics/metrics_service_browsertest.cc",
+      "../browser/metrics/startup_metrics_browsertest.cc",
       "../browser/metrics/tab_reactivation_tracker_browsertest.cc",
       "../browser/net/cookie_policy_browsertest.cc",
       "../browser/net/dns_probe_browsertest.cc",
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 8628f5942c..b51708c0c 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -72,7 +72,7 @@
   inputs = [
     "//net/base/load_states_list.h",
   ]
-  package_name = "org/chromium/net/impl"
+  package_path = "org/chromium/net/impl"
 }
 
 _generated_api_version_java_dir =
diff --git a/components/dom_distiller/core/android/BUILD.gn b/components/dom_distiller/core/android/BUILD.gn
index 658408dd..534a3bf 100644
--- a/components/dom_distiller/core/android/BUILD.gn
+++ b/components/dom_distiller/core/android/BUILD.gn
@@ -21,7 +21,7 @@
 }
 
 java_cpp_template("dom_distiller_core_font_family_javagen") {
-  package_name = "org/chromium/components/dom_distiller/core"
+  package_path = "org/chromium/components/dom_distiller/core"
   sources = [
     "java/src/org/chromium/components/dom_distiller/core/FontFamily.template",
   ]
@@ -31,7 +31,7 @@
 }
 
 java_cpp_template("dom_distiller_core_theme_javagen") {
-  package_name = "org/chromium/components/dom_distiller/core"
+  package_path = "org/chromium/components/dom_distiller/core"
   sources = [
     "java/src/org/chromium/components/dom_distiller/core/Theme.template",
   ]
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 0277ceb..6a09498 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -972,9 +972,7 @@
           'id': 285,
           'caption': '''Requires that the name of the local user and the remote access host owner match''',
           'tags': [],
-          'desc': '''Requires that the name of the local user and the remote access host owner match.
-
-          If this setting is enabled, then the remote access host compares the name of the local user (that the host is associated with) and the name of the Google account registered as the host owner (i.e. "johndoe" if the host is owned by "johndoe@example.com" Google account).  The remote access host will not start if the name of the host owner is different from the name of the local user that the host is associated with.  RemoteAccessHostMatchUsername policy should be used together with RemoteAccessHostDomain to also enforce that the Google account of the host owner is associated with a specific domain (i.e. "example.com").
+          'desc': '''If this setting is enabled, then the remote access host compares the name of the local user (that the host is associated with) and the name of the Google account registered as the host owner (i.e. "johndoe" if the host is owned by "johndoe@example.com" Google account).  The remote access host will not start if the name of the host owner is different from the name of the local user that the host is associated with.  RemoteAccessHostMatchUsername policy should be used together with RemoteAccessHostDomain to also enforce that the Google account of the host owner is associated with a specific domain (i.e. "example.com").
 
           If this setting is disabled or not set, then the remote access host can be associated with any local user.''',
         },
@@ -991,9 +989,7 @@
           'id': 286,
           'caption': '''URL where remote access clients should obtain their authentication token''',
           'tags': ['website-sharing'],
-          'desc': '''URL where remote access clients should obtain their authentication token.
-
-          If this policy is set, the remote access host will require authenticating clients to obtain an authentication token from this URL in order to connect. Must be used in conjunction with RemoteAccessHostTokenValidationUrl.
+          'desc': '''If this policy is set, the remote access host will require authenticating clients to obtain an authentication token from this URL in order to connect. Must be used in conjunction with RemoteAccessHostTokenValidationUrl.
 
           This feature is currently disabled server-side.''',
         },
@@ -1010,9 +1006,7 @@
           'id': 287,
           'caption': '''URL for validating remote access client authentication token''',
           'tags': ['website-sharing'],
-          'desc': '''URL for validating remote access client authentication token.
-
-          If this policy is set, the remote access host will use this URL to validate authentication tokens from remote access clients, in order to accept connections. Must be used in conjunction with RemoteAccessHostTokenUrl.
+          'desc': '''If this policy is set, the remote access host will use this URL to validate authentication tokens from remote access clients, in order to accept connections. Must be used in conjunction with RemoteAccessHostTokenUrl.
 
           This feature is currently disabled server-side.''',
         },
@@ -1029,9 +1023,7 @@
           'id': 288,
           'caption': '''Client certificate for connecting to RemoteAccessHostTokenValidationUrl''',
           'tags': [],
-          'desc': '''Client certificate for connecting to RemoteAccessHostTokenValidationUrl.
-
-          If this policy is set, the host will use a client certificate with the given issuer CN to authenticate to RemoteAccessHostTokenValidationUrl. Set it to "*" to use any available client certificate.
+          'desc': '''If this policy is set, the host will use a client certificate with the given issuer CN to authenticate to RemoteAccessHostTokenValidationUrl. Set it to "*" to use any available client certificate.
 
           This feature is currently disabled server-side.''',
         },
@@ -1297,8 +1289,7 @@
           'id': 16,
           'caption': '''Enable saving passwords to the password manager''',
           'tags': [],
-          'desc': '''
-          If this setting is enabled, users can have <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> memorize passwords and provide them automatically the next time they log in to a site.
+          'desc': '''If this setting is enabled, users can have <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> memorize passwords and provide them automatically the next time they log in to a site.
 
           If this settings is disabled, users cannot save new passwords but they
           may still use passwords that have been saved previously.
@@ -1517,9 +1508,7 @@
       'id': 358,
       'caption': '''Enable the creation of roaming copies for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> profile data''',
       'tags': ['local-data-access'],
-      'desc': '''Enables the creation of roaming copies for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> profile data.
-
-      If you enable this setting, the settings stored in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> profiles like bookmarks, autofill data, passwords, etc. will also be written to a file stored in the Roaming user profile folder or a location specified by the Administrator through the <ph name="ROAMINGPROFILELOCATION_POLICY_NAME">$1<ex>RoamingProfileLocation</ex></ph> policy.
+      'desc': '''If you enable this setting, the settings stored in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> profiles like bookmarks, autofill data, passwords, etc. will also be written to a file stored in the Roaming user profile folder or a location specified by the Administrator through the <ph name="ROAMINGPROFILELOCATION_POLICY_NAME">$1<ex>RoamingProfileLocation</ex></ph> policy.
 
       Google Sync is automatically disabled when this policy is enabled.
 
@@ -1582,11 +1571,9 @@
       'deprecated': True,
       'example_value': False,
       'id': 265,
-      'caption': '''Enables the old web-based signin''',
+      'caption': '''Enables the old web-based signin flow''',
       'tags': [],
-      'desc': '''Enables the old web-based signin flow.
-
-      This setting was named EnableWebBasedSignin prior to Chrome 42, and support for it will be removed entirely in Chrome 43.
+      'desc': '''This setting was named EnableWebBasedSignin prior to Chrome 42, and support for it will be removed entirely in Chrome 43.
 
       This setting is useful for enterprise customers who are using SSO solutions that are not compatible with the new inline signin flow yet.
       If you enable this setting, the old web-based signin flow would be used.
@@ -2250,8 +2237,7 @@
           'id': 34,
           'caption': '''Configure the list of force-installed apps and extensions''',
           'tags': ['full-admin-access'],
-          'desc': '''
-          Specifies a list of apps and extensions that are installed silently,
+          'desc': '''Specifies a list of apps and extensions that are installed silently,
           without user interaction, and which cannot be uninstalled by the
           user. All permissions requested by the apps/extensions are granted
           implicitly, without user interaction, including any additional
@@ -2632,9 +2618,7 @@
       'id': 39,
       'caption': '''Block third party cookies''',
       'tags': [],
-      'desc': '''Blocks third party cookies.
-
-      Enabling this setting prevents cookies from being set by web page elements that are not from the domain that is in the browser's address bar.
+      'desc': '''Enabling this setting prevents cookies from being set by web page elements that are not from the domain that is in the browser's address bar.
 
       Disabling this setting allows cookies to be set by web page elements that are not from the domain that is in the browser's address bar and prevents users from changing this setting.
 
@@ -3842,9 +3826,7 @@
       'id': 55,
       'caption': '''Disable support for 3D graphics APIs''',
       'tags': [],
-      'desc': '''Disable support for 3D graphics APIs.
-
-      Enabling this setting prevents web pages from accessing the graphics processing unit (GPU). Specifically, web pages can not access the WebGL API and plugins can not use the Pepper 3D API.
+      'desc': '''Enabling this setting prevents web pages from accessing the graphics processing unit (GPU). Specifically, web pages can not access the WebGL API and plugins can not use the Pepper 3D API.
 
       Disabling this setting or leaving it not set potentially allows web pages to use the WebGL API and plugins to use the Pepper 3D API. The default settings of the browser may still require command line arguments to be passed in order to use these APIs.
 
@@ -4028,9 +4010,9 @@
           'id': 60,
           'caption': '''Allow <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> to handle the listed content types''',
           'tags': [],
-          'desc': '''Allow <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> to handle the listed content types.
+          'desc': '''If this policy is set, the specified content types are handled by <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>.
 
-          If this policy is not set the default renderer will be used for all sites as specified by the 'ChromeFrameRendererSettings' policy.''',
+          If this policy is not set, the default renderer is used for all sites. (The <ph name="CHROMEFRAMERENDERERSETTINGS_POLICY_NAME">ChromeFrameRendererSettings</ph> policy may be used to configure the default renderer.)''',
         },
       ],
     },
@@ -4180,9 +4162,7 @@
       'id': 81,
       'caption': '''Allow running plugins that are outdated''',
       'tags': ['system-security'],
-      'desc': '''Allows <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to run plugins that are outdated.
-
-      If you enable this setting, outdated plugins are used as normal plugins.
+      'desc': '''If you enable this setting, outdated plugins are used as normal plugins.
 
       If you disable this setting, outdated plugins will not be used and users will not be asked for permission to run them.
 
@@ -4201,9 +4181,7 @@
       'id': 86,
       'caption': '''Always runs plugins that require authorization''',
       'tags': ['system-security'],
-      'desc': '''Allows <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to run plugins that require authorization.
-
-      If you enable this setting, plugins that are not outdated always run.
+      'desc': '''If you enable this setting, plugins that are not outdated always run.
 
       If this setting is disabled or not set, users will be asked for permission to run plugins that require authorization. These are plugins that can compromise security.''',
     },
@@ -4221,9 +4199,7 @@
       'id': 82,
       'caption': '''Enable Bookmark Bar''',
       'tags': [],
-      'desc': '''Enables the bookmark bar on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
-
-      If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will show a bookmark bar.
+      'desc': '''If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will show a bookmark bar.
 
       If you disable this setting, users will never see the bookmark bar.
 
@@ -4244,9 +4220,7 @@
       'id': 83,
       'caption': '''Enables or disables bookmark editing''',
       'tags': [],
-      'desc': '''Enables or disables editing bookmarks in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
-
-      If you enable this setting, bookmarks can be added, removed or modified. This is the default also when this policy is not set.
+      'desc': '''If you enable this setting, bookmarks can be added, removed or modified. This is the default also when this policy is not set.
 
       If you disable this setting, bookmarks can not be added, removed or modified. Existing bookmarks are still available.''',
     },
@@ -4519,9 +4493,7 @@
       'id': 103,
       'caption': '''Block access to a list of URLs''',
       'tags': ['filtering'],
-      'desc': '''Blocks access to the listed URLs.
-
-      This policy prevents the user from loading web pages from blacklisted URLs. The blacklist provides a list of URL patterns that specify which URLs will be blacklisted.
+      'desc': '''This policy prevents the user from loading web pages from blacklisted URLs. The blacklist provides a list of URL patterns that specify which URLs will be blacklisted.
 
       A URL pattern has to be formatted according to https://www.chromium.org/administrators/url-blacklist-filter-format.
 
@@ -4883,9 +4855,7 @@
       'id': 254,
       'caption': '''Limit the time for which a user authenticated via SAML can log in offline''',
       'tags': [],
-      'desc': '''Limit the time for which a user authenticated via SAML can log in offline.
-
-      During login, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can authenticate against a server (online) or using a cached password (offline).
+      'desc': '''During login, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can authenticate against a server (online) or using a cached password (offline).
 
       When this policy is set to a value of -1, the user can authenticate offline indefinitely. When this policy is set to any other value, it specifies the length of time since the last online authentication after which the user must use online authentication again.
 
@@ -5917,9 +5887,7 @@
       'id': 159,
       'caption': '''Allow playing audio''',
       'tags': [],
-      'desc': '''Allow playing audio.
-
-      When this policy is set to false, audio output will not be available on the device while the user is logged in.
+      'desc': '''When this policy is set to false, audio output will not be available on the device while the user is logged in.
 
       This policy affects all types of audio output and not only the built-in speakers. Audio accessibility features are also inhibited by this policy. Do not enable this policy if a screen reader is required for the user.
 
@@ -5938,9 +5906,7 @@
       'id': 160,
       'caption': '''Allow or deny audio capture''',
       'tags': [],
-      'desc': '''Allow or deny audio capture.
-
-      If enabled or not configured (default), the user will be prompted for
+      'desc': '''If enabled or not configured (default), the user will be prompted for
       audio capture access except for URLs configured in the
       AudioCaptureAllowedUrls list which will be granted access without prompting.
 
@@ -5985,9 +5951,7 @@
       'id': 167,
       'caption': '''Allow or deny video capture''',
       'tags': [],
-      'desc': '''Allow or deny video capture.
-
-      If enabled or not configured (default), the user will be prompted for
+      'desc': '''If enabled or not configured (default), the user will be prompted for
       video capture access except for URLs configured in the
       VideoCaptureAllowedUrls list which will be granted access without prompting.
 
@@ -6032,9 +5996,7 @@
       'id': 153,
       'caption': '''Disable taking screenshots''',
       'tags': [],
-      'desc': '''Disables taking screenshots.
-
-      If enabled screenshots cannot be taken using keyboard shortcuts or extension APIs.
+      'desc': '''If enabled, screenshots cannot be taken using keyboard shortcuts or extension APIs.
 
       If disabled or not specified, taking screenshots is allowed.'''
     },
@@ -6118,9 +6080,7 @@
       'id': 164,
       'caption': '''Add a logout button to the system tray''',
       'tags': [],
-      'desc': '''Adds a logout button to the system tray.
-
-      If enabled, a big, red logout button is shown in the system tray while a session is active and the screen is not locked.
+      'desc': '''If enabled, a big, red logout button is shown in the system tray while a session is active and the screen is not locked.
 
       If disabled or not specified, no big, red logout button is shown in the system tray.''',
     },
@@ -6219,11 +6179,9 @@
       },
       'example_value': 3600000,
       'id': 170,
-      'caption': '''Limit the session length''',
+      'caption': '''Limit the length of a user session''',
       'tags': [],
-      'desc': '''Limit the maximum length of a user session.
-
-      When this policy is set, it specifies the length of time after which a user is automatically logged out, terminating the session. The user is informed about the remaining time by a countdown timer shown in the system tray.
+      'desc': '''When this policy is set, it specifies the length of time after which a user is automatically logged out, terminating the session. The user is informed about the remaining time by a countdown timer shown in the system tray.
 
       When this policy is not set, the session length is not limited.
 
@@ -6244,9 +6202,7 @@
       'id': 240,
       'caption': '''Allow fullscreen mode''',
       'tags': [],
-      'desc': '''Allow fullscreen mode.
-
-      This policy controls the availability of fullscreen mode in which all <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> UI is hidden and only web content is visible.
+      'desc': '''This policy controls the availability of fullscreen mode in which all <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> UI is hidden and only web content is visible.
 
       If this policy is set to true or not not configured, the user, apps and extensions with appropriate permissions can enter fullscreen mode.
 
@@ -6568,9 +6524,7 @@
           'id': 180,
           'caption': '''Action to take when the idle delay is reached''',
           'tags': [],
-          'desc': '''Specify the action to take when the idle delay is reached.
-
-          Note that this policy is deprecated and will be removed in the future.
+          'desc': '''Note that this policy is deprecated and will be removed in the future.
 
           This policy provides a fallback value for the more-specific <ph name="IDLEACTIONAC_POLICY_NAME">IdleActionAC</ph> and <ph name="IDLEACTIONBATTERY_POLICY_NAME">IdleActionBattery</ph> policies. If this policy is set, its value gets used if the respective more-specific policy is not set.
 
@@ -6615,9 +6569,7 @@
           'id': 226,
           'caption': '''Action to take when the idle delay is reached while running on AC power''',
           'tags': [],
-          'desc': '''Specify the action to take when the idle delay is reached while running on AC power.
-
-          When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately.
+          'desc': '''When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately.
 
           When this policy is unset, the default action is taken, which is suspend.
 
@@ -6662,9 +6614,7 @@
           'id': 222,
           'caption': '''Action to take when the idle delay is reached while running on battery power''',
           'tags': [],
-          'desc': '''Specify the action to take when the idle delay is reached while running on battery power.
-
-          When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately.
+          'desc': '''When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately.
 
           When this policy is unset, the default action is taken, which is suspend.
 
@@ -6708,9 +6658,7 @@
           'id': 181,
           'caption': '''Action to take when the user closes the lid''',
           'tags': [],
-          'desc': '''Specify the action to take when the user closes the lid.
-
-          When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user closes the device's lid.
+          'desc': '''When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user closes the device's lid.
 
           When this policy is unset, the default action is taken, which is suspend.
 
@@ -6729,9 +6677,7 @@
           'id': 182,
           'caption': '''Specify whether audio activity affects power management''',
           'tags': [],
-          'desc': '''Specifies whether audio activity affects power management.
-
-          If this policy is set to True or is unset, the user is not considered to be idle while audio is playing. This prevents the idle timeout from being reached and the idle action from being taken. However, screen dimming, screen off and screen lock will be performed after the configured timeouts, irrespective of audio activity.
+          'desc': '''If this policy is set to True or is unset, the user is not considered to be idle while audio is playing. This prevents the idle timeout from being reached and the idle action from being taken. However, screen dimming, screen off and screen lock will be performed after the configured timeouts, irrespective of audio activity.
 
           If this policy is set to False, audio activity does not prevent the user from being considered idle.''',
         },
@@ -6748,9 +6694,7 @@
           'id': 183,
           'caption': '''Specify whether video activity affects power management''',
           'tags': [],
-          'desc': '''Specifies whether video activity affects power management.
-
-          If this policy is set to True or is unset, the user is not considered to be idle while video is playing. This prevents the idle delay, screen dim delay, screen off delay and screen lock delay from being reached and the corresponding actions from being taken.
+          'desc': '''If this policy is set to True or is unset, the user is not considered to be idle while video is playing. This prevents the idle delay, screen dim delay, screen off delay and screen lock delay from being reached and the corresponding actions from being taken.
 
           If this policy is set to False, video activity does not prevent the user from being considered idle.''',
           'arc_support': 'Video playing in Android apps is not taken into consideration, even if this policy is set to <ph name="TRUE">True</ph>.',
@@ -6916,9 +6860,7 @@
           'id': 258,
           'caption': '''Power management settings when the user becomes idle''',
           'tags': [],
-          'desc': '''Configure power management settings when the user becomes idle.
-
-          This policy controls multiple settings for the power management strategy when the user becomes idle.
+          'desc': '''This policy controls multiple settings for the power management strategy when the user becomes idle.
 
           There are four types of action:
           * The screen will be dimmed if the user remains idle for the time specified by |ScreenDim|.
@@ -7127,9 +7069,7 @@
           'id': 188,
           'caption': '''Show accessibility options in system tray menu''',
           'tags': [],
-          'desc': '''Show <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> accessibility options in the system menu.
-
-          If this policy is set to true, Accessibility options always appear in system tray menu.
+          'desc': '''If this policy is set to true, Accessibility options always appear in system tray menu.
 
           If this policy is set to false, Accessibility options never appear in system tray menu.
 
@@ -7282,9 +7222,7 @@
           'id': 214,
           'caption': '''Set screen magnifier type''',
           'tags': [],
-          'desc': '''Set the type of screen magnifier that is enabled.
-
-          If this policy is set, it controls the type of screen magnifier that is enabled. Setting the policy to "None" disables the screen magnifier.
+          'desc': '''If this policy is set, it controls the type of screen magnifier that is enabled. Setting the policy to "None" disables the screen magnifier.
 
           If you set this policy, users cannot change or override it.
 
@@ -7683,9 +7621,7 @@
           'id': 204,
           'caption': '''Default behavior for sites not in any content pack''',
           'tags': [],
-          'desc': '''The default behavior for sites not in any content pack.
-
-          This policy is for internal use by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> itself.''',
+          'desc': '''This policy is for internal use by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> itself.''',
         },
         {
           'name': 'ContentPackManualBehaviorHosts',
@@ -7902,9 +7838,7 @@
       'id': 249,
       'caption': '''User avatar image''',
       'tags': [],
-      'desc': '''Configure user avatar image.
-
-      This policy allows you to configure the avatar image representing the user on the login screen. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the avatar image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its size must not exceed 512kB. The URL must be accessible without any authentication.
+      'desc': '''This policy allows you to configure the avatar image representing the user on the login screen. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the avatar image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its size must not exceed 512kB. The URL must be accessible without any authentication.
 
       The avatar image is downloaded and cached. It will be re-downloaded whenever the URL or the hash changes.
 
@@ -7949,9 +7883,7 @@
       'id': 262,
       'caption': '''Wallpaper image''',
       'tags': [],
-      'desc': '''Configure wallpaper image.
-
-      This policy allows you to configure the wallpaper image that is shown on the desktop and on the login screen background for the user. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the wallpaper image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its file size must not exceed 16MB. The URL must be accessible without any authentication.
+      'desc': '''This policy allows you to configure the wallpaper image that is shown on the desktop and on the login screen background for the user. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the wallpaper image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its file size must not exceed 16MB. The URL must be accessible without any authentication.
 
       The wallpaper image is downloaded and cached. It will be re-downloaded whenever the URL or the hash changes.
 
@@ -8051,9 +7983,7 @@
       'id': 272,
       'caption': '''Allows Smart Lock to be used''',
       'tags': [],
-      'desc': '''Allows Smart Lock to be used on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices.
-
-      If you enable this setting, users will be allowed to use Smart Lock if the requirements for the feature are satisfied.
+      'desc': '''If you enable this setting, users will be allowed to use Smart Lock if the requirements for the feature are satisfied.
 
       If you disable this setting, users will not be allowed to use Smart Lock.
 
@@ -8539,9 +8469,7 @@
       'id': 303,
       'caption': 'Enable showing the welcome page on the first browser launch following OS upgrade',
       'tags': [],
-      'desc': '''Enable showing the welcome page on the first browser launch following OS upgrade.
-
-      If this policy is set to true or not configured, the browser will re-show the welcome page on the first launch following an OS upgrade.
+      'desc': '''If this policy is set to true or not configured, the browser will re-show the welcome page on the first launch following an OS upgrade.
 
       If this policy is set to false, the browser will not re-show the welcome page on the first launch following an OS upgrade.''',
       'features': {
@@ -8563,9 +8491,7 @@
       'id': 304,
       'caption': '''Use hardware acceleration when available''',
       'tags': [],
-      'desc': '''Use hardware acceleration when available.
-
-      If this policy is set to true or left unset, hardware acceleration will be enabled unless a certain GPU feature is blacklisted.
+      'desc': '''If this policy is set to true or left unset, hardware acceleration will be enabled unless a certain GPU feature is blacklisted.
 
       If this policy is set to false, hardware acceleration will be disabled.''',
     },
@@ -8896,9 +8822,7 @@
     {
       'name': 'TaskManagerEndProcessEnabled',
       'caption': '''Enables ending processes in Task Manager''',
-      'desc': '''Enables ending processes in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s Task Manager.
-
-      If set to false, the 'End process' button is disabled in the Task Manager.
+      'desc': '''If set to false, the 'End process' button is disabled in the Task Manager.
 
       If set to true or not configured, the user can end processes in the Task Manager.''',
       'type': 'main',
@@ -9005,9 +8929,7 @@
     {
       'name': 'AllowScreenLock',
       'caption': '''Permit locking the screen''',
-      'desc': '''Permit locking the screen.
-
-      If this policy is set to false, users will not be able to lock the screen (only signing out from the user session will be possible). If this setting is set to true or not set, users who authenticated with a password can lock the screen.''',
+      'desc': '''If this policy is set to false, users will not be able to lock the screen (only signing out from the user session will be possible). If this setting is set to true or not set, users who authenticated with a password can lock the screen.''',
       'type': 'main',
       'schema': { 'type': 'boolean' },
       'supported_on': ['chrome_os:52-'],
@@ -9437,11 +9359,12 @@
           'id': 354,
           'caption': '''Sets the minimum length of the lock screen PIN''',
           'tags': [],
-          'desc': '''This setting controls the minimum PIN length.
+          'desc': '''If the policy is set, the configured minimal PIN length is
+          enforced. (The absolute minimum PIN length is 1; values less than 1
+          are treated as 1.)
 
-          The absolute minimum PIN length is 1; values less than 1 are treated as 1.
-
-          The default and recommended minimum PIN length is 6 digits.''',
+          If the policy is not set, a minimal PIN length of 6 digits is
+          enforced. This is the recommended minimum.''',
         },
         {
           'name': 'PinUnlockMaximumLength',
@@ -9456,13 +9379,9 @@
           'id': 355,
           'caption': '''Sets the maximum length of the lock screen PIN''',
           'tags': [],
-          'desc': '''This setting controls the maximum PIN length.
+          'desc': '''If the policy is set, the configured maximal PIN length is enforced. A value of 0 or less means no maximum length; in that case the user may set a PIN as long as they want. If this setting is less than <ph name="PIN_UNLOCK_MINIMUM_LENGTH_POLICY_NAME">PinUnlockMinimumLength</ph> but greater than 0, the maximum length is the same as the minimum length.
 
-          If this setting is 0 or less, there is no maximum length; the user can set a PIN as long as they want.
-
-          If this setting is less than <ph name="PIN_UNLOCK_MINIMUM_LENGTH_POLICY_NAME">PinUnlockMinimumLength</ph> but greater than 0, the maximum length is the same as the minimum length.
-
-          This setting defaults to no maximum length.''',
+          If the policy is not set, no maximum length is enforced.''',
         },
         {
           'name': 'PinUnlockWeakPinsAllowed',
diff --git a/components/profile_metrics/OWNERS b/components/profile_metrics/OWNERS
index e43d48c..eccc04a 100644
--- a/components/profile_metrics/OWNERS
+++ b/components/profile_metrics/OWNERS
@@ -1,5 +1,4 @@
 anthonyvd@chromium.org
 erg@chromium.org
-mlerman@chromium.org
 
 # COMPONENT: UI>Browser>Profiles
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index f1ad613..93c77d4 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -39,7 +39,7 @@
 
 // Mark as volatile to defensively make sure usage is thread-safe.
 // Note that at the time of this writing, access is only on the UI thread.
-volatile bool g_non_browser_ui_displayed = false;
+volatile bool g_main_window_startup_interrupted = false;
 
 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks =
     LAZY_INSTANCE_INITIALIZER;
@@ -388,12 +388,12 @@
 // also the time taken to synchronously resolve base::Time::Now() and
 // base::TimeTicks::Now() at play, but in practice it is pretty much instant
 // compared to multi-seconds startup timings.
-base::TimeTicks StartupTimeToTimeTicks(const base::Time& time) {
-  // First get a base which represents the same point in time in both units.
-  // Bump the priority of this thread while doing this as the wall clock time it
-  // takes to resolve these two calls affects the precision of this method and
-  // bumping the priority reduces the likelihood of a context switch interfering
-  // with this computation.
+base::TimeTicks StartupTimeToTimeTicks(base::Time time) {
+// First get a base which represents the same point in time in both units.
+// Bump the priority of this thread while doing this as the wall clock time it
+// takes to resolve these two calls affects the precision of this method and
+// bumping the priority reduces the likelihood of a context switch interfering
+// with this computation.
 
 // Enabling this logic on OS X causes a significant performance regression.
 // https://crbug.com/601270
@@ -455,9 +455,9 @@
 
 // Record renderer main entry time histogram.
 void RecordRendererMainEntryHistogram() {
-  const base::TimeTicks& browser_main_entry_point_ticks =
+  const base::TimeTicks browser_main_entry_point_ticks =
       g_browser_main_entry_point_ticks.Get();
-  const base::TimeTicks& renderer_main_entry_point_ticks =
+  const base::TimeTicks renderer_main_entry_point_ticks =
       g_renderer_main_entry_point_ticks.Get();
 
   if (!browser_main_entry_point_ticks.is_null() &&
@@ -548,6 +548,11 @@
                            g_startups_with_current_version);
 }
 
+bool ShouldLogStartupHistogram() {
+  return !WasMainWindowStartupInterrupted() &&
+         !g_process_creation_ticks.Get().is_null();
+}
+
 }  // namespace
 
 void RegisterPrefs(PrefRegistrySimple* registry) {
@@ -557,21 +562,25 @@
   registry->RegisterIntegerPref(prefs::kSameVersionStartupCount, 0);
 }
 
-bool WasNonBrowserUIDisplayed() {
-  return g_non_browser_ui_displayed;
+bool WasMainWindowStartupInterrupted() {
+  return g_main_window_startup_interrupted;
 }
 
 void SetNonBrowserUIDisplayed() {
-  g_non_browser_ui_displayed = true;
+  g_main_window_startup_interrupted = true;
 }
 
-void RecordStartupProcessCreationTime(const base::Time& time) {
+void SetBackgroundModeEnabled() {
+  g_main_window_startup_interrupted = true;
+}
+
+void RecordStartupProcessCreationTime(base::Time time) {
   DCHECK(g_process_creation_ticks.Get().is_null());
   g_process_creation_ticks.Get() = StartupTimeToTimeTicks(time);
   DCHECK(!g_process_creation_ticks.Get().is_null());
 }
 
-void RecordMainEntryPointTime(const base::Time& time) {
+void RecordMainEntryPointTime(base::Time time) {
   DCHECK(g_browser_main_entry_point_ticks.Get().is_null());
   g_browser_main_entry_point_ticks.Get() = StartupTimeToTimeTicks(time);
   DCHECK(!g_browser_main_entry_point_ticks.Get().is_null());
@@ -583,13 +592,13 @@
   DCHECK(!g_browser_main_entry_point_time.Get().is_null());
 }
 
-void RecordExeMainEntryPointTicks(const base::TimeTicks& ticks) {
+void RecordExeMainEntryPointTicks(base::TimeTicks ticks) {
   DCHECK(g_browser_exe_main_entry_point_ticks.Get().is_null());
   g_browser_exe_main_entry_point_ticks.Get() = ticks;
   DCHECK(!g_browser_exe_main_entry_point_ticks.Get().is_null());
 }
 
-void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
+void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
                                        bool is_first_run,
                                        PrefService* pref_service) {
   DCHECK(pref_service);
@@ -604,8 +613,7 @@
   // Record timing of the browser message-loop start time.
   base::StackSamplingProfiler::SetProcessMilestone(
       metrics::CallStackProfileMetricsProvider::MAIN_LOOP_START);
-  const base::TimeTicks& process_creation_ticks =
-      g_process_creation_ticks.Get();
+  const base::TimeTicks process_creation_ticks = g_process_creation_ticks.Get();
   if (!is_first_run && !process_creation_ticks.is_null()) {
     UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
         UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserMessageLoopStartTime",
@@ -657,12 +665,12 @@
   }
 }
 
-void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) {
+void RecordBrowserWindowDisplay(base::TimeTicks ticks) {
   static bool is_first_call = true;
   if (!is_first_call || ticks.is_null())
     return;
   is_first_call = false;
-  if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+  if (!ShouldLogStartupHistogram())
     return;
 
   UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
@@ -670,7 +678,7 @@
       g_process_creation_ticks.Get(), ticks);
 }
 
-void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) {
+void RecordBrowserOpenTabsDelta(base::TimeDelta delta) {
   static bool is_first_call = true;
   if (!is_first_call)
     return;
@@ -680,19 +688,19 @@
       UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserOpenTabs", delta);
 }
 
-void RecordRendererMainEntryTime(const base::TimeTicks& ticks) {
+void RecordRendererMainEntryTime(base::TimeTicks ticks) {
   // Record the renderer main entry time, but don't log the UMA metric
   // immediately because the startup temperature is not known yet.
   if (g_renderer_main_entry_point_ticks.Get().is_null())
     g_renderer_main_entry_point_ticks.Get() = ticks;
 }
 
-void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) {
+void RecordFirstWebContentsMainFrameLoad(base::TimeTicks ticks) {
   static bool is_first_call = true;
   if (!is_first_call || ticks.is_null())
     return;
   is_first_call = false;
-  if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+  if (!ShouldLogStartupHistogram())
     return;
 
   UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
@@ -700,7 +708,7 @@
       g_process_creation_ticks.Get(), ticks);
 }
 
-void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) {
+void RecordFirstWebContentsNonEmptyPaint(base::TimeTicks ticks) {
   static bool is_first_call = true;
   if (!is_first_call || ticks.is_null())
     return;
@@ -710,7 +718,7 @@
   // entry time and the startup temperature are known.
   RecordRendererMainEntryHistogram();
 
-  if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+  if (!ShouldLogStartupHistogram())
     return;
 
   base::StackSamplingProfiler::SetProcessMilestone(
@@ -720,13 +728,13 @@
       g_process_creation_ticks.Get(), ticks);
 }
 
-void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
+void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
                                                WebContentsWorkload workload) {
   static bool is_first_call = true;
   if (!is_first_call || ticks.is_null())
     return;
   is_first_call = false;
-  if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+  if (!ShouldLogStartupHistogram())
     return;
 
   base::StackSamplingProfiler::SetProcessMilestone(
@@ -752,13 +760,12 @@
   }
 }
 
-void RecordFirstWebContentsMainNavigationFinished(
-    const base::TimeTicks& ticks) {
+void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks) {
   static bool is_first_call = true;
   if (!is_first_call || ticks.is_null())
     return;
   is_first_call = false;
-  if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+  if (!ShouldLogStartupHistogram())
     return;
 
   base::StackSamplingProfiler::SetProcessMilestone(
@@ -769,6 +776,34 @@
       g_process_creation_ticks.Get(), ticks);
 }
 
+void RecordBrowserWindowFirstPaint(base::TimeTicks ticks) {
+  static bool is_first_call = true;
+  if (!is_first_call || ticks.is_null())
+    return;
+  is_first_call = false;
+  if (!ShouldLogStartupHistogram())
+    return;
+
+  UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE(
+      UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserWindow.FirstPaint",
+      g_process_creation_ticks.Get(), ticks);
+}
+
+void RecordBrowserWindowFirstPaintCompositingEnded(
+    const base::TimeTicks ticks) {
+  static bool is_first_call = true;
+  if (!is_first_call || ticks.is_null())
+    return;
+  is_first_call = false;
+  if (!ShouldLogStartupHistogram())
+    return;
+
+  UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE(
+      UMA_HISTOGRAM_LONG_TIMES_100,
+      "Startup.BrowserWindow.FirstPaint.CompositingEnded",
+      g_process_creation_ticks.Get(), ticks);
+}
+
 base::TimeTicks MainEntryPointTicks() {
   return g_browser_main_entry_point_ticks.Get();
 }
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/browser/startup_metric_utils.h
index 5ebb8ff..2e6fd0d 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.h
+++ b/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -30,10 +30,9 @@
 // Registers startup related prefs in |registry|.
 void RegisterPrefs(PrefRegistrySimple* registry);
 
-// Returns true if any UI other than the browser window has been displayed
-// so far.  Useful to test if UI has been displayed before the first browser
-// window was shown, which would invalidate any surrounding timing metrics.
-bool WasNonBrowserUIDisplayed();
+// Returns true when browser UI was not launched normally: some other UI was
+// shown first or browser was launched in background mode.
+bool WasMainWindowStartupInterrupted();
 
 // Call this when displaying UI that might potentially delay startup events.
 //
@@ -43,54 +42,66 @@
 // been displayed or not.
 void SetNonBrowserUIDisplayed();
 
+// Call this when background mode gets enabled, as it might delay startup
+// events.
+void SetBackgroundModeEnabled();
+
 // Call this with the creation time of the startup (initial/main) process.
-void RecordStartupProcessCreationTime(const base::Time& time);
+void RecordStartupProcessCreationTime(base::Time time);
 
 // Call this with a time recorded as early as possible in the startup process.
 // On Android, the entry point time is the time at which the Java code starts.
 // In Mojo, the entry point time is the time at which the shell starts.
-void RecordMainEntryPointTime(const base::Time& time);
+void RecordMainEntryPointTime(base::Time time);
 
 // Call this with the time when the executable is loaded and main() is entered.
 // Can be different from |RecordMainEntryPointTime| when the startup process is
 // contained in a separate dll, such as with chrome.exe / chrome.dll on Windows.
-void RecordExeMainEntryPointTicks(const base::TimeTicks& time);
+void RecordExeMainEntryPointTicks(base::TimeTicks time);
 
 // Call this with the time recorded just before the message loop is started.
 // |is_first_run| - is the current launch part of a first run. |pref_service| is
 // used to store state for stats that span multiple startups.
-void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
+void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
                                        bool is_first_run,
                                        PrefService* pref_service);
 
 // Call this with the time when the first browser window became visible.
-void RecordBrowserWindowDisplay(const base::TimeTicks& ticks);
+void RecordBrowserWindowDisplay(base::TimeTicks ticks);
 
 // Call this with the time delta that the browser spent opening its tabs.
-void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta);
+void RecordBrowserOpenTabsDelta(base::TimeDelta delta);
 
 // Call this with a renderer main entry time. The value provided for the first
 // call to this function is used to compute
 // Startup.LoadTime.BrowserMainToRendererMain. Further calls to this
 // function are ignored.
-void RecordRendererMainEntryTime(const base::TimeTicks& ticks);
+void RecordRendererMainEntryTime(base::TimeTicks ticks);
 
 // Call this with the time when the first web contents loaded its main frame,
 // only if the first web contents was unimpended in its attempt to do so.
-void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks);
+void RecordFirstWebContentsMainFrameLoad(base::TimeTicks ticks);
 
 // Call this with the time when the first web contents had a non-empty paint,
 // only if the first web contents was unimpended in its attempt to do so.
-void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks);
+void RecordFirstWebContentsNonEmptyPaint(base::TimeTicks ticks);
 
 // Call this with the time when the first web contents began navigating its main
 // frame. Adds a suffix to its metrics according to |workload|.
-void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
+void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
                                                WebContentsWorkload workload);
 
 // Call this with the time when the first web contents successfully committed
 // its navigation for the main frame.
-void RecordFirstWebContentsMainNavigationFinished(const base::TimeTicks& ticks);
+void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks);
+
+// Call this with the time when the Browser window painted its children for the
+// first time.
+void RecordBrowserWindowFirstPaint(base::TimeTicks ticks);
+
+// Call this with the time when the Browser window painted its children for the
+// first time and we got a CompositingEnded after that.
+void RecordBrowserWindowFirstPaintCompositingEnded(base::TimeTicks ticks);
 
 // Returns the TimeTicks corresponding to main entry as recorded by
 // RecordMainEntryPointTime. Returns a null TimeTicks if a value has not been
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
index 3031908..05d70c1 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
@@ -100,12 +100,6 @@
 ContentSubresourceFilterDriverFactory::
     ~ContentSubresourceFilterDriverFactory() {}
 
-bool ContentSubresourceFilterDriverFactory::IsWhitelisted(
-    const GURL& url) const {
-  return whitelisted_hosts_.find(url.host()) != whitelisted_hosts_.end() ||
-         client_->IsWhitelistedByContentSettings(url);
-}
-
 void ContentSubresourceFilterDriverFactory::
     OnMainResourceMatchedSafeBrowsingBlacklist(
         const GURL& url,
@@ -116,15 +110,11 @@
       url, GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata));
 }
 
-void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet(
-    const GURL& url) {
-  if (url.has_host() && url.SchemeIsHTTPOrHTTPS())
-    whitelisted_hosts_.insert(url.host());
-}
-
 ContentSubresourceFilterDriverFactory::ActivationDecision
-ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL(
-    const GURL& url) const {
+ContentSubresourceFilterDriverFactory::
+    ComputeActivationDecisionForMainFrameNavigation(
+        content::NavigationHandle* navigation_handle) const {
+  const GURL& url(navigation_handle->GetURL());
   if (configuration_.activation_level == ActivationLevel::DISABLED)
     return ActivationDecision::ACTIVATION_DISABLED;
 
@@ -133,7 +123,10 @@
 
   if (!url.SchemeIsHTTPOrHTTPS())
     return ActivationDecision::UNSUPPORTED_SCHEME;
-  if (IsWhitelisted(url))
+  // TODO(csharrison): The throttle manager also performs this check. Remove
+  // this one when the activation decision is sent directly to the throttle
+  // manager.
+  if (client_->ShouldSuppressActivation(navigation_handle))
     return ActivationDecision::URL_WHITELISTED;
 
   switch (configuration_.activation_scope) {
@@ -173,7 +166,7 @@
           subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)) {
     client_->WhitelistByContentSettings(whitelist_url);
   } else {
-    AddHostOfURLToWhitelistSet(whitelist_url);
+    client_->WhitelistInCurrentWebContents(whitelist_url);
   }
   web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
 }
@@ -195,10 +188,11 @@
   if (configuration_.should_whitelist_site_on_reload &&
       NavigationIsPageReload(url, referrer, transition)) {
     // Whitelist this host for the current as well as subsequent navigations.
-    AddHostOfURLToWhitelistSet(url);
+    client_->WhitelistInCurrentWebContents(url);
   }
 
-  activation_decision_ = ComputeActivationDecisionForMainFrameURL(url);
+  activation_decision_ =
+      ComputeActivationDecisionForMainFrameNavigation(navigation_handle);
   DCHECK(activation_decision_ != ActivationDecision::UNKNOWN);
   if (activation_decision_ != ActivationDecision::ACTIVATED) {
     ResetActivationState();
@@ -224,9 +218,7 @@
 
 bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation(
     content::NavigationHandle* navigation_handle) {
-  // Never suppress subframe navigations.
-  return navigation_handle->IsInMainFrame() &&
-         IsWhitelisted(navigation_handle->GetURL());
+  return client_->ShouldSuppressActivation(navigation_handle);
 }
 
 void ContentSubresourceFilterDriverFactory::ResetActivationState() {
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
index 0e1ce22..f6c4865 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
+++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
@@ -36,7 +36,6 @@
 enum class ActivationLevel;
 enum class ActivationList;
 
-using HostPathSet = std::set<std::string>;
 using URLToActivationListsMap =
     std::unordered_map<std::string, std::set<ActivationList>>;
 
@@ -91,11 +90,6 @@
       std::unique_ptr<SubresourceFilterClient> client);
   ~ContentSubresourceFilterDriverFactory() override;
 
-  // Whitelists the host of |url|, so that page loads with the main-frame
-  // document being loaded from this host will be exempted from subresource
-  // filtering for the lifetime of this WebContents.
-  void AddHostOfURLToWhitelistSet(const GURL& url);
-
   // Called when Safe Browsing detects that the |url| corresponding to the load
   // of the main frame belongs to the blacklist with |threat_type|. If the
   // blacklist is the Safe Browsing Social Engineering ads landing, then |url|
@@ -134,14 +128,14 @@
     configuration_ = std::move(configuration);
   }
 
+  SubresourceFilterClient* client() { return client_.get(); }
+
  private:
   friend class ContentSubresourceFilterDriverFactoryTest;
   friend class safe_browsing::SafeBrowsingServiceTest;
 
   void ResetActivationState();
 
-  bool IsWhitelisted(const GURL& url) const;
-
   // content::WebContentsObserver:
   void DidStartNavigation(
       content::NavigationHandle* navigation_handle) override;
@@ -150,8 +144,8 @@
 
   // Checks base on the value of |url| and current activation scope if
   // activation signal should be sent.
-  ActivationDecision ComputeActivationDecisionForMainFrameURL(
-      const GURL& url) const;
+  ActivationDecision ComputeActivationDecisionForMainFrameNavigation(
+      content::NavigationHandle* navigation_handle) const;
 
   bool DidURLMatchActivationList(const GURL& url,
                                  ActivationList activation_list) const;
@@ -170,10 +164,6 @@
 
   std::unique_ptr<ContentSubresourceFilterThrottleManager> throttle_manager_;
 
-  // Hosts to whitelist. This is only used for per-WebContents whitelisting and
-  // is distinct from content settings whitelisting.
-  HostPathSet whitelisted_hosts_;
-
   ActivationLevel activation_level_;
   ActivationDecision activation_decision_;
   bool measure_performance_;
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
index b230b21..8f75b85 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
 
+#include <set>
+#include <string>
+
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial.h"
@@ -190,11 +193,17 @@
 
   ~MockSubresourceFilterClient() override = default;
 
-  bool IsWhitelistedByContentSettings(const GURL& url) override {
-    return false;
+  bool ShouldSuppressActivation(content::NavigationHandle* handle) override {
+    return handle->IsInMainFrame() &&
+           whitelisted_hosts_.find(handle->GetURL().host()) !=
+               whitelisted_hosts_.end();
   }
 
   void WhitelistByContentSettings(const GURL& url) override {}
+  void WhitelistInCurrentWebContents(const GURL& url) override {
+    if (url.SchemeIsHTTPOrHTTPS())
+      whitelisted_hosts_.insert(url.host());
+  }
 
   VerifiedRulesetDealer::Handle* GetRulesetDealer() override {
     return ruleset_dealer_;
@@ -203,6 +212,7 @@
   MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
 
  private:
+  std::set<std::string> whitelisted_hosts_;
   // Owned by the test harness.
   VerifiedRulesetDealer::Handle* ruleset_dealer_;
 
@@ -524,7 +534,7 @@
   const GURL url(kExampleUrlWithParams);
   NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
                               ActivationDecision::ACTIVATION_DISABLED);
-  factory()->AddHostOfURLToWhitelistSet(url);
+  factory()->client()->WhitelistInCurrentWebContents(url);
   NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
                               ActivationDecision::ACTIVATION_DISABLED);
 }
@@ -779,7 +789,7 @@
   const GURL url(kExampleUrlWithParams);
   NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
                               test_data.expected_activation_decision);
-  factory()->AddHostOfURLToWhitelistSet(url);
+  factory()->client()->WhitelistInCurrentWebContents(url);
   NavigateAndExpectActivation(
       {true}, {GURL(kExampleUrlWithParams)}, NO_REDIRECTS_HIT,
       GetActiveConfiguration().activation_level == ActivationLevel::DISABLED
@@ -830,7 +840,7 @@
                               {test_url}, expected_pattern,
                               test_data.expected_activation_decision);
   if (test_data.url_matches_activation_list) {
-    factory()->AddHostOfURLToWhitelistSet(test_url);
+    factory()->client()->WhitelistInCurrentWebContents(test_url);
     NavigateAndExpectActivation(
         {test_data.url_matches_activation_list}, {GURL(kExampleUrlWithParams)},
         expected_pattern,
diff --git a/components/subresource_filter/content/browser/subresource_filter_client.h b/components/subresource_filter/content/browser/subresource_filter_client.h
index b9be5a5..eb61f07 100644
--- a/components/subresource_filter/content/browser/subresource_filter_client.h
+++ b/components/subresource_filter/content/browser/subresource_filter_client.h
@@ -6,9 +6,14 @@
 #define COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_CLIENT_H_
 
 #include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
+#include "content/public/browser/web_contents.h"
 
 class GURL;
 
+namespace content {
+class NavigationHandle;
+}  // namespace content
+
 namespace subresource_filter {
 
 class SubresourceFilterClient {
@@ -23,14 +28,19 @@
   // off.
   virtual void ToggleNotificationVisibility(bool visibility) = 0;
 
-  // Returns true if the given URL is whitelisted from activation via content
-  // settings. This should only be called for main frame URLs.
-  virtual bool IsWhitelistedByContentSettings(const GURL& url) = 0;
+  // Returns true if the navigation is in a main frame and the URL is
+  // whitelisted from activation via content settings or by the per-tab
+  // whitelist.
+  virtual bool ShouldSuppressActivation(
+      content::NavigationHandle* navigation_handle) = 0;
 
   // Adds |url| to the BLOCKED state via content settings for the current
   // profile.
   virtual void WhitelistByContentSettings(const GURL& url) = 0;
 
+  // Adds |url| to a per-WebContents whitelist.
+  virtual void WhitelistInCurrentWebContents(const GURL& url) = 0;
+
   virtual VerifiedRulesetDealer::Handle* GetRulesetDealer() = 0;
 };
 
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
index 790fc4ff..3e55118 100644
--- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
+++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -120,8 +120,9 @@
   ~MockSubresourceFilterClient() override = default;
 
   MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
-  MOCK_METHOD1(IsWhitelistedByContentSettings, bool(const GURL&));
+  MOCK_METHOD1(ShouldSuppressActivation, bool(content::NavigationHandle*));
   MOCK_METHOD1(WhitelistByContentSettings, void(const GURL&));
+  MOCK_METHOD1(WhitelistInCurrentWebContents, void(const GURL&));
   MOCK_METHOD0(GetRulesetDealer, VerifiedRulesetDealer::Handle*());
 
  private:
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index c208d95..1b2a0b9 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -767,6 +767,8 @@
     "indexed_db/indexed_db_context_impl.h",
     "indexed_db/indexed_db_cursor.cc",
     "indexed_db/indexed_db_cursor.h",
+    "indexed_db/indexed_db_data_format_version.cc",
+    "indexed_db/indexed_db_data_format_version.h",
     "indexed_db/indexed_db_data_loss_info.h",
     "indexed_db/indexed_db_database.cc",
     "indexed_db/indexed_db_database.h",
diff --git a/content/browser/android/content_feature_list.cc b/content/browser/android/content_feature_list.cc
index c184a48a..9734477 100644
--- a/content/browser/android/content_feature_list.cc
+++ b/content/browser/android/content_feature_list.cc
@@ -7,6 +7,7 @@
 #include "base/android/jni_string.h"
 #include "base/feature_list.h"
 #include "base/macros.h"
+#include "content/public/common/content_features.h"
 #include "jni/ContentFeatureList_jni.h"
 
 using base::android::ConvertJavaStringToUTF8;
@@ -21,7 +22,7 @@
 // this array may either refer to features defined in the header of this file or
 // in other locations in the code base (e.g. content_features.h).
 const base::Feature* kFeaturesExposedToJava[] = {
-    &kRequestUnbufferedDispatch,
+    &kRequestUnbufferedDispatch, &features::kWebNfc,
 };
 
 const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index 92ff51c8..9d2b89b 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -25,6 +25,7 @@
 #include "content/browser/indexed_db/indexed_db_blob_info.h"
 #include "content/browser/indexed_db/indexed_db_class_factory.h"
 #include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_data_format_version.h"
 #include "content/browser/indexed_db/indexed_db_database_error.h"
 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
 #include "content/browser/indexed_db/indexed_db_tracing.h"
@@ -46,7 +47,6 @@
 #include "storage/common/database/database_identifier.h"
 #include "storage/common/fileapi/file_system_mount_option.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
-#include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h"
 #include "third_party/leveldatabase/env_chromium.h"
 
 using base::FilePath;
@@ -335,24 +335,19 @@
     return true;
   }
 
-  const uint32_t latest_known_data_version =
-      blink::kSerializedScriptValueVersion;
-  int64_t db_data_version = 0;
-  s = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found);
+  int64_t raw_db_data_version = 0;
+  s = GetInt(db, DataVersionKey::Encode(), &raw_db_data_version, &found);
   if (!s.ok())
     return false;
   if (!found) {
     *known = true;
     return true;
   }
-  if (db_data_version < 0)
+  if (raw_db_data_version < 0)
     return false;  // Only corruption should cause this.
-  if (db_data_version > latest_known_data_version) {
-    *known = false;
-    return true;
-  }
 
-  *known = true;
+  *known = IndexedDBDataFormatVersion::GetCurrent().IsAtLeast(
+      IndexedDBDataFormatVersion::Decode(raw_db_data_version));
   return true;
 }
 
@@ -1143,8 +1138,8 @@
 }
 
 WARN_UNUSED_RESULT Status IndexedDBBackingStore::SetUpMetadata() {
-  const uint32_t latest_known_data_version =
-      blink::kSerializedScriptValueVersion;
+  const IndexedDBDataFormatVersion latest_known_data_version =
+      IndexedDBDataFormatVersion::GetCurrent();
   const std::string schema_version_key = SchemaVersionKey::Encode();
   const std::string data_version_key = DataVersionKey::Encode();
 
@@ -1152,7 +1147,7 @@
       IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
 
   int64_t db_schema_version = 0;
-  int64_t db_data_version = 0;
+  IndexedDBDataFormatVersion db_data_version;
   bool found = false;
   Status s =
       GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
@@ -1165,7 +1160,7 @@
     db_schema_version = kLatestKnownSchemaVersion;
     PutInt(transaction.get(), schema_version_key, db_schema_version);
     db_data_version = latest_known_data_version;
-    PutInt(transaction.get(), data_version_key, db_data_version);
+    PutInt(transaction.get(), data_version_key, db_data_version.Encode());
     // If a blob directory already exists for this database, blow it away.  It's
     // leftover from a partially-purged previous generation of data.
     if (!base::DeleteFile(blob_path_, true)) {
@@ -1206,8 +1201,8 @@
     if (s.ok() && db_schema_version < 2) {
       db_schema_version = 2;
       PutInt(transaction.get(), schema_version_key, db_schema_version);
-      db_data_version = blink::kSerializedScriptValueVersion;
-      PutInt(transaction.get(), data_version_key, db_data_version);
+      db_data_version = latest_known_data_version;
+      PutInt(transaction.get(), data_version_key, db_data_version.Encode());
     }
     if (db_schema_version < 3) {
       db_schema_version = 3;
@@ -1225,7 +1220,8 @@
 
   // All new values will be written using this serialization version.
   found = false;
-  s = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
+  int64_t raw_db_data_version = 0;
+  s = GetInt(transaction.get(), data_version_key, &raw_db_data_version, &found);
   if (!s.ok()) {
     INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
     return s;
@@ -1234,13 +1230,20 @@
     INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
     return InternalInconsistencyStatus();
   }
-  if (db_data_version < latest_known_data_version) {
+  db_data_version = IndexedDBDataFormatVersion::Decode(raw_db_data_version);
+  if (latest_known_data_version == db_data_version) {
+    // Up to date. Nothing to do.
+  } else if (latest_known_data_version.IsAtLeast(db_data_version)) {
     db_data_version = latest_known_data_version;
-    PutInt(transaction.get(), data_version_key, db_data_version);
+    PutInt(transaction.get(), data_version_key, db_data_version.Encode());
+  } else {
+    // |db_data_version| is in the future according to at least one component.
+    INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
+    return InternalInconsistencyStatus();
   }
 
   DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion);
-  DCHECK_EQ(db_data_version, latest_known_data_version);
+  DCHECK(db_data_version == latest_known_data_version);
 
   s = transaction->Commit();
   if (!s.ok())
diff --git a/content/browser/indexed_db/indexed_db_data_format_version.cc b/content/browser/indexed_db/indexed_db_data_format_version.cc
new file mode 100644
index 0000000..b8a363c
--- /dev/null
+++ b/content/browser/indexed_db/indexed_db_data_format_version.cc
@@ -0,0 +1,16 @@
+// 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 "content/browser/indexed_db/indexed_db_data_format_version.h"
+
+#include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h"
+
+namespace content {
+
+// static
+IndexedDBDataFormatVersion IndexedDBDataFormatVersion::current_(
+    0,
+    blink::kSerializedScriptValueVersion);
+
+}  // namespace content
diff --git a/content/browser/indexed_db/indexed_db_data_format_version.h b/content/browser/indexed_db/indexed_db_data_format_version.h
new file mode 100644
index 0000000..72d09db
--- /dev/null
+++ b/content/browser/indexed_db/indexed_db_data_format_version.h
@@ -0,0 +1,72 @@
+// 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 CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_FORMAT_VERSION_H_
+#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_FORMAT_VERSION_H_
+
+#include <cstdint>
+#include <limits>
+
+#include "base/logging.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Contains version data for the wire format used for encoding IndexedDB values.
+// A version tuple (a, b) is at least as new as (a', b')
+// iff a >= a' and b >= b'.
+class IndexedDBDataFormatVersion {
+ public:
+  constexpr IndexedDBDataFormatVersion() {}
+  constexpr IndexedDBDataFormatVersion(uint32_t v8_version,
+                                       uint32_t blink_version)
+      : v8_version_(v8_version), blink_version_(blink_version) {}
+
+  static IndexedDBDataFormatVersion GetCurrent() { return current_; }
+  static IndexedDBDataFormatVersion& GetMutableCurrentForTesting() {
+    return current_;
+  }
+
+  uint32_t v8_version() const { return v8_version_; }
+  uint32_t blink_version() const { return blink_version_; }
+
+  bool operator==(const IndexedDBDataFormatVersion& other) const {
+    return v8_version_ == other.v8_version_ &&
+           blink_version_ == other.blink_version_;
+  }
+  bool operator!=(const IndexedDBDataFormatVersion& other) const {
+    return !operator==(other);
+  }
+
+  bool IsAtLeast(const IndexedDBDataFormatVersion& other) const {
+    return v8_version_ >= other.v8_version_ &&
+           blink_version_ >= other.blink_version_;
+  }
+
+  // Encodes and decodes the tuple from an int64_t.
+  // This scheme is chosen so that earlier versions (before we reported both the
+  // Blink and V8 versions) decode properly, with a V8 version of 0.
+  int64_t Encode() const {
+    // Since negative values are considered invalid, this scheme will only work
+    // as long as the v8 version would not overflow int32_t.  We check both
+    // components, to be consistent.
+    DCHECK_GE(static_cast<int32_t>(v8_version_), 0);
+    DCHECK_GE(static_cast<int32_t>(blink_version_), 0);
+    return (static_cast<int64_t>(v8_version_) << 32) | blink_version_;
+  }
+  static IndexedDBDataFormatVersion Decode(int64_t encoded) {
+    DCHECK_GE(encoded, 0);
+    return IndexedDBDataFormatVersion(encoded >> 32, encoded);
+  }
+
+ private:
+  uint32_t v8_version_ = 0;
+  uint32_t blink_version_ = 0;
+
+  CONTENT_EXPORT static IndexedDBDataFormatVersion current_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATA_FORMAT_VERSION_H_
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index b097121..ce1f127 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -5,6 +5,7 @@
 #include <stdint.h>
 #include <utility>
 
+#include "base/auto_reset.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
@@ -16,6 +17,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/browser/indexed_db/indexed_db_connection.h"
 #include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_data_format_version.h"
 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
@@ -70,24 +72,28 @@
 
 class IndexedDBFactoryTest : public testing::Test {
  public:
-  IndexedDBFactoryTest() {
+  void SetUp() override {
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     task_runner_ = new base::TestSimpleTaskRunner();
     quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr);
     context_ = new IndexedDBContextImpl(
-        base::FilePath(), nullptr /* special_storage_policy */,
+        temp_dir_.GetPath(), nullptr /* special_storage_policy */,
         quota_manager_proxy_.get(), task_runner_.get());
     idb_factory_ = new MockIDBFactory(context_.get());
   }
-  ~IndexedDBFactoryTest() override {
+
+  void TearDown() override {
     quota_manager_proxy_->SimulateQuotaManagerDestroyed();
   }
 
  protected:
+  IndexedDBFactoryTest() {}
   MockIDBFactory* factory() const { return idb_factory_.get(); }
   void clear_factory() { idb_factory_ = nullptr; }
   IndexedDBContextImpl* context() const { return context_.get(); }
 
  private:
+  base::ScopedTempDir temp_dir_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   scoped_refptr<IndexedDBContextImpl> context_;
   scoped_refptr<MockIDBFactory> idb_factory_;
@@ -515,4 +521,81 @@
   factory()->ForceClose(origin);
 }
 
+namespace {
+
+class DataLossCallbacks final : public MockIndexedDBCallbacks {
+ public:
+  blink::WebIDBDataLoss data_loss() const { return data_loss_; }
+  void OnSuccess(std::unique_ptr<IndexedDBConnection> connection,
+                 const IndexedDBDatabaseMetadata& metadata) override {
+    if (!connection_)
+      connection_ = std::move(connection);
+  }
+  void OnError(const IndexedDBDatabaseError& error) final {
+    ADD_FAILURE() << "Unexpected IDB error: " << error.message();
+  }
+  void OnUpgradeNeeded(int64_t old_version,
+                       std::unique_ptr<IndexedDBConnection> connection,
+                       const content::IndexedDBDatabaseMetadata& metadata,
+                       const IndexedDBDataLossInfo& data_loss) final {
+    connection_ = std::move(connection);
+    data_loss_ = data_loss.status;
+  }
+
+ private:
+  ~DataLossCallbacks() final {}
+  blink::WebIDBDataLoss data_loss_ = blink::kWebIDBDataLossNone;
+};
+
+TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
+  auto try_open = [this](const Origin& origin,
+                         const IndexedDBDataFormatVersion& version) {
+    base::AutoReset<IndexedDBDataFormatVersion> override_version(
+        &IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version);
+    auto db_callbacks = base::MakeShared<MockIndexedDBDatabaseCallbacks>();
+    auto callbacks = base::MakeShared<DataLossCallbacks>();
+    const int64_t transaction_id = 1;
+    factory()->Open(ASCIIToUTF16("test_db"),
+                    base::MakeUnique<IndexedDBPendingConnection>(
+                        callbacks, db_callbacks, 0 /* child_process_id */,
+                        transaction_id, 1 /* version */),
+                    nullptr /* request_context */, origin,
+                    context()->data_path());
+    base::RunLoop().RunUntilIdle();
+    auto* connection = callbacks->connection();
+    EXPECT_TRUE(connection);
+    connection->database()->Commit(connection->GetTransaction(transaction_id));
+    connection->Close();
+    factory()->ForceClose(origin);
+    return callbacks->data_loss();
+  };
+
+  using blink::kWebIDBDataLossNone;
+  using blink::kWebIDBDataLossTotal;
+  static const struct {
+    const char* origin;
+    IndexedDBDataFormatVersion open_version_1;
+    IndexedDBDataFormatVersion open_version_2;
+    blink::WebIDBDataLoss expected_data_loss;
+  } kTestCases[] = {
+      {"http://same-version.com/", {3, 4}, {3, 4}, kWebIDBDataLossNone},
+      {"http://blink-upgrade.com/", {3, 4}, {3, 5}, kWebIDBDataLossNone},
+      {"http://v8-upgrade.com/", {3, 4}, {4, 4}, kWebIDBDataLossNone},
+      {"http://both-upgrade.com/", {3, 4}, {4, 5}, kWebIDBDataLossNone},
+      {"http://blink-downgrade.com/", {3, 4}, {3, 3}, kWebIDBDataLossTotal},
+      {"http://v8-downgrade.com/", {3, 4}, {2, 4}, kWebIDBDataLossTotal},
+      {"http://both-downgrade.com/", {3, 4}, {2, 3}, kWebIDBDataLossTotal},
+      {"http://v8-up-blink-down.com/", {3, 4}, {4, 2}, kWebIDBDataLossTotal},
+      {"http://v8-down-blink-up.com/", {3, 4}, {2, 5}, kWebIDBDataLossTotal},
+  };
+  for (const auto& test : kTestCases) {
+    SCOPED_TRACE(test.origin);
+    const Origin origin(GURL(test.origin));
+    ASSERT_EQ(kWebIDBDataLossNone, try_open(origin, test.open_version_1));
+    EXPECT_EQ(test.expected_data_loss, try_open(origin, test.open_version_2));
+  }
+}
+
+}  // namespace
+
 }  // namespace content
diff --git a/content/browser/indexed_db/leveldb_coding_scheme.md b/content/browser/indexed_db/leveldb_coding_scheme.md
index f567416..1a449d3b 100644
--- a/content/browser/indexed_db/leveldb_coding_scheme.md
+++ b/content/browser/indexed_db/leveldb_coding_scheme.md
@@ -150,7 +150,7 @@
 ------------------------------------|------
 «0, 0, 0, 0»                        | backing store schema version (Int) [`SchemaVersionKey`]
 «0, 0, 0, 1»                        | maximum allocated database (Int) [`MaxDatabaseIdKey`]
-«0, 0, 0, 2»                        | SerializedScriptValue version (Int) [`DataVersionKey`]
+«0, 0, 0, 2»                        | data format version (Int) [`DataVersionKey`]
 «0, 0, 0, 3»                        | primary BlobJournal [`BlobJournalKey`]
 «0, 0, 0, 4»                        | live BlobJournal [`LiveBlobJournalKey`]
 «0, 0, 0, 100, database id (VarInt)» | Existence implies the database id is in the free list  [`DatabaseFreeListKey`] - _obsolete_
@@ -161,6 +161,10 @@
 sufficient.
 ***
 
+The data format version encodes a `content::IndexedDBDataFormatVersion` object.
+It includes a 32-bit version for the V8 serialization code in its most
+significant bits, and a 32-bit version for the Blink serialization code in its
+least significant 32 bits.
 
 ## Database metadata
 [`DatabaseMetaDataKey`]
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
index a6ce049..5ec74f7d 100644
--- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
+++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -27,58 +27,6 @@
 namespace content {
 namespace {
 
-void UpdateLatencyCoordinatesImpl(const blink::WebTouchEvent& touch,
-                                  LatencyInfo* latency,
-                                  float device_scale_factor) {
-  for (uint32_t i = 0; i < touch.touches_length; ++i) {
-    gfx::PointF coordinate(touch.touches[i].position.x * device_scale_factor,
-                           touch.touches[i].position.y * device_scale_factor);
-    if (!latency->AddInputCoordinate(coordinate))
-      break;
-  }
-}
-
-void UpdateLatencyCoordinatesImpl(const WebGestureEvent& gesture,
-                                  LatencyInfo* latency,
-                                  float device_scale_factor) {
-  latency->AddInputCoordinate(gfx::PointF(gesture.x * device_scale_factor,
-                                          gesture.y * device_scale_factor));
-}
-
-void UpdateLatencyCoordinatesImpl(const WebMouseEvent& mouse,
-                                  LatencyInfo* latency,
-                                  float device_scale_factor) {
-  latency->AddInputCoordinate(
-      gfx::PointF(mouse.PositionInWidget().x * device_scale_factor,
-                  mouse.PositionInWidget().y * device_scale_factor));
-}
-
-void UpdateLatencyCoordinatesImpl(const WebMouseWheelEvent& wheel,
-                                  LatencyInfo* latency,
-                                  float device_scale_factor) {
-  latency->AddInputCoordinate(
-      gfx::PointF(wheel.PositionInWidget().x * device_scale_factor,
-                  wheel.PositionInWidget().y * device_scale_factor));
-}
-
-void UpdateLatencyCoordinates(const WebInputEvent& event,
-                              float device_scale_factor,
-                              LatencyInfo* latency) {
-  if (WebInputEvent::IsMouseEventType(event.GetType())) {
-    UpdateLatencyCoordinatesImpl(static_cast<const WebMouseEvent&>(event),
-                                 latency, device_scale_factor);
-  } else if (WebInputEvent::IsGestureEventType(event.GetType())) {
-    UpdateLatencyCoordinatesImpl(static_cast<const WebGestureEvent&>(event),
-                                 latency, device_scale_factor);
-  } else if (WebInputEvent::IsTouchEventType(event.GetType())) {
-    UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event),
-                                 latency, device_scale_factor);
-  } else if (event.GetType() == WebInputEvent::kMouseWheel) {
-    UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event),
-                                 latency, device_scale_factor);
-  }
-}
-
 std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) {
   if (type == blink::WebInputEvent::kMouseWheel) {
     return "Wheel";
@@ -272,8 +220,6 @@
       ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_,
       ++last_event_id_, WebInputEvent::GetName(event.GetType()));
 
-  UpdateLatencyCoordinates(event, device_scale_factor_, latency);
-
   if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
     has_seen_first_gesture_scroll_update_ = false;
   } else if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
index 53fc6de3..827441a 100644
--- a/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
+++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc
@@ -198,7 +198,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(wheel_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(1U, wheel_latency.input_coordinates_size());
       tracker()->OnInputEventAck(wheel, &wheel_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
       tracker()->OnGpuSwapBuffersCompleted(wheel_latency);
@@ -290,7 +289,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(wheel_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(1U, wheel_latency.input_coordinates_size());
       tracker()->OnInputEventAck(wheel, &wheel_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
       tracker()->OnGpuSwapBuffersCompleted(wheel_latency);
@@ -366,7 +364,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(scroll_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(1U, scroll_latency.input_coordinates_size());
       tracker()->OnInputEventAck(scroll, &scroll_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
     }
@@ -388,7 +385,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(touch_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(2U, touch_latency.input_coordinates_size());
       tracker()->OnInputEventAck(touch, &touch_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
       tracker()->OnGpuSwapBuffersCompleted(touch_latency);
@@ -486,7 +482,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(scroll_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(1U, scroll_latency.input_coordinates_size());
       tracker()->OnInputEventAck(scroll, &scroll_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
     }
@@ -508,7 +503,6 @@
           tracker()->latency_component_id(), nullptr));
       EXPECT_TRUE(touch_latency.FindLatency(
           ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
-      EXPECT_EQ(2U, touch_latency.input_coordinates_size());
       tracker()->OnInputEventAck(touch, &touch_latency,
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
       tracker()->OnGpuSwapBuffersCompleted(touch_latency);
@@ -666,66 +660,6 @@
   EXPECT_TRUE(HistogramSizeEq("Event.Latency.ScrollUpdate.GpuSwap", 0));
 }
 
-TEST_F(RenderWidgetHostLatencyTrackerTest, InputCoordinatesPopulated) {
-  {
-    auto event =
-        SyntheticWebMouseWheelEventBuilder::Build(0, 0, -5, 0, 0, true);
-    event.SetPositionInWidget(100, 200);
-    ui::LatencyInfo latency_info;
-    tracker()->OnInputEvent(event, &latency_info);
-    EXPECT_EQ(1u, latency_info.input_coordinates_size());
-    EXPECT_EQ(100, latency_info.input_coordinates()[0].x());
-    EXPECT_EQ(200, latency_info.input_coordinates()[0].y());
-  }
-
-  {
-    auto event =
-        SyntheticWebMouseEventBuilder::Build(WebInputEvent::kMouseMove);
-    event.SetPositionInWidget(300, 400);
-    ui::LatencyInfo latency_info;
-    tracker()->OnInputEvent(event, &latency_info);
-    EXPECT_EQ(1u, latency_info.input_coordinates_size());
-    EXPECT_EQ(300, latency_info.input_coordinates()[0].x());
-    EXPECT_EQ(400, latency_info.input_coordinates()[0].y());
-  }
-
-  {
-    auto event = SyntheticWebGestureEventBuilder::Build(
-        WebInputEvent::kGestureScrollBegin,
-        blink::kWebGestureDeviceTouchscreen);
-    event.x = 500;
-    event.y = 600;
-    ui::LatencyInfo latency_info;
-    tracker()->OnInputEvent(event, &latency_info);
-    EXPECT_EQ(1u, latency_info.input_coordinates_size());
-    EXPECT_EQ(500, latency_info.input_coordinates()[0].x());
-    EXPECT_EQ(600, latency_info.input_coordinates()[0].y());
-  }
-
-  {
-    SyntheticWebTouchEvent event;
-    event.PressPoint(700, 800);
-    event.PressPoint(900, 1000);
-    event.PressPoint(1100, 1200);  // LatencyInfo only holds two coordinates.
-    ui::LatencyInfo latency_info;
-    tracker()->OnInputEvent(event, &latency_info);
-    EXPECT_EQ(2u, latency_info.input_coordinates_size());
-    EXPECT_EQ(700, latency_info.input_coordinates()[0].x());
-    EXPECT_EQ(800, latency_info.input_coordinates()[0].y());
-    EXPECT_EQ(900, latency_info.input_coordinates()[1].x());
-    EXPECT_EQ(1000, latency_info.input_coordinates()[1].y());
-  }
-
-  {
-    NativeWebKeyboardEvent event(blink::WebKeyboardEvent::kKeyDown,
-                                 blink::WebInputEvent::kNoModifiers,
-                                 base::TimeTicks::Now());
-    ui::LatencyInfo latency_info;
-    tracker()->OnInputEvent(event, &latency_info);
-    EXPECT_EQ(0u, latency_info.input_coordinates_size());
-  }
-}
-
 TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) {
   auto scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(
       5, -5, blink::kWebGestureDeviceTouchscreen);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 372a996..f9e8318 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -1084,9 +1084,13 @@
 
 // Test that scrolling a nested out-of-process iframe bubbles unused scroll
 // delta to a parent frame.
-// Flaky: https://crbug.com/627238
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#define MAYBE_ScrollBubblingFromOOPIFTest DISABLED_ScrollBubblingFromOOPIFTest
+#else
+#define MAYBE_ScrollBubblingFromOOPIFTest ScrollBubblingFromOOPIFTest
+#endif
 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
-                       DISABLED_ScrollBubblingFromOOPIFTest) {
+                       MAYBE_ScrollBubblingFromOOPIFTest) {
   GURL main_url(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(b)"));
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -1154,6 +1158,10 @@
   scroll_event.SetPositionInWidget(1, 1);
   scroll_event.delta_x = 0.0f;
   scroll_event.delta_y = -5.0f;
+  // Set has_precise_scroll_deltas to keep these events off the animated scroll
+  // pathways, which currently break this test.
+  // https://bugs.chromium.org/p/chromium/issues/detail?id=710513
+  scroll_event.has_precise_scrolling_deltas = true;
   rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
 
   // Ensure that the view position is propagated to the child properly.
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index d0a3c95..d51e61f 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -370,6 +370,11 @@
                                                 false);
   }
 
+#if defined(OS_ANDROID)
+  if (base::FeatureList::IsEnabled(features::kWebNfc))
+    WebRuntimeFeatures::EnableWebNfc(true);
+#endif
+
   // Enable explicitly enabled features, and then disable explicitly disabled
   // ones.
   if (command_line.HasSwitch(switches::kEnableBlinkFeatures)) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java b/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
index 5312887..4c81d32 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentFeatureList.java
@@ -31,6 +31,7 @@
 
     // Alphabetical:
     public static final String REQUEST_UNBUFFERED_DISPATCH = "RequestUnbufferedDispatch";
+    public static final String WEB_NFC = "WebNFC";
 
     private static native boolean nativeIsEnabled(String featureName);
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
index 2ff817a75..0e8df902 100644
--- a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
@@ -80,7 +80,9 @@
             implements InterfaceRegistrar<WebContents> {
         @Override
         public void registerInterfaces(InterfaceRegistry registry, final WebContents webContents) {
-            registry.addInterface(Nfc.MANAGER, new NfcFactory(webContents));
+            if (ContentFeatureList.isEnabled(ContentFeatureList.WEB_NFC)) {
+                registry.addInterface(Nfc.MANAGER, new NfcFactory(webContents));
+            }
         }
     }
 
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index b8443f8..e923d8a0 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -303,7 +303,13 @@
 // The JavaScript API for payments on the web.
 const base::Feature kWebPayments{"WebPayments",
                                  base::FEATURE_ENABLED_BY_DEFAULT};
-#else
+
+// Controls whether the WebNFC API is enabled:
+// https://w3c.github.io/web-nfc/
+const base::Feature kWebNfc{"WebNFC", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
+#if !defined(OS_ANDROID)
 // The JavaScript API for payments on the web.
 const base::Feature kWebPayments{"WebPayments",
                                  base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index a01873c..cde01d02 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -81,6 +81,7 @@
 CONTENT_EXPORT extern const base::Feature kImeThread;
 CONTENT_EXPORT extern const base::Feature kSeccompSandboxAndroid;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
+CONTENT_EXPORT extern const base::Feature kWebNfc;
 #endif  // defined(OS_ANDROID)
 
 #if !defined(OS_ANDROID)
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index 4fb9c66..4cc2bbb 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -304,8 +304,8 @@
     return;
 
   running_ = true;
-  message_loop_runner_ = new MessageLoopRunner;
-  message_loop_runner_->Run();
+  run_loop_.reset(new base::RunLoop);
+  run_loop_->Run();
   EXPECT_TRUE(seen_);
 }
 
@@ -322,7 +322,7 @@
   if (!running_)
     return;
 
-  message_loop_runner_->Quit();
+  run_loop_->Quit();
   running_ = false;
 }
 
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h
index 2b8235d0..b69b200 100644
--- a/content/public/test/test_utils.h
+++ b/content/public/test/test_utils.h
@@ -238,7 +238,7 @@
 
   NotificationSource source_;
   NotificationDetails details_;
-  scoped_refptr<MessageLoopRunner> message_loop_runner_;
+  std::unique_ptr<base::RunLoop> run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserver);
 };
diff --git a/extensions/test/extension_test_notification_observer.cc b/extensions/test/extension_test_notification_observer.cc
index 3d2f23f..69c30d70 100644
--- a/extensions/test/extension_test_notification_observer.cc
+++ b/extensions/test/extension_test_notification_observer.cc
@@ -194,16 +194,15 @@
     return;
   condition_ = condition;
 
-  scoped_refptr<content::MessageLoopRunner> runner(
-      new content::MessageLoopRunner);
-  quit_closure_ = runner->QuitClosure();
+  base::RunLoop run_loop;
+  quit_closure_ = run_loop.QuitClosure();
 
   std::unique_ptr<base::CallbackList<void()>::Subscription> subscription;
   if (notification_set) {
     subscription = notification_set->callback_list().Add(base::Bind(
         &ExtensionTestNotificationObserver::MaybeQuit, base::Unretained(this)));
   }
-  runner->Run();
+  run_loop.Run();
 
   condition_.Reset();
   quit_closure_.Reset();
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 25c25d8..e4183cb 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -2117,6 +2117,17 @@
                           identity:nil
                         completion:completion];
       break;
+    case AUTHENTICATION_OPERATION_SIGNIN_PROMO_CONTINUE_AS: {
+      NSArray* identities = ios::GetChromeBrowserProvider()
+                                ->GetChromeIdentityService()
+                                ->GetAllIdentitiesSortedForDisplay();
+      DCHECK(identities.count > 0);
+      [_signinInteractionController
+          signInWithViewController:self.mainViewController
+                          identity:identities[0]
+                        completion:completion];
+      break;
+    }
   }
 }
 
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd
index 554dbeb..3d77c503 100644
--- a/ios/chrome/app/strings/ios_chromium_strings.grd
+++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -285,6 +285,9 @@
       <message name="IDS_IOS_SIGNIN_PROMO_SETTINGS" desc="Text to inform the user that they can sign in to get personal settings">
         To get your settings on all your devices, sign in to Chromium.
       </message>
+      <message name="IDS_IOS_SIGNIN_PROMO_RECENT_TABS" desc="Text to inform the user that they can sign in to get the recent tabs from other computers">
+        To get your tabs on all your devices, sign in to Chromium.
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd
index 8aeee5de..d16708f 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings.grd
+++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -285,6 +285,9 @@
       <message name="IDS_IOS_SIGNIN_PROMO_SETTINGS" desc="Text to inform the user that they can sign in to get personal settings">
         To get your settings on all your devices, sign in to Chrome.
       </message>
+      <message name="IDS_IOS_SIGNIN_PROMO_RECENT_TABS" desc="Text to inform the user that they can sign in to get the recent tabs from other computers">
+        To get your tabs on all your devices, sign in to Chrome.
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ios/chrome/browser/browser_state_metrics/OWNERS b/ios/chrome/browser/browser_state_metrics/OWNERS
index e43d48c..eccc04a 100644
--- a/ios/chrome/browser/browser_state_metrics/OWNERS
+++ b/ios/chrome/browser/browser_state_metrics/OWNERS
@@ -1,5 +1,4 @@
 anthonyvd@chromium.org
 erg@chromium.org
-mlerman@chromium.org
 
 # COMPONENT: UI>Browser>Profiles
diff --git a/ios/chrome/browser/payments/js_payment_request_manager.h b/ios/chrome/browser/payments/js_payment_request_manager.h
index b92244ea..ae33808 100644
--- a/ios/chrome/browser/payments/js_payment_request_manager.h
+++ b/ios/chrome/browser/payments/js_payment_request_manager.h
@@ -43,6 +43,14 @@
                            completionHandler:
                                (ProceduralBlockWithBool)completionHandler;
 
+// Resolves the JavaScript promise returned by the call to canMakePayment on the
+// current PaymentRequest, with the specified |value|. If |completionHandler| is
+// not nil, it will be invoked with YES after the operation has completed
+// successfully or with NO otherwise.
+- (void)resolveCanMakePaymentPromiseWithValue:(bool)value
+                            completionHandler:
+                                (ProceduralBlockWithBool)completionHandler;
+
 // Resolves the promise returned by PaymentRequest.prototype.abort.
 - (void)resolveAbortPromiseWithCompletionHandler:
     (ProceduralBlockWithBool)completionHandler;
diff --git a/ios/chrome/browser/payments/js_payment_request_manager.mm b/ios/chrome/browser/payments/js_payment_request_manager.mm
index 87bac00..9ca9a8c 100644
--- a/ios/chrome/browser/payments/js_payment_request_manager.mm
+++ b/ios/chrome/browser/payments/js_payment_request_manager.mm
@@ -68,6 +68,16 @@
   [self executeScript:script completionHandler:completionHandler];
 }
 
+- (void)resolveCanMakePaymentPromiseWithValue:(bool)value
+                            completionHandler:
+                                (ProceduralBlockWithBool)completionHandler {
+  NSString* script = value ? @"__gCrWeb['paymentRequestManager']."
+                             @"resolveCanMakePaymentPromise(true)"
+                           : @"__gCrWeb['paymentRequestManager']."
+                             @"resolveCanMakePaymentPromise(false)";
+  [self executeScript:script completionHandler:completionHandler];
+}
+
 - (void)resolveAbortPromiseWithCompletionHandler:
     (ProceduralBlockWithBool)completionHandler {
   NSString* script = @"__gCrWeb['paymentRequestManager'].resolveAbortPromise()";
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h
index 881260a..e7341c78 100644
--- a/ios/chrome/browser/payments/payment_request.h
+++ b/ios/chrome/browser/payments/payment_request.h
@@ -5,7 +5,9 @@
 #ifndef IOS_CHROME_BROWSER_PAYMENTS_PAYMENT_REQUEST_H_
 #define IOS_CHROME_BROWSER_PAYMENTS_PAYMENT_REQUEST_H_
 
+#include <memory>
 #include <set>
+#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -38,6 +40,11 @@
     return personal_data_manager_;
   }
 
+  // Returns the web::PaymentRequest that was used to build this PaymentRequest.
+  const web::PaymentRequest& web_payment_request() const {
+    return web_payment_request_;
+  }
+
   // Returns the payment details from |web_payment_request_|.
   const web::PaymentDetails& payment_details() const {
     return web_payment_request_.details;
@@ -141,6 +148,9 @@
     return selected_shipping_option_;
   }
 
+  // Returns whether the current PaymentRequest can be used to make a payment.
+  bool CanMakePayment() const;
+
  private:
   // Fetches the autofill profiles for this user from the PersonalDataManager,
   // and stores copies of them, owned by this PaymentRequest, in profile_cache_.
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm
index 31dcf99..3b9fe0a 100644
--- a/ios/chrome/browser/payments/payment_request.mm
+++ b/ios/chrome/browser/payments/payment_request.mm
@@ -84,6 +84,10 @@
   return credit_cards_.front();
 }
 
+bool PaymentRequest::CanMakePayment() const {
+  return !credit_cards_.empty();
+}
+
 void PaymentRequest::PopulateProfileCache() {
   const std::vector<autofill::AutofillProfile*>& profiles_to_suggest =
       personal_data_manager_->GetProfilesToSuggest();
diff --git a/ios/chrome/browser/payments/payment_request_manager.mm b/ios/chrome/browser/payments/payment_request_manager.mm
index 1f64f28..aa3cf2e 100644
--- a/ios/chrome/browser/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/payments/payment_request_manager.mm
@@ -41,8 +41,9 @@
 #endif
 
 namespace {
+
 // Command prefix for injected JavaScript.
-const std::string kCommandPrefix = "paymentRequest";
+const char kCommandPrefix[] = "paymentRequest";
 
 // Time interval between attempts to unblock the webview's JS event queue.
 const NSTimeInterval kNoopInterval = 0.1;
@@ -122,6 +123,10 @@
 // was successful.
 - (BOOL)handleRequestAbort:(const base::DictionaryValue&)message;
 
+// Handles invocations of PaymentRequest.canMakePayment(). Returns YES if the
+// invocation was successful.
+- (BOOL)handleCanMakePayment:(const base::DictionaryValue&)message;
+
 // Called by |_updateEventTimeoutTimer|, displays an error message. Upon
 // dismissal of the error message, cancels the Payment Request as if it was
 // performend by the user.
@@ -299,6 +304,9 @@
   if (command == "paymentRequest.requestAbort") {
     return [self handleRequestAbort:JSONCommand];
   }
+  if (command == "paymentRequest.requestCanMakePayment") {
+    return [self handleCanMakePayment:JSONCommand];
+  }
   if (command == "paymentRequest.responseComplete") {
     return [self handleResponseComplete:JSONCommand];
   }
@@ -308,12 +316,10 @@
   return NO;
 }
 
-- (BOOL)handleRequestShow:(const base::DictionaryValue&)message {
-  // TODO(crbug.com/602666): check that there's not already a pending request.
-  // TODO(crbug.com/602666): compare our supported payment types (i.e. autofill
-  //   credit card types) against the merchant supported types and return NO
-  //   if the intersection is empty.
-
+// Ensures that |_paymentRequest| is set to the correct value for |message|.
+// Returns YES if |_paymentRequest| was already set to the right value, or if it
+// was updated to match |message|.
+- (BOOL)createPaymentRequestFromMessage:(const base::DictionaryValue&)message {
   const base::DictionaryValue* paymentRequestData;
   web::PaymentRequest webPaymentRequest;
   if (!message.GetDictionary("payment_request", &paymentRequestData)) {
@@ -325,8 +331,27 @@
     return NO;
   }
 
+  // TODO(crbug.com/711419): make sure multiple PaymentRequests can be active
+  // simultaneously.
+  if (_paymentRequest &&
+      (_paymentRequest->web_payment_request() == webPaymentRequest)) {
+    return YES;
+  }
+
   _paymentRequest =
       base::MakeUnique<PaymentRequest>(webPaymentRequest, _personalDataManager);
+  return YES;
+}
+
+- (BOOL)handleRequestShow:(const base::DictionaryValue&)message {
+  // TODO(crbug.com/602666): check that there's not already a pending request.
+  // TODO(crbug.com/602666): compare our supported payment types (i.e. autofill
+  //   credit card types) against the merchant supported types and return NO
+  //   if the intersection is empty.
+
+  if (![self createPaymentRequestFromMessage:message]) {
+    return NO;
+  }
 
   UIImage* pageFavicon = nil;
   web::NavigationItem* navigationItem =
@@ -377,6 +402,20 @@
   return YES;
 }
 
+- (BOOL)handleCanMakePayment:(const base::DictionaryValue&)message {
+  if (![self createPaymentRequestFromMessage:message]) {
+    return NO;
+  }
+
+  // TODO(crbug.com/602666): reject the promise if quota (TBD) was exceeded.
+
+  [_paymentRequestJsManager
+      resolveCanMakePaymentPromiseWithValue:_paymentRequest->CanMakePayment()
+                          completionHandler:nil];
+
+  return YES;
+}
+
 - (BOOL)displayErrorThenCancelRequest {
   // TODO(crbug.com/602666): Check that there is already a pending request.
 
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn
index f5707b2..4006c8d 100644
--- a/ios/chrome/browser/ui/authentication/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -137,6 +137,7 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/colors",
+    "//ios/chrome/browser/ui/commands",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/signin",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view.h b/ios/chrome/browser/ui/authentication/signin_promo_view.h
index f5980a7b..1935e8a 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view.h
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view.h
@@ -36,6 +36,9 @@
 @property(nonatomic, readonly) UILabel* textLabel;
 @property(nonatomic, readonly) MDCFlatButton* primaryButton;
 @property(nonatomic, readonly) MDCFlatButton* secondaryButton;
+// If set to YES, ShowSigninCommand is sent when primary or secondary buttons
+// are tapped.
+@property(nonatomic, getter=doesSendChromeCommand) BOOL sendChromeCommand;
 
 // Horizontal padding used for |textLabel|, |primaryButton| and
 // |secondaryButton|. Used to compute the preferred max layout width of
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/signin_promo_view.mm
index b4a86b4..37086776 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view.mm
@@ -6,6 +6,8 @@
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
+#import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
+#import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
@@ -39,6 +41,7 @@
 @synthesize textLabel = _textLabel;
 @synthesize primaryButton = _primaryButton;
 @synthesize secondaryButton = _secondaryButton;
+@synthesize sendChromeCommand = _sendChromeCommand;
 
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
@@ -58,11 +61,17 @@
     _primaryButton = [[MDCFlatButton alloc] init];
     _primaryButton.translatesAutoresizingMaskIntoConstraints = NO;
     _primaryButton.accessibilityIdentifier = @"signin_promo_primary_button";
+    [_primaryButton addTarget:self
+                       action:@selector(onPrimaryButtonAction:)
+             forControlEvents:UIControlEventTouchUpInside];
     [self addSubview:_primaryButton];
 
     _secondaryButton = [[MDCFlatButton alloc] init];
     _secondaryButton.translatesAutoresizingMaskIntoConstraints = NO;
     _secondaryButton.accessibilityIdentifier = @"signin_promo_secondary_button";
+    [_secondaryButton addTarget:self
+                         action:@selector(onSecondaryButtonAction:)
+               forControlEvents:UIControlEventTouchUpInside];
     [self addSubview:_secondaryButton];
 
     // Adding style.
@@ -195,6 +204,39 @@
   return kHorizontalPadding;
 }
 
+- (void)onPrimaryButtonAction:(id)unused {
+  if (!_sendChromeCommand) {
+    return;
+  }
+  ShowSigninCommand* command = nil;
+  switch (_mode) {
+    case SigninPromoViewModeColdState:
+      command = [[ShowSigninCommand alloc]
+          initWithOperation:AUTHENTICATION_OPERATION_SIGNIN
+          signInAccessPoint:signin_metrics::AccessPoint::
+                                ACCESS_POINT_RECENT_TABS];
+      break;
+    case SigninPromoViewModeWarmState:
+      command = [[ShowSigninCommand alloc]
+          initWithOperation:AUTHENTICATION_OPERATION_SIGNIN_PROMO_CONTINUE_AS
+          signInAccessPoint:signin_metrics::AccessPoint::
+                                ACCESS_POINT_RECENT_TABS];
+      break;
+  }
+  DCHECK(command);
+  [self chromeExecuteCommand:command];
+}
+
+- (void)onSecondaryButtonAction:(id)unused {
+  if (!_sendChromeCommand) {
+    return;
+  }
+  ShowSigninCommand* command = [[ShowSigninCommand alloc]
+      initWithOperation:AUTHENTICATION_OPERATION_SIGNIN
+      signInAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS];
+  [self chromeExecuteCommand:command];
+}
+
 #pragma mark - NSObject(Accessibility)
 
 - (NSArray<UIAccessibilityCustomAction*>*)accessibilityCustomActions {
diff --git a/ios/chrome/browser/ui/commands/show_signin_command.h b/ios/chrome/browser/ui/commands/show_signin_command.h
index 9010cfc1..8f0a58c 100644
--- a/ios/chrome/browser/ui/commands/show_signin_command.h
+++ b/ios/chrome/browser/ui/commands/show_signin_command.h
@@ -24,6 +24,10 @@
   // Operation to start a sign-in operation. The user is presented with the
   // SSOAuth sign in page (SSOAuth account picker or SSOAuth sign-in web page).
   AUTHENTICATION_OPERATION_SIGNIN,
+
+  // Operation to start a sign-in operation based on the first known identity.
+  // The users are presented with the sync confirmation screen.
+  AUTHENTICATION_OPERATION_SIGNIN_PROMO_CONTINUE_AS,
 };
 
 // A command to perform a sign in operation.
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn
index cde8e4cc..dab645e4 100644
--- a/ios/chrome/browser/ui/infobars/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -31,6 +31,7 @@
 }
 
 source_set("unit_tests") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
     "infobar_view_unittest.mm",
diff --git a/ios/chrome/browser/ui/infobars/infobar_view_unittest.mm b/ios/chrome/browser/ui/infobars/infobar_view_unittest.mm
index 7916777..2e29452 100644
--- a/ios/chrome/browser/ui/infobars/infobar_view_unittest.mm
+++ b/ios/chrome/browser/ui/infobars/infobar_view_unittest.mm
@@ -8,6 +8,10 @@
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 @interface InfoBarView (Testing)
 - (CGFloat)buttonsHeight;
 - (CGFloat)buttonMargin;
@@ -29,9 +33,9 @@
   void SetUp() override {
     PlatformTest::SetUp();
     CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
-    infobarView_.reset([[InfoBarView alloc]
-        initWithFrame:CGRectMake(0, 0, screenWidth, 0)
-             delegate:NULL]);
+    infobarView_ =
+        [[InfoBarView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 0)
+                                  delegate:NULL];
     [infobarView_ addCloseButtonWithTag:0 target:nil action:nil];
   }
 
@@ -75,7 +79,7 @@
     }
   }
 
-  base::scoped_nsobject<InfoBarView> infobarView_;
+  InfoBarView* infobarView_;
 };
 
 TEST_F(InfoBarViewTest, TestLayoutWithNoLabel) {
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
index 8035fb2..782cb8d 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
@@ -27,12 +27,15 @@
     "//components/sync",
     "//ios/chrome/app/strings",
     "//ios/chrome/app/theme",
+    "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui/authentication:authentication_arc",
+    "//ios/chrome/browser/ui/authentication:authentication_ui",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/context_menu",
     "//ios/chrome/browser/ui/ntp",
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
index 8b8ff0f..a37ea1c7 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
@@ -14,10 +14,15 @@
 #include "components/sync/driver/sync_service.h"
 #include "components/sync_sessions/open_tabs_ui_delegate.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
 #include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios.h"
 #include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h"
 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
+#import "ios/chrome/browser/ui/authentication/signin_promo_view.h"
+#import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h"
+#import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h"
+#import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
@@ -36,6 +41,7 @@
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/url_loader.h"
+#include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ios/web/public/referrer.h"
 #import "ios/web/public/web_state/context_menu_params.h"
@@ -59,6 +65,9 @@
 // Tag to extract the section headers from the cells.
 enum { kSectionHeader = 1 };
 
+// Margin at the top of the sigin-in promo view.
+const CGFloat kSigninPromoViewTopMargin = 24;
+
 // Types of sections.
 enum SectionType {
   SEPARATOR_SECTION,
@@ -77,6 +86,7 @@
   CELL_OTHER_DEVICES_SIGNED_OUT,
   CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF,
   CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS,
+  CELL_OTHER_DEVICES_SIGNIN_PROMO,
   CELL_OTHER_DEVICES_SYNC_IN_PROGRESS,
   CELL_SESSION_SECTION_HEADER,
   CELL_SESSION_TAB_DATA,
@@ -84,7 +94,7 @@
 
 }  // namespace
 
-@interface RecentTabsTableViewController () {
+@interface RecentTabsTableViewController ()<SigninPromoViewConsumer> {
   ios::ChromeBrowserState* _browserState;  // weak
   // The service that manages the recently closed tabs.
   sessions::TabRestoreService* _tabRestoreService;  // weak
@@ -96,11 +106,14 @@
   std::unique_ptr<synced_sessions::SyncedSessions> _syncedSessions;
   // Handles displaying the context menu for all form factors.
   ContextMenuCoordinator* _contextMenuCoordinator;
+  SigninPromoViewMediator* _signinPromoViewMediator;
 }
 // Returns the type of the section at index |section|.
 - (SectionType)sectionType:(NSInteger)section;
 // Returns the type of the cell at the path |indexPath|.
 - (CellType)cellType:(NSIndexPath*)indexPath;
+// Returns the index of a section based on |sectionType|.
+- (NSInteger)sectionIndexForSectionType:(SectionType)sectionType;
 // Returns the number of sections before the other devices or session sections.
 - (NSInteger)numberOfSectionsBeforeSessionOrOtherDevicesSections;
 // Dismisses the modal containing the Recent Tabs panel (iPhone only).
@@ -175,6 +188,9 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
   self.view.accessibilityIdentifier = @"recent_tabs_view_controller";
+  self.tableView.rowHeight = UITableViewAutomaticDimension;
+  self.tableView.estimatedRowHeight =
+      [SessionTabDataView desiredHeightInUITableViewCell];
   [self.tableView setSeparatorColor:[UIColor clearColor]];
   [self.tableView setDataSource:self];
   [self.tableView setDelegate:self];
@@ -249,7 +265,10 @@
       }
       switch (_sessionState) {
         case SessionsSyncUserState::USER_SIGNED_OUT:
-          return CELL_OTHER_DEVICES_SIGNED_OUT;
+          if (experimental_flags::IsSigninPromoEnabled()) {
+            return CELL_OTHER_DEVICES_SIGNIN_PROMO;
+          } else
+            return CELL_OTHER_DEVICES_SIGNED_OUT;
         case SessionsSyncUserState::USER_SIGNED_IN_SYNC_OFF:
           return CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF;
         case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS:
@@ -264,6 +283,16 @@
   }
 }
 
+- (NSInteger)sectionIndexForSectionType:(SectionType)sectionType {
+  NSUInteger sectionCount = [self numberOfSectionsInTableView:self.tableView];
+  for (NSUInteger sectionIndex = 0; sectionIndex < sectionCount;
+       ++sectionIndex) {
+    if ([self sectionType:sectionIndex] == sectionType)
+      return sectionIndex;
+  }
+  return NSNotFound;
+}
+
 - (NSInteger)numberOfSectionsBeforeSessionOrOtherDevicesSections {
   // The 2 sections are CLOSED_TAB_SECTION and SEPARATOR_SECTION.
   return 2;
@@ -524,6 +553,9 @@
   [self.tableView insertSections:indexesToBeInserted
                 withRowAnimation:UITableViewRowAnimationFade];
   [self.tableView endUpdates];
+
+  if (_sessionState != SessionsSyncUserState::USER_SIGNED_OUT)
+    _signinPromoViewMediator = nil;
 }
 
 - (NSInteger)numberOfSessionSections {
@@ -736,6 +768,7 @@
       [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                              reuseIdentifier:nil];
   UIView* contentView = cell.contentView;
+  CGFloat contentViewTopMargin = 0;
 
   UIView* subview;
   CellType cellType = [self cellType:indexPath];
@@ -785,6 +818,27 @@
       subview = [[SignedInSyncOnNoSessionsView alloc] initWithFrame:CGRectZero];
       [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
       break;
+    case CELL_OTHER_DEVICES_SIGNIN_PROMO: {
+      if (!_signinPromoViewMediator) {
+        _signinPromoViewMediator = [[SigninPromoViewMediator alloc] init];
+        _signinPromoViewMediator.consumer = self;
+      }
+      contentViewTopMargin = kSigninPromoViewTopMargin;
+      SigninPromoView* signinPromoView =
+          [[SigninPromoView alloc] initWithFrame:CGRectZero];
+      signinPromoView.sendChromeCommand = YES;
+      signinPromoView.textLabel.text =
+          l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_RECENT_TABS);
+      signinPromoView.textLabel.preferredMaxLayoutWidth =
+          CGRectGetWidth(self.tableView.bounds) -
+          2 * signinPromoView.horizontalPadding;
+      SigninPromoViewConfigurator* configurator =
+          [_signinPromoViewMediator createConfigurator];
+      [configurator configureSigninPromoView:signinPromoView];
+      subview = signinPromoView;
+      [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
+      break;
+    }
     case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS:
       subview = [[SignedInSyncInProgressView alloc] initWithFrame:CGRectZero];
       [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
@@ -823,7 +877,7 @@
   // RecentlyClosedSectionFooter.
   // clang-format off
   NSArray* constraints = @[
-    @"V:|-0-[view]-0-|",
+    @"V:|-(TopMargin)-[view]-0-|",
     @"H:|-(>=0)-[view(<=548)]-(>=0)-|",
     @"H:[view(==548@500)]"
   ];
@@ -836,7 +890,8 @@
                                           attribute:NSLayoutAttributeCenterX
                                          multiplier:1
                                            constant:0]];
-  ApplyVisualConstraints(constraints, viewsDictionary, contentView);
+  NSDictionary* metrics = @{ @"TopMargin" : @(contentViewTopMargin) };
+  ApplyVisualConstraintsWithMetrics(constraints, viewsDictionary, metrics);
   return cell;
 }
 
@@ -858,6 +913,7 @@
     case CELL_OTHER_DEVICES_SIGNED_OUT:
     case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF:
     case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS:
+    case CELL_OTHER_DEVICES_SIGNIN_PROMO:
     case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS:
       return nil;
   }
@@ -891,6 +947,7 @@
     case CELL_OTHER_DEVICES_SIGNED_OUT:
     case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF:
     case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS:
+    case CELL_OTHER_DEVICES_SIGNIN_PROMO:
     case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS:
       NOTREACHED();
       break;
@@ -912,6 +969,8 @@
       return [SignedInSyncOffView desiredHeightInUITableViewCell];
     case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS:
       return [SignedInSyncOnNoSessionsView desiredHeightInUITableViewCell];
+    case CELL_OTHER_DEVICES_SIGNIN_PROMO:
+      return UITableViewAutomaticDimension;
     case CELL_SESSION_SECTION_HEADER:
       return [SessionSectionHeaderView desiredHeightInUITableViewCell];
     case CELL_CLOSED_TAB_DATA:
@@ -947,4 +1006,29 @@
   [delegate_ recentTabsTableViewContentMoved:self.tableView];
 }
 
+#pragma mark - SigninPromoViewConsumer
+
+- (void)configureSigninPromoViewWithNewIdentity:(BOOL)newIdentity
+                                   configurator:(SigninPromoViewConfigurator*)
+                                                    configurator {
+  DCHECK(_signinPromoViewMediator);
+  NSInteger sectionIndex =
+      [self sectionIndexForSectionType:OTHER_DEVICES_SECTION];
+  DCHECK(sectionIndex != NSNotFound);
+  NSIndexPath* indexPath =
+      [NSIndexPath indexPathForRow:1 inSection:sectionIndex];
+  if (newIdentity) {
+    [self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
+                          withRowAnimation:UITableViewRowAnimationNone];
+    return;
+  }
+  UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
+  NSArray<UIView*>* contentViews = cell.contentView.subviews;
+  DCHECK(contentViews.count == 1);
+  UIView* subview = contentViews[0];
+  DCHECK([subview isKindOfClass:[SigninPromoView class]]);
+  SigninPromoView* signinPromoView = (SigninPromoView*)subview;
+  [configurator configureSigninPromoView:signinPromoView];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/print/BUILD.gn b/ios/chrome/browser/ui/print/BUILD.gn
index 84b27e9..3215362 100644
--- a/ios/chrome/browser/ui/print/BUILD.gn
+++ b/ios/chrome/browser/ui/print/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 source_set("print") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
     "print_controller.h",
     "print_controller.mm",
diff --git a/ios/chrome/browser/ui/print/print_controller.mm b/ios/chrome/browser/ui/print/print_controller.mm
index c5576d3..7f55cf4b 100644
--- a/ios/chrome/browser/ui/print/print_controller.mm
+++ b/ios/chrome/browser/ui/print/print_controller.mm
@@ -11,12 +11,10 @@
 
 #include "base/callback_helpers.h"
 #import "base/ios/ios_util.h"
-#import "base/ios/weak_nsobject.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/mac/bind_objc_block.h"
 #include "base/mac/foundation_util.h"
-#import "base/mac/scoped_nsobject.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
@@ -32,6 +30,10 @@
 #include "net/url_request/url_request_context_getter.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using net::URLFetcher;
 using net::URLFetcherDelegate;
 using net::URLRequestContextGetter;
@@ -98,8 +100,8 @@
   }
 
  private:
-  __unsafe_unretained PrintController* owner_;
-  __unsafe_unretained UIViewController* view_controller_;
+  __weak PrintController* owner_;
+  __weak UIViewController* view_controller_;
   DISALLOW_COPY_AND_ASSIGN(PrintPDFFetcherDelegate);
 };
 }  // namespace
@@ -118,10 +120,10 @@
   // offers a cancel button which will cancel the download. It is created when
   // downloading begins and is released when downloading ends (either due to
   // cancellation or completion).
-  base::scoped_nsobject<LoadingAlertCoordinator> _PDFDownloadingDialog;
+  LoadingAlertCoordinator* _PDFDownloadingDialog;
 
   // A dialog which indicates that the print preview failed.
-  base::scoped_nsobject<AlertCoordinator> _PDFDownloadingErrorDialog;
+  AlertCoordinator* _PDFDownloadingErrorDialog;
 }
 
 #pragma mark - Class methods.
@@ -144,7 +146,7 @@
     // and |printingItem| will no longer be used.
     if (!base::ios::IsRunningOnIOS10OrLater() && isPDF) {
       web::WebThread::PostBlockingPoolTask(
-          FROM_HERE, base::BindBlock(^{
+          FROM_HERE, base::BindBlockArc(^{
             NSFileManager* manager = [NSFileManager defaultManager];
             NSString* tempDir = NSTemporaryDirectory();
             NSError* tempDirError = nil;
@@ -235,8 +237,7 @@
   }
 
   if (!isPDFURL) {
-    base::scoped_nsobject<UIPrintPageRenderer> renderer(
-        [[UIPrintPageRenderer alloc] init]);
+    UIPrintPageRenderer* renderer = [[UIPrintPageRenderer alloc] init];
     [renderer addPrintFormatter:[view viewPrintFormatter]
           startingAtPageAtIndex:0];
     printInteractionController.printPageRenderer = renderer;
@@ -250,7 +251,7 @@
   _fetcher.reset();
   [self dismissPDFDownloadingDialog];
   [_PDFDownloadingErrorDialog stop];
-  _PDFDownloadingErrorDialog.reset();
+  _PDFDownloadingErrorDialog = nil;
   [[UIPrintInteractionController sharedPrintController]
       dismissAnimated:animated];
 }
@@ -263,31 +264,31 @@
 
   NSString* title = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_PREPARATION);
 
-  base::WeakNSObject<PrintController> weakSelf(self);
+  __weak PrintController* weakSelf = self;
   ProceduralBlock cancelHandler = ^{
-    base::scoped_nsobject<PrintController> strongSelf([weakSelf retain]);
+    PrintController* strongSelf = weakSelf;
     if (strongSelf)
-      strongSelf.get()->_fetcher.reset();
+      strongSelf->_fetcher.reset();
   };
 
-  _PDFDownloadingDialog.reset([[LoadingAlertCoordinator alloc]
+  _PDFDownloadingDialog = [[LoadingAlertCoordinator alloc]
       initWithBaseViewController:viewController
                            title:title
-                   cancelHandler:cancelHandler]);
+                   cancelHandler:cancelHandler];
 
   dispatch_after(
       dispatch_time(DISPATCH_TIME_NOW, kPDFDownloadDialogDelay * NSEC_PER_SEC),
       dispatch_get_main_queue(), ^{
-        base::scoped_nsobject<PrintController> strongSelf([weakSelf retain]);
+        PrintController* strongSelf = weakSelf;
         if (!strongSelf)
           return;
-        [strongSelf.get()->_PDFDownloadingDialog start];
+        [strongSelf->_PDFDownloadingDialog start];
       });
 }
 
 - (void)dismissPDFDownloadingDialog {
   [_PDFDownloadingDialog stop];
-  _PDFDownloadingDialog.reset();
+  _PDFDownloadingDialog = nil;
 }
 
 - (void)showPDFDownloadErrorWithURL:(const GURL)URL
@@ -295,12 +296,12 @@
   NSString* title = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_ERROR_TITLE);
   NSString* message = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_ERROR_SUBTITLE);
 
-  _PDFDownloadingErrorDialog.reset([[AlertCoordinator alloc]
-      initWithBaseViewController:viewController
-                           title:title
-                         message:message]);
+  _PDFDownloadingErrorDialog =
+      [[AlertCoordinator alloc] initWithBaseViewController:viewController
+                                                     title:title
+                                                   message:message];
 
-  base::WeakNSObject<PrintController> weakSelf(self);
+  __weak PrintController* weakSelf = self;
 
   [_PDFDownloadingErrorDialog
       addItemWithTitle:l10n_util::GetNSString(IDS_IOS_PRINT_PDF_TRY_AGAIN)
@@ -331,7 +332,7 @@
 - (void)finishedDownloadingPDF:(UIViewController*)viewController {
   [self dismissPDFDownloadingDialog];
   DCHECK(_fetcher);
-  base::ScopedClosureRunner fetcherResetter(base::BindBlock(^{
+  base::ScopedClosureRunner fetcherResetter(base::BindBlockArc(^{
     _fetcher.reset();
   }));
   int responseCode = _fetcher->GetResponseCode();
diff --git a/ios/chrome/browser/ui/promos/BUILD.gn b/ios/chrome/browser/ui/promos/BUILD.gn
index 2d3c07b..2a8131f 100644
--- a/ios/chrome/browser/ui/promos/BUILD.gn
+++ b/ios/chrome/browser/ui/promos/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 source_set("promos") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
     "promo_view_controller.h",
     "signin_promo_view_controller.h",
diff --git a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
index b1cebbb..e4bcdd9 100644
--- a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
+++ b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/ui/promos/signin_promo_view_controller.h"
 
-#include "base/mac/scoped_nsobject.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/sys_string_conversions.h"
@@ -20,6 +19,10 @@
 #import "ios/public/provider/chrome/browser/signin/chrome_identity_service.h"
 #include "net/base/network_change_notifier.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 // Key in the UserDefaults to record the version of the application when the
 // SSO Recall promo has been displayed.
 NSString* kDisplayedSSORecallForMajorVersionKey =
@@ -173,9 +176,9 @@
 
 + (UIViewController*)controllerToPresentForBrowserState:
     (ios::ChromeBrowserState*)browserState {
-  base::scoped_nsobject<UIViewController> controller(
-      [[SigninPromoViewController alloc] initWithBrowserState:browserState]);
-  return controller.autorelease();
+  UIViewController* controller =
+      [[SigninPromoViewController alloc] initWithBrowserState:browserState];
+  return controller;
 }
 
 #pragma mark - ChromeSigninViewControllerDelegate
diff --git a/ios/chrome/browser/ui/settings/utils/BUILD.gn b/ios/chrome/browser/ui/settings/utils/BUILD.gn
index 3700356..06dcac4 100644
--- a/ios/chrome/browser/ui/settings/utils/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/utils/BUILD.gn
@@ -20,6 +20,7 @@
 }
 
 source_set("test_support") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
     "fake_observable_boolean.h",
diff --git a/ios/chrome/browser/ui/settings/utils/fake_observable_boolean.mm b/ios/chrome/browser/ui/settings/utils/fake_observable_boolean.mm
index d8d25f2..bb41a680 100644
--- a/ios/chrome/browser/ui/settings/utils/fake_observable_boolean.mm
+++ b/ios/chrome/browser/ui/settings/utils/fake_observable_boolean.mm
@@ -4,6 +4,10 @@
 
 #import "ios/chrome/browser/ui/settings/utils/fake_observable_boolean.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 @implementation FakeObservableBoolean
 
 @synthesize value = _value;
diff --git a/ios/chrome/browser/web/resources/payment_request.js b/ios/chrome/browser/web/resources/payment_request.js
index f55ae4f..e31b819 100644
--- a/ios/chrome/browser/web/resources/payment_request.js
+++ b/ios/chrome/browser/web/resources/payment_request.js
@@ -304,7 +304,7 @@
 
   /**
    * Rejects the pending PaymentRequest.
-   * @param {!string} message An error message explaining why the Promise is
+   * @param {string} message An error message explaining why the Promise is
    * being rejected.
    */
   __gCrWeb['paymentRequestManager'].rejectRequestPromise = function(message) {
@@ -335,6 +335,42 @@
   };
 
   /**
+   * Resolves the promise returned by calling canMakePayment on the current
+   * PaymentRequest.
+   * @param {boolean} value The response to provide to the resolve function of
+   *     the Promise.
+   */
+  __gCrWeb['paymentRequestManager'].resolveCanMakePaymentPromise = function(
+      value) {
+    if (!__gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver) {
+      throw new Error('Internal PaymentRequest error: No Promise to resolve.');
+    }
+
+    __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver.resolve(
+        value);
+    __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver = null;
+  };
+
+  /**
+   * Rejects the promise returned by calling canMakePayment on the current
+   * PaymentRequest.
+   * @param {string} message An error message explaining why the Promise is
+   *     being rejected.
+   */
+  __gCrWeb['paymentRequestManager'].rejectCanMakePaymentPromise = function(
+      message) {
+    if (!__gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver) {
+      throw new Error(
+          'Internal PaymentRequest error: No Promise to reject. ',
+          'Message was: ', message);
+    }
+
+    __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver.reject(
+        message);
+    __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver = null;
+  };
+
+  /**
    * Serializes |paymentRequest| to a SerializedPaymentRequest object.
    * @param {window.PaymentRequest} paymentRequest
    * @return {SerializedPaymentRequest}
@@ -599,6 +635,29 @@
 };
 
 /**
+ * May be called before calling show() to determine if the PaymentRequest object
+ * can be used to make a payment.
+ * @return {!Promise<boolean>} A promise to notify the caller whether the
+ *     PaymentRequest object can be used to make a payment.
+ */
+window.PaymentRequest.prototype.canMakePayment = function() {
+  // TODO(crbug.com/602666): return a promise rejected with InvalidStateError if
+  // |this.state| != 'created'.
+
+  var message = {
+    'command': 'paymentRequest.requestCanMakePayment',
+    'payment_request':
+        __gCrWeb['paymentRequestManager'].serializePaymentRequest(this),
+  };
+  __gCrWeb.message.invokeOnHost(message);
+
+  __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver =
+      new __gCrWeb.PromiseResolver();
+  return __gCrWeb['paymentRequestManager'].canMakePaymentPromiseResolver
+      .promise;
+};
+
+/**
  * @typedef {{
  *   supportedMethods: !Array<string>,
  *   data: (Object|undefined)
diff --git a/ios/shared/chrome/browser/ui/coordinators/BUILD.gn b/ios/shared/chrome/browser/ui/coordinators/BUILD.gn
index 2f45aeb..ef49fcc 100644
--- a/ios/shared/chrome/browser/ui/coordinators/BUILD.gn
+++ b/ios/shared/chrome/browser/ui/coordinators/BUILD.gn
@@ -33,7 +33,9 @@
     ":coordinators",
     "//base",
     "//base/test:test_support",
+    "//ios/chrome/browser/browser_state:test_support",
     "//ios/chrome/test/base",
+    "//ios/shared/chrome/browser/ui/browser_list",
     "//testing/gtest",
   ]
 }
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm
index bfea7462..429ad0c3 100644
--- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm
+++ b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator.mm
@@ -128,6 +128,7 @@
   [coordinator willBeRemovedFromParentCoordinator];
   [self.childCoordinators removeObject:coordinator];
   coordinator.parentCoordinator = nil;
+  coordinator.browser = nil;
 }
 
 - (void)wasAddedToParentCoordinator:(BrowserCoordinator*)parentCoordinator {
diff --git a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm
index a448dc4..72f3c6c 100644
--- a/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm
+++ b/ios/shared/chrome/browser/ui/coordinators/browser_coordinator_unittest.mm
@@ -5,8 +5,12 @@
 #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h"
 #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h"
 
+#include "base/memory/ptr_util.h"
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#import "ios/shared/chrome/browser/ui/browser_list/browser.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
+#include "testing/platform_test.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -74,7 +78,25 @@
 
 namespace {
 
-TEST(BrowserCoordinatorTest, TestDontStopOnDealloc) {
+class BrowserCoordinatorTest : public PlatformTest {
+ protected:
+  BrowserCoordinatorTest() {
+    // Initialize the browser.
+    TestChromeBrowserState::Builder builder;
+    chrome_browser_state_ = builder.Build();
+    browser_ = base::MakeUnique<Browser>(chrome_browser_state_.get());
+  }
+
+  Browser* GetBrowser() { return browser_.get(); };
+
+ private:
+  std::unique_ptr<Browser> browser_;
+  std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
+};
+
+}  // namespace
+
+TEST_F(BrowserCoordinatorTest, TestDontStopOnDealloc) {
   __block BOOL called = NO;
 
   {
@@ -87,7 +109,7 @@
   EXPECT_FALSE(called);
 }
 
-TEST(BrowserCoordinatorTest, TestChildren) {
+TEST_F(BrowserCoordinatorTest, TestChildren) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
 
@@ -109,7 +131,7 @@
   EXPECT_EQ(otherParent, otherChild.parentCoordinator);
 }
 
-TEST(BrowserCoordinatorTest, TestOverlay) {
+TEST_F(BrowserCoordinatorTest, TestOverlay) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
   TestCoordinator* grandchild = [[TestCoordinator alloc] init];
@@ -158,7 +180,7 @@
   EXPECT_FALSE(thirdOverlay.overlaying);
 }
 
-TEST(BrowserCoordinatorTest, AddedRemoved) {
+TEST_F(BrowserCoordinatorTest, AddedRemoved) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
 
@@ -174,7 +196,7 @@
   EXPECT_TRUE(child.willBeRemovedCalled);
 }
 
-TEST(BrowserCoordinatorTest, DidStartWillStop) {
+TEST_F(BrowserCoordinatorTest, DidStartWillStop) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
   [parent addChildCoordinator:child];
@@ -190,7 +212,7 @@
   EXPECT_TRUE(parent.childWillStopCalled);
 }
 
-TEST(BrowserCoordinatorTest, StopStopsStartedChildren) {
+TEST_F(BrowserCoordinatorTest, StopStopsStartedChildren) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
   [parent addChildCoordinator:child];
@@ -209,7 +231,7 @@
   EXPECT_TRUE(called);
 }
 
-TEST(BrowserCoordinatorTest, StopStopsNonStartedChildren) {
+TEST_F(BrowserCoordinatorTest, StopStopsNonStartedChildren) {
   TestCoordinator* parent = [[TestCoordinator alloc] init];
   TestCoordinator* child = [[TestCoordinator alloc] init];
   [parent addChildCoordinator:child];
@@ -227,4 +249,16 @@
   EXPECT_TRUE(called);
 }
 
-}  // namespace
+TEST_F(BrowserCoordinatorTest, BrowserIsNilAfterCoordinatorIsRemoved) {
+  TestCoordinator* parent = [[TestCoordinator alloc] init];
+  TestCoordinator* child = [[TestCoordinator alloc] init];
+  parent.browser = GetBrowser();
+  [parent addChildCoordinator:child];
+
+  EXPECT_NE(nil, child.browser);
+
+  // Remove the child.
+  [parent removeChildCoordinator:child];
+
+  EXPECT_EQ(nil, child.browser);
+}
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn
index 9e74e582..2edf372 100644
--- a/mojo/common/BUILD.gn
+++ b/mojo/common/BUILD.gn
@@ -16,6 +16,7 @@
   sources = [
     "file.mojom",
     "file_path.mojom",
+    "process_id.mojom",
     "string16.mojom",
     "text_direction.mojom",
     "time.mojom",
diff --git a/mojo/common/common_custom_types_struct_traits.h b/mojo/common/common_custom_types_struct_traits.h
index b20c795..426489f 100644
--- a/mojo/common/common_custom_types_struct_traits.h
+++ b/mojo/common/common_custom_types_struct_traits.h
@@ -7,11 +7,13 @@
 
 #include "base/files/file.h"
 #include "base/i18n/rtl.h"
+#include "base/process/process_handle.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/unguessable_token.h"
 #include "base/version.h"
 #include "mojo/common/file.mojom-shared.h"
 #include "mojo/common/mojo_common_export.h"
+#include "mojo/common/process_id.mojom-shared.h"
 #include "mojo/common/string16.mojom-shared.h"
 #include "mojo/common/text_direction.mojom-shared.h"
 #include "mojo/common/time.mojom-shared.h"
@@ -63,6 +65,19 @@
 };
 
 template <>
+struct StructTraits<common::mojom::ProcessIdDataView, base::ProcessId> {
+  static uint32_t pid(const base::ProcessId& process_id) {
+    return static_cast<uint32_t>(process_id);
+  }
+
+  static bool Read(common::mojom::ProcessIdDataView data,
+                   base::ProcessId* process_id) {
+    *process_id = static_cast<base::ProcessId>(data.pid());
+    return true;
+  }
+};
+
+template <>
 struct StructTraits<common::mojom::TimeDeltaDataView, base::TimeDelta> {
   static int64_t microseconds(const base::TimeDelta& delta) {
     return delta.InMicroseconds();
diff --git a/mojo/common/common_custom_types_unittest.cc b/mojo/common/common_custom_types_unittest.cc
index b0943783..fd0cad1 100644
--- a/mojo/common/common_custom_types_unittest.cc
+++ b/mojo/common/common_custom_types_unittest.cc
@@ -7,9 +7,12 @@
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/numerics/safe_math.h"
+#include "base/process/process_handle.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
+#include "mojo/common/process_id.mojom.h"
 #include "mojo/common/test_common_custom_types.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -226,6 +229,15 @@
   run_loop.Run();
 }
 
+TEST_F(CommonCustomTypesTest, ProcessId) {
+  base::ProcessId pid = base::GetCurrentProcId();
+  base::ProcessId out_pid = base::kNullProcessId;
+  ASSERT_NE(pid, out_pid);
+  EXPECT_TRUE(mojom::ProcessId::Deserialize(mojom::ProcessId::Serialize(&pid),
+                                            &out_pid));
+  EXPECT_EQ(pid, out_pid);
+}
+
 TEST_F(CommonCustomTypesTest, Time) {
   base::RunLoop run_loop;
 
diff --git a/mojo/common/process_id.mojom b/mojo/common/process_id.mojom
new file mode 100644
index 0000000..d72fe6e
--- /dev/null
+++ b/mojo/common/process_id.mojom
@@ -0,0 +1,12 @@
+// 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.
+
+module mojo.common.mojom;
+
+struct ProcessId {
+  // This is the storage for the pid, on windows the pid is a DWORD and the
+  // value can be DWORD_MAX which maps gracefully to uint32 while on linux
+  // the pid is a signed int with a max value of 2^22.
+  uint32 pid;
+};
diff --git a/mojo/common/process_id.typemap b/mojo/common/process_id.typemap
new file mode 100644
index 0000000..6714540
--- /dev/null
+++ b/mojo/common/process_id.typemap
@@ -0,0 +1,13 @@
+# 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 = "//mojo/common/process_id.mojom"
+public_headers = [ "//base/process/process_handle.h" ]
+traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
+public_deps = [
+  "//mojo/common:struct_traits",
+]
+
+type_mappings =
+    [ "mojo.common.mojom.ProcessId=base::ProcessId[copyable_pass_by_value]" ]
diff --git a/mojo/common/typemaps.gni b/mojo/common/typemaps.gni
index ae36031..1909b4bc 100644
--- a/mojo/common/typemaps.gni
+++ b/mojo/common/typemaps.gni
@@ -5,6 +5,7 @@
 typemaps = [
   "//mojo/common/file.typemap",
   "//mojo/common/file_path.typemap",
+  "//mojo/common/process_id.typemap",
   "//mojo/common/string16.typemap",
   "//mojo/common/text_direction.typemap",
   "//mojo/common/time.typemap",
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index 8ef0eb7..1bce9a3 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -132,7 +132,7 @@
 }
 
 java_cpp_template("net_errors_java") {
-  package_name = "org/chromium/net"
+  package_path = "org/chromium/net"
   sources = [
     "java/NetError.template",
   ]
diff --git a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc
index 7bb49b6..fcf7e6e 100644
--- a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc
+++ b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.cc
@@ -5,6 +5,7 @@
 #include "services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h"
 
 #include "base/trace_event/memory_dump_request_args.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
 #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
 
 namespace mojo {
@@ -135,6 +136,8 @@
     return false;
   if (!input.ReadOsDump(&out->os_dump))
     return false;
+  if (!input.ReadExtraProcessesDump(&out->extra_processes_dump))
+    return false;
   return true;
 }
 
diff --git a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
index c9c6770b78..817b667 100644
--- a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
+++ b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
@@ -5,7 +5,9 @@
 #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_INSTRUMENTATION_STRUCT_TRAITS_H_
 #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_INSTRUMENTATION_STRUCT_TRAITS_H_
 
+#include "base/process/process_handle.h"
 #include "base/trace_event/memory_dump_request_args.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
 #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
 
 namespace mojo {
@@ -95,6 +97,12 @@
       const base::trace_event::MemoryDumpCallbackResult& args) {
     return args.chrome_dump;
   }
+  static const std::map<base::ProcessId,
+                        base::trace_event::MemoryDumpCallbackResult::OSMemDump>&
+  extra_processes_dump(
+      const base::trace_event::MemoryDumpCallbackResult& args) {
+    return args.extra_processes_dump;
+  }
   static bool Read(
       memory_instrumentation::mojom::MemoryDumpCallbackResultDataView input,
       base::trace_event::MemoryDumpCallbackResult* out);
diff --git a/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom b/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom
index 12244c6..80978bc 100644
--- a/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom
+++ b/services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom
@@ -4,6 +4,8 @@
 
 module memory_instrumentation.mojom;
 
+import "mojo/common/process_id.mojom";
+
 enum DumpType {
   PERIODIC_INTERVAL,
   EXPLICITLY_TRIGGERED,
@@ -36,7 +38,8 @@
 struct MemoryDumpCallbackResult {
   OSMemDump os_dump;
   ChromeMemDump chrome_dump;
-}; 
+  map<mojo.common.mojom.ProcessId, OSMemDump> extra_processes_dump;
+};
 
 // There should be at most one implementation of this interface per process.
 interface ProcessLocalDumpManager {
diff --git a/third_party/.gitignore b/third_party/.gitignore
index c79ea463..5ad1c8d 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -32,6 +32,7 @@
 /cardboard-java/src
 /catapult
 /ced/src
+/checkstyle/*.jar
 /chromeos_login_manager
 /chromeos_text_input
 /chromite
diff --git a/third_party/WebKit/LayoutTests/PRESUBMIT.py b/third_party/WebKit/LayoutTests/PRESUBMIT.py
index 87d981c1..ca7b4f9 100644
--- a/third_party/WebKit/LayoutTests/PRESUBMIT.py
+++ b/third_party/WebKit/LayoutTests/PRESUBMIT.py
@@ -87,10 +87,27 @@
     return errors
 
 
+def _CheckFilesUsingEventSender(input_api, output_api):
+    """Check if any new layout tests still use eventSender. If they do, we encourage replacing them with
+       chrome.gpuBenchmarking.pointerActionSequence.
+    """
+    results = []
+    actions = ["eventSender.touch", "eventSender.mouse", "eventSender.gesture"]
+    for f in input_api.AffectedFiles():
+        if f.Action() == 'A':
+            for line_num, line in f.ChangedContents():
+                if any(action in line for action in actions):
+                    results.append(output_api.PresubmitError(
+                        'Files that still use eventSender: %s:%d %s, please use chrome.gpuBenchmarking.pointerActionSequence instead.' %
+                        (f.LocalPath(), line_num, line)))
+    return results
+
+
 def CheckChangeOnUpload(input_api, output_api):
     results = []
     results.extend(_CheckTestharnessResults(input_api, output_api))
     results.extend(_CheckIdenticalFiles(input_api, output_api))
+    results.extend(_CheckFilesUsingEventSender(input_api, output_api))
     return results
 
 
@@ -98,4 +115,5 @@
     results = []
     results.extend(_CheckTestharnessResults(input_api, output_api))
     results.extend(_CheckIdenticalFiles(input_api, output_api))
+    results.extend(_CheckFilesUsingEventSender(input_api, output_api))
     return results
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5c8e07d..e7837c1b 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2418,7 +2418,6 @@
 crbug.com/626703 external/wpt/streams/piping/multiple-propagation.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/streams/piping/pipe-through.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/streams/piping/transform-streams.sharedworker.html [ Timeout ]
-crbug.com/626703 external/wpt/streams/readable-byte-streams/general.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/bad-strategies.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/bad-underlying-sources.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/brand-checks.sharedworker.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index e174aae3..55d9f7c 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -55385,6 +55385,11 @@
      {}
     ]
    ],
+   "./check_stability.ini": [
+    [
+     {}
+    ]
+   ],
    "./check_stability.py": [
     [
      {}
@@ -55405,6 +55410,11 @@
      {}
     ]
    ],
+   "./ci_unittest.sh": [
+    [
+     {}
+    ]
+   ],
    "./lint.whitelist": [
     [
      {}
@@ -57425,6 +57435,21 @@
      {}
     ]
    ],
+   "content-security-policy/frame-src/frame-src-redirect.html.headers": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/frame-src/support/frame.html": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/frame-src/support/testharness-helper.sub.js": [
+    [
+     {}
+    ]
+   ],
    "content-security-policy/generic/fail-0_1.js": [
     [
      {}
@@ -57785,6 +57810,11 @@
      {}
     ]
    ],
+   "content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html.headers": [
+    [
+     {}
+    ]
+   ],
    "content-security-policy/securitypolicyviolation/support/inside-worker.sub.js": [
     [
      {}
@@ -57795,6 +57825,16 @@
      {}
     ]
    ],
+   "content-security-policy/securitypolicyviolation/support/testharness-helper.sub.js": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html.headers": [
+    [
+     {}
+    ]
+   ],
    "content-security-policy/style-src/resources/style-src-import.sub.css": [
     [
      {}
@@ -57955,21 +57995,6 @@
      {}
     ]
    ],
-   "css-timing-1/frames-timing-functions-output-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "css-timing-1/frames-timing-functions-syntax-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "css-timing-1/step-timing-functions-output-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "css-timing-1/testcommon.js": [
     [
      {}
@@ -72605,11 +72630,6 @@
      {}
     ]
    ],
-   "dom/ranges/Range-mutations-splitText-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "dom/ranges/Range-mutations.js": [
     [
      {}
@@ -73560,11 +73580,6 @@
      {}
     ]
    ],
-   "fetch/api/headers/headers-combine-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "fetch/api/headers/headers-idl-expected.txt": [
     [
      {}
@@ -73575,11 +73590,6 @@
      {}
     ]
    ],
-   "fetch/api/headers/headers-record-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "fetch/api/policies/csp-blocked-worker-expected.txt": [
     [
      {}
@@ -83970,36 +83980,16 @@
      {}
     ]
    ],
-   "html/semantics/scripting-1/the-script-element/nomodule-reflect-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script-expected.txt": [
     [
      {}
     ]
    ],
-   "html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-module-script-expected.txt": [
     [
      {}
     ]
    ],
-   "html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/semantics/scripting-1/the-script-element/resources/cocoa-module.js": [
     [
      {}
@@ -91130,31 +91120,11 @@
      {}
     ]
    ],
-   "streams/writable-streams/aborting-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/aborting.dedicatedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/aborting.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/aborting.serviceworker.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/aborting.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/bad-strategies.js": [
     [
      {}
@@ -91175,86 +91145,26 @@
      {}
     ]
    ],
-   "streams/writable-streams/close-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/close.dedicatedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/close.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/close.serviceworker.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/close.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/constructor-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/constructor.dedicatedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/constructor.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/constructor.serviceworker.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/constructor.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/count-queuing-strategy.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/error-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/error.dedicatedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/error.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/error.serviceworker.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/error.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/floating-point-total-queue-size.js": [
     [
      {}
@@ -91265,31 +91175,11 @@
      {}
     ]
    ],
-   "streams/writable-streams/properties-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/properties.dedicatedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/properties.js": [
     [
      {}
     ]
    ],
-   "streams/writable-streams/properties.serviceworker.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "streams/writable-streams/properties.sharedworker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "streams/writable-streams/reentrant-strategy.js": [
     [
      {}
@@ -91930,11 +91820,6 @@
      {}
     ]
    ],
-   "web-animations/interfaces/AnimationEffectTiming/easing-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "web-animations/interfaces/AnimationEffectTiming/getComputedStyle-expected.txt": [
     [
      {}
@@ -99587,6 +99472,12 @@
      {}
     ]
    ],
+   "content-security-policy/frame-src/frame-src-redirect.html": [
+    [
+     "/content-security-policy/frame-src/frame-src-redirect.html",
+     {}
+    ]
+   ],
    "content-security-policy/generic/generic-0_1-img-src.html": [
     [
      "/content-security-policy/generic/generic-0_1-img-src.html",
@@ -99987,6 +99878,12 @@
      {}
     ]
    ],
+   "content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html": [
+    [
+     "/content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html",
+     {}
+    ]
+   ],
    "content-security-policy/securitypolicyviolation/inside-dedicated-worker.html": [
     [
      "/content-security-policy/securitypolicyviolation/inside-dedicated-worker.html",
@@ -100059,6 +99956,12 @@
      {}
     ]
    ],
+   "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html": [
+    [
+     "/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html",
+     {}
+    ]
+   ],
    "content-security-policy/style-src/style-src-error-event-fires.html": [
     [
      "/content-security-policy/style-src/style-src-error-event-fires.html",
@@ -132389,11 +132292,11 @@
    "support"
   ],
   "./.gitmodules": [
-   "078f9de776005fb33e6c58bf1aad5deab425ab39",
+   "525f7d93f00f11086aabc1f652cf06623e21986c",
    "support"
   ],
   "./.travis.yml": [
-   "412ca6450f30e77589d7f6aea15d111ccb394b9d",
+   "e4e94641cee55e5f34abf9ab36a8ac3f50082e06",
    "support"
   ],
   "./CONTRIBUTING.md": [
@@ -132405,11 +132308,15 @@
    "support"
   ],
   "./README.md": [
-   "a5a62e25369497e37f04f7870b7b470b2eb7f8af",
+   "a00890035c46ef53ab51d51107fde1891265379e",
+   "support"
+  ],
+  "./check_stability.ini": [
+   "4ee10945191db8ce3e1d8bfae86bc3f0ad40868f",
    "support"
   ],
   "./check_stability.py": [
-   "f818356e2394747a7c0828cd1e2eabeb73265601",
+   "0b0bdd5f77a017fed6bdcc2dba20aa758488942a",
    "support"
   ],
   "./ci_built_diff.sh": [
@@ -132424,8 +132331,12 @@
    "2d54d770ed8439a93e98961b3105b3248684744d",
    "support"
   ],
+  "./ci_unittest.sh": [
+   "7781565feffccf99e891a16bcd3c70b62ad15f20",
+   "support"
+  ],
   "./lint.whitelist": [
-   "6ca96c50b84670517ffb4baff14b424fd8c54f88",
+   "283ee81b61e69eb4458f99ef6bfeb4160a7af114",
    "support"
   ],
   "./update-built-tests.sh": [
@@ -132469,7 +132380,7 @@
    "testharness"
   ],
   "FileAPI/blob/Blob-constructor-expected.txt": [
-   "458870f050a401d2be24aff18989d9ab68bb74fe",
+   "f05c2375c382db6a12ce8ff2748b9084119ecdec",
    "support"
   ],
   "FileAPI/blob/Blob-constructor.html": [
@@ -134245,7 +134156,7 @@
    "testharness"
   ],
   "XMLHttpRequest/getallresponseheaders-cl-expected.txt": [
-   "e67ae5d72f4c764ce8a5f64d43e8dcd84946f25b",
+   "0ad5f6f073f8ff6368da6a99b0d842d0306a7e4a",
    "support"
   ],
   "XMLHttpRequest/getallresponseheaders-cl.htm": [
@@ -137200,6 +137111,22 @@
    "51e1354d16cfa4967e91206be8bd0d8c6ca577af",
    "support"
   ],
+  "content-security-policy/frame-src/frame-src-redirect.html": [
+   "16ac0d81d039fc2514b72a68fa491159ad46f59c",
+   "testharness"
+  ],
+  "content-security-policy/frame-src/frame-src-redirect.html.headers": [
+   "3df52b9299a0ada67d3211c5190269fa8b046211",
+   "support"
+  ],
+  "content-security-policy/frame-src/support/frame.html": [
+   "3f5fd74f92250b09f2dd790d154ade7bc4748d78",
+   "support"
+  ],
+  "content-security-policy/frame-src/support/testharness-helper.sub.js": [
+   "c11acf3aff5ffaf1a581ff8c73f077b7c0ee0a26",
+   "support"
+  ],
   "content-security-policy/generic/fail-0_1.js": [
    "357bbab837dcc2794a46fb07e31ea49b16b447cf",
    "support"
@@ -137748,6 +137675,14 @@
    "5f2ff4a87aa476168cf3d13b10a8d81a387b8e42",
    "testharness"
   ],
+  "content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html": [
+   "e338e94ea726419db64ed5b98c95b862c394409e",
+   "testharness"
+  ],
+  "content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html.headers": [
+   "960ee8a9f7ccf33ea435890e2eae0e68399f32ed",
+   "support"
+  ],
   "content-security-policy/securitypolicyviolation/inside-dedicated-worker.html": [
    "46d18c97d554716b714856c00bdc49388d211868",
    "testharness"
@@ -137800,10 +137735,22 @@
    "ac19897e2693ba3228640d03c770cd5a33c51381",
    "support"
   ],
+  "content-security-policy/securitypolicyviolation/support/testharness-helper.sub.js": [
+   "71244cc74fa8f8ee8082c876264e053348905fbd",
+   "support"
+  ],
   "content-security-policy/securitypolicyviolation/targeting.html": [
    "36ec8dd9ef0bd1be3615913015d857aa1a7c9e97",
    "testharness"
   ],
+  "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html": [
+   "ec7ce3c14a571eae99473dd595a39c2019ba9e36",
+   "testharness"
+  ],
+  "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html.headers": [
+   "6e15d48ddd21d1bbb9603081d5d7fef98ebfa106",
+   "support"
+  ],
   "content-security-policy/style-src/resources/style-src-import.sub.css": [
    "37de4f39b0399d9a5a230b5446883f9e4b49a061",
    "support"
@@ -138100,26 +138047,14 @@
    "77a45437209844f7e5128bd6aa2efeeacf876187",
    "testharness"
   ],
-  "css-timing-1/frames-timing-functions-output-expected.txt": [
-   "fe0c5ed2207897d4c7a9af3d2a2be745e9f83800",
-   "support"
-  ],
   "css-timing-1/frames-timing-functions-output.html": [
    "fe9a931466f31605f1a09d5f95589cc54ee34663",
    "testharness"
   ],
-  "css-timing-1/frames-timing-functions-syntax-expected.txt": [
-   "613677c126bf89209ea3ad481f4c94c83fbe6f2c",
-   "support"
-  ],
   "css-timing-1/frames-timing-functions-syntax.html": [
    "7ac5eef9cec74746aa076912285398f525b01c06",
    "testharness"
   ],
-  "css-timing-1/step-timing-functions-output-expected.txt": [
-   "aa33ab0aed875bb1206592f8f854bd1a1b5cd45e",
-   "support"
-  ],
   "css-timing-1/step-timing-functions-output.html": [
    "4b514aac1efca5813e5a551290f8c84f678bd41d",
    "testharness"
@@ -170125,7 +170060,7 @@
    "testharness"
   ],
   "dom/interfaces-expected.txt": [
-   "748d57b237ac32ba300ce035ef5806eb41c1e9e9",
+   "18caa958b5d7f055ada6fb1d5980eb18c69b223e",
    "support"
   ],
   "dom/interfaces.html": [
@@ -170241,7 +170176,7 @@
    "testharness"
   ],
   "dom/nodes/DOMImplementation-createDocumentType.html": [
-   "09a9749b83780791c66d8695023165cd544ec23c",
+   "515a2a4dc52fafb890899ff340201ed87418fc1f",
    "testharness"
   ],
   "dom/nodes/DOMImplementation-createHTMLDocument.html": [
@@ -170593,7 +170528,7 @@
    "testharness"
   ],
   "dom/nodes/Document-createElementNS.js": [
-   "9b6cf141da4b259fd2a032d47082b70ccfe4a59b",
+   "b0a2c15e7f3091eec203fc6b505b9f84f87a8f99",
    "support"
   ],
   "dom/nodes/Document-createEvent-expected.txt": [
@@ -171161,7 +171096,7 @@
    "support"
   ],
   "dom/nodes/attributes.html": [
-   "1b93fbf6c7d2c3e018cb34f50c5332d2c43b5355",
+   "cddff48a942168622772069ca2b2bcf0318deed4",
    "testharness"
   ],
   "dom/nodes/attributes.js": [
@@ -171452,10 +171387,6 @@
    "c0d01268022a85b23d1f56a9d6bb1a78ad10311e",
    "testharness"
   ],
-  "dom/ranges/Range-mutations-splitText-expected.txt": [
-   "6051705c2fe0845ba1bb93d348a20fcfa2d59fde",
-   "support"
-  ],
   "dom/ranges/Range-mutations-splitText.html": [
    "12572e308272e555bc8f4f25063e373081f53fab",
    "testharness"
@@ -173200,10 +173131,6 @@
    "c83fdd0119c17b30051ab437e66934dc22c8c420",
    "testharness"
   ],
-  "fetch/api/headers/headers-combine-expected.txt": [
-   "2603c1022fbba9b7bddfd7eaa04b3a1f3524c1c1",
-   "support"
-  ],
   "fetch/api/headers/headers-combine.html": [
    "0edea47e706ac6fae40ae78665f6a839f04c2b22",
    "testharness"
@@ -173228,10 +173155,6 @@
    "6ccdfba06f9a8692029d72ef81aee16a1996ca01",
    "testharness"
   ],
-  "fetch/api/headers/headers-record-expected.txt": [
-   "d8d03a608ee0af8ba54c18dcc1e8040dbe4e86bd",
-   "support"
-  ],
   "fetch/api/headers/headers-record.html": [
    "26b2eb6cb1836f6431f16b1e60256919d9427f2b",
    "testharness"
@@ -178541,7 +178464,7 @@
    "testharness"
   ],
   "html/dom/reflection-misc-expected.txt": [
-   "fa14f5d001bf1a69081be667ee4f4c5e7fb814fa",
+   "13fb579d28b688f1d101bb854710f9c3ed5d720c",
    "support"
   ],
   "html/dom/reflection-misc.html": [
@@ -185257,7 +185180,7 @@
    "support"
   ],
   "html/semantics/forms/the-form-element/form-autocomplete.html": [
-   "e3548e62923d62b5844f8d4d7222006bbfd3cb2a",
+   "c3aae63b6c007e3f39a7bf39c56bcdb7172273ad",
    "testharness"
   ],
   "html/semantics/forms/the-form-element/form-elements-interfaces-01.html": [
@@ -186548,18 +186471,10 @@
    "997cee37dcd202498196e63e0f66035979121b7f",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/nomodule-reflect-expected.txt": [
-   "4b3d01ab4fad799660d3bb3c4b0637ee58a9dd29",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/nomodule-reflect.html": [
    "ac2b3c16e9e9263cd4c14de205b63709c14ec2e3",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script-expected.txt": [
-   "59cc2ed73a7042c5bc4af507141c3c98853227ed",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html": [
    "5b4a532b21caa6235bed10a28878c65523a816aa",
    "testharness"
@@ -186572,10 +186487,6 @@
    "f43755d9dffe2983a377f2c00b855f106776b617",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts-expected.txt": [
-   "978ff3c903965984600e3cf06f68dd6877db7480",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts.html": [
    "2b6654342c5a2e2d85df2bc8ec805b5fa7ed1550",
    "testharness"
@@ -186588,10 +186499,6 @@
    "071d6550f88d5f04de77fd28a314dbc7121b758f",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts-expected.txt": [
-   "277836f9b4f884c319a831e99ef12e093d2b4609",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html": [
    "a5600b1fcb40e3dbdf223fbeee40c0a3f096eed1",
    "testharness"
@@ -200237,11 +200144,11 @@
    "testharness"
   ],
   "service-workers/service-worker/fetch-event.https-expected.txt": [
-   "8ec52dcd7d6f34ccfa647c9670b02199dffadcb1",
+   "eacfa942f91037514c56d7d379897bd578aa2cfd",
    "support"
   ],
   "service-workers/service-worker/fetch-event.https.html": [
-   "fb2b3ea20415d9148cfda983ac785f0de16e6889",
+   "2b3d7086eb6733d81c7b06516721b655d853682d",
    "testharness"
   ],
   "service-workers/service-worker/fetch-frame-resource.https.html": [
@@ -202385,7 +202292,7 @@
    "testharness"
   ],
   "streams/readable-byte-streams/general.js": [
-   "b5d2f4c72f2e365e0716897a2fd398600e4eac6c",
+   "e8d971fb6491da06f9ceedb1b6cd6a5c06b6f3b4",
    "support"
   ],
   "streams/readable-byte-streams/general.serviceworker.https-expected.txt": [
@@ -202688,14 +202595,6 @@
    "099c7bce47262455ad4c51e59a2c92f5f6a9eb9c",
    "support"
   ],
-  "streams/writable-streams/aborting-expected.txt": [
-   "78ce21b210a6a8f73647ea919060bbbee6e0b49e",
-   "support"
-  ],
-  "streams/writable-streams/aborting.dedicatedworker-expected.txt": [
-   "78ce21b210a6a8f73647ea919060bbbee6e0b49e",
-   "support"
-  ],
   "streams/writable-streams/aborting.dedicatedworker.html": [
    "89cfc3ba5cfbb426b6ac60c32aa5cfe9dd0ad8b4",
    "testharness"
@@ -202708,18 +202607,10 @@
    "73be2b0af40871af1e2cd65d99f4591d45cee3aa",
    "support"
   ],
-  "streams/writable-streams/aborting.serviceworker.https-expected.txt": [
-   "f8aa67d00624163e1c2cb89eda86d3ad94a7e8a2",
-   "support"
-  ],
   "streams/writable-streams/aborting.serviceworker.https.html": [
    "b69530ebf51ccaf781ff78172be2f4607ee22c86",
    "testharness"
   ],
-  "streams/writable-streams/aborting.sharedworker-expected.txt": [
-   "78ce21b210a6a8f73647ea919060bbbee6e0b49e",
-   "support"
-  ],
   "streams/writable-streams/aborting.sharedworker.html": [
    "9e792fad19cd10a96440478cb7e0486f41b70bf4",
    "testharness"
@@ -202804,14 +202695,6 @@
    "3c576d902e34976313357126d3688a4639a4e5a7",
    "testharness"
   ],
-  "streams/writable-streams/close-expected.txt": [
-   "e59e0f69187bec32019ecdcd9cf7a97ebc0cf18f",
-   "support"
-  ],
-  "streams/writable-streams/close.dedicatedworker-expected.txt": [
-   "e59e0f69187bec32019ecdcd9cf7a97ebc0cf18f",
-   "support"
-  ],
   "streams/writable-streams/close.dedicatedworker.html": [
    "cccf37e3bcc4be858fb41be465c38e7785db4508",
    "testharness"
@@ -202824,30 +202707,14 @@
    "a0f0183652427bdcd049eac90eb52d1ba5e09110",
    "support"
   ],
-  "streams/writable-streams/close.serviceworker.https-expected.txt": [
-   "d15bee93a795b34f445ec2ddcb307ff18b7fc507",
-   "support"
-  ],
   "streams/writable-streams/close.serviceworker.https.html": [
    "5461a766e8047c6d50b7943d99f8ebb4c140a547",
    "testharness"
   ],
-  "streams/writable-streams/close.sharedworker-expected.txt": [
-   "e59e0f69187bec32019ecdcd9cf7a97ebc0cf18f",
-   "support"
-  ],
   "streams/writable-streams/close.sharedworker.html": [
    "b2aeb127d5ae7087b42e3fc08faaa113c84e6fd8",
    "testharness"
   ],
-  "streams/writable-streams/constructor-expected.txt": [
-   "742d264da53440cac0d79cadaea4e503f374cf48",
-   "support"
-  ],
-  "streams/writable-streams/constructor.dedicatedworker-expected.txt": [
-   "742d264da53440cac0d79cadaea4e503f374cf48",
-   "support"
-  ],
   "streams/writable-streams/constructor.dedicatedworker.html": [
    "6c954f0d265d21fe1dae9d85afbcc79e8d875797",
    "testharness"
@@ -202860,18 +202727,10 @@
    "0f67e4c79f7a7d32c29b14b917e8921dbb3171c1",
    "support"
   ],
-  "streams/writable-streams/constructor.serviceworker.https-expected.txt": [
-   "6ac9443f3fb0c27b576535cea31b1be4289f2066",
-   "support"
-  ],
   "streams/writable-streams/constructor.serviceworker.https.html": [
    "025f934a714ce8c52df953ba570a527cbcb88399",
    "testharness"
   ],
-  "streams/writable-streams/constructor.sharedworker-expected.txt": [
-   "742d264da53440cac0d79cadaea4e503f374cf48",
-   "support"
-  ],
   "streams/writable-streams/constructor.sharedworker.html": [
    "f6ce1491f86ee048da0f6135440b7aa5359caa22",
    "testharness"
@@ -202896,14 +202755,6 @@
    "875e0dffe7710c21bfcb8f554c2216626c2eb013",
    "testharness"
   ],
-  "streams/writable-streams/error-expected.txt": [
-   "bc51f025fe06daa1a605ad5443cb3c47b994f70e",
-   "support"
-  ],
-  "streams/writable-streams/error.dedicatedworker-expected.txt": [
-   "bc51f025fe06daa1a605ad5443cb3c47b994f70e",
-   "support"
-  ],
   "streams/writable-streams/error.dedicatedworker.html": [
    "c1876a4e28900174a13d59d82acb4e60e7b4a965",
    "testharness"
@@ -202916,18 +202767,10 @@
    "4d453557abcefc69168fa399e04226f37dbf1142",
    "support"
   ],
-  "streams/writable-streams/error.serviceworker.https-expected.txt": [
-   "3c1c28dc37a8af3b94218ab49ac646e5505acebf",
-   "support"
-  ],
   "streams/writable-streams/error.serviceworker.https.html": [
    "d8a0b8b68a7a59c9bf186336a6e22f34912fb7e5",
    "testharness"
   ],
-  "streams/writable-streams/error.sharedworker-expected.txt": [
-   "bc51f025fe06daa1a605ad5443cb3c47b994f70e",
-   "support"
-  ],
   "streams/writable-streams/error.sharedworker.html": [
    "0eaf67b6f635e95fe96a95082d4015cc9f427eef",
    "testharness"
@@ -202972,14 +202815,6 @@
    "44f9ceaa3bfc9d8b92885997d322486bd0f237a6",
    "testharness"
   ],
-  "streams/writable-streams/properties-expected.txt": [
-   "5eda14d2b172954c097a528aa24205edf481eaea",
-   "support"
-  ],
-  "streams/writable-streams/properties.dedicatedworker-expected.txt": [
-   "5eda14d2b172954c097a528aa24205edf481eaea",
-   "support"
-  ],
   "streams/writable-streams/properties.dedicatedworker.html": [
    "0d766237560b16ddb1bfcd02e701089132f1b3ec",
    "testharness"
@@ -202992,18 +202827,10 @@
    "651d62037ceff95818e8cd33c078a31e09dafd5c",
    "support"
   ],
-  "streams/writable-streams/properties.serviceworker.https-expected.txt": [
-   "26d1488fd4e2f091dea6f368965386c1377bfb35",
-   "support"
-  ],
   "streams/writable-streams/properties.serviceworker.https.html": [
    "2ef8fc878249c429a89e0748e6a98fac47c1a99a",
    "testharness"
   ],
-  "streams/writable-streams/properties.sharedworker-expected.txt": [
-   "5eda14d2b172954c097a528aa24205edf481eaea",
-   "support"
-  ],
   "streams/writable-streams/properties.sharedworker.html": [
    "5c855e897d1143092ecc10b58268e6a576882184",
    "testharness"
@@ -203924,10 +203751,6 @@
    "54858f64784c74a3d112e559fb765a1dbb9ba279",
    "testharness"
   ],
-  "web-animations/interfaces/AnimationEffectTiming/easing-expected.txt": [
-   "b1ff3a9b783d6f258b587ac7371c047b8423bf66",
-   "support"
-  ],
   "web-animations/interfaces/AnimationEffectTiming/easing.html": [
    "a4b8b1c715795d5e66c0e32c2415a2e8fb587147",
    "testharness"
@@ -204033,7 +203856,7 @@
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt": [
-   "47223dc5350adf8c2f70e95424dac0d2ae0bac35",
+   "ec538ee9201ee99bd1d4b4b954b84449a5395d6b",
    "support"
   ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument.html": [
@@ -204185,7 +204008,7 @@
    "testharness"
   ],
   "web-animations/timing-model/time-transformations/transformed-progress-expected.txt": [
-   "55a3ac611b5a2c74ca67994d84584bc130f1118e",
+   "68dceee1b821f40681564036377150e53188a59e",
    "support"
   ],
   "web-animations/timing-model/time-transformations/transformed-progress.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/.gitmodules b/third_party/WebKit/LayoutTests/external/wpt/.gitmodules
index 5eb46bc..41d2a660 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/.gitmodules
+++ b/third_party/WebKit/LayoutTests/external/wpt/.gitmodules
@@ -1,14 +1,12 @@
-[submodule "resources"]
-	path = resources
-	url = https://github.com/w3c/testharness.js.git
-	ignore = dirty
-[submodule "tools"]
-	path = tools
-	url = https://github.com/w3c/wpt-tools.git
-	ignore = dirty
 [submodule "css/tools/apiclient"]
 	path = css/tools/apiclient
 	url = https://github.com/w3c/csswg-apiclient.git
 [submodule "css/tools/w3ctestlib"]
 	path = css/tools/w3ctestlib
 	url = https://github.com/w3c/csswg-w3ctestlib.git
+[submodule "tools/html5lib/html5lib/tests/testdata"]
+	path = tools/html5lib/html5lib/tests/testdata
+	url = https://github.com/html5lib/html5lib-tests.git
+[submodule "resources/webidl2/test/widlproc"]
+	path = resources/webidl2/test/widlproc
+	url = https://github.com/dontcallmedom/widlproc.git
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/.travis.yml b/third_party/WebKit/LayoutTests/external/wpt/.travis.yml
index a558820..1ba2ba2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/.travis.yml
+++ b/third_party/WebKit/LayoutTests/external/wpt/.travis.yml
@@ -48,6 +48,14 @@
       env:
         - secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
         - SCRIPT=ci_stability.sh PRODUCT=chrome:unstable
+    - python: 2.7
+      env: TOXENV=py27 HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
+    - python: 3.5
+      env: TOXENV=py35 HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
+    - python: 3.6
+      env: TOXENV=py36 HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
+    - python: pypy
+      env: TOXENV=pypy HYPOTHESIS_PROFILE=ci_pypy SCRIPT=ci_unittest.sh
   exclude:
     - env:  # exclude empty env from the top-level above
   allow_failures:
diff --git a/third_party/WebKit/LayoutTests/external/wpt/README.md b/third_party/WebKit/LayoutTests/external/wpt/README.md
index 7553e10..266d4ec 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/README.md
+++ b/third_party/WebKit/LayoutTests/external/wpt/README.md
@@ -40,13 +40,6 @@
 If you are behind a proxy, you also need to make sure the domains above are
 excluded from your proxy lookups.
 
-Because web-platform-tests uses git submodules, you must ensure that
-these are up to date. In the root of your checkout, run:
-
-```
-git submodule update --init --recursive
-```
-
 The test environment can then be started using
 
     ./serve
@@ -77,6 +70,55 @@
 "ssl": {"openssl": {"binary": "/path/to/openssl"}}
 ```
 
+<span id="submodules">Submodules</span>
+=======================================
+
+Some optional components of web-platform-tests (test components from
+third party software and pieces of the CSS build system) are included
+as submodules. To obtain these components run the following in the
+root of your checkout:
+
+```
+git submodule update --init --recursive
+```
+
+Prior to commit `39d07eb01fab607ab1ffd092051cded1bdd64d78` submodules
+were requried for basic functionality. If you are working with an
+older checkout, the above command is required in all cases.
+
+When moving between a commit prior to `39d07eb` and one after it git
+may complain
+
+```
+$ git checkout master
+error: The following untracked working tree files would be overwritten by checkout:
+[…]
+```
+
+followed by a long list of files. To avoid this error remove
+the `resources` and `tools` directories before switching branches:
+
+```
+$ rm -r resources/ tools/
+$ git checkout master
+Switched to branch 'master'
+Your branch is up-to-date with 'origin/master'
+```
+
+When moving in the opposite direction, i.e. to a commit that does have
+submodules, you will need to `git submodule update`, as above. If git
+throws an error like:
+
+```
+fatal: No url found for submodule path 'resources/webidl2/test/widlproc' in .gitmodules
+Failed to recurse into submodule path 'resources/webidl2'
+fatal: No url found for submodule path 'tools/html5lib' in .gitmodules
+Failed to recurse into submodule path 'resources'
+Failed to recurse into submodule path 'tools'
+```
+
+then remove the `tools` and `resources` directories, as above.
+
 <span id="windows-notes">Windows Notes</span>
 =============================================
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/check_stability.ini b/third_party/WebKit/LayoutTests/external/wpt/check_stability.ini
new file mode 100644
index 0000000..cf18896
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/check_stability.ini
@@ -0,0 +1,9 @@
+[file detection]
+skip_tests: conformance-checkers docs tools
+# The vast majority of tests rely on files located within the `resources`
+# directory. Because of this, modifications to that directory's contents have
+# the potential to introduce instability in a large number of tests.
+# Exhaustively validating such changes is highly resource intensive
+# (particularly in terms of execution time), making it impractical in most
+# cases.
+ignore_changes: resources
diff --git a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
index dea4c70a..a533206 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
+++ b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
@@ -1,6 +1,7 @@
 from __future__ import print_function
 
 import argparse
+from ConfigParser import SafeConfigParser
 import logging
 import os
 import re
@@ -439,24 +440,34 @@
     return branch_point
 
 
-def get_files_changed(branch_point):
-    """Get and return files changed since current branch diverged from master."""
+def get_files_changed(branch_point, ignore_changes):
+    """Get and return files changed since current branch diverged from master,
+    excluding those that are located within any directory specifed by
+    `ignore_changes`."""
     root = os.path.abspath(os.curdir)
     git = get_git_cmd(wpt_root)
     files = git("diff", "--name-only", "-z", "%s..." % branch_point)
     if not files:
-        return []
+        return [], []
     assert files[-1] == "\0"
-    return [os.path.join(wpt_root, item)
-            for item in files[:-1].split("\0")]
 
+    changed = []
+    ignored = []
+    for item in files[:-1].split("\0"):
+        fullpath = os.path.join(wpt_root, item)
+        topmost_dir = item.split(os.sep, 1)[0]
+        if topmost_dir in ignore_changes:
+            ignored.append(fullpath)
+        else:
+            changed.append(fullpath)
 
-def get_affected_testfiles(files_changed):
+    return changed, ignored
+
+def get_affected_testfiles(files_changed, skip_tests):
     """Determine and return list of test files that reference changed files."""
     affected_testfiles = set()
     nontests_changed = set(files_changed)
     manifest_file = os.path.join(wpt_root, "MANIFEST.json")
-    skip_dirs = ["conformance-checkers", "docs", "tools"]
     test_types = ["testharness", "reftest", "wdspec"]
 
     wpt_manifest = manifest.load(wpt_root, manifest_file)
@@ -477,7 +488,7 @@
             # (because it's not part of any test).
             continue
         top_level_subdir = path_components[0]
-        if top_level_subdir in skip_dirs:
+        if top_level_subdir in skip_tests:
             continue
         repo_path = "/" + os.path.relpath(full_path, wpt_root).replace(os.path.sep, "/")
         nontest_changed_paths.add((full_path, repo_path))
@@ -486,7 +497,7 @@
         # Walk top_level_subdir looking for test files containing either the
         # relative filepath or absolute filepatch to the changed files.
         if root == wpt_root:
-            for dir_name in skip_dirs:
+            for dir_name in skip_tests:
                 dirs.remove(dir_name)
         for fname in fnames:
             test_full_path = os.path.join(root, fname)
@@ -706,7 +717,9 @@
 
 def get_parser():
     """Create and return script-specific argument parser."""
-    parser = argparse.ArgumentParser()
+    description = """Detect instabilities in new tests by executing tests
+    repeatedly and comparing results between executions."""
+    parser = argparse.ArgumentParser(description=description)
     parser.add_argument("--root",
                         action="store",
                         default=os.path.join(os.path.expanduser("~"), "build"),
@@ -730,6 +743,11 @@
                         action="store",
                         type=int,
                         help="Maximum number of bytes to write to standard output/error")
+    parser.add_argument("--config-file",
+                        action="store",
+                        type=str,
+                        help="Location of ini-formatted configuration file",
+                        default="check_stability.ini")
     parser.add_argument("product",
                         action="store",
                         help="Product to run against (`browser-name` or 'browser-name:channel')")
@@ -746,6 +764,12 @@
     parser = get_parser()
     args = parser.parse_args()
 
+    with open(args.config_file, 'r') as config_fp:
+        config = SafeConfigParser()
+        config.readfp(config_fp)
+        skip_tests = config.get("file detection", "skip_tests").split()
+        ignore_changes = set(config.get("file detection", "ignore_changes").split())
+
     if args.output_bytes is not None:
         replace_streams(args.output_bytes,
                         "Log reached capacity (%s bytes); output disabled." % args.output_bytes)
@@ -782,7 +806,11 @@
 
         # For now just pass the whole list of changed files to wptrunner and
         # assume that it will run everything that's actually a test
-        files_changed = get_files_changed(branch_point)
+        files_changed, files_ignored = get_files_changed(branch_point, ignore_changes)
+
+        if files_ignored:
+            logger.info("Ignoring %s changed files:\n%s" % (len(files_ignored),
+                                                            "".join(" * %s\n" % item for item in files_ignored)))
 
         if not files_changed:
             logger.info("No files changed")
@@ -804,7 +832,7 @@
 
         logger.debug("Files changed:\n%s" % "".join(" * %s\n" % item for item in files_changed))
 
-        affected_testfiles = get_affected_testfiles(files_changed)
+        affected_testfiles = get_affected_testfiles(files_changed, skip_tests)
 
         logger.debug("Affected tests:\n%s" % "".join(" * %s\n" % item for item in affected_testfiles))
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/ci_unittest.sh b/third_party/WebKit/LayoutTests/external/wpt/ci_unittest.sh
new file mode 100755
index 0000000..c75584f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/ci_unittest.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -e
+
+pip install -U tox codecov
+cd tools
+tox
+coverage combine
+codecov
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocument-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocument-expected.txt
index 20db23f..1c7dbd6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocument-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocument-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 391 tests; 389 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 391 tests; 368 PASS, 23 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS DOMImplementation.createDocument(namespace, qualifiedName, doctype) 
 PASS createDocument test: null,null,null,null 
 PASS createDocument test: metadata for null,null,null 
@@ -32,11 +32,11 @@
 PASS createDocument test: null,"fo o",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: null,"-foo",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: null,".foo",null,"INVALID_CHARACTER_ERR" 
-PASS createDocument test: null,":foo",null,"NAMESPACE_ERR" 
-PASS createDocument test: null,"f:oo",null,"NAMESPACE_ERR" 
-PASS createDocument test: null,"foo:",null,"NAMESPACE_ERR" 
-PASS createDocument test: null,"f:o:o",null,"NAMESPACE_ERR" 
-PASS createDocument test: null,":",null,"NAMESPACE_ERR" 
+FAIL createDocument test: null,":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: null,"f:oo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The namespace URI provided ('') is not valid for the qualified name provided ('f:oo')." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: null,"foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: null,"f:o:o",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: null,":",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: null,"xml",null,null 
 PASS createDocument test: metadata for null,"xml",null 
 PASS createDocument test: characterSet aliases for null,"xml",null 
@@ -51,9 +51,9 @@
 PASS createDocument test: "",null,null,null 
 PASS createDocument test: metadata for "",null,null 
 PASS createDocument test: characterSet aliases for "",null,null 
-PASS createDocument test: "",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "","f:oo",null,"NAMESPACE_ERR" 
-PASS createDocument test: "","foo:",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: undefined,null,null,null 
 PASS createDocument test: metadata for undefined,null,null 
 PASS createDocument test: characterSet aliases for undefined,null,null 
@@ -70,10 +70,10 @@
 PASS createDocument test: undefined,"foo1",null,null 
 PASS createDocument test: metadata for undefined,"foo1",null 
 PASS createDocument test: characterSet aliases for undefined,"foo1",null 
-PASS createDocument test: undefined,":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: undefined,":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: undefined,"f:oo",null,"NAMESPACE_ERR" 
-PASS createDocument test: undefined,"foo:",null,"NAMESPACE_ERR" 
-PASS createDocument test: undefined,"f::oo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: undefined,"foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: undefined,"f::oo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: undefined,"xml",null,null 
 PASS createDocument test: metadata for undefined,"xml",null 
 PASS createDocument test: characterSet aliases for undefined,"xml",null 
@@ -98,19 +98,19 @@
 PASS createDocument test: "http://example.com/","foo1",null,null 
 PASS createDocument test: metadata for "http://example.com/","foo1",null 
 PASS createDocument test: characterSet aliases for "http://example.com/","foo1",null 
-PASS createDocument test: "http://example.com/",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://example.com/",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://example.com/","f:oo",null,null 
 PASS createDocument test: metadata for "http://example.com/","f:oo",null 
 PASS createDocument test: characterSet aliases for "http://example.com/","f:oo",null 
-PASS createDocument test: "http://example.com/","f:o:o",null,"NAMESPACE_ERR" 
-PASS createDocument test: "http://example.com/","foo:",null,"NAMESPACE_ERR" 
-PASS createDocument test: "http://example.com/","f::oo",null,"NAMESPACE_ERR" 
-FAIL createDocument test: "http://example.com/","a:0",null,"NAMESPACE_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "InvalidCharacterError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('a:0') contains the invalid name-start character '0'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
+FAIL createDocument test: "http://example.com/","f:o:o",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: "http://example.com/","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocument test: "http://example.com/","f::oo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+PASS createDocument test: "http://example.com/","a:0",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","0:a",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","a:_",null,null 
 PASS createDocument test: metadata for "http://example.com/","a:_",null 
 PASS createDocument test: characterSet aliases for "http://example.com/","a:_",null 
-FAIL createDocument test: "http://example.com/","a:ெ",null,"NAMESPACE_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "InvalidCharacterError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('a:ெ') contains the invalid name-start character 'ெ'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
+PASS createDocument test: "http://example.com/","a:ெ",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","ெ:a",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","a:aெ",null,null 
 PASS createDocument test: metadata for "http://example.com/","a:aெ",null 
@@ -171,7 +171,7 @@
 PASS createDocument test: "http://example.com/","xmlfoo:bar",null,null 
 PASS createDocument test: metadata for "http://example.com/","xmlfoo:bar",null 
 PASS createDocument test: characterSet aliases for "http://example.com/","xmlfoo:bar",null 
-PASS createDocument test: "http://example.com/","prefix::local",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://example.com/","prefix::local",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('prefix::local') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://example.com/","namespaceURI:{",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","namespaceURI:}",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://example.com/","namespaceURI:~",null,"INVALID_CHARACTER_ERR" 
@@ -209,11 +209,11 @@
 PASS createDocument test: "/","foo1",null,null 
 PASS createDocument test: metadata for "/","foo1",null 
 PASS createDocument test: characterSet aliases for "/","foo1",null 
-PASS createDocument test: "/",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "/",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "/","f:oo",null,null 
 PASS createDocument test: metadata for "/","f:oo",null 
 PASS createDocument test: characterSet aliases for "/","f:oo",null 
-PASS createDocument test: "/","foo:",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "/","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "/","xml",null,null 
 PASS createDocument test: metadata for "/","xml",null 
 PASS createDocument test: characterSet aliases for "/","xml",null 
@@ -236,11 +236,11 @@
 PASS createDocument test: "http://www.w3.org/XML/1998/namespace","foo1",null,null 
 PASS createDocument test: metadata for "http://www.w3.org/XML/1998/namespace","foo1",null 
 PASS createDocument test: characterSet aliases for "http://www.w3.org/XML/1998/namespace","foo1",null 
-PASS createDocument test: "http://www.w3.org/XML/1998/namespace",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://www.w3.org/XML/1998/namespace",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://www.w3.org/XML/1998/namespace","f:oo",null,null 
 PASS createDocument test: metadata for "http://www.w3.org/XML/1998/namespace","f:oo",null 
 PASS createDocument test: characterSet aliases for "http://www.w3.org/XML/1998/namespace","f:oo",null 
-PASS createDocument test: "http://www.w3.org/XML/1998/namespace","foo:",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://www.w3.org/XML/1998/namespace","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://www.w3.org/XML/1998/namespace","xml",null,null 
 PASS createDocument test: metadata for "http://www.w3.org/XML/1998/namespace","xml",null 
 PASS createDocument test: characterSet aliases for "http://www.w3.org/XML/1998/namespace","xml",null 
@@ -261,9 +261,9 @@
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","1foo",null,"INVALID_CHARACTER_ERR" 
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","f1oo",null,"NAMESPACE_ERR" 
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","foo1",null,"NAMESPACE_ERR" 
-PASS createDocument test: "http://www.w3.org/2000/xmlns/",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://www.w3.org/2000/xmlns/",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","f:oo",null,"NAMESPACE_ERR" 
-PASS createDocument test: "http://www.w3.org/2000/xmlns/","foo:",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "http://www.w3.org/2000/xmlns/","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","xml",null,"NAMESPACE_ERR" 
 PASS createDocument test: "http://www.w3.org/2000/xmlns/","xmlns",null,null 
 PASS createDocument test: metadata for "http://www.w3.org/2000/xmlns/","xmlns",null 
@@ -285,11 +285,11 @@
 PASS createDocument test: "foo:","foo1",null,null 
 PASS createDocument test: metadata for "foo:","foo1",null 
 PASS createDocument test: characterSet aliases for "foo:","foo1",null 
-PASS createDocument test: "foo:",":foo",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "foo:",":foo",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "foo:","f:oo",null,null 
 PASS createDocument test: metadata for "foo:","f:oo",null 
 PASS createDocument test: characterSet aliases for "foo:","f:oo",null 
-PASS createDocument test: "foo:","foo:",null,"NAMESPACE_ERR" 
+FAIL createDocument test: "foo:","foo:",null,"INVALID_CHARACTER_ERR" assert_throws: function "function () { document.implementation.createDocument(namespace, qualifiedName, doctype) }" threw object "NamespaceError: Failed to execute 'createDocument' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createDocument test: "foo:","xml",null,null 
 PASS createDocument test: metadata for "foo:","xml",null 
 PASS createDocument test: characterSet aliases for "foo:","xml",null 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType-expected.txt
new file mode 100644
index 0000000..4420a02
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType-expected.txt
@@ -0,0 +1,92 @@
+This is a testharness.js-based test.
+Found 82 tests; 79 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS DOMImplementation.createDocumentType(qualifiedName, publicId, systemId) 
+PASS createDocumentType("", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("test:root", "1234", "") should work 
+PASS createDocumentType("test:root", "1234", "test") should work 
+PASS createDocumentType("test:root", "test", "") should work 
+PASS createDocumentType("test:root", "test", "test") should work 
+PASS createDocumentType("_:_", "", "") should work 
+PASS createDocumentType("_:h0", "", "") should work 
+PASS createDocumentType("_:test", "", "") should work 
+PASS createDocumentType("_:_.", "", "") should work 
+PASS createDocumentType("_:a-", "", "") should work 
+PASS createDocumentType("l_:_", "", "") should work 
+PASS createDocumentType("ns:_0", "", "") should work 
+PASS createDocumentType("ns:a0", "", "") should work 
+PASS createDocumentType("ns0:test", "", "") should work 
+PASS createDocumentType("ns:EEE.", "", "") should work 
+PASS createDocumentType("ns:_-", "", "") should work 
+PASS createDocumentType("a.b:c", "", "") should work 
+PASS createDocumentType("a-b:c.j", "", "") should work 
+PASS createDocumentType("a-b:c", "", "") should work 
+PASS createDocumentType("foo", "", "") should work 
+PASS createDocumentType("1foo", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("foo1", "", "") should work 
+PASS createDocumentType("f1oo", "", "") should work 
+PASS createDocumentType("@foo", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("foo@", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("f@oo", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:{", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:}", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:~", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:'", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:!", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:@", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:#", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:$", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:%", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:^", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:&", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:*", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:(", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:)", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:+", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:=", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:[", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:]", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:\\", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:/", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:;", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:`", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:<", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:>", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:,", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:a ", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("edi:\"", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("{", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("}", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("'", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("~", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("`", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("@", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("#", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("$", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("%", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("^", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("&", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("*", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("(", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType(")", "", "") should throw INVALID_CHARACTER_ERR 
+PASS createDocumentType("f:oo", "", "") should work 
+FAIL createDocumentType(":foo", "", "") should throw INVALID_CHARACTER_ERR assert_throws: function "function () {
+          document.implementation.createDocumentType(qualifiedName, publicId, systemId)
+        }" threw object "NamespaceError: Failed to execute 'createDocumentType' on 'DOMImplementation': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocumentType("foo:", "", "") should throw INVALID_CHARACTER_ERR assert_throws: function "function () {
+          document.implementation.createDocumentType(qualifiedName, publicId, systemId)
+        }" threw object "NamespaceError: Failed to execute 'createDocumentType' on 'DOMImplementation': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createDocumentType("prefix::local", "", "") should throw INVALID_CHARACTER_ERR assert_throws: function "function () {
+          document.implementation.createDocumentType(qualifiedName, publicId, systemId)
+        }" threw object "NamespaceError: Failed to execute 'createDocumentType' on 'DOMImplementation': The qualified name provided ('prefix::local') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+PASS createDocumentType("foo", "foo", "") should work 
+PASS createDocumentType("foo", "", "foo") should work 
+PASS createDocumentType("foo", "f'oo", "") should work 
+PASS createDocumentType("foo", "", "f'oo") should work 
+PASS createDocumentType("foo", "f\"oo", "") should work 
+PASS createDocumentType("foo", "", "f\"oo") should work 
+PASS createDocumentType("foo", "f'o\"o", "") should work 
+PASS createDocumentType("foo", "", "f'o\"o") should work 
+PASS createDocumentType("foo", "foo>", "") should work 
+PASS createDocumentType("foo", "", "foo>") should work 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType.html b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType.html
index ac79ddd..f7e6e18b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/DOMImplementation-createDocumentType.html
@@ -80,9 +80,9 @@
     ["(", "", "", "INVALID_CHARACTER_ERR"],
     [")", "", "", "INVALID_CHARACTER_ERR"],
     ["f:oo", "", "", null],
-    [":foo", "", "", "NAMESPACE_ERR"],
-    ["foo:", "", "", "NAMESPACE_ERR"],
-    ["prefix::local", "", "", "NAMESPACE_ERR"],
+    [":foo", "", "", "INVALID_CHARACTER_ERR"],
+    ["foo:", "", "", "INVALID_CHARACTER_ERR"],
+    ["prefix::local", "", "", "INVALID_CHARACTER_ERR"],
     ["foo", "foo", "", null],
     ["foo", "", "foo", null],
     ["foo", "f'oo", "", null],
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS-expected.txt
index 42db7b6..cb33d42 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 581 tests; 575 PASS, 6 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 581 tests; 512 PASS, 69 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS createElementNS test in HTML document: null,null,null 
 PASS createElementNS test in XML document: null,null,null 
 PASS createElementNS test in XHTML document: null,null,null 
@@ -63,21 +63,21 @@
 PASS createElementNS test in HTML document: null,".foo","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XML document: null,".foo","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XHTML document: null,".foo","INVALID_CHARACTER_ERR" 
-PASS createElementNS test in HTML document: null,":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: null,":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: null,":foo","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: null,"f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: null,"f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: null,"f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: null,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: null,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: null,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: null,"f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: null,"f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: null,"f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: null,":","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: null,":","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: null,":","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: null,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: null,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: null,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: null,"f:oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The namespace URI provided ('') is not valid for the qualified name provided ('f:oo')." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: null,"f:oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The namespace URI provided ('') is not valid for the qualified name provided ('f:oo')." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: null,"f:oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The namespace URI provided ('') is not valid for the qualified name provided ('f:oo')." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: null,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: null,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: null,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: null,"f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: null,"f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: null,"f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: null,":","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: null,":","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: null,":","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: null,"xml",null 
 PASS createElementNS test in XML document: null,"xml",null 
 PASS createElementNS test in XHTML document: null,"xml",null 
@@ -102,15 +102,15 @@
 PASS createElementNS test in HTML document: "",null,null 
 PASS createElementNS test in XML document: "",null,null 
 PASS createElementNS test in XHTML document: "",null,null 
-PASS createElementNS test in HTML document: "",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "","f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XML document: "","f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XHTML document: "","f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: "","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "","foo:","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: undefined,null,null 
 PASS createElementNS test in XML document: undefined,null,null 
 PASS createElementNS test in XHTML document: undefined,null,null 
@@ -129,18 +129,18 @@
 PASS createElementNS test in HTML document: undefined,"foo1",null 
 PASS createElementNS test in XML document: undefined,"foo1",null 
 PASS createElementNS test in XHTML document: undefined,"foo1",null 
-PASS createElementNS test in HTML document: undefined,":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: undefined,":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: undefined,":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: undefined,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: undefined,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: undefined,":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: undefined,"f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XML document: undefined,"f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XHTML document: undefined,"f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: undefined,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: undefined,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: undefined,"foo:","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: undefined,"f::oo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: undefined,"f::oo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: undefined,"f::oo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: undefined,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: undefined,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: undefined,"foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: undefined,"f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: undefined,"f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: undefined,"f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: undefined,"xml",null 
 PASS createElementNS test in XML document: undefined,"xml",null 
 PASS createElementNS test in XHTML document: undefined,"xml",null 
@@ -183,33 +183,33 @@
 PASS createElementNS test in HTML document: "http://example.com/","foo1",null 
 PASS createElementNS test in XML document: "http://example.com/","foo1",null 
 PASS createElementNS test in XHTML document: "http://example.com/","foo1",null 
-PASS createElementNS test in HTML document: "http://example.com/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://example.com/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://example.com/",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://example.com/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://example.com/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://example.com/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://example.com/","f:oo",null 
 PASS createElementNS test in XML document: "http://example.com/","f:oo",null 
 PASS createElementNS test in XHTML document: "http://example.com/","f:oo",null 
-PASS createElementNS test in HTML document: "http://example.com/","f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://example.com/","f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://example.com/","f:o:o","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: "http://example.com/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://example.com/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://example.com/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: "http://example.com/","f::oo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://example.com/","f::oo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://example.com/","f::oo","NAMESPACE_ERR" 
-FAIL createElementNS test in HTML document: "http://example.com/","a:0","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:0') contains the invalid name-start character '0'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
-FAIL createElementNS test in XML document: "http://example.com/","a:0","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:0') contains the invalid name-start character '0'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
-FAIL createElementNS test in XHTML document: "http://example.com/","a:0","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:0') contains the invalid name-start character '0'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
+FAIL createElementNS test in HTML document: "http://example.com/","f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://example.com/","f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://example.com/","f:o:o","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f:o:o') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: "http://example.com/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://example.com/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://example.com/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in HTML document: "http://example.com/","f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://example.com/","f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://example.com/","f::oo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('f::oo') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+PASS createElementNS test in HTML document: "http://example.com/","a:0","INVALID_CHARACTER_ERR" 
+PASS createElementNS test in XML document: "http://example.com/","a:0","INVALID_CHARACTER_ERR" 
+PASS createElementNS test in XHTML document: "http://example.com/","a:0","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in HTML document: "http://example.com/","0:a","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XML document: "http://example.com/","0:a","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XHTML document: "http://example.com/","0:a","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in HTML document: "http://example.com/","a:_",null 
 PASS createElementNS test in XML document: "http://example.com/","a:_",null 
 PASS createElementNS test in XHTML document: "http://example.com/","a:_",null 
-FAIL createElementNS test in HTML document: "http://example.com/","a:ெ","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:ெ') contains the invalid name-start character 'ெ'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
-FAIL createElementNS test in XML document: "http://example.com/","a:ெ","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:ெ') contains the invalid name-start character 'ெ'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
-FAIL createElementNS test in XHTML document: "http://example.com/","a:ெ","NAMESPACE_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "InvalidCharacterError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('a:ெ') contains the invalid name-start character 'ெ'." that is not a DOMException NAMESPACE_ERR: property "code" is equal to 5, expected 14
+PASS createElementNS test in HTML document: "http://example.com/","a:ெ","INVALID_CHARACTER_ERR" 
+PASS createElementNS test in XML document: "http://example.com/","a:ெ","INVALID_CHARACTER_ERR" 
+PASS createElementNS test in XHTML document: "http://example.com/","a:ெ","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in HTML document: "http://example.com/","ெ:a","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XML document: "http://example.com/","ெ:a","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XHTML document: "http://example.com/","ெ:a","INVALID_CHARACTER_ERR" 
@@ -282,9 +282,9 @@
 PASS createElementNS test in HTML document: "http://example.com/","xmlfoo:bar",null 
 PASS createElementNS test in XML document: "http://example.com/","xmlfoo:bar",null 
 PASS createElementNS test in XHTML document: "http://example.com/","xmlfoo:bar",null 
-PASS createElementNS test in HTML document: "http://example.com/","prefix::local","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://example.com/","prefix::local","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://example.com/","prefix::local","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://example.com/","prefix::local","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('prefix::local') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://example.com/","prefix::local","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('prefix::local') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://example.com/","prefix::local","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('prefix::local') contains multiple colons." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://example.com/","namespaceURI:{","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XML document: "http://example.com/","namespaceURI:{","INVALID_CHARACTER_ERR" 
 PASS createElementNS test in XHTML document: "http://example.com/","namespaceURI:{","INVALID_CHARACTER_ERR" 
@@ -378,15 +378,15 @@
 PASS createElementNS test in HTML document: "/","foo1",null 
 PASS createElementNS test in XML document: "/","foo1",null 
 PASS createElementNS test in XHTML document: "/","foo1",null 
-PASS createElementNS test in HTML document: "/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "/",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "/","f:oo",null 
 PASS createElementNS test in XML document: "/","f:oo",null 
 PASS createElementNS test in XHTML document: "/","f:oo",null 
-PASS createElementNS test in HTML document: "/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "/","foo:","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "/","xml",null 
 PASS createElementNS test in XML document: "/","xml",null 
 PASS createElementNS test in XHTML document: "/","xml",null 
@@ -417,15 +417,15 @@
 PASS createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace","foo1",null 
 PASS createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace","foo1",null 
 PASS createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace","foo1",null 
-PASS createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace","f:oo",null 
 PASS createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace","f:oo",null 
 PASS createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace","f:oo",null 
-PASS createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace","foo:","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace","xml",null 
 PASS createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace","xml",null 
 PASS createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace","xml",null 
@@ -462,15 +462,15 @@
 PASS createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/","foo1","NAMESPACE_ERR" 
 PASS createElementNS test in XML document: "http://www.w3.org/2000/xmlns/","foo1","NAMESPACE_ERR" 
 PASS createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/","foo1","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://www.w3.org/2000/xmlns/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/","f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XML document: "http://www.w3.org/2000/xmlns/","f:oo","NAMESPACE_ERR" 
 PASS createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/","f:oo","NAMESPACE_ERR" 
-PASS createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "http://www.w3.org/2000/xmlns/","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/","foo:","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "http://www.w3.org/2000/xmlns/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/","xml","NAMESPACE_ERR" 
 PASS createElementNS test in XML document: "http://www.w3.org/2000/xmlns/","xml","NAMESPACE_ERR" 
 PASS createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/","xml","NAMESPACE_ERR" 
@@ -504,15 +504,15 @@
 PASS createElementNS test in HTML document: "foo:","foo1",null 
 PASS createElementNS test in XML document: "foo:","foo1",null 
 PASS createElementNS test in XHTML document: "foo:","foo1",null 
-PASS createElementNS test in HTML document: "foo:",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "foo:",":foo","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "foo:",":foo","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "foo:",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "foo:",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "foo:",":foo","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided (':foo') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "foo:","f:oo",null 
 PASS createElementNS test in XML document: "foo:","f:oo",null 
 PASS createElementNS test in XHTML document: "foo:","f:oo",null 
-PASS createElementNS test in HTML document: "foo:","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XML document: "foo:","foo:","NAMESPACE_ERR" 
-PASS createElementNS test in XHTML document: "foo:","foo:","NAMESPACE_ERR" 
+FAIL createElementNS test in HTML document: "foo:","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XML document: "foo:","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
+FAIL createElementNS test in XHTML document: "foo:","foo:","INVALID_CHARACTER_ERR" assert_throws: function "function () { doc.createElementNS(namespace, qualifiedName) }" threw object "NamespaceError: Failed to execute 'createElementNS' on 'Document': The qualified name provided ('foo:') has an empty local name." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS createElementNS test in HTML document: "foo:","xml",null 
 PASS createElementNS test in XML document: "foo:","xml",null 
 PASS createElementNS test in XHTML document: "foo:","xml",null 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS.js b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS.js
index 1abd333..d01efe88 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElementNS.js
@@ -25,11 +25,11 @@
   [null, "fo o", "INVALID_CHARACTER_ERR"],
   [null, "-foo", "INVALID_CHARACTER_ERR"],
   [null, ".foo", "INVALID_CHARACTER_ERR"],
-  [null, ":foo", "NAMESPACE_ERR"],
-  [null, "f:oo", "NAMESPACE_ERR"],
-  [null, "foo:", "NAMESPACE_ERR"],
-  [null, "f:o:o", "NAMESPACE_ERR"],
-  [null, ":", "NAMESPACE_ERR"],
+  [null, ":foo", "INVALID_CHARACTER_ERR"],
+  [null, "f:oo", "INVALID_CHARACTER_ERR"],
+  [null, "foo:", "INVALID_CHARACTER_ERR"],
+  [null, "f:o:o", "INVALID_CHARACTER_ERR"],
+  [null, ":", "INVALID_CHARACTER_ERR"],
   [null, "xml", null],
   [null, "xmlns", "NAMESPACE_ERR"],
   [null, "xmlfoo", null],
@@ -38,19 +38,19 @@
   [null, "xmlfoo:bar", "NAMESPACE_ERR"],
   [null, "null:xml", "NAMESPACE_ERR"],
   ["", null, null],
-  ["", ":foo", "NAMESPACE_ERR"],
+  ["", ":foo", "INVALID_CHARACTER_ERR"],
   ["", "f:oo", "NAMESPACE_ERR"],
-  ["", "foo:", "NAMESPACE_ERR"],
+  ["", "foo:", "INVALID_CHARACTER_ERR"],
   [undefined, null, null],
   [undefined, undefined, null],
   [undefined, "foo", null],
   [undefined, "1foo", "INVALID_CHARACTER_ERR"],
   [undefined, "f1oo", null],
   [undefined, "foo1", null],
-  [undefined, ":foo", "NAMESPACE_ERR"],
+  [undefined, ":foo", "INVALID_CHARACTER_ERR"],
   [undefined, "f:oo", "NAMESPACE_ERR"],
-  [undefined, "foo:", "NAMESPACE_ERR"],
-  [undefined, "f::oo", "NAMESPACE_ERR"],
+  [undefined, "foo:", "INVALID_CHARACTER_ERR"],
+  [undefined, "f::oo", "INVALID_CHARACTER_ERR"],
   [undefined, "xml", null],
   [undefined, "xmlns", "NAMESPACE_ERR"],
   [undefined, "xmlfoo", null],
@@ -65,15 +65,15 @@
   ["http://example.com/", ".foo", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "f1oo", null],
   ["http://example.com/", "foo1", null],
-  ["http://example.com/", ":foo", "NAMESPACE_ERR"],
+  ["http://example.com/", ":foo", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "f:oo", null],
-  ["http://example.com/", "f:o:o", "NAMESPACE_ERR"],
-  ["http://example.com/", "foo:", "NAMESPACE_ERR"],
-  ["http://example.com/", "f::oo", "NAMESPACE_ERR"],
-  ["http://example.com/", "a:0", "NAMESPACE_ERR"],
+  ["http://example.com/", "f:o:o", "INVALID_CHARACTER_ERR"],
+  ["http://example.com/", "foo:", "INVALID_CHARACTER_ERR"],
+  ["http://example.com/", "f::oo", "INVALID_CHARACTER_ERR"],
+  ["http://example.com/", "a:0", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "0:a", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "a:_", null],
-  ["http://example.com/", "a:\u0BC6", "NAMESPACE_ERR"],
+  ["http://example.com/", "a:\u0BC6", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "\u0BC6:a", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "a:a\u0BC6", null],
   ["http://example.com/", "a\u0BC6:a", null],
@@ -98,7 +98,7 @@
   ["http://example.com/", "xmlns:foo", "NAMESPACE_ERR"],
   ["http://example.com/", "XMLNS:foo", null],
   ["http://example.com/", "xmlfoo:bar", null],
-  ["http://example.com/", "prefix::local", "NAMESPACE_ERR"],
+  ["http://example.com/", "prefix::local", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "namespaceURI:{", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "namespaceURI:}", "INVALID_CHARACTER_ERR"],
   ["http://example.com/", "namespaceURI:~", "INVALID_CHARACTER_ERR"],
@@ -130,9 +130,9 @@
   ["/", "1foo", "INVALID_CHARACTER_ERR"],
   ["/", "f1oo", null],
   ["/", "foo1", null],
-  ["/", ":foo", "NAMESPACE_ERR"],
+  ["/", ":foo", "INVALID_CHARACTER_ERR"],
   ["/", "f:oo", null],
-  ["/", "foo:", "NAMESPACE_ERR"],
+  ["/", "foo:", "INVALID_CHARACTER_ERR"],
   ["/", "xml", null],
   ["/", "xmlns", "NAMESPACE_ERR"],
   ["/", "xmlfoo", null],
@@ -143,9 +143,9 @@
   ["http://www.w3.org/XML/1998/namespace", "1foo", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/XML/1998/namespace", "f1oo", null],
   ["http://www.w3.org/XML/1998/namespace", "foo1", null],
-  ["http://www.w3.org/XML/1998/namespace", ":foo", "NAMESPACE_ERR"],
+  ["http://www.w3.org/XML/1998/namespace", ":foo", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/XML/1998/namespace", "f:oo", null],
-  ["http://www.w3.org/XML/1998/namespace", "foo:", "NAMESPACE_ERR"],
+  ["http://www.w3.org/XML/1998/namespace", "foo:", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/XML/1998/namespace", "xml", null],
   ["http://www.w3.org/XML/1998/namespace", "xmlns", "NAMESPACE_ERR"],
   ["http://www.w3.org/XML/1998/namespace", "xmlfoo", null],
@@ -158,9 +158,9 @@
   ["http://www.w3.org/2000/xmlns/", "1foo", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/2000/xmlns/", "f1oo", "NAMESPACE_ERR"],
   ["http://www.w3.org/2000/xmlns/", "foo1", "NAMESPACE_ERR"],
-  ["http://www.w3.org/2000/xmlns/", ":foo", "NAMESPACE_ERR"],
+  ["http://www.w3.org/2000/xmlns/", ":foo", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/2000/xmlns/", "f:oo", "NAMESPACE_ERR"],
-  ["http://www.w3.org/2000/xmlns/", "foo:", "NAMESPACE_ERR"],
+  ["http://www.w3.org/2000/xmlns/", "foo:", "INVALID_CHARACTER_ERR"],
   ["http://www.w3.org/2000/xmlns/", "xml", "NAMESPACE_ERR"],
   ["http://www.w3.org/2000/xmlns/", "xmlns", null],
   ["http://www.w3.org/2000/xmlns/", "xmlfoo", "NAMESPACE_ERR"],
@@ -172,9 +172,9 @@
   ["foo:", "1foo", "INVALID_CHARACTER_ERR"],
   ["foo:", "f1oo", null],
   ["foo:", "foo1", null],
-  ["foo:", ":foo", "NAMESPACE_ERR"],
+  ["foo:", ":foo", "INVALID_CHARACTER_ERR"],
   ["foo:", "f:oo", null],
-  ["foo:", "foo:", "NAMESPACE_ERR"],
+  ["foo:", "foo:", "INVALID_CHARACTER_ERR"],
   ["foo:", "xml", null],
   ["foo:", "xmlns", "NAMESPACE_ERR"],
   ["foo:", "xmlfoo", null],
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes-expected.txt
index c0004a4..f1fe8eb 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 58 tests; 50 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 58 tests; 49 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS When qualifiedName does not match the Name production, an INVALID_CHARACTER_ERR exception is to be thrown. (setAttribute) 
 PASS When qualifiedName does not match the Name production, an INVALID_CHARACTER_ERR exception is to be thrown, even if the attribute is already present. (setAttribute) 
 PASS setAttribute should lowercase its name argument (upper case attribute) 
@@ -11,7 +11,7 @@
 PASS setAttribute should set the attribute with the given qualified name 
 PASS When qualifiedName does not match the Name production, an INVALID_CHARACTER_ERR exception is to be thrown. (setAttributeNS) 
 PASS When qualifiedName does not match the Name production, an INVALID_CHARACTER_ERR exception is to be thrown, even if the attribute is already present. (setAttributeNS) 
-PASS When qualifiedName does not match the QName production, an NAMESPACE_ERR exception is to be thrown. 
+FAIL When qualifiedName does not match the QName production, an INVALID_CHARACTER_ERR exception is to be thrown. assert_throws: Expected exception for :a. function "function () { el.setAttributeNS("a", invalid_qnames[i], "fail") }" threw object "NamespaceError: Failed to execute 'setAttributeNS' on 'Element': The qualified name provided (':a') has an empty namespace prefix." that is not a DOMException INVALID_CHARACTER_ERR: property "code" is equal to 14, expected 5
 PASS null and the empty string should result in a null namespace. 
 PASS A namespace is required to use a prefix. 
 PASS The xml prefix should not be allowed for arbitrary namespaces 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes.html b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes.html
index c401c2a..9746cc6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/attributes.html
@@ -130,12 +130,12 @@
 test(function() {
   var el = document.createElement("foo")
   for (var i = 0, il = invalid_qnames.length; i < il; ++i) {
-    assert_throws("NAMESPACE_ERR",
+    assert_throws("INVALID_CHARACTER_ERR",
                   function() { el.setAttributeNS("a", invalid_qnames[i], "fail") },
                   "Expected exception for " + invalid_qnames[i] + ".")
   }
 }, "When qualifiedName does not match the QName production, an " +
-   "NAMESPACE_ERR exception is to be thrown.")
+   "INVALID_CHARACTER_ERR exception is to be thrown.")
 
 // Step 3
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
index 440510b..9d2f8769 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete-expected.txt
@@ -1,61 +1,63 @@
 This is a testharness.js-based test.
-Found 57 tests; 53 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 59 tests; 0 PASS, 59 FAIL, 0 TIMEOUT, 0 NOTRUN.
 FAIL form autocomplete attribute missing assert_equals: expected "on" but got ""
 FAIL form autocomplete attribute on assert_equals: expected "on" but got ""
 FAIL form autocomplete attribute off assert_equals: expected "off" but got ""
 FAIL form autocomplete attribute invalid assert_equals: expected "on" but got ""
-PASS name is an allowed autocomplete field name 
-PASS honorific-prefix is an allowed autocomplete field name 
-PASS given-name is an allowed autocomplete field name 
-PASS additional-name is an allowed autocomplete field name 
-PASS family-name is an allowed autocomplete field name 
-PASS honorific-suffix is an allowed autocomplete field name 
-PASS nickname is an allowed autocomplete field name 
-PASS username is an allowed autocomplete field name 
-PASS new-password is an allowed autocomplete field name 
-PASS current-password is an allowed autocomplete field name 
-PASS organization-title is an allowed autocomplete field name 
-PASS organization is an allowed autocomplete field name 
-PASS street-address is an allowed autocomplete field name 
-PASS address-line1 is an allowed autocomplete field name 
-PASS address-line2 is an allowed autocomplete field name 
-PASS address-line3 is an allowed autocomplete field name 
-PASS address-level4 is an allowed autocomplete field name 
-PASS address-level3 is an allowed autocomplete field name 
-PASS address-level2 is an allowed autocomplete field name 
-PASS address-level1 is an allowed autocomplete field name 
-PASS country is an allowed autocomplete field name 
-PASS country-name is an allowed autocomplete field name 
-PASS postal-code is an allowed autocomplete field name 
-PASS cc-name is an allowed autocomplete field name 
-PASS cc-given-name is an allowed autocomplete field name 
-PASS cc-additional-name is an allowed autocomplete field name 
-PASS cc-family-name is an allowed autocomplete field name 
-PASS cc-number is an allowed autocomplete field name 
-PASS cc-exp is an allowed autocomplete field name 
-PASS cc-exp-month is an allowed autocomplete field name 
-PASS cc-exp-year is an allowed autocomplete field name 
-PASS cc-csc is an allowed autocomplete field name 
-PASS cc-type is an allowed autocomplete field name 
-PASS transaction-currency is an allowed autocomplete field name 
-PASS transaction-amount is an allowed autocomplete field name 
-PASS language is an allowed autocomplete field name 
-PASS bday is an allowed autocomplete field name 
-PASS bday-day is an allowed autocomplete field name 
-PASS bday-month is an allowed autocomplete field name 
-PASS bday-year is an allowed autocomplete field name 
-PASS sex is an allowed autocomplete field name 
-PASS url is an allowed autocomplete field name 
-PASS photo is an allowed autocomplete field name 
-PASS tel is an allowed autocomplete field name 
-PASS tel-country-code is an allowed autocomplete field name 
-PASS tel-national is an allowed autocomplete field name 
-PASS tel-area-code is an allowed autocomplete field name 
-PASS tel-local is an allowed autocomplete field name 
-PASS tel-local-prefix is an allowed autocomplete field name 
-PASS tel-local-suffix is an allowed autocomplete field name 
-PASS tel-extension is an allowed autocomplete field name 
-PASS email is an allowed autocomplete field name 
-PASS impp is an allowed autocomplete field name 
+FAIL on is an allowed autocomplete field name assert_equals: expected "on" but got " ON\t"
+FAIL off is an allowed autocomplete field name assert_equals: expected "off" but got " OFF\t"
+FAIL name is an allowed autocomplete field name assert_equals: expected "name" but got " NAME\t"
+FAIL honorific-prefix is an allowed autocomplete field name assert_equals: expected "honorific-prefix" but got " HONORIFIC-PREFIX\t"
+FAIL given-name is an allowed autocomplete field name assert_equals: expected "given-name" but got " GIVEN-NAME\t"
+FAIL additional-name is an allowed autocomplete field name assert_equals: expected "additional-name" but got " ADDITIONAL-NAME\t"
+FAIL family-name is an allowed autocomplete field name assert_equals: expected "family-name" but got " FAMILY-NAME\t"
+FAIL honorific-suffix is an allowed autocomplete field name assert_equals: expected "honorific-suffix" but got " HONORIFIC-SUFFIX\t"
+FAIL nickname is an allowed autocomplete field name assert_equals: expected "nickname" but got " NICKNAME\t"
+FAIL username is an allowed autocomplete field name assert_equals: expected "username" but got " USERNAME\t"
+FAIL new-password is an allowed autocomplete field name assert_equals: expected "new-password" but got " NEW-PASSWORD\t"
+FAIL current-password is an allowed autocomplete field name assert_equals: expected "current-password" but got " CURRENT-PASSWORD\t"
+FAIL organization-title is an allowed autocomplete field name assert_equals: expected "organization-title" but got " ORGANIZATION-TITLE\t"
+FAIL organization is an allowed autocomplete field name assert_equals: expected "organization" but got " ORGANIZATION\t"
+FAIL street-address is an allowed autocomplete field name assert_equals: expected "street-address" but got " STREET-ADDRESS\t"
+FAIL address-line1 is an allowed autocomplete field name assert_equals: expected "address-line1" but got " ADDRESS-LINE1\t"
+FAIL address-line2 is an allowed autocomplete field name assert_equals: expected "address-line2" but got " ADDRESS-LINE2\t"
+FAIL address-line3 is an allowed autocomplete field name assert_equals: expected "address-line3" but got " ADDRESS-LINE3\t"
+FAIL address-level4 is an allowed autocomplete field name assert_equals: expected "address-level4" but got " ADDRESS-LEVEL4\t"
+FAIL address-level3 is an allowed autocomplete field name assert_equals: expected "address-level3" but got " ADDRESS-LEVEL3\t"
+FAIL address-level2 is an allowed autocomplete field name assert_equals: expected "address-level2" but got " ADDRESS-LEVEL2\t"
+FAIL address-level1 is an allowed autocomplete field name assert_equals: expected "address-level1" but got " ADDRESS-LEVEL1\t"
+FAIL country is an allowed autocomplete field name assert_equals: expected "country" but got " COUNTRY\t"
+FAIL country-name is an allowed autocomplete field name assert_equals: expected "country-name" but got " COUNTRY-NAME\t"
+FAIL postal-code is an allowed autocomplete field name assert_equals: expected "postal-code" but got " POSTAL-CODE\t"
+FAIL cc-name is an allowed autocomplete field name assert_equals: expected "cc-name" but got " CC-NAME\t"
+FAIL cc-given-name is an allowed autocomplete field name assert_equals: expected "cc-given-name" but got " CC-GIVEN-NAME\t"
+FAIL cc-additional-name is an allowed autocomplete field name assert_equals: expected "cc-additional-name" but got " CC-ADDITIONAL-NAME\t"
+FAIL cc-family-name is an allowed autocomplete field name assert_equals: expected "cc-family-name" but got " CC-FAMILY-NAME\t"
+FAIL cc-number is an allowed autocomplete field name assert_equals: expected "cc-number" but got " CC-NUMBER\t"
+FAIL cc-exp is an allowed autocomplete field name assert_equals: expected "cc-exp" but got " CC-EXP\t"
+FAIL cc-exp-month is an allowed autocomplete field name assert_equals: expected "cc-exp-month" but got " CC-EXP-MONTH\t"
+FAIL cc-exp-year is an allowed autocomplete field name assert_equals: expected "cc-exp-year" but got " CC-EXP-YEAR\t"
+FAIL cc-csc is an allowed autocomplete field name assert_equals: expected "cc-csc" but got " CC-CSC\t"
+FAIL cc-type is an allowed autocomplete field name assert_equals: expected "cc-type" but got " CC-TYPE\t"
+FAIL transaction-currency is an allowed autocomplete field name assert_equals: expected "transaction-currency" but got " TRANSACTION-CURRENCY\t"
+FAIL transaction-amount is an allowed autocomplete field name assert_equals: expected "transaction-amount" but got " TRANSACTION-AMOUNT\t"
+FAIL language is an allowed autocomplete field name assert_equals: expected "language" but got " LANGUAGE\t"
+FAIL bday is an allowed autocomplete field name assert_equals: expected "bday" but got " BDAY\t"
+FAIL bday-day is an allowed autocomplete field name assert_equals: expected "bday-day" but got " BDAY-DAY\t"
+FAIL bday-month is an allowed autocomplete field name assert_equals: expected "bday-month" but got " BDAY-MONTH\t"
+FAIL bday-year is an allowed autocomplete field name assert_equals: expected "bday-year" but got " BDAY-YEAR\t"
+FAIL sex is an allowed autocomplete field name assert_equals: expected "sex" but got " SEX\t"
+FAIL url is an allowed autocomplete field name assert_equals: expected "url" but got " URL\t"
+FAIL photo is an allowed autocomplete field name assert_equals: expected "photo" but got " PHOTO\t"
+FAIL tel is an allowed autocomplete field name assert_equals: expected "tel" but got " TEL\t"
+FAIL tel-country-code is an allowed autocomplete field name assert_equals: expected "tel-country-code" but got " TEL-COUNTRY-CODE\t"
+FAIL tel-national is an allowed autocomplete field name assert_equals: expected "tel-national" but got " TEL-NATIONAL\t"
+FAIL tel-area-code is an allowed autocomplete field name assert_equals: expected "tel-area-code" but got " TEL-AREA-CODE\t"
+FAIL tel-local is an allowed autocomplete field name assert_equals: expected "tel-local" but got " TEL-LOCAL\t"
+FAIL tel-local-prefix is an allowed autocomplete field name assert_equals: expected "tel-local-prefix" but got " TEL-LOCAL-PREFIX\t"
+FAIL tel-local-suffix is an allowed autocomplete field name assert_equals: expected "tel-local-suffix" but got " TEL-LOCAL-SUFFIX\t"
+FAIL tel-extension is an allowed autocomplete field name assert_equals: expected "tel-extension" but got " TEL-EXTENSION\t"
+FAIL email is an allowed autocomplete field name assert_equals: expected "email" but got " EMAIL\t"
+FAIL impp is an allowed autocomplete field name assert_equals: expected "impp" but got " IMPP\t"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
index c50ea73..5c1d05b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-form-element/form-autocomplete.html
@@ -47,12 +47,14 @@
   autocompletetest(document.forms.autocomplete_off, ["off", "off", "on", "off", ""], "form autocomplete attribute off");
   autocompletetest(document.forms.autocomplete_invalid, ["on", "on", "on", "off", ""], "form autocomplete attribute invalid");
 
-  var keywords = [ "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp" ];
+  var keywords = [ "on", "off", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp" ];
 
   keywords.forEach(function(keyword) {
     test(function(){
       var input = document.createElement("input");
-      input.setAttribute("autocomplete", keyword);
+      // Include whitespace to test splitting tokens on whitespace.
+      // Convert to uppercase to ensure that the tokens are normalized to lowercase.
+      input.setAttribute("autocomplete", " " + keyword.toUpperCase() + "\t");
       assert_equals(input.autocomplete, keyword);
     }, keyword + " is an allowed autocomplete field name");
   });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
index 1e78fa7c..1855e63f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
+++ b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
@@ -767,3 +767,5 @@
 CSS-COLLIDING-SUPPORT-NAME: css/css-display-3/support/util.js
 CSS-COLLIDING-SUPPORT-NAME: css/CSS2/normal-flow/support/replaced-min-max-1.png
 CSS-COLLIDING-SUPPORT-NAME: css/vendor-imports/mozilla/mozilla-central-reftests/ui3/support/replaced-min-max-1.png
+
+WEBIDL2.JS:.gitmodules
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/.gitmodules b/third_party/WebKit/LayoutTests/external/wpt/resources/.gitmodules
deleted file mode 100644
index 8903572..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/resources/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "webidl2"]
-	path = webidl2
-	url = https://github.com/darobin/webidl2.js.git
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
index db7db151..b42a030 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
@@ -437,6 +437,11 @@
 IdlArray.prototype.assert_type_is = function(value, type)
 //@{
 {
+    if (type.idlType in this.members
+    && this.members[type.idlType] instanceof IdlTypedef) {
+        this.assert_type_is(value, this.members[type.idlType].idlType);
+        return;
+    }
     if (type.union) {
         for (var i = 0; i < type.idlType.length; i++) {
             try {
@@ -644,10 +649,6 @@
     {
         // TODO: Test when we actually have something to test this on
     }
-    else if (this.members[type] instanceof IdlTypedef)
-    {
-        // TODO: Test when we actually have something to test this on
-    }
     else
     {
         throw "Type " + type + " isn't an interface or dictionary";
@@ -2023,8 +2024,8 @@
     /** Self-explanatory. */
     this.name = obj.name;
 
-    /** An array of values produced by the "typedef" production. */
-    this.values = obj.values;
+    /** The idlType that we are supposed to be typedeffing to. */
+    this.idlType = obj.idlType;
 
 }
 //@}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general-expected.txt
index a39da246..d144e5c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 1 PASS, 70 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 72 tests; 1 PASS, 71 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS getReader({mode: "byob"}) throws on non-bytes streams 
 FAIL ReadableStream with byte source can be constructed with no errors bytes type is not yet implemented
 FAIL getReader({mode}) must perform ToString() bytes type is not yet implemented
@@ -67,6 +67,7 @@
 FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it bytes type is not yet implemented
+FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader can be constructed directly bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream bytes type is not yet implemented
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.dedicatedworker-expected.txt
index a39da246..d144e5c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.dedicatedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.dedicatedworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 1 PASS, 70 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 72 tests; 1 PASS, 71 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS getReader({mode: "byob"}) throws on non-bytes streams 
 FAIL ReadableStream with byte source can be constructed with no errors bytes type is not yet implemented
 FAIL getReader({mode}) must perform ToString() bytes type is not yet implemented
@@ -67,6 +67,7 @@
 FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it bytes type is not yet implemented
+FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader can be constructed directly bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream bytes type is not yet implemented
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.js b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.js
index 374c52c..2398911 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.js
@@ -1897,6 +1897,28 @@
 }, 'ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is ' +
    'errored in it');
 
+promise_test(() => {
+  // Tests https://github.com/whatwg/streams/issues/686
+
+  let controller;
+  const rs = new ReadableStream({
+    autoAllocateChunkSize: 128,
+    start(c) {
+      controller = c;
+    },
+    type: "bytes"
+  });
+
+  const readPromise = rs.getReader().read();
+
+  const br = controller.byobRequest;
+  controller.close();
+
+  br.respond(0);
+
+  return readPromise;
+}, 'ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction');
+
 test(() => {
   const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
   const stream = new ReadableStream({ type: 'bytes' });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.serviceworker.https-expected.txt
index c1e9227..0f373fb 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.serviceworker.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.serviceworker.https-expected.txt
@@ -67,6 +67,7 @@
 FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it bytes type is not yet implemented
+FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader can be constructed directly bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream bytes type is not yet implemented
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.sharedworker-expected.txt
index a39da246..d144e5c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.sharedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/general.sharedworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 1 PASS, 70 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 72 tests; 1 PASS, 71 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS getReader({mode: "byob"}) throws on non-bytes streams 
 FAIL ReadableStream with byte source can be constructed with no errors bytes type is not yet implemented
 FAIL getReader({mode}) must perform ToString() bytes type is not yet implemented
@@ -67,6 +67,7 @@
 FAIL ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is errored in it bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream bytes type is not yet implemented
 FAIL ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is errored in it bytes type is not yet implemented
+FAIL ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader can be constructed directly bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires a ReadableStream argument bytes type is not yet implemented
 FAIL ReadableStreamBYOBReader constructor requires an unlocked ReadableStream bytes type is not yet implemented
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-percentages-and-orthogonal-flows.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-percentages-and-orthogonal-flows.html
index eacf0a22..5844119f 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-percentages-and-orthogonal-flows.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-percentages-and-orthogonal-flows.html
@@ -17,6 +17,16 @@
     grid-template-columns: 100px 25%;
     grid-template-rows: 50% 150px;
 }
+
+.definiteGridWithPercentageGaps {
+    grid-template: 5px 5px / auto;
+    grid-row-gap: 80%;
+    grid-column-gap: 20%;
+    height: 200px;
+    width: 100px;
+    justify-content: start;
+    align-content: start;
+}
 </style>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
@@ -74,4 +84,9 @@
     </div>
 </div>
 
+<p>HORIZONTAL-TB container with VERTICAL-LR item with percentage gaps.</p>
+<div class="grid definiteGridWithPercentageGaps" data-expected-width="100" data-expected-height="200">
+    <div class="bothRowFirstColumn verticalLR" style="background: cyan;" data-expected-width="10" data-expected-height="170">XXXX XXXXX</div>
+</div>
+
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/credentialmanager/idl-expected.txt b/third_party/WebKit/LayoutTests/http/tests/credentialmanager/idl-expected.txt
index 80cb4d5..3f2f8d5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/credentialmanager/idl-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/credentialmanager/idl-expected.txt
@@ -26,7 +26,7 @@
 PASS Stringification of new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) 
 PASS PasswordCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "idName" with the proper type (0) 
 PASS PasswordCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "passwordName" with the proper type (1) 
-PASS PasswordCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "additionalData" with the proper type (2) 
+FAIL PasswordCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "additionalData" with the proper type (2) Unrecognized type FormData
 PASS SiteBoundCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "name" with the proper type (0) 
 PASS SiteBoundCredential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "iconURL" with the proper type (1) 
 PASS Credential interface: new PasswordCredential({ id: "id", password: "pencil", iconURL: "https://example.com/", name: "name" }) must inherit property "id" with the proper type (0) 
diff --git a/third_party/WebKit/LayoutTests/resources/idlharness.js b/third_party/WebKit/LayoutTests/resources/idlharness.js
index db7db151..b42a030 100644
--- a/third_party/WebKit/LayoutTests/resources/idlharness.js
+++ b/third_party/WebKit/LayoutTests/resources/idlharness.js
@@ -437,6 +437,11 @@
 IdlArray.prototype.assert_type_is = function(value, type)
 //@{
 {
+    if (type.idlType in this.members
+    && this.members[type.idlType] instanceof IdlTypedef) {
+        this.assert_type_is(value, this.members[type.idlType].idlType);
+        return;
+    }
     if (type.union) {
         for (var i = 0; i < type.idlType.length; i++) {
             try {
@@ -644,10 +649,6 @@
     {
         // TODO: Test when we actually have something to test this on
     }
-    else if (this.members[type] instanceof IdlTypedef)
-    {
-        // TODO: Test when we actually have something to test this on
-    }
     else
     {
         throw "Type " + type + " isn't an interface or dictionary";
@@ -2023,8 +2024,8 @@
     /** Self-explanatory. */
     this.name = obj.name;
 
-    /** An array of values produced by the "typedef" production. */
-    this.values = obj.values;
+    /** The idlType that we are supposed to be typedeffing to. */
+    this.idlType = obj.idlType;
 
 }
 //@}
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8DOMActivityLogger.cpp b/third_party/WebKit/Source/bindings/core/v8/V8DOMActivityLogger.cpp
index c36709a..91de2053 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8DOMActivityLogger.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8DOMActivityLogger.cpp
@@ -83,8 +83,6 @@
 
   v8::HandleScope handle_scope(isolate);
   v8::Local<v8::Context> context = isolate->GetCurrentContext();
-  if (context.IsEmpty() || !ToLocalDOMWindow(context))
-    return 0;
 
   V8PerContextData* context_data = ScriptState::From(context)->PerContextData();
   if (!context_data)
@@ -101,8 +99,6 @@
 
   v8::HandleScope handle_scope(isolate);
   v8::Local<v8::Context> context = isolate->GetCurrentContext();
-  if (context.IsEmpty() || !ToLocalDOMWindow(context))
-    return 0;
 
   ScriptState* script_state = ScriptState::From(context);
   if (!script_state->World().IsIsolatedWorld())
diff --git a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
index 877cf756..c119aba 100644
--- a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
+++ b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
@@ -224,8 +224,9 @@
     }
   }
 
-  grid_area_size += layout_grid_->GuttersSize(
-      grid_, kForRows, span.StartLine(), span.IntegerSpan(), sizing_operation_);
+  grid_area_size +=
+      layout_grid_->GuttersSize(grid_, kForRows, span.StartLine(),
+                                span.IntegerSpan(), AvailableSpace(kForRows));
 
   return grid_area_is_indefinite
              ? std::max(child.MaxPreferredLogicalWidth(), grid_area_size)
@@ -246,7 +247,7 @@
 
   grid_area_breadth +=
       layout_grid_->GuttersSize(grid_, direction, span.StartLine(),
-                                span.IntegerSpan(), sizing_operation_);
+                                span.IntegerSpan(), AvailableSpace(direction));
 
   return grid_area_breadth;
 }
@@ -538,12 +539,11 @@
     // really matter as we know the track is a flex sized track. It'd be nice
     // not to have to do that.
     flex_fraction = std::max(
-        flex_fraction,
-        NormalizedFlexFraction(
-            all_tracks[track_index],
-            algorithm_.GetGridTrackSize(direction, track_index, kTrackSizing)
-                .MaxTrackBreadth()
-                .Flex()));
+        flex_fraction, NormalizedFlexFraction(
+                           all_tracks[track_index],
+                           algorithm_.GetGridTrackSize(direction, track_index)
+                               .MaxTrackBreadth()
+                               .Flex()));
   }
 
   const Grid& grid = algorithm_.GetGrid();
@@ -595,7 +595,7 @@
   free_space =
       std::max(free_space, min_size) -
       layout_grid->GuttersSize(grid, kForRows, 0, grid.NumTracks(kForRows),
-                               kIntrinsicSizeComputation);
+                               AvailableSpace());
 
   size_t number_of_tracks = algorithm_.Tracks(Direction()).size();
   flex_fraction = FindFrUnitSize(
@@ -604,10 +604,29 @@
 }
 
 Optional<LayoutUnit> GridTrackSizingAlgorithm::FreeSpace(
-    GridTrackSizingDirection direction) {
+    GridTrackSizingDirection direction) const {
   return direction == kForRows ? free_space_rows_ : free_space_columns_;
 }
 
+Optional<LayoutUnit> GridTrackSizingAlgorithm::AvailableSpace(
+    GridTrackSizingDirection direction) const {
+  return direction == kForRows ? available_space_rows_
+                               : available_space_columns_;
+}
+
+Optional<LayoutUnit> GridTrackSizingAlgorithm::AvailableSpace() const {
+  return AvailableSpace(direction_);
+}
+
+void GridTrackSizingAlgorithm::SetAvailableSpace(
+    GridTrackSizingDirection direction,
+    Optional<LayoutUnit> available_space) {
+  if (direction == kForColumns)
+    available_space_columns_ = available_space;
+  else
+    available_space_rows_ = available_space;
+}
+
 Vector<GridTrack>& GridTrackSizingAlgorithm::Tracks(
     GridTrackSizingDirection direction) {
   return direction == kForColumns ? columns_ : rows_;
@@ -685,13 +704,6 @@
 GridTrackSize GridTrackSizingAlgorithm::GetGridTrackSize(
     GridTrackSizingDirection direction,
     size_t translated_index) const {
-  return GetGridTrackSize(direction, translated_index, sizing_operation_);
-}
-
-GridTrackSize GridTrackSizingAlgorithm::GetGridTrackSize(
-    GridTrackSizingDirection direction,
-    size_t translated_index,
-    SizingOperation sizing_operation) const {
   // Collapse empty auto repeat tracks if auto-fit.
   if (grid_.HasAutoRepeatEmptyTracks(direction) &&
       grid_.IsEmptyAutoRepeatTrack(direction, translated_index))
@@ -707,9 +719,11 @@
   // If the logical width/height of the grid container is indefinite, percentage
   // values are treated as <auto>.
   if (min_track_breadth.HasPercentage() || max_track_breadth.HasPercentage()) {
-    // For the inline axis this only happens when we're computing the intrinsic
-    // sizes.
-    if ((sizing_operation == kIntrinsicSizeComputation) ||
+    // TODO(svillar): we should remove the second check later. We need it
+    // because during the second iteration of the algorithm we set definite
+    // sizes in the grid container so percents would not resolve properly (it
+    // would think that the height is definite when it is not).
+    if (!AvailableSpace(direction) ||
         (direction == kForRows &&
          !layout_grid_->CachedHasDefiniteLogicalHeight())) {
       if (min_track_breadth.HasPercentage())
@@ -735,9 +749,10 @@
     return LayoutUnit();
 
   const Length& track_length = grid_length.length();
-  if (track_length.IsSpecified())
+  if (track_length.IsSpecified()) {
     return ValueForLength(track_length,
-                          available_space_.value_or(LayoutUnit()));
+                          AvailableSpace().value_or(LayoutUnit()));
+  }
 
   DCHECK(track_length.IsMinContent() || track_length.IsAuto() ||
          track_length.IsMaxContent());
@@ -752,9 +767,10 @@
     return base_size;
 
   const Length& track_length = grid_length.length();
-  if (track_length.IsSpecified())
+  if (track_length.IsSpecified()) {
     return ValueForLength(track_length,
-                          available_space_.value_or(LayoutUnit()));
+                          AvailableSpace().value_or(LayoutUnit()));
+  }
 
   DCHECK(track_length.IsMinContent() || track_length.IsAuto() ||
          track_length.IsMaxContent());
@@ -765,7 +781,7 @@
   DCHECK(content_sized_tracks_index_.IsEmpty());
   DCHECK(flexible_sized_tracks_index_.IsEmpty());
   Vector<GridTrack>& track_list = Tracks(direction_);
-  bool has_definite_free_space = !!available_space_;
+  bool has_definite_free_space = !!AvailableSpace();
   size_t num_tracks = track_list.size();
   for (size_t i = 0; i < num_tracks; ++i) {
     GridTrackSize track_size = GetGridTrackSize(direction_, i);
@@ -778,7 +794,7 @@
       GridLength grid_length = track_size.FitContentTrackBreadth();
       if (!grid_length.HasPercentage() || has_definite_free_space) {
         track.SetGrowthLimitCap(ValueForLength(
-            grid_length.length(), available_space_.value_or(LayoutUnit())));
+            grid_length.length(), AvailableSpace().value_or(LayoutUnit())));
       }
     }
 
@@ -816,7 +832,7 @@
       growth_limit =
           std::min(growth_limit,
                    ValueForLength(track_size.FitContentTrackBreadth().length(),
-                                  available_space_.value_or(LayoutUnit())));
+                                  AvailableSpace().value_or(LayoutUnit())));
     }
     track.SetGrowthLimit(std::max(track.GrowthLimit(), growth_limit));
   }
@@ -1152,7 +1168,7 @@
 
     spanning_tracks_size +=
         layout_grid_->GuttersSize(grid_, direction_, item_span.StartLine(),
-                                  item_span.IntegerSpan(), sizing_operation_);
+                                  item_span.IntegerSpan(), AvailableSpace());
 
     LayoutUnit extra_space = ItemSizeForTrackSizeComputationPhase(
                                  phase, grid_item_with_span.GridItem()) -
@@ -1243,7 +1259,7 @@
     size += track.BaseSize();
 
   size += layout_grid_->GuttersSize(grid_, direction_, 0, all_tracks.size(),
-                                    sizing_operation_);
+                                    AvailableSpace());
 
   return size;
 }
@@ -1407,9 +1423,9 @@
   DCHECK(needs_setup_);
   DCHECK_EQ(!!available_space, !!free_space);
   direction_ = direction;
-  available_space_ = available_space
-                         ? available_space.value().ClampNegativeToZero()
-                         : available_space;
+  SetAvailableSpace(
+      direction, available_space ? available_space.value().ClampNegativeToZero()
+                                 : available_space);
 
   sizing_operation_ = sizing_operation;
 
@@ -1471,6 +1487,8 @@
   rows_.Shrink(0);
   content_sized_tracks_index_.Shrink(0);
   flexible_sized_tracks_index_.Shrink(0);
+  SetAvailableSpace(kForRows, WTF::kNullopt);
+  SetAvailableSpace(kForColumns, WTF::kNullopt);
 }
 
 #if DCHECK_IS_ON()
diff --git a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
index 63dfb3f..c052494 100644
--- a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
+++ b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.h
@@ -97,24 +97,25 @@
   // Required by LayoutGrid. Try to minimize the exposed surface.
   const Grid& GetGrid() const { return grid_; }
   GridTrackSize GetGridTrackSize(GridTrackSizingDirection,
-                                 size_t translated_index,
-                                 SizingOperation) const;
+                                 size_t translated_index) const;
   LayoutUnit MinContentSize() const { return min_content_size_; };
   LayoutUnit MaxContentSize() const { return max_content_size_; };
 
   Vector<GridTrack>& Tracks(GridTrackSizingDirection);
   const Vector<GridTrack>& Tracks(GridTrackSizingDirection) const;
 
-  Optional<LayoutUnit> FreeSpace(GridTrackSizingDirection);
+  Optional<LayoutUnit> FreeSpace(GridTrackSizingDirection) const;
   void SetFreeSpace(GridTrackSizingDirection, Optional<LayoutUnit>);
 
+  Optional<LayoutUnit> AvailableSpace(GridTrackSizingDirection) const;
+  void SetAvailableSpace(GridTrackSizingDirection, Optional<LayoutUnit>);
+
 #if DCHECK_IS_ON()
   bool TracksAreWiderThanMinTrackBreadth() const;
 #endif
 
  private:
-  GridTrackSize GetGridTrackSize(GridTrackSizingDirection,
-                                 size_t translated_index) const;
+  Optional<LayoutUnit> AvailableSpace() const;
   GridTrackSize RawGridTrackSize(GridTrackSizingDirection,
                                  size_t translated_index) const;
   LayoutUnit AssumedRowsSizeForOrthogonalChild(const LayoutBox&) const;
@@ -177,7 +178,8 @@
 
   // Data.
   bool needs_setup_{true};
-  Optional<LayoutUnit> available_space_;
+  Optional<LayoutUnit> available_space_columns_;
+  Optional<LayoutUnit> available_space_rows_;
 
   Optional<LayoutUnit> free_space_columns_;
   Optional<LayoutUnit> free_space_rows_;
@@ -274,6 +276,9 @@
   void DistributeSpaceToTracks(Vector<GridTrack*>& tracks,
                                LayoutUnit& available_logical_space) const;
   const LayoutGrid* GetLayoutGrid() const { return algorithm_.layout_grid_; }
+  Optional<LayoutUnit> AvailableSpace() const {
+    return algorithm_.AvailableSpace();
+  }
 
   // Helper functions
   static LayoutUnit ComputeMarginLogicalSizeForChild(
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 957ecad..4131e73 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -139,6 +139,20 @@
          old_style.NamedGridColumnLines() != StyleRef().NamedGridColumnLines();
 }
 
+// This method optimizes the gutters computation by skiping the available size
+// call if gaps are fixed size (it's only needed for percentages).
+Optional<LayoutUnit> LayoutGrid::AvailableSpaceForGutters(
+    GridTrackSizingDirection direction) const {
+  bool is_row_axis = direction == kForColumns;
+  const Length& gap =
+      is_row_axis ? StyleRef().GridColumnGap() : StyleRef().GridRowGap();
+  if (!gap.IsPercent())
+    return WTF::kNullopt;
+
+  return is_row_axis ? AvailableLogicalWidth()
+                     : AvailableLogicalHeightForPercentageComputation();
+}
+
 LayoutUnit LayoutGrid::ComputeTrackBasedLogicalHeight() const {
   LayoutUnit logical_height;
 
@@ -146,8 +160,8 @@
   for (const auto& row : all_rows)
     logical_height += row.BaseSize();
 
-  logical_height +=
-      GuttersSize(grid_, kForRows, 0, all_rows.size(), kTrackSizing);
+  logical_height += GuttersSize(grid_, kForRows, 0, all_rows.size(),
+                                AvailableSpaceForGutters(kForRows));
 
   return logical_height;
 }
@@ -157,7 +171,8 @@
     LayoutUnit available_space) {
   LayoutUnit free_space =
       available_space - GuttersSize(grid_, direction, 0,
-                                    grid_.NumTracks(direction), kTrackSizing);
+                                    grid_.NumTracks(direction),
+                                    available_space);
   track_sizing_algorithm_.Setup(direction, NumTracks(direction, grid_),
                                 kTrackSizing, available_space, free_space);
   track_sizing_algorithm_.Run();
@@ -232,6 +247,7 @@
     LayoutState state(*this);
 
     LayoutSize previous_size = Size();
+    has_definite_logical_height_ = HasDefiniteLogicalHeight();
 
     // We need to clear both own and containingBlock override sizes to
     // ensure we get the same result when grid's intrinsic size is
@@ -249,11 +265,11 @@
     }
 
     UpdateLogicalWidth();
-    has_definite_logical_height_ = HasDefiniteLogicalHeight();
 
     TextAutosizer::LayoutScope text_autosizer_layout_scope(this, &layout_scope);
 
-    PlaceItemsOnGrid(grid_, kTrackSizing);
+    LayoutUnit available_space_for_columns = AvailableLogicalWidth();
+    PlaceItemsOnGrid(grid_, available_space_for_columns);
 
     // 1- First, the track sizing algorithm is used to resolve the sizes of the
     // grid columns.
@@ -262,7 +278,6 @@
     // same for heights though because many code paths inside
     // updateLogicalHeight() require a previous call to setLogicalHeight() to
     // resolve heights properly (like for positioned items for example).
-    LayoutUnit available_space_for_columns = AvailableLogicalWidth();
     ComputeTrackSizesForDefiniteSize(kForColumns, available_space_for_columns);
 
     // 2- Next, the track sizing algorithm resolves the sizes of the grid rows,
@@ -331,14 +346,20 @@
   ClearNeedsLayout();
 }
 
-LayoutUnit LayoutGrid::GridGapForDirection(
-    GridTrackSizingDirection direction,
-    SizingOperation sizing_operation) const {
-  LayoutUnit available_size;
+LayoutUnit LayoutGrid::GridGap(GridTrackSizingDirection direction,
+                               Optional<LayoutUnit> available_size) const {
   const Length& gap = direction == kForColumns ? StyleRef().GridColumnGap()
                                                : StyleRef().GridRowGap();
-  if (sizing_operation == kTrackSizing && gap.IsPercent())
-    available_size = direction == kForColumns
+  return ValueForLength(gap, available_size.value_or(LayoutUnit()));
+}
+
+LayoutUnit LayoutGrid::GridGap(GridTrackSizingDirection direction) const {
+  LayoutUnit available_size;
+  bool is_row_axis = direction == kForColumns;
+  const Length& gap =
+      is_row_axis ? StyleRef().GridColumnGap() : StyleRef().GridRowGap();
+  if (gap.IsPercent())
+    available_size = is_row_axis
                          ? AvailableLogicalWidth()
                          : AvailableLogicalHeightForPercentageComputation();
 
@@ -351,11 +372,11 @@
                                    GridTrackSizingDirection direction,
                                    size_t start_line,
                                    size_t span,
-                                   SizingOperation sizing_operation) const {
+                                   Optional<LayoutUnit> available_size) const {
   if (span <= 1)
     return LayoutUnit();
 
-  LayoutUnit gap = GridGapForDirection(direction, sizing_operation);
+  LayoutUnit gap = GridGap(direction, available_size);
 
   // Fast path, no collapsing tracks.
   if (!grid.HasAutoRepeatEmptyTracks(direction))
@@ -421,7 +442,7 @@
     LayoutUnit& min_logical_width,
     LayoutUnit& max_logical_width) const {
   Grid grid(this);
-  PlaceItemsOnGrid(grid, kIntrinsicSizeComputation);
+  PlaceItemsOnGrid(grid, WTF::kNullopt);
 
   GridTrackSizingAlgorithm algorithm(this, grid);
   ComputeTrackSizesForIndefiniteSize(algorithm, kForColumns, grid,
@@ -446,8 +467,8 @@
   max_intrinsic_size = algo.MaxContentSize();
 
   size_t number_of_tracks = algo.Tracks(direction).size();
-  LayoutUnit total_gutters_size = GuttersSize(
-      grid, direction, 0, number_of_tracks, kIntrinsicSizeComputation);
+  LayoutUnit total_gutters_size =
+      GuttersSize(grid, direction, 0, number_of_tracks, WTF::kNullopt);
   min_intrinsic_size += total_gutters_size;
   max_intrinsic_size += total_gutters_size;
 
@@ -496,9 +517,18 @@
   return child.IsHorizontalWritingMode() != IsHorizontalWritingMode();
 }
 
+// Unfortunately there are still many layout methods that return -1 for
+// non-resolvable sizes. We prefer to represent them with WTF::nullopt.
+static Optional<LayoutUnit> ConvertLayoutUnitToOptional(LayoutUnit size) {
+  if (size == -1)
+    return WTF::kNullopt;
+  return size;
+}
+
 size_t LayoutGrid::ComputeAutoRepeatTracksCount(
     GridTrackSizingDirection direction,
-    SizingOperation sizing_operation) const {
+    Optional<LayoutUnit> available_size) const {
+  DCHECK(!available_size || available_size.value() != -1);
   bool is_row_axis = direction == kForColumns;
   const auto& auto_repeat_tracks = is_row_axis
                                        ? StyleRef().GridAutoRepeatColumns()
@@ -508,27 +538,21 @@
   if (!auto_repeat_track_list_length)
     return 0;
 
-  LayoutUnit available_size;
-  if (is_row_axis) {
-    available_size = sizing_operation == kIntrinsicSizeComputation
-                         ? LayoutUnit(-1)
-                         : AvailableLogicalWidth();
-  } else {
-    available_size = AvailableLogicalHeightForPercentageComputation();
-    if (available_size == -1) {
+  if (!is_row_axis) {
+    if (!available_size) {
       const Length& max_length = StyleRef().LogicalMaxHeight();
       if (!max_length.IsMaxSizeNone()) {
-        available_size = ConstrainContentBoxLogicalHeightByMinMax(
-            AvailableLogicalHeightUsing(max_length,
-                                        kExcludeMarginBorderPadding),
-            LayoutUnit(-1));
+        available_size = ConvertLayoutUnitToOptional(
+            ConstrainContentBoxLogicalHeightByMinMax(
+                AvailableLogicalHeightUsing(max_length,
+                                            kExcludeMarginBorderPadding),
+                LayoutUnit(-1)));
       }
     }
   }
 
   bool needs_to_fulfill_minimum_size = false;
-  bool indefinite_main_and_max_sizes = available_size == LayoutUnit(-1);
-  if (indefinite_main_and_max_sizes) {
+  if (!available_size) {
     const Length& min_size = is_row_axis ? StyleRef().LogicalMinWidth()
                                          : StyleRef().LogicalMinHeight();
     if (!min_size.IsSpecified())
@@ -552,7 +576,8 @@
     auto track_length = has_definite_max_track_sizing_function
                             ? auto_track_size.MaxTrackBreadth().length()
                             : auto_track_size.MinTrackBreadth().length();
-    auto_repeat_tracks_size += ValueForLength(track_length, available_size);
+    auto_repeat_tracks_size +=
+        ValueForLength(track_length, available_size.value());
   }
   // For the purpose of finding the number of auto-repeated tracks, the UA must
   // floor the track size to a UA-specified value to avoid division by zero. It
@@ -577,15 +602,15 @@
     tracks_size += ValueForLength(has_definite_max_track_breadth
                                       ? track.MaxTrackBreadth().length()
                                       : track.MinTrackBreadth().length(),
-                                  available_size);
+                                  available_size.value());
   }
 
   // Add gutters as if there where only 1 auto repeat track. Gaps between auto
   // repeat tracks will be added later when computing the repetitions.
-  LayoutUnit gap_size = GridGapForDirection(direction, sizing_operation);
+  LayoutUnit gap_size = GridGap(direction, available_size);
   tracks_size += gap_size * track_sizes.size();
 
-  LayoutUnit free_space = available_size - tracks_size;
+  LayoutUnit free_space = available_size.value() - tracks_size;
   if (free_space <= 0)
     return auto_repeat_track_list_length;
 
@@ -659,12 +684,19 @@
                   static_cast<size_t>(kGridMaxTracks) - insertion_point);
 }
 
-void LayoutGrid::PlaceItemsOnGrid(Grid& grid,
-                                  SizingOperation sizing_operation) const {
-  size_t auto_repeat_rows =
-      ComputeAutoRepeatTracksCount(kForRows, sizing_operation);
+// TODO(svillar): we shouldn't have to pass the available logical width as
+// argument. The problem is that availableLogicalWidth() does always return a
+// value even if we cannot resolve it like when computing the intrinsic size
+// (preferred widths). That's why we pass the responsibility to the caller who
+// does know whether the available logical width is indefinite or not.
+void LayoutGrid::PlaceItemsOnGrid(
+    Grid& grid,
+    Optional<LayoutUnit> available_logical_width) const {
+  size_t auto_repeat_rows = ComputeAutoRepeatTracksCount(
+      kForRows, ConvertLayoutUnitToOptional(
+                    AvailableLogicalHeightForPercentageComputation()));
   size_t auto_repeat_columns =
-      ComputeAutoRepeatTracksCount(kForColumns, sizing_operation);
+      ComputeAutoRepeatTracksCount(kForColumns, available_logical_width);
 
   auto_repeat_rows = ClampAutoRepeatTracks(kForRows, auto_repeat_rows);
   auto_repeat_columns = ClampAutoRepeatTracks(kForColumns, auto_repeat_columns);
@@ -1023,9 +1055,7 @@
 
   DCHECK(!grid_.NeedsItemsPlacement());
   bool has_collapsed_tracks = grid_.HasAutoRepeatEmptyTracks(direction);
-  LayoutUnit gap = !has_collapsed_tracks
-                       ? GridGapForDirection(direction, kTrackSizing)
-                       : LayoutUnit();
+  LayoutUnit gap = !has_collapsed_tracks ? GridGap(direction) : LayoutUnit();
   tracks.ReserveCapacity(num_positions - 1);
   for (size_t i = 0; i < num_positions - 2; ++i)
     tracks.push_back(positions[i + 1] - positions[i] - offset_between_tracks -
@@ -1038,7 +1068,7 @@
   size_t remaining_empty_tracks =
       grid_.AutoRepeatEmptyTracks(direction)->size();
   size_t last_line = tracks.size();
-  gap = GridGapForDirection(direction, kTrackSizing);
+  gap = GridGap(direction);
   for (size_t i = 1; i < last_line; ++i) {
     if (grid_.IsEmptyAutoRepeatTrack(direction, i - 1)) {
       --remaining_empty_tracks;
@@ -1082,7 +1112,7 @@
   Vector<unsigned> auto_sized_tracks_index;
   for (unsigned i = 0; i < all_tracks.size(); ++i) {
     const GridTrackSize& track_size =
-        track_sizing_algorithm_.GetGridTrackSize(direction, i, kTrackSizing);
+        track_sizing_algorithm_.GetGridTrackSize(direction, i);
     if (track_size.HasAutoMaxTrackBreadth())
       auto_sized_tracks_index.push_back(i);
   }
@@ -1273,6 +1303,8 @@
            GridPositionsResolver::FinalPositionSide(direction))) ||
       (end_line < 0) || (end_line > last_line);
 
+  Optional<LayoutUnit> available_size_for_gutters =
+      AvailableSpaceForGutters(direction);
   LayoutUnit start;
   if (!start_is_auto) {
     if (is_for_columns) {
@@ -1305,7 +1337,8 @@
     // consider them for the edges of the grid.
     if (end_line > 0 && end_line < last_line) {
       DCHECK(!grid_.NeedsItemsPlacement());
-      end -= GuttersSize(grid_, direction, end_line - 1, 2, kTrackSizing);
+      end -= GuttersSize(grid_, direction, end_line - 1, 2,
+                         available_size_for_gutters);
       end -= is_for_columns ? offset_between_columns_ : offset_between_rows_;
     }
   }
@@ -1327,7 +1360,8 @@
 
       if (end_line > 0 && end_line < last_line) {
         DCHECK(!grid_.NeedsItemsPlacement());
-        offset += GuttersSize(grid_, direction, end_line - 1, 2, kTrackSizing);
+        offset += GuttersSize(grid_, direction, end_line - 1, 2,
+                              available_size_for_gutters);
         offset +=
             is_for_columns ? offset_between_columns_ : offset_between_rows_;
       }
@@ -1385,9 +1419,7 @@
     // as we might not compute the gap between two consecutive tracks without
     // examining the surrounding ones.
     bool has_collapsed_tracks = grid.HasAutoRepeatEmptyTracks(direction);
-    LayoutUnit gap = !has_collapsed_tracks
-                         ? GridGapForDirection(direction, kTrackSizing)
-                         : LayoutUnit();
+    LayoutUnit gap = !has_collapsed_tracks ? GridGap(direction) : LayoutUnit();
     size_t next_to_last_line = number_of_lines - 2;
     for (size_t i = 0; i < next_to_last_line; ++i)
       positions[i + 1] = positions[i] + offset.distribution_offset +
@@ -1399,7 +1431,7 @@
     // collapse (they coincide exactly) except on the edges of the grid where
     // they become 0.
     if (has_collapsed_tracks) {
-      gap = GridGapForDirection(direction, kTrackSizing);
+      gap = GridGap(direction);
       size_t remaining_empty_tracks =
           grid.AutoRepeatEmptyTracks(direction)->size();
       LayoutUnit gap_accumulator;
@@ -2098,7 +2130,7 @@
       // alignment) and gutters so we need to subtract them to get the actual
       // end position for a given row (this does not have to be done for the
       // last track as there are no more m_columnPositions after it).
-      LayoutUnit track_gap = GridGapForDirection(kForRows, kTrackSizing);
+      LayoutUnit track_gap = GridGap(kForRows);
       if (child_end_line < row_positions_.size() - 1) {
         end_of_row -= track_gap;
         end_of_row -= offset_between_rows_;
@@ -2140,7 +2172,7 @@
       // alignment) and gutters so we need to subtract them to get the actual
       // end position for a given column (this does not have to be done for the
       // last track as there are no more m_columnPositions after it).
-      LayoutUnit track_gap = GridGapForDirection(kForColumns, kTrackSizing);
+      LayoutUnit track_gap = GridGap(kForColumns);
       if (child_end_line < column_positions_.size() - 1) {
         end_of_column -= track_gap;
         end_of_column -= offset_between_columns_;
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.h b/third_party/WebKit/Source/core/layout/LayoutGrid.h
index ac55656..34b5414 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.h
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.h
@@ -94,7 +94,7 @@
                          GridTrackSizingDirection,
                          size_t start_line,
                          size_t span,
-                         SizingOperation) const;
+                         Optional<LayoutUnit> available_size) const;
   bool CachedHasDefiniteLogicalHeight() const;
   bool IsOrthogonalChild(const LayoutBox&) const;
   bool IsBaselineContextComputed(GridAxis) const;
@@ -130,11 +130,14 @@
 
   void StyleDidChange(StyleDifference, const ComputedStyle*) override;
 
+  Optional<LayoutUnit> AvailableSpaceForGutters(GridTrackSizingDirection) const;
+
   bool ExplicitGridDidResize(const ComputedStyle&) const;
   bool NamedGridLinesDefinitionDidChange(const ComputedStyle&) const;
 
-  size_t ComputeAutoRepeatTracksCount(GridTrackSizingDirection,
-                                      SizingOperation) const;
+  size_t ComputeAutoRepeatTracksCount(
+      GridTrackSizingDirection,
+      Optional<LayoutUnit> available_size) const;
   size_t ClampAutoRepeatTracks(GridTrackSizingDirection,
                                size_t auto_repeat_tracks) const;
 
@@ -142,7 +145,8 @@
       Grid&,
       GridTrackSizingDirection) const;
 
-  void PlaceItemsOnGrid(Grid&, SizingOperation) const;
+  void PlaceItemsOnGrid(Grid&,
+                        Optional<LayoutUnit> available_logical_width) const;
   void PopulateExplicitGridAndOrderIterator(Grid&) const;
   std::unique_ptr<GridArea> CreateEmptyGridAreaAtSpecifiedPositionsOutsideGrid(
       const Grid&,
@@ -259,8 +263,9 @@
   LayoutUnit ColumnAxisBaselineOffsetForChild(const LayoutBox&) const;
   LayoutUnit RowAxisBaselineOffsetForChild(const LayoutBox&) const;
 
-  LayoutUnit GridGapForDirection(GridTrackSizingDirection,
-                                 SizingOperation) const;
+  LayoutUnit GridGap(GridTrackSizingDirection,
+                     Optional<LayoutUnit> available_size) const;
+  LayoutUnit GridGap(GridTrackSizingDirection) const;
 
   size_t GridItemSpan(const LayoutBox&, GridTrackSizingDirection);
 
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 6b7ac6a..ff366f0 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -47,6 +47,10 @@
   RuntimeEnabledFeatures::setWebAssemblyStreamingEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableWebNfc(bool enable) {
+  RuntimeEnabledFeatures::setWebNFCEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableWebUsb(bool enable) {
   RuntimeEnabledFeatures::setWebUSBEnabled(enable);
 }
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index 966c1cd..07b76a3 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -132,6 +132,7 @@
   BLINK_EXPORT static void EnableWebFontsInterventionTrigger(bool);
   BLINK_EXPORT static void EnableWebGLDraftExtensions(bool);
   BLINK_EXPORT static void EnableWebGLImageChromium(bool);
+  BLINK_EXPORT static void EnableWebNfc(bool);
   BLINK_EXPORT static void EnableWebUsb(bool);
   BLINK_EXPORT static void EnableWebVR(bool);
   BLINK_EXPORT static void EnableWebVRExperimentalRendering(bool);
diff --git a/third_party/checkstyle/OWNERS b/third_party/checkstyle/OWNERS
index 812e8d9..3daedd9 100644
--- a/third_party/checkstyle/OWNERS
+++ b/third_party/checkstyle/OWNERS
@@ -1 +1,5 @@
-aurimas@chromium.org
+agrieve@chromium.org
+jbudorick@chromium.org
+nyquist@chromium.org
+zpeng@chromium.org
+
diff --git a/third_party/checkstyle/README.chromium b/third_party/checkstyle/README.chromium
index e84fcf8..25b28ed 100644
--- a/third_party/checkstyle/README.chromium
+++ b/third_party/checkstyle/README.chromium
@@ -1,8 +1,8 @@
 Name: Checkstyle is a development tool to help programmers write Java code that
       adheres to a coding standard.
 Short Name: checkstyle
-URL: http://checkstyle.sourceforge.net/
-Version: 6.5
+URL: https://github.com/checkstyle/checkstyle
+Version: 7.6.1
 License: LGPL 2.1
 License File: NOT_SHIPPED
 Security Critical: no
@@ -11,5 +11,19 @@
 Checkstyle is used to validate Java code style on Chromium PRESUBMIT step.
 
 Local Modifications:
-- Downloaded checkstyle-6.5-all.jar without source code development
-  documentation.
+None
+
+Update instructions (requires @google.com account):
+- Download fat jar from https://sourceforge.net/projects/checkstyle/files/checkstyle/
+- Modify tools/android/checkstyle/checkstyle.py and verify the new fat jar works
+- Remove existing SHA1 file
+- If gcloud auth tokens are not set up, run
+$ download_from_google_storage --config
+- Upload new fat jar to gcloud. In third_party/checkstyle, run
+$ upload_to_google_storage.py -b chromium-android-tools/checkstyle {new_far_jar}
+- Check in new SHA1 file
+- Before submitting the change, verify presubmit works fine by:
+  1) modifying a Java file and including it in the patch
+  2) running the chromium_presubmit trybot in the CQ on the patch
+  3) reverting the Java file change
+
diff --git a/third_party/checkstyle/checkstyle-6.5-all.jar b/third_party/checkstyle/checkstyle-6.5-all.jar
deleted file mode 100644
index b4f571f..0000000
--- a/third_party/checkstyle/checkstyle-6.5-all.jar
+++ /dev/null
Binary files differ
diff --git a/third_party/checkstyle/checkstyle-7.6.1-all.jar.sha1 b/third_party/checkstyle/checkstyle-7.6.1-all.jar.sha1
new file mode 100644
index 0000000..e0aec8e
--- /dev/null
+++ b/third_party/checkstyle/checkstyle-7.6.1-all.jar.sha1
@@ -0,0 +1 @@
+c6889fa07ec9afb0ca8029be75de31dc29dc4f05
\ No newline at end of file
diff --git a/tools/android/checkstyle/checkstyle.py b/tools/android/checkstyle/checkstyle.py
index 44e1ecf5..2433850 100644
--- a/tools/android/checkstyle/checkstyle.py
+++ b/tools/android/checkstyle/checkstyle.py
@@ -13,7 +13,15 @@
     os.path.join(os.path.dirname(__file__),
                  os.pardir, os.pardir, os.pardir))
 CHECKSTYLE_ROOT = os.path.join(CHROMIUM_SRC, 'third_party', 'checkstyle',
-                               'checkstyle-6.5-all.jar')
+                               'checkstyle-7.6.1-all.jar')
+
+
+def FormatCheckstyleOutput(checkstyle_output):
+  lines = checkstyle_output.splitlines(True)
+  if 'Checkstyle ends with' in lines[-1]:
+    return ''.join(lines[:-1])
+  else:
+    return checkstyle_output
 
 
 def RunCheckstyle(input_api, output_api, style_file, black_list=None):
@@ -49,8 +57,10 @@
   result_errors = []
   result_warnings = []
 
+  formatted_checkstyle_output = FormatCheckstyleOutput(stdout)
+
   local_path = input_api.PresubmitLocalPath()
-  root = xml.dom.minidom.parseString(stdout)
+  root = xml.dom.minidom.parseString(formatted_checkstyle_output)
   for fileElement in root.getElementsByTagName('file'):
     fileName = fileElement.attributes['name'].value
     fileName = os.path.relpath(fileName, local_path)
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
index ad0b28c95..a913dc23 100644
--- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc
+++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -1589,21 +1589,12 @@
     // TODO(inferno): Add param traits for |latency_components|.
     int64_t trace_id = p->trace_id();
     bool terminated = p->terminated();
-    uint32_t input_coordinates_size = static_cast<uint32_t>(
-        RandInRange(ui::LatencyInfo::kMaxInputCoordinates + 1));
-    gfx::PointF input_coordinates[ui::LatencyInfo::kMaxInputCoordinates];
-    if (!FuzzParamArray(
-        input_coordinates, input_coordinates_size, fuzzer))
-      return false;
     if (!FuzzParam(&trace_id, fuzzer))
       return false;
     if (!FuzzParam(&terminated, fuzzer))
       return false;
 
     ui::LatencyInfo latency(trace_id, terminated);
-    for (size_t i = 0; i < input_coordinates_size; i++) {
-      latency.AddInputCoordinate(input_coordinates[i]);
-    }
     *p = latency;
 
     return true;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 456522f..6a2daa8 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -36203,6 +36203,9 @@
 </histogram>
 
 <histogram name="Net.QuicDiskCache.APICall" enum="QuicDiskCacheAPICall">
+  <obsolete>
+    Deprecated as of 4/15/2017.
+  </obsolete>
   <owner>rtenneti@chromium.org</owner>
   <summary>
     Tracks number of times data read/parse/write API calls of QuicServerInfo to
@@ -36356,6 +36359,9 @@
 </histogram>
 
 <histogram name="Net.QuicServerInfo.DiskCacheLoadTime" units="ms">
+  <obsolete>
+    Deprecated as of 4/15/2017.
+  </obsolete>
   <owner>rtenneti@chromium.org</owner>
   <summary>Time spent to load QUIC server information from disk cache.</summary>
 </histogram>
@@ -36386,6 +36392,9 @@
 
 <histogram name="Net.QuicServerInfo.ExpectConfigMissingFromDiskCache"
     enum="BooleanMissingFromDiskCache">
+  <obsolete>
+    Deprecated as of 4/15/2017.
+  </obsolete>
   <owner>rtenneti@chromium.org</owner>
   <summary>
     The number of times AlternateProtocolMap supports QUIC, but there is no QUIC
@@ -36406,6 +36415,9 @@
 </histogram>
 
 <histogram name="Net.QuicServerInfo.WaitForDataReadyToRtt" units="%">
+  <obsolete>
+    Deprecated as of 4/15/2017.
+  </obsolete>
   <owner>rtenneti@chromium.org</owner>
   <summary>
     The ratio of the time spent waiting to load QUIC server information from
@@ -67023,14 +67035,14 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.CacheSizeOnInit" units="KB">
+<histogram base="true" name="SimpleCache.CacheSizeOnInit" units="KB">
   <owner>jkarlin@chromium.org</owner>
   <summary>
     The size of the cache at the time that the index has finished initializing.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.CheckCRCResult" enum="CheckCRCResult">
+<histogram base="true" name="SimpleCache.CheckCRCResult" enum="CheckCRCResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Whether or not the CRC was checked at the moment when the last reference to
@@ -67038,7 +67050,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.CreationToIndex" units="ms">
+<histogram base="true" name="SimpleCache.CreationToIndex" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The time from the creation of the simple cache backend until the index has
@@ -67046,7 +67058,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.CreationToIndexFail" units="ms">
+<histogram base="true" name="SimpleCache.CreationToIndexFail" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The time from the creation of the simple cache backend until the index fails
@@ -67062,7 +67074,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.EntryCreatedAndStream2Omitted"
+<histogram base="true" name="SimpleCache.EntryCreatedAndStream2Omitted"
     enum="SimpleCache.EntryCreatedAndStream2Omitted">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67071,7 +67083,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.EntryCreationResult" enum="BooleanSuccess">
+<histogram base="true" name="SimpleCache.EntryCreationResult"
+    enum="BooleanSuccess">
   <owner>gavinp@chromium.org</owner>
   <summary>
     For entry creation operations that were sent to the disk, the result of
@@ -67079,12 +67092,12 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.EntryCreationTime" units="ms">
+<histogram base="true" name="SimpleCache.EntryCreationTime" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>The time, in ms, spent creating a new entry on disk.</summary>
 </histogram>
 
-<histogram name="SimpleCache.EntryOpenedAndStream2Removed"
+<histogram base="true" name="SimpleCache.EntryOpenedAndStream2Removed"
     enum="SimpleCache.EntryOpenedAndStream2Removed">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67093,7 +67106,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.EntryOperationsPending">
+<histogram base="true" name="SimpleCache.EntryOperationsPending">
   <owner>gavinp@chromium.org</owner>
   <summary>
     At the time that operations are run, the number of pending operations on a
@@ -67109,12 +67122,12 @@
   <summary>The size of the cache at the beginning of an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.CacheSizeOnStart2" units="KB">
+<histogram base="true" name="SimpleCache.Eviction.CacheSizeOnStart2" units="KB">
   <owner>gavinp@chromium.org</owner>
   <summary>The size of the cache at the beginning of an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.EntryCount">
+<histogram base="true" name="SimpleCache.Eviction.EntryCount">
   <owner>gavinp@chromium.org</owner>
   <summary>The number of entries to be erased in an eviction.</summary>
 </histogram>
@@ -67129,14 +67142,15 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.MaxCacheSizeOnStart2" units="KB">
+<histogram base="true" name="SimpleCache.Eviction.MaxCacheSizeOnStart2"
+    units="KB">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The maximum allowed size of the cache at the beginning of an eviction.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.Result" enum="BooleanSuccess">
+<histogram base="true" name="SimpleCache.Eviction.Result" enum="BooleanSuccess">
   <owner>gavinp@chromium.org</owner>
   <summary>The result of an eviction.</summary>
 </histogram>
@@ -67149,7 +67163,7 @@
   <summary>The number of bytes to be erased in an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.SizeOfEvicted2" units="KB">
+<histogram base="true" name="SimpleCache.Eviction.SizeOfEvicted2" units="KB">
   <owner>gavinp@chromium.org</owner>
   <summary>The amount of memory freed in an eviction.</summary>
 </histogram>
@@ -67162,22 +67176,23 @@
   <summary>The size of the cache after running an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.SizeWhenDone2" units="KB">
+<histogram base="true" name="SimpleCache.Eviction.SizeWhenDone2" units="KB">
   <owner>gavinp@chromium.org</owner>
   <summary>The size of the cache after running an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.TimeToDone" units="ms">
+<histogram base="true" name="SimpleCache.Eviction.TimeToDone" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>Time spent completing an eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.Eviction.TimeToSelectEntries" units="ms">
+<histogram base="true" name="SimpleCache.Eviction.TimeToSelectEntries"
+    units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>Time spent selecting entries for eviction.</summary>
 </histogram>
 
-<histogram name="SimpleCache.FileDescriptorLimitHard">
+<histogram base="true" name="SimpleCache.FileDescriptorLimitHard">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The maximum limit of how many file descriptors a process can open.  Emitted
@@ -67186,7 +67201,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.FileDescriptorLimitSoft">
+<histogram base="true" name="SimpleCache.FileDescriptorLimitSoft">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The current limit of how many file descriptors a process can open.  Emitted
@@ -67195,7 +67210,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.FileDescriptorLimitStatus"
+<histogram base="true" name="SimpleCache.FileDescriptorLimitStatus"
     enum="SimpleCache.FileDescriptorLimitStatus">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67204,7 +67219,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.GlobalOpenEntryCount">
+<histogram base="true" name="SimpleCache.GlobalOpenEntryCount">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The number of open entries across all caches backed by the Simple Cache. An
@@ -67214,7 +67229,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSize" units="bytes">
+<histogram base="true" name="SimpleCache.HeaderSize" units="bytes">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The size of the header stream of a Simple Cache entry, emitted every time
@@ -67222,7 +67237,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSizeChange"
+<histogram base="true" name="SimpleCache.HeaderSizeChange"
     enum="SimpleCacheHeaderSizeChange">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67232,7 +67247,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSizeDecreaseAbsolute" units="bytes">
+<histogram base="true" name="SimpleCache.HeaderSizeDecreaseAbsolute"
+    units="bytes">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The absolute size decrease of the header stream of a Simple Cache entry,
@@ -67240,7 +67256,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSizeDecreasePercentage" units="%">
+<histogram base="true" name="SimpleCache.HeaderSizeDecreasePercentage"
+    units="%">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The relative size decrease of the header stream of a Simple Cache entry,
@@ -67248,7 +67265,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSizeIncreaseAbsolute" units="bytes">
+<histogram base="true" name="SimpleCache.HeaderSizeIncreaseAbsolute"
+    units="bytes">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The absolute size increase of the header stream of a Simple Cache entry,
@@ -67256,7 +67274,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.HeaderSizeIncreasePercentage" units="%">
+<histogram base="true" name="SimpleCache.HeaderSizeIncreasePercentage"
+    units="%">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The relative size increase of the header stream of a Simple Cache entry,
@@ -67264,22 +67283,22 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexCorrupt" enum="BooleanCorrupt">
+<histogram base="true" name="SimpleCache.IndexCorrupt" enum="BooleanCorrupt">
   <owner>gavinp@chromium.org</owner>
   <summary>For each index load, whether the index file was corrupt.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexCreatedEntryCount">
+<histogram base="true" name="SimpleCache.IndexCreatedEntryCount">
   <owner>gavinp@chromium.org</owner>
   <summary>The number of entries in a newly created index file.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexEntriesLoaded">
+<histogram base="true" name="SimpleCache.IndexEntriesLoaded">
   <owner>gavinp@chromium.org</owner>
   <summary>Number of entries loaded from the index file on start.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexEntriesRestored">
+<histogram base="true" name="SimpleCache.IndexEntriesRestored">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Number of entries restored from disk when there was no index or the index
@@ -67287,14 +67306,15 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexFileStateOnLoad" enum="SimpleIndexState">
+<histogram base="true" name="SimpleCache.IndexFileStateOnLoad"
+    enum="SimpleIndexState">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The state the index file is at when an attempt is made to load from it.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexInitializationWaiters">
+<histogram base="true" name="SimpleCache.IndexInitializationWaiters">
   <owner>gavinp@chromium.org</owner>
   <summary>
     At the time of index initialization, the number of enqueued jobs awaiting
@@ -67302,20 +67322,20 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexInitializeMethod"
+<histogram base="true" name="SimpleCache.IndexInitializeMethod"
     enum="SimpleCacheIndexInitializeMethod">
   <owner>gavinp@chromium.org</owner>
   <summary>The method used to initialize the simple cache index.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexLoadTime" units="ms">
+<histogram base="true" name="SimpleCache.IndexLoadTime" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Time (as measured on the worker pool) spent loading the index file.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexNumEntriesOnInit" units="entries">
+<histogram base="true" name="SimpleCache.IndexNumEntriesOnInit" units="entries">
   <owner>jkarlin@chromium.org</owner>
   <summary>
     The number of entries in the index at the time that the index has finished
@@ -67323,12 +67343,12 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexNumEntriesOnWrite">
+<histogram base="true" name="SimpleCache.IndexNumEntriesOnWrite">
   <owner>gavinp@chromium.org</owner>
   <summary>The number of entries written to the index on a flush.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexRestoreTime" units="ms">
+<histogram base="true" name="SimpleCache.IndexRestoreTime" units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Time (as measured on the worker pool) spent restoring the index file by
@@ -67344,21 +67364,23 @@
   <summary>For each index load, whether the index file was stale.</summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteInterval.Background" units="ms">
+<histogram base="true" name="SimpleCache.IndexWriteInterval.Background"
+    units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The interval between index saves, for apps in the background.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteInterval.Foreground" units="ms">
+<histogram base="true" name="SimpleCache.IndexWriteInterval.Foreground"
+    units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The interval between index saves, for apps in the foreground.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteReason"
+<histogram base="true" name="SimpleCache.IndexWriteReason"
     enum="SimpleCacheIndexWriteReason">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67367,7 +67389,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteReasonAtLoad"
+<histogram base="true" name="SimpleCache.IndexWriteReasonAtLoad"
     enum="SimpleCacheIndexWriteReason">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67391,7 +67413,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteToDiskTime.Background" units="ms">
+<histogram base="true" name="SimpleCache.IndexWriteToDiskTime.Background"
+    units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The amount of time spend writing the index file to disk, for apps in the
@@ -67400,7 +67423,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.IndexWriteToDiskTime.Foreground" units="ms">
+<histogram base="true" name="SimpleCache.IndexWriteToDiskTime.Foreground"
+    units="ms">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The amount of time spend writing the index file to disk, for apps in the
@@ -67421,7 +67445,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.LastClusterLossPercent" units="%">
+<histogram base="true" name="SimpleCache.LastClusterLossPercent" units="%">
   <owner>gavinp@chromium.org</owner>
   <summary>
     For each file in the Simple Cache, the percentage of disk space used by the
@@ -67430,7 +67454,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.LastClusterSize" units="bytes">
+<histogram base="true" name="SimpleCache.LastClusterSize" units="bytes">
   <owner>gavinp@chromium.org</owner>
   <summary>
     For each file in the Simple Cache, the number of bytes in the last 4096 byte
@@ -67438,7 +67462,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.MaxCacheSizeOnInit" units="KB">
+<histogram base="true" name="SimpleCache.MaxCacheSizeOnInit" units="KB">
   <owner>jkarlin@chromium.org</owner>
   <summary>
     The maximum allowed size of the cache at the time that the index has
@@ -67446,7 +67470,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.OpenEntryIndexState"
+<histogram base="true" name="SimpleCache.OpenEntryIndexState"
     enum="SimpleCacheOpenEntryIndexState">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67454,7 +67478,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.PercentFullOnInit" units="%">
+<histogram base="true" name="SimpleCache.PercentFullOnInit" units="%">
   <owner>jkarlin@chromium.org</owner>
   <summary>
     The fullness (in percent) of the cache at the time that the index has
@@ -67463,7 +67487,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.ReadIsParallelizable"
+<histogram base="true" name="SimpleCache.ReadIsParallelizable"
     enum="SimpleCacheReadParallelizable">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67472,12 +67496,14 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.ReadResult" enum="SimpleCacheReadResult">
+<histogram base="true" name="SimpleCache.ReadResult"
+    enum="SimpleCacheReadResult">
   <owner>gavinp@chromium.org</owner>
   <summary>The outcome of Entry::ReadData in the simple cache.</summary>
 </histogram>
 
-<histogram name="SimpleCache.StaleIndexExtraEntryCount" units="entries">
+<histogram base="true" name="SimpleCache.StaleIndexExtraEntryCount"
+    units="entries">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Count of the number of entries recorded in the index, but not actually
@@ -67486,7 +67512,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.StaleIndexMissedEntryCount" units="entries">
+<histogram base="true" name="SimpleCache.StaleIndexMissedEntryCount"
+    units="entries">
   <owner>gavinp@chromium.org</owner>
   <summary>
     Count of the number of entries present in a cache, but not recorded in the
@@ -67495,7 +67522,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.StaleIndexQuality"
+<histogram base="true" name="SimpleCache.StaleIndexQuality"
     enum="SimpleCacheStaleIndexQuality">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67504,7 +67531,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncCheckEOFHasCrc" enum="BooleanHasCrc">
+<histogram base="true" name="SimpleCache.SyncCheckEOFHasCrc"
+    enum="BooleanHasCrc">
   <owner>gavinp@chromium.org</owner>
   <summary>
     For each EOFRecord found with a valid magic number, indicates if the record
@@ -67512,7 +67540,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncCheckEOFResult"
+<histogram base="true" name="SimpleCache.SyncCheckEOFResult"
     enum="SimpleCacheSyncCheckEOFResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67521,14 +67549,15 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncCloseResult" enum="SimpleCacheSyncCloseResult">
+<histogram base="true" name="SimpleCache.SyncCloseResult"
+    enum="SimpleCacheSyncCloseResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The result, at the synchronous layer, of closing a cache entry.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncCreatePlatformFileError"
+<histogram base="true" name="SimpleCache.SyncCreatePlatformFileError"
     enum="PlatformFileError">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67537,7 +67566,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncCreateResult"
+<histogram base="true" name="SimpleCache.SyncCreateResult"
     enum="SimpleCacheSyncCreateResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67546,7 +67575,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncKeySHA256Result"
+<histogram base="true" name="SimpleCache.SyncKeySHA256Result"
     enum="SimpleCacheSyncSHA256Result">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67555,7 +67584,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncOpenEntryAge" units="hours">
+<histogram base="true" name="SimpleCache.SyncOpenEntryAge" units="hours">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The age of the entry (time since last modified), when opened at the
@@ -67563,7 +67592,7 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncOpenPlatformFileError"
+<histogram base="true" name="SimpleCache.SyncOpenPlatformFileError"
     enum="PlatformFileError">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67572,7 +67601,8 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncOpenResult" enum="SimpleCacheSyncOpenResult">
+<histogram base="true" name="SimpleCache.SyncOpenResult"
+    enum="SimpleCacheSyncOpenResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The result, at the synchronous layer, reported when attempting to open a new
@@ -67580,14 +67610,15 @@
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.SyncWriteResult" enum="SimpleCacheSyncWriteResult">
+<histogram base="true" name="SimpleCache.SyncWriteResult"
+    enum="SimpleCacheSyncWriteResult">
   <owner>gavinp@chromium.org</owner>
   <summary>
     The result, at the synchronous layer, of writing to a cache entry.
   </summary>
 </histogram>
 
-<histogram name="SimpleCache.WriteDependencyType"
+<histogram base="true" name="SimpleCache.WriteDependencyType"
     enum="SimpleCacheWriteDependencyType">
   <owner>gavinp@chromium.org</owner>
   <summary>
@@ -67605,7 +67636,8 @@
   <summary>The outcome of Entry::WriteData in the simple cache.</summary>
 </histogram>
 
-<histogram name="SimpleCache.WriteResult2" enum="SimpleCacheWriteResult">
+<histogram base="true" name="SimpleCache.WriteResult2"
+    enum="SimpleCacheWriteResult">
   <owner>gavinp@chromium.org</owner>
   <summary>The outcome of Entry::WriteData in the simple cache.</summary>
 </histogram>
@@ -69518,6 +69550,24 @@
   </summary>
 </histogram>
 
+<histogram name="Startup.BrowserWindow.FirstPaint" units="ms">
+  <owner>mblsha@yandex-team.ru</owner>
+  <summary>
+    Time from browser startup to the time the first Browser window has finished
+    painting its children.
+  </summary>
+</histogram>
+
+<histogram name="Startup.BrowserWindow.FirstPaint.CompositingEnded" units="ms">
+  <owner>mblsha@yandex-team.ru</owner>
+  <summary>
+    Time from browser startup to the time the GPU has finished compositing after
+    first Browser window has finished painting its children. At this point the
+    Browser interface is visible on screen. Measures how much time does it take
+    for GPU to actually paint the first time.
+  </summary>
+</histogram>
+
 <histogram name="Startup.BrowserWindowDisplay" units="ms">
   <owner>fdoray@chromium.org</owner>
   <summary>
@@ -103243,6 +103293,7 @@
   <int value="-344343842" label="disable-experimental-app-list"/>
   <int value="-340622848" label="disable-javascript-harmony-shipping"/>
   <int value="-340255045" label="allow-nacl-socket-api"/>
+  <int value="-340023285" label="WebNFC:enabled"/>
   <int value="-329727402" label="disable-files-quick-view"/>
   <int value="-328361990" label="enable-experimental-extension-apis"/>
   <int value="-323831744" label="token-binding:enabled"/>
@@ -103441,6 +103492,7 @@
   <int value="494733611" label="disable-drop-sync-credential"/>
   <int value="503245473" label="disable-translate-new-ux"/>
   <int value="504994663" label="GenericSensor:disabled"/>
+  <int value="506680761" label="WebNFC:disabled"/>
   <int value="510814146" label="OfflineBookmarks:enabled"/>
   <int value="535976218" label="enable-plugin-power-saver"/>
   <int value="538468149" label="OfflinePagesCT:enabled"/>
@@ -126787,6 +126839,8 @@
       name="Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun2"/>
   <affected-histogram name="Startup.BrowserMessageLoopStartTimeFromMainEntry2"/>
   <affected-histogram name="Startup.BrowserOpenTabs"/>
+  <affected-histogram name="Startup.BrowserWindow.FirstPaint"/>
+  <affected-histogram name="Startup.BrowserWindow.FirstPaint.CompositingEnded"/>
   <affected-histogram name="Startup.BrowserWindowDisplay"/>
   <affected-histogram name="Startup.FirstWebContents.MainFrameLoad"/>
   <affected-histogram name="Startup.FirstWebContents.MainFrameLoad2"/>
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json
index c83df9d8..554c9fc 100644
--- a/tools/perf/page_sets/data/system_health_desktop.json
+++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -39,6 +39,12 @@
         "browse:social:twitter": {
             "DEFAULT": "system_health_desktop_019.wpr"
         },
+        "browse:tools:earth": {
+            "DEFAULT": "system_health_desktop_050.wpr"
+        },
+        "browse:tools:maps": {
+            "DEFAULT": "system_health_desktop_052.wpr"
+        },
         "load:games:alphabetty": {
             "DEFAULT": "system_health_desktop_005.wpr"
         },
@@ -189,4 +195,4 @@
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
\ No newline at end of file
+}
diff --git a/tools/perf/page_sets/data/system_health_desktop_050.wpr.sha1 b/tools/perf/page_sets/data/system_health_desktop_050.wpr.sha1
new file mode 100644
index 0000000..58dd4aa
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_050.wpr.sha1
@@ -0,0 +1 @@
+7122563e956204fb0850b609e7173fd7c7271d3a
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_desktop_051.wpr.sha1 b/tools/perf/page_sets/data/system_health_desktop_051.wpr.sha1
new file mode 100644
index 0000000..741f648
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_051.wpr.sha1
@@ -0,0 +1 @@
+f20971206602450edb4b034ab253da8b1102de73
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_desktop_052.wpr.sha1 b/tools/perf/page_sets/data/system_health_desktop_052.wpr.sha1
new file mode 100644
index 0000000..d5067ace
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_052.wpr.sha1
@@ -0,0 +1 @@
+07eb10abc76d5ec071711be08fd8fe3fbbf034c4
\ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index 3d5e1d58..b1236f69 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -645,3 +645,138 @@
   def _ClickLink(self, selector, action_runner):
     action_runner.WaitForElement(selector=selector)
     action_runner.ClickElement(selector=selector)
+
+
+# crbug.com/712694 on all platforms.
+@decorators.Disabled('all')
+class GoogleMapsStory(_BrowsingStory):
+  """
+  Google maps story:
+    _ Start at https://www.maps.google.com/maps
+    _ Search for "restaurents near me" and wait for 4 sec.
+    _ Click ZoomIn two times, waiting for 3 sec in between.
+    _ Scroll the map horizontally and vertically.
+    _ Pick a restaurant and ask for directions.
+  """
+  # When recording this story:
+  # Force tactile using this: http://google.com/maps?force=tt
+  # Force webgl using this: http://google.com/maps?force=webgl
+  # Reduce the speed as mentioned in the comment below for
+  # RepeatableBrowserDrivenScroll
+  NAME = 'browse:tools:maps'
+  URL = 'https://www.maps.google.com/maps'
+  _MAPS_SEARCH_BOX_SELECTOR = 'input[aria-label="Search Google Maps"]'
+  _MAPS_ZOOM_IN_SELECTOR = '[aria-label="Zoom in"]'
+  _RESTAURANTS_LOADING = ('[class="searchbox searchbox-shadow noprint '
+                          'clear-button-shown loading"]')
+  _RESTAURANTS_LOADED = ('[class="searchbox searchbox-shadow noprint '
+                         'clear-button-shown"]')
+  _RESTAURANTS_LINK = '[data-result-index="1"]'
+  _DIRECTIONS_LINK = '[class="section-hero-header-directions-icon"]'
+  _DIRECTIONS_FROM_BOX = '[class="tactile-searchbox-input"]'
+  _DIRECTIONS_LOADED = '[class="section-directions-trip clearfix selected"]'
+  SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
+  TAGS = [story_tags.JAVASCRIPT_HEAVY]
+
+  def _DidLoadDocument(self, action_runner):
+    # Click on the search box.
+    action_runner.WaitForElement(selector=self._MAPS_SEARCH_BOX_SELECTOR)
+    action_runner.ClickElement(selector=self._MAPS_SEARCH_BOX_SELECTOR)
+
+    # Submit search query.
+    action_runner.EnterText('restaurants near me')
+    action_runner.PressKey('Return')
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADED)
+    action_runner.WaitForElement(selector=self._MAPS_ZOOM_IN_SELECTOR)
+    action_runner.Wait(1)
+
+    # ZoomIn two times.
+    action_runner.ClickElement(selector=self._MAPS_ZOOM_IN_SELECTOR)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADING)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADED)
+    # This wait is required to fetch the data for all the tiles in the map.
+    action_runner.Wait(1)
+    action_runner.ClickElement(selector=self._MAPS_ZOOM_IN_SELECTOR)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADING)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADED)
+    # This wait is required to fetch the data for all the tiles in the map.
+    action_runner.Wait(1)
+
+    # Reduce the speed (the current wpr is recorded with speed set to 50)  when
+    # recording the wpr. If we scroll too fast, the data will not be recorded
+    # well. After recording reset it back to the original value to have a more
+    # realistic scroll.
+    action_runner.RepeatableBrowserDrivenScroll(
+        x_scroll_distance_ratio = 0.0, y_scroll_distance_ratio = 0.5,
+        repeat_count=2, speed=500, timeout=120, repeat_delay_ms=2000)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADING)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADED)
+    action_runner.RepeatableBrowserDrivenScroll(
+        x_scroll_distance_ratio = 0.5, y_scroll_distance_ratio = 0,
+        repeat_count=2, speed=500, timeout=120, repeat_delay_ms=2000)
+
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADING)
+    action_runner.WaitForElement(selector=self._RESTAURANTS_LOADED)
+    # To make the recording more realistic.
+    action_runner.Wait(1)
+    action_runner.ClickElement(selector=self._RESTAURANTS_LINK)
+    # To make the recording more realistic.
+    action_runner.Wait(1)
+    action_runner.WaitForElement(selector=self._DIRECTIONS_LINK)
+    action_runner.ClickElement(selector=self._DIRECTIONS_LINK)
+    action_runner.ClickElement(selector=self._DIRECTIONS_FROM_BOX)
+    action_runner.EnterText('6 Pancras Road London')
+    action_runner.PressKey('Return')
+    action_runner.WaitForElement(selector=self._DIRECTIONS_LOADED)
+    action_runner.Wait(2)
+
+
+# crbug.com/708590 on all platforms.
+@decorators.Disabled('all')
+class GoogleEarthStory(_BrowsingStory):
+  """
+  Google Earth story:
+    _ Start at https://www.maps.google.com/maps
+    _ Click on the Earth link
+    _ Click ZoomIn three times, waiting for 3 sec in between.
+
+  """
+  # When recording this story:
+  # Force tactile using this: http://google.com/maps?force=tt
+  # Force webgl using this: http://google.com/maps?force=webgl
+  # Change the speed as mentioned in the comment below for
+  # RepeatableBrowserDrivenScroll
+  NAME = 'browse:tools:earth'
+  # Randomly picked location.
+  URL = 'https://www.google.co.uk/maps/@51.4655936,-0.0985949,3329a,35y,40.58t/data=!3m1!1e3'
+  _EARTH_BUTTON_SELECTOR = '[aria-labelledby="widget-minimap-caption"]'
+  _EARTH_ZOOM_IN_SELECTOR = '[aria-label="Zoom in"]'
+  _MAPS_SEARCH_BOX_SELECTOR = 'input[aria-label="Search Google Maps"]'
+  SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
+  TAGS = [story_tags.JAVASCRIPT_HEAVY]
+
+  def _DidLoadDocument(self, action_runner):
+    # Zommin three times.
+    action_runner.WaitForElement(selector=self._EARTH_ZOOM_IN_SELECTOR)
+    action_runner.ClickElement(selector=self._EARTH_ZOOM_IN_SELECTOR)
+    # To make the recording more realistic.
+    action_runner.Wait(1)
+    action_runner.ClickElement(selector=self._EARTH_ZOOM_IN_SELECTOR)
+    # To make the recording more realistic.
+    action_runner.Wait(1)
+    action_runner.ClickElement(selector=self._EARTH_ZOOM_IN_SELECTOR)
+    # To make the recording more realistic.
+    action_runner.Wait(1)
+    action_runner.ClickElement(selector=self._EARTH_ZOOM_IN_SELECTOR)
+    action_runner.Wait(4)
+
+    # Reduce the speed (the current wpr is recorded with speed set to 50)  when
+    # recording the wpr. If we scroll too fast, the data will not be recorded
+    # well. After recording reset it back to the original value to have a more
+    # realistic scroll.
+    action_runner.RepeatableBrowserDrivenScroll(
+        x_scroll_distance_ratio = 0.0, y_scroll_distance_ratio = 1,
+        repeat_count=3, speed=400, timeout=120)
+    action_runner.RepeatableBrowserDrivenScroll(
+        x_scroll_distance_ratio = 1, y_scroll_distance_ratio = 0,
+        repeat_count=3, speed=500, timeout=120)
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index 6f178cac..ebc27076 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -2207,17 +2207,9 @@
   DISALLOW_COPY_AND_ASSIGN(TestMetricsReporter);
 };
 
-// TODO(crbug/709080): LayerWithRealCompositorTest.ReportMetrics is flaky on
-// Windows.
-#if defined(OS_WIN)
-#define MAYBE_ReportMetrics DISABLED_ReportMetrics
-#else
-#define MAYBE_ReportMetrics ReportMetrics
-#endif
-
 // Starts an animation and tests that incrementing compositor frame count can
 // be used to report animation smoothness metrics.
-TEST_F(LayerWithRealCompositorTest, MAYBE_ReportMetrics) {
+TEST_F(LayerWithRealCompositorTest, ReportMetrics) {
   std::unique_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
   GetCompositor()->SetRootLayer(root.get());
   LayerAnimator* animator = root->GetAnimator();
diff --git a/ui/latency/ipc/latency_info_param_traits.cc b/ui/latency/ipc/latency_info_param_traits.cc
index 23a4eede9..d1e6f50 100644
--- a/ui/latency/ipc/latency_info_param_traits.cc
+++ b/ui/latency/ipc/latency_info_param_traits.cc
@@ -42,10 +42,6 @@
                                            const param_type& p) {
   GetParamSize(s, p.trace_name_);
   GetParamSize(s, p.latency_components_);
-  GetParamSize(s, p.input_coordinates_size_);
-  for (size_t i = 0; i < p.input_coordinates_size_; i++) {
-    GetParamSize(s, p.input_coordinates_[i]);
-  }
   GetParamSize(s, p.trace_id_);
   GetParamSize(s, p.terminated_);
   GetParamSize(s, p.source_event_type_);
@@ -54,10 +50,6 @@
 void ParamTraits<ui::LatencyInfo>::Write(base::Pickle* m, const param_type& p) {
   WriteParam(m, p.trace_name_);
   WriteParam(m, p.latency_components_);
-  WriteParam(m, p.input_coordinates_size_);
-  for (size_t i = 0; i < p.input_coordinates_size_; i++) {
-    WriteParam(m, p.input_coordinates_[i]);
-  }
   WriteParam(m, p.trace_id_);
   WriteParam(m, p.terminated_);
   WriteParam(m, p.source_event_type_);
@@ -71,17 +63,6 @@
   if (!ReadParam(m, iter, &p->latency_components_))
     return false;
 
-  gfx::PointF input_coordinates;
-  uint32_t input_coordinates_size;
-  if (!ReadParam(m, iter, &input_coordinates_size))
-    return false;
-  for (size_t i = 0; i < input_coordinates_size; i++) {
-    if (!ReadParam(m, iter, &input_coordinates))
-      return false;
-    if (!p->AddInputCoordinate(input_coordinates))
-      return false;
-  }
-
   if (!ReadParam(m, iter, &p->trace_id_))
     return false;
   if (!ReadParam(m, iter, &p->terminated_))
@@ -97,12 +78,6 @@
   l->append(" ");
   LogParam(p.latency_components_, l);
   l->append(" ");
-  LogParam(p.input_coordinates_size_, l);
-  l->append(" ");
-  for (size_t i = 0; i < p.input_coordinates_size_; i++) {
-    LogParam(p.input_coordinates_[i], l);
-    l->append(" ");
-  }
   LogParam(p.trace_id_, l);
   l->append(" ");
   LogParam(p.terminated_, l);
diff --git a/ui/latency/ipc/latency_info_param_traits_unittest.cc b/ui/latency/ipc/latency_info_param_traits_unittest.cc
index 0ffb1b4..b41a10ad 100644
--- a/ui/latency/ipc/latency_info_param_traits_unittest.cc
+++ b/ui/latency/ipc/latency_info_param_traits_unittest.cc
@@ -16,19 +16,13 @@
 TEST(LatencyInfoParamTraitsTest, Basic) {
   LatencyInfo latency;
   ASSERT_FALSE(latency.terminated());
-  ASSERT_EQ(0u, latency.input_coordinates_size());
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 1234, 0);
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1234, 100);
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT,
                            1234, 0);
-  EXPECT_TRUE(latency.AddInputCoordinate(gfx::PointF(100, 200)));
-  EXPECT_TRUE(latency.AddInputCoordinate(gfx::PointF(101, 201)));
-  // Up to 2 InputCoordinate is allowed.
-  EXPECT_FALSE(latency.AddInputCoordinate(gfx::PointF(102, 202)));
 
   EXPECT_EQ(100, latency.trace_id());
   EXPECT_TRUE(latency.terminated());
-  EXPECT_EQ(2u, latency.input_coordinates_size());
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
   IPC::WriteParam(&msg, latency);
@@ -38,13 +32,6 @@
 
   EXPECT_EQ(latency.trace_id(), output.trace_id());
   EXPECT_EQ(latency.terminated(), output.terminated());
-  EXPECT_EQ(latency.input_coordinates_size(), output.input_coordinates_size());
-  for (size_t i = 0; i < latency.input_coordinates_size(); i++) {
-    EXPECT_EQ(latency.input_coordinates()[i].x(),
-              output.input_coordinates()[i].x());
-    EXPECT_EQ(latency.input_coordinates()[i].y(),
-              output.input_coordinates()[i].y());
-  }
 
   EXPECT_TRUE(output.FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
                                  1234,
@@ -66,9 +53,6 @@
   IPC::WriteParam(&msg, std::string());
   ui::LatencyInfo::LatencyMap components;
   IPC::WriteParam(&msg, components);
-  // input_coordinates_size is 2 but only one InputCoordinate is written.
-  IPC::WriteParam(&msg, static_cast<uint32_t>(2));
-  IPC::WriteParam(&msg, gfx::PointF());
   IPC::WriteParam(&msg, static_cast<int64_t>(1234));
   IPC::WriteParam(&msg, true);
 
diff --git a/ui/latency/latency_info.cc b/ui/latency/latency_info.cc
index 0d5d111..9427c4c 100644
--- a/ui/latency/latency_info.cc
+++ b/ui/latency/latency_info.cc
@@ -133,8 +133,7 @@
 LatencyInfo::LatencyInfo() : LatencyInfo(SourceEventType::UNKNOWN) {}
 
 LatencyInfo::LatencyInfo(SourceEventType type)
-    : input_coordinates_size_(0),
-      trace_id_(-1),
+    : trace_id_(-1),
       coalesced_(false),
       terminated_(false),
       source_event_type_(type) {}
@@ -144,8 +143,7 @@
 LatencyInfo::~LatencyInfo() {}
 
 LatencyInfo::LatencyInfo(int64_t trace_id, bool terminated)
-    : input_coordinates_size_(0),
-      trace_id_(trace_id),
+    : trace_id_(trace_id),
       terminated_(terminated),
       source_event_type_(SourceEventType::UNKNOWN) {}
 
@@ -295,11 +293,9 @@
     terminated_ = true;
 
     if (*latency_info_enabled) {
-      TRACE_EVENT_COPY_ASYNC_END2(kTraceCategoriesForAsyncEvents,
-                                  trace_name_.c_str(),
-                                  TRACE_ID_DONT_MANGLE(trace_id_),
-                                  "data", AsTraceableData(),
-                                  "coordinates", CoordinatesAsTraceableData());
+      TRACE_EVENT_COPY_ASYNC_END1(
+          kTraceCategoriesForAsyncEvents, trace_name_.c_str(),
+          TRACE_ID_DONT_MANGLE(trace_id_), "data", AsTraceableData());
     }
 
     TRACE_EVENT_WITH_FLOW0("input,benchmark",
@@ -330,19 +326,6 @@
   return LatencyInfoTracedValue::FromValue(std::move(record_data));
 }
 
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-LatencyInfo::CoordinatesAsTraceableData() {
-  std::unique_ptr<base::ListValue> coordinates(new base::ListValue());
-  for (size_t i = 0; i < input_coordinates_size_; i++) {
-    std::unique_ptr<base::DictionaryValue> coordinate_pair(
-        new base::DictionaryValue());
-    coordinate_pair->SetDouble("x", input_coordinates_[i].x());
-    coordinate_pair->SetDouble("y", input_coordinates_[i].y());
-    coordinates->Append(std::move(coordinate_pair));
-  }
-  return LatencyInfoTracedValue::FromValue(std::move(coordinates));
-}
-
 bool LatencyInfo::FindLatency(LatencyComponentType type,
                               int64_t id,
                               LatencyComponent* output) const {
@@ -379,11 +362,4 @@
   }
 }
 
-bool LatencyInfo::AddInputCoordinate(const gfx::PointF& input_coordinate) {
-  if (input_coordinates_size_ >= kMaxInputCoordinates)
-    return false;
-  input_coordinates_[input_coordinates_size_++] = input_coordinate;
-  return true;
-}
-
 }  // namespace ui
diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h
index 11cb6c71..84c5434 100644
--- a/ui/latency/latency_info.h
+++ b/ui/latency/latency_info.h
@@ -198,13 +198,6 @@
 
   void RemoveLatency(LatencyComponentType type);
 
-  // Returns true if there is still room for keeping the |input_coordinate|,
-  // false otherwise.
-  bool AddInputCoordinate(const gfx::PointF& input_coordinate);
-
-  uint32_t input_coordinates_size() const { return input_coordinates_size_; }
-  const gfx::PointF* input_coordinates() const { return input_coordinates_; }
-
   const LatencyMap& latency_components() const { return latency_components_; }
 
   const SourceEventType& source_event_type() const {
@@ -230,8 +223,6 @@
   // Converts latencyinfo into format that can be dumped into trace buffer.
   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
   AsTraceableData();
-  std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-  CoordinatesAsTraceableData();
 
   // Shown as part of the name of the trace event for this LatencyInfo.
   // String is empty if no tracing is enabled.
@@ -239,10 +230,6 @@
 
   LatencyMap latency_components_;
 
-  // These coordinates represent window coordinates of the original input event.
-  uint32_t input_coordinates_size_;
-  gfx::PointF input_coordinates_[kMaxInputCoordinates];
-
   // The unique id for matching the ASYNC_BEGIN/END trace event.
   int64_t trace_id_;
   // Whether this event has been coalesced into another event.
diff --git a/ui/latency/mojo/latency_info.mojom b/ui/latency/mojo/latency_info.mojom
index 94703b5..5b40d32 100644
--- a/ui/latency/mojo/latency_info.mojom
+++ b/ui/latency/mojo/latency_info.mojom
@@ -104,7 +104,6 @@
 struct LatencyInfo {
   string trace_name;
   array<LatencyComponentPair> latency_components;
-  array<gfx.mojom.PointF> input_coordinates;
   int64 trace_id;
   bool coalesced;
   bool terminated;
diff --git a/ui/latency/mojo/latency_info_struct_traits.cc b/ui/latency/mojo/latency_info_struct_traits.cc
index a3a60d6..55a97949 100644
--- a/ui/latency/mojo/latency_info_struct_traits.cc
+++ b/ui/latency/mojo/latency_info_struct_traits.cc
@@ -242,12 +242,6 @@
              ui::LatencyInfo>::latency_components(const ui::LatencyInfo& info) {
   return info.latency_components();
 }
-InputCoordinateArray
-StructTraits<ui::mojom::LatencyInfoDataView,
-             ui::LatencyInfo>::input_coordinates(const ui::LatencyInfo& info) {
-  return {info.input_coordinates_size_, ui::LatencyInfo::kMaxInputCoordinates,
-          const_cast<gfx::PointF*>(info.input_coordinates_)};
-}
 
 int64_t StructTraits<ui::mojom::LatencyInfoDataView, ui::LatencyInfo>::trace_id(
     const ui::LatencyInfo& info) {
@@ -283,14 +277,6 @@
       return false;
   }
 
-  InputCoordinateArray input_coordinate_array = {
-      0, ui::LatencyInfo::kMaxInputCoordinates, out->input_coordinates_};
-  if (!data.ReadInputCoordinates(&input_coordinate_array))
-    return false;
-  // TODO(fsamuel): ui::LatencyInfo::input_coordinates_size_ should be a size_t.
-  out->input_coordinates_size_ =
-      static_cast<uint32_t>(input_coordinate_array.size);
-
   out->trace_id_ = data.trace_id();
   out->coalesced_ = data.coalesced();
   out->terminated_ = data.terminated();
diff --git a/ui/latency/mojo/latency_info_struct_traits.h b/ui/latency/mojo/latency_info_struct_traits.h
index a409b98..aec6630 100644
--- a/ui/latency/mojo/latency_info_struct_traits.h
+++ b/ui/latency/mojo/latency_info_struct_traits.h
@@ -11,8 +11,6 @@
 
 namespace mojo {
 
-using InputCoordinateArray = CArray<gfx::PointF>;
-
 template <>
 struct ArrayTraits<ui::LatencyInfo::LatencyMap> {
   using Element = ui::LatencyInfo::LatencyMap::value_type;
@@ -85,8 +83,6 @@
   static const std::string& trace_name(const ui::LatencyInfo& info);
   static const ui::LatencyInfo::LatencyMap& latency_components(
       const ui::LatencyInfo& info);
-  static uint32_t input_coordinates_size(const ui::LatencyInfo& info);
-  static InputCoordinateArray input_coordinates(const ui::LatencyInfo& info);
   static int64_t trace_id(const ui::LatencyInfo& info);
   static bool coalesced(const ui::LatencyInfo& info);
   static bool terminated(const ui::LatencyInfo& info);
diff --git a/ui/latency/mojo/struct_traits_unittest.cc b/ui/latency/mojo/struct_traits_unittest.cc
index 5a30329..0fdd7da 100644
--- a/ui/latency/mojo/struct_traits_unittest.cc
+++ b/ui/latency/mojo/struct_traits_unittest.cc
@@ -78,19 +78,13 @@
 TEST_F(StructTraitsTest, LatencyInfo) {
   LatencyInfo latency;
   ASSERT_FALSE(latency.terminated());
-  ASSERT_EQ(0u, latency.input_coordinates_size());
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 1234, 0);
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1234, 100);
   latency.AddLatencyNumber(INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT,
                            1234, 0);
-  EXPECT_TRUE(latency.AddInputCoordinate(gfx::PointF(100, 200)));
-  EXPECT_TRUE(latency.AddInputCoordinate(gfx::PointF(101, 201)));
-  // Up to 2 InputCoordinate is allowed.
-  EXPECT_FALSE(latency.AddInputCoordinate(gfx::PointF(102, 202)));
 
   EXPECT_EQ(100, latency.trace_id());
   EXPECT_TRUE(latency.terminated());
-  EXPECT_EQ(2u, latency.input_coordinates_size());
 
   mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
   LatencyInfo output;
@@ -98,13 +92,6 @@
 
   EXPECT_EQ(latency.trace_id(), output.trace_id());
   EXPECT_EQ(latency.terminated(), output.terminated());
-  EXPECT_EQ(latency.input_coordinates_size(), output.input_coordinates_size());
-  for (size_t i = 0; i < latency.input_coordinates_size(); i++) {
-    EXPECT_EQ(latency.input_coordinates()[i].x(),
-              output.input_coordinates()[i].x());
-    EXPECT_EQ(latency.input_coordinates()[i].y(),
-              output.input_coordinates()[i].y());
-  }
 
   EXPECT_TRUE(output.FindLatency(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 1234,
                                  nullptr));